\ ========== Copyright Header Begin ==========================================
\ Hypervisor Software File: disforw.fth
\ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
\ - Do no alter or remove copyright notices
\ - Redistribution and use of this software in source and binary forms, with
\ or without modification, are permitted provided that the following
\ - Redistribution of source code must retain the above copyright notice,
\ this list of conditions and the following disclaimer.
\ - Redistribution in binary form must reproduce the above copyright notice,
\ this list of conditions and the following disclaimer in the
\ documentation and/or other materials provided with the distribution.
\ Neither the name of Sun Microsystems, Inc. or the names of contributors
\ may be used to endorse or promote products derived from this software
\ without specific prior written permission.
\ This software is provided "AS IS," without a warranty of any kind.
\ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
\ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
\ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
\ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
\ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
\ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
\ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
\ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
\ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
\ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
\ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
\ You acknowledge that this software is not designed, licensed or
\ intended for use in the design, construction, operation or maintenance of
\ ========== Copyright Header End ============================================
id: @(#)disforw.fth 2.31 06/04/21 17:08:22
purpose: SPARC disassembler - prefix syntax
copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved
copyright: Use is subject to license terms.
\ Copyright 1985-1990 Bradley Forthware
\ lddf disassembler needs to specify f register, not i register
\ ldxfsr is not properly disassembled
also disassembler also definitions
64\ true constant sparc-v9?
32\ false constant sparc-v9?
," %g0" ," %g1" ," %g2" ," %g3"
," %g4" ," %g5" ," %g6" ," %g7"
," %o0" ," %o1" ," %o2" ," %o3"
," %o4" ," %o5" ," %o6" ," %o7"
," %l0" ," %l1" ," %l2" ," %l3"
," %l4" ," %l5" ," %l6" ," %l7"
," %i0" ," %i1" ," %i2" ," %i3"
," %i4" ," %i5" ," %i6" ," %i7"
defer regs ' real-regs is regs
( 0 ) ," add" ," and" ," or" ," xor"
( 4 ) ," sub" ," andn" ," orn" ," xnor"
( 8 ) ," addx" ," mulx" ," umul" ," smul"
( c ) ," subx" ," udivx" ," udiv" ," sdiv"
( 10 ) ," addcc" ," andcc" ," orcc" ," xorcc"
( 14 ) ," subcc" ," andncc" ," orncc" ," xnorcc"
( 18 ) ," addxcc" ," ???" ," umulcc" ," smulcc"
( 1c ) ," subxcc" ," ???" ," udivcc" ," sdivcc"
( 20 ) ," taddcc" ," tsubcc" ," taddcctv" ," tsubcctv"
( 24 ) ," mulscc" ," sll" ," srl" ," sra"
( 28 ) ," rdasr" ," rdpsr" ," rdpr" ," rdtbr"
( 2c ) ," movcc" ," sdivx" ," popc" ," movr"
( 30 ) ," wrasr" ," wrpsr" ," wrpr" ," wrtbr"
( 34 ) ," fpop1" ," fpop2" ," cpop1" ," cpop2"
( 38 ) ," jmp" ," rett" ," ticc" ," iflush"
( 3c ) ," save" ," restore" ," ???"
( 0 ) ," ld" ," ldub" ," lduh" ," ldd"
( 4 ) ," st" ," stb" ," sth" ," std"
( 8 ) ," ldsw" ," ldsb" ," ldsh" ," ldx"
( c ) ," ???" ," ldstub" ," stx" ," swapl"
( 10 ) ," lda" ," lduba" ," lduha" ," ldda"
( 14 ) ," sta" ," stba" ," stha" ," stda"
( 18 ) ," ldswa" ," ldsba" ," ldsha" ," ldxa"
( 1c ) ," ???" ," ldstba" ," stxa" ," swapa"
( 20 ) ," ldf" ," ldfsr" ," ldqf" ," lddf"
32\ ( 24 ) ," stf" ," stfsr" ," stdfq" ," stdf"
64\ ( 24 ) ," stf" ," stfsr" ," stqf" ," stdf"
( 28 ) ," ???" ," ???" ," ???" ," ???"
( 2c ) ," ???" ," prefetch" ," ???" ," ???"
( 30 ) ," ldfa" ," ???" ," ldqfa" ," lddfa"
( 34 ) ," stfa" ," ???" ," stqfa" ," stdfa"
( 38 ) ," ???" ," ???" ," ???" ," ???"
( 3c ) ," casa" ," prefetcha" ," casxa" ," ???"
string-array fiops \ Op-field - 0xc0
," ???" ," fstoir" ," fdtoir" ," fxtoir"
," fitos" ," ???" ," fdtos" ," fxtos"
," fitod" ," fstod" ," ???" ," fxtod"
," fitox" ," fstox" ," fdtox" ," ???"
," ???" ," fstoi" ," fdtoi" ," fxtoi"
string-array f2ops \ Op-field - 0x40
," ???" ," fadds" ," faddd" ," faddx"
," ???" ," fsubs" ," fsubd" ," fsubx"
," ???" ," fmuls" ," fmuld" ," fmulx"
," ???" ," fdivs" ," fdivd" ," fdivx"
string-array f2ops+ \ Op-field - 0x60
," ???" ," ???" ," ???" ," ???"
," ???" ," ???" ," ???" ," ???"
," ???" ," fsmuld" ," ???" ," ???"
," ???" ," ???" ," fdmulx" ," ???"
string-array fcmpops \ Op-field - 0x50
," ???" ," fcmps" ," fcmpd" ," fcmpx"
," ???" ," fcmpes" ," fcmped" ," fcmpex"
string-array conds \ Conditional names for integer branches and traps
( 0 ) ," n" ," e" ," le" ," l" ," leu" ," cs" ," neg" ," vs"
( 8 ) ," a" ," ne" ," gt" ," ge" ," gu" ," cc" ," pos" ," vc"
string-array fconds \ Conditional names for floating point branches
( 0 ) ," n" ," ne" ," lg" ," ul" ," l" ," ug" ," g" ," u"
( 8 ) ," a" ," e" ," ue" ," ge" ," uge" ," le" ," ule" ," o"
string-array cconds \ Conditional names for coprocessor branches
( 0 ) ," n" ," 123" ," 12" ," 13" ," 1" ," 23" ," 2" ," 3"
( 8 ) ," a" ," 0" ," 03" ," 02" ," 023" ," 01" ," 013" ," 012"
string-array rconds \ Conditional names for BPr MOVr and FMOVr
," ??" ," z" ," lez" ," lz" ," ??" ," nz" ," gz" ," gez"
\ Generates a mask with #bits set in the low part. 4 >mask yields 0000000f
variable display-offset 0 display-offset !
variable branch-target \ Help for tracing/single-stepping
variable alternate? alternate? off
variable max-branch-target \ Help determine if end was found
: (inst@ ( adr -- opcode ) l@ ;
defer inst@ ' (inst@ is inst@
: pc@l@ ( -- opcode ) pc@ inst@ ;
: 4u# ( n -- n' ) u# u# u# u# ;
: 4u#. ( n -- n' ) 4u# ascii . hold ;
defer showaddr ( addr -- )
[ /n /l > [if] ] \ Compile-time test; do we need two more of these?
: +offset ( adr -- adr' ) display-offset @ - ;
: >mask ( #bits -- mask ) 1 swap << 1- ;
: bits ( right-bit #bits -- field )
instruction @ rot >> ( mask shifted-instruction )
: 5bits ( right-bit -- field ) 5 bits ;
: rd ( -- field ) d# 25 5bits ;
: rs1 ( -- field ) d# 14 5bits ;
: rs2 ( -- field ) 0 5bits ;
: shcnt ( -- field ) 0 6 bits ;
: bit? ( bit# -- f ) instruction @ 1 rot << and ;
: bit13? ( -- flag ) d# 13 bit? ;
: bit12? ( -- flag ) d# 12 bit? ;
: op-col ( -- ) start-column @ d# 12 + to-column ;
: .reg ( n -- ) regs ". ;
: .asreg ( n -- ) ." %r" .d ;
: >freg ( n mask -- freg# )
: .creg ( n -- ) ." %c" .d ;
: .frsrd ( -- ) rs2 .freg ., rd .freg ;
: .3fregs ( -- ) rs1 .freg ., .frsrd ;
: op.3fregs ( -- ) op-col .3fregs ;
: .frs1rs2 ( -- ) rs1 .freg ., rs2 .freg ;
: op.rd ( -- ) op-col .rd ;
: sext ( n wid' -- n' ) tuck << l->n swap >>a ; \ Sign extend
\ Extract the Sign-Extended immediate field (starting at bit-position zero)
\ Three popular sizes of Sign-Extended immediate fields:
: immedop ( -- n ) d# 13 simm# ;
: simm10 ( -- n ) d# 10 simm# ;
: simm11 ( -- n ) d# 11 simm# ;
\ Stuff the branch-target and update the max-branch-target
: branch-target! ( targ-addr -- )
dup branch-target ! ( targ-addr )
max-branch-target @ umax max-branch-target !
\ An unconditional ("always") branch ends the disassembly
\ if there are no branch-targets forward of its location.
pc@ max-branch-target @ >= end-found !
: .rs2 ( -- ) bit13? if immedop (u.) type else rs2 .reg then ;
: .src ( -- ) .rs1 ., .rs2 .?asi ;
: op.src ( -- ) op-col .src ;
: .illegal ( -- ) ." Illegal instruction: " instruction @ u. ;
: opcode ( -- n ) d# 19 6 bits ;
opcode h# 3d and h# 3c = if
dup 0> if ." + " else ." - " then abs (.) type
rs2 ?dup if ." + " .reg then
defer .impl-asi-ea ' .ea-sparc is .impl-asi-ea
\ This may get re-vectored for variant implementations.
\ Non-implementation-dependent or reserved ASIs are:
\ 10, 11, 18, 19, 80..83, and 88..bf
\ (Ref: SPARC Arch. Manual, sec 6.3.1.3, Table 12)
: ea-sparc? ( -- Use-.ea-sparc? )
" "( 10 11 18 19 80 81 82 83 )" \ Inconveniently-grouped-ASI-list
rot scantochar <> nip ( asi match? )
if .ea-sparc else .impl-asi-ea then
\ The condition-code field may occur in either of two
\ bit-positions within an instruction.
\ Take the bit-position as a parameter and print the
\ integer conditional name
: .#cond ( bit# -- ) 4 bits conds ". ;
: .cond ( -- ) d# 25 .#cond ;
: .rcond ( n -- ) rconds ". ;
\ Likewise the floating point conditional name
: .#fcond ( bit# -- ) 4 bits fconds ". ;
: .(op2) ( -- ) opcode op2s ". ;
: .op2 ( -- ) .(op2) op-col ;
: .frs1rs2-double ( -- ) rs1 .freg-double ., rs2 .freg-double ;
: .3fregs-double ( -- ) .frs1rs2-double ., rd .freg-double ;
h# 23 of .freg-double endof \ double operation
h# 22 of .freg-quad endof \ quad
opcode dup op3s ". op-col ( op-code )
\ XXX Is the next line correct for the "ldc" class of instruction?
dup h# 10 and if alternate? on then
." [" .rs1 ." ] " .?asi ., .rs2 ., .rd
swap h# 2f and h# 0e = or
if .r/fd ., .ea else .ea ., .r/fd then
: fp-op ( -- n ) 5 9 bits ;
: op.frsrd ( -- ) op-col .frsrd ;
fp-op h# c0 h# d3 between if \ Type conversion operators
fp-op h# c0 - fiops ". op.frsrd
fp-op h# 40 h# 4f between if \ Arithmetic operators
fp-op h# 40 - f2ops ". op.3fregs
fp-op h# 60 h# 6f between if \ More arithmetic operators
fp-op h# 60 - f2ops+ ". op.3fregs
fp-op case \ Miscellaneous operators
1 of ." fmovs" op.frsrd endof
5 of ." fnegs" op.frsrd endof
9 of ." fabss" op.frsrd endof
h# 29 of ." fsqrts" op.frsrd endof
h# 2a of ." fsqrtd" op.frsrd endof
h# 2b of ." fsqrtx" op.frsrd endof
fp-op h# 50 - fcmpops ". op-col .frs1rs2
: .stbar ( -- ) ." stbar" ;
: .wry ( -- ) ." wry" op.src ;
: .rdy ( -- ) ." rdy" op.rd ;
: .op2+src+dest ( -- ) .op2 .src ., .rd ;
: .op2-wra ( -- ) .op2+src+dest .asreg ;
: .op2-rda ( -- ) .op2 rs1 .asreg ., .rd ;
defer .impl-wrasr ' .illegal is .impl-wrasr
defer .impl-rdasr ' .illegal is .impl-rdasr
rd d# 16 d# 31 between if
2 of ." wrccr" op.src endof
3 of ." wrasi" op.src endof
6 of ." wrfprs" op.src endof
: .wrasr ( -- ) sparc-v9? if .wrasr-v9 else .wrasr-v8 then ;
rs1 d# 16 d# 31 between if
2 of ." rdccr" op.rd endof
3 of ." rdasi" op.rd endof
4 of ." rdtick" op.rd endof
5 of ." rdpc" op.rd endof
6 of ." rdfprs" op.rd endof
: .rdasr ( -- ) sparc-v9? if .rdasr-v9 else .rdasr-v8 then ;
: .shift ( -- ) \ Called when opcode is between h# 25 thru h# 27
.(op2) bit12? if ." x" then
op-col .rs1 ., shcnt bit13? if
bit12? if h# 3f else h# 1f then and (u.) type
," tpc" ," tnpc" ," tstate" ," tt"
," tick" ," tba" ," pstate" ," tl"
," pil" ," cwp" ," cansave" ," canrestore"
," cleanwin" ," otherwin" ," wstate" ," fq"
." rd" rs1 priv-regs ". op.rd exit
." wr" rd priv-regs ". op.src exit
\ Depending upon the rcond field in the instruction, generate
\ appropriate instruction:
\ rcond=001b movrz; rcond=010b movrlez; rcond=011b movrlz
\ rcond=101b movrnz; rcond=110b movrgz; rcond=111b movrgez
\ rcond=000b or 100b (reserved) movr???
." movr" d# 10 3 bits .rcond op-col .rs1 ., bit13? if
\ The cc1|cc0 field may occur in either of two
\ bit-positions within an instruction.
\ Take the bit-position as a parameter and show the field
0= if ." %icc" else ." ???" then
\ Show the cc1|cc0 field of a Class 0, Format 2
\ instruction, (branches Bicc BPcc, BPr, etc.)
\ where it occurs in bit-position d# 20
\ Show the cc1|cc0 field of a Class 2, Format 4
\ instruction, (traps Tcc and MOVcc, FMOVcc)
\ where it occurs in bit-position d# 11
: .txcc ( -- ) d# 11 .#xcc ;
\ Show the Tcc instruction
\ Extract bits 0..10 as a "simm11" field.
\ Bits 7..10 are reserved.
\ Let's show what's actually there.
\ Alternatively, we could highlight an error, thus:
\ h# 780 and if ." "t"t\ Illegal Trap #" then
\ Condition field of a MOVcc or MOVFcc instruction
d# 14 \ bit-position where it occurs
." mov" .(mov)cond op-col
else d# 11 2 bits ." %fcc" 1 .r .,
." popc" op-col .rs2 ., .rd
defer .impdep1 ' .illegal is .impdep1
defer .impdep2 ' .illegal is .impdep2
opcode h# 38 h# 39 between end-found !
opcode h# 25 h# 27 between if .shift exit then
h# 29 of .op2 .rd endof \ RDPSR
sparc-v9? if .rdpr else ." rdwim" op.rd then
sparc-v9? if .wrpr else ." wrwim" op.src then
h# 33 of .op2 .src endof \ WRTBR
?end-found end-found @ is annulled?
end-found off false is annulled?
( default ) .op2+src+dest
\ Given a signed immediate, show it as a displacement
\ Also works for a call instruction, which uses
\ all but its upper two bits for the offset.
: .disp ( simm|call-instruction -- )
2 << \ Convert longword offset to byte offset
l->n \ Make sure it's sign-extended...
dup branch-target! \ Might advance max-branch-target
0 d# 14 bits d# 20 2 bits d# 14 << or ( n=16bits )
d# 16 ( n wid' ) \ wid=16 which happens to equal wid' (32 - wid)
." sethi" op-col instruction @ d# 10 << n->l (u.) type ., .rd
end-found on false is annulled?
\ Extract the condition field of a Bcc, BPcc, FBcc or CBcc instruction
\ For unconditional ("always") branch, check for end of disassembly
: (bra)cond@ ( -- condition-code )
d# 25 4 bits ( condition-code )
dup 8 = if ?end-found then ( ) \ cc = 8 ==> "always"
\ Display the "annulled" field (bit 29) of a branch instruction.
\ Also, if the branch that ends the disassembly is annulled,
\ suppress displaying the -- possibly non-valid -- non-executed
: .annul ( -- ) d# 29 bit? dup is annulled? if ." ,a" then ;
\ Common routine to print the condition-field extracted above,
\ after the appropriate condition-list's string-array has been
\ invoked. Annul bit (29) is also shared with the Bcc, BPcc,
\ FBcc and CBcc instructions, but BPcc differs from the others
\ in that it uses 19-bit instead of 22-bit displacement.
: .(cond) ( p$addr -- ) ". .annul ;
\ Common part of Bcc and BPcc
: .(bra)cond ( -- ) (bra)cond@ conds .(cond) ;
: .bcc ( -- ) ." b" .(bra)cond .disp22 ;
: .fbcc ( -- ) ." fb" (bra)cond@ fconds .(cond) .disp22 ;
: .predict ( -- ) d# 19 bit? if ." ,pt" else ." ,pn" then ;
: .bpcc ( -- ) ." bp" .(bra)cond .predict op-col .cc .disp19 ;
." bpr" d# 25 3 bits .rcond
: .fbpfcc ( -- ) ." fbp %fcc XXX " ;
: .cbcc ( -- ) ." cb" (bra)cond@ cconds .(cond) .disp22 ;
0 of sparc-v9? if ." illtrap" else ." unimp" then endof
1 of sparc-v9? if .bpcc else .illegal then endof
3 of sparc-v9? if .bpr else .illegal then endof
5 of sparc-v9? if .fbpfcc else .illegal then endof
7 of sparc-v9? if .illegal else .cbcc then endof
\ Common code for disassembler access, independent of vectoring of inst@
pc@ +offset showaddr 4 spaces #out @ start-column !
end-found off max-branch-target off
begin (dis1) end-found @ exit? or until
annulled? 0= if (dis1) then \ Disassemble the delay instruction too
previous previous definitions