Diff for /gforth/arch/mips/disasm.fs between versions 1.3 and 1.16

version 1.3, 2000/06/01 21:04:26 version 1.16, 2010/12/31 18:09:02
Line 1 Line 1
 \ disasm.fs     disassembler file (for MIPS R3000)  \ disasm.fs     disassembler file (for MIPS32)
 \  \
 \ Copyright (C) 1995-97 Martin Anton Ertl, Christian Pirker  \ Copyright (C) 2000,2007,2010 Free Software Foundation, Inc.
 \  
 \ This file is part of RAFTS.  
 \  
 \       RAFTS is free software; you can redistribute it and/or  
 \       modify it under the terms of the GNU General Public License  
 \       as published by the Free Software Foundation; either version 2  
 \       of the License, or (at your option) any later version.  
 \  
 \       This program is distributed in the hope that it will be useful,  
 \       but WITHOUT ANY WARRANTY; without even the implied warranty of  
 \       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
 \       GNU General Public License for more details.  
 \  
 \       You should have received a copy of the GNU General Public License  
 \       along with this program; if not, write to the Free Software  
 \       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
   
 : disasm-illegal ( addr w -- )  \ This file is part of Gforth.
     \ disassemble illegal instruction w at addr  
     hex. ." , ( illegal inst ) " drop ;  
   
 : init-disasm-table ( n -- )  \ Gforth is free software; you can redistribute it and/or
     \ initialize table with n entries with disasm-illegal  \ modify it under the terms of the GNU General Public License
     0 ?do  \ as published by the Free Software Foundation, either version 3
         ['] disasm-illegal ,  \ of the License, or (at your option) any later version.
     loop ;  
   
 create opc-table $40 init-disasm-table \ top-level decode table  \ This program is distributed in the hope that it will be useful,
 create funct-table $40 init-disasm-table \ special function table  \ but WITHOUT ANY WARRANTY; without even the implied warranty of
 create regimm-table $20 init-disasm-table \ regim instructions rt field  \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 create copz-rs-table $20 init-disasm-table \ COPz instructions rs field  \ GNU General Public License for more details.
 create copz-rt-table $20 init-disasm-table \ COPz instructions rt field  
 create cp0-table $40 init-disasm-table \ COP0 function table  
   
 \ fields  \ You should have received a copy of the GNU General Public License
   \ along with this program. If not, see http://www.gnu.org/licenses/.
   
   \ this disassembler is based on data from the R4400 manual
   \ http://www.mips.com/Documentation/R4400_Uman_book_Ed2.pdf, in
   \ particular pages A3, A181, A182 (p. 471, 649, 650 in xpdf).
   \ it is limited to the R3000 (MIPS-I) architecture, though.
   
   \ test this with
   \ gforth arch/mips/disasm.fs -e "here" arch/mips/testdisasm.fs -e "here over - disasm bye" |sed 's/([^)]*) //'|diff -u - arch/mips/testasm.fs
   
   get-current
   vocabulary disassembler
   also disassembler definitions
   
   \ instruction fields
   
 : disasm-op ( w -- u )  : disasm-op ( w -- u )
     26 rshift ;      26 rshift ;
Line 59  create cp0-table $40 init-disasm-table \ Line 53  create cp0-table $40 init-disasm-table \
 : disasm-copz ( w -- u )  : disasm-copz ( w -- u )
     disasm-op 3 and ;      disasm-op 3 and ;
   
   : disasm-uimm ( w -- u )
       $ffff and ;
   
 : disasm-imm ( w -- n )  : disasm-imm ( w -- n )
     $ffff and dup 15 rshift negate 15 lshift or ;      disasm-uimm dup 15 rshift negate 15 lshift or ;
   
 : disasm-relative ( addr n -- w )  : disasm-relative ( addr n -- w )
     \ compute printable form of relative address n relative to addr      \ compute printable form of relative address n relative to addr
     nip ( + ) ;      2 lshift nip ( + ) ;
   
   \ decode tables
   
   : disasm-illegal ( addr w -- )
       \ disassemble illegal/unknown instruction w at addr
       hex. ." , ( illegal inst ) " drop ;
   
   : disasm-table ( n "name" -- )
       \ initialize table with n entries with disasm-illegal
       create 0 ?do
           ['] disasm-illegal ,
       loop
   does> ( u -- addr )
       swap cells + ;
   
   $40 disasm-table opc-tab-entry     \ top-level decode table
   $40 disasm-table funct-tab-entry   \ special function table
   $40 disasm-table funct-tab2-entry  \ special2 function table
   $20 disasm-table regimm-tab-entry  \ regim instructions rt table
   $20 disasm-table copz-rs-tab-entry \ COPz instructions rs table
   $20 disasm-table copz-rt-tab-entry \ COPz BC instructions rt table
   $40 disasm-table cp0-tab-entry     \ COP0 CO instructions funct table
   
 \ disassembler central decode cascade  \ disassembler central decode cascade
   
   dup set-current
   
 : disasm-inst ( addr w -- )  : disasm-inst ( addr w -- )
     \G disassemble instruction w at addr (addr is used for computing      \G disassemble instruction w at addr (addr is used for computing
     \G branch targets)      \G branch targets)
     dup disasm-op cells opc-table + @ execute ;      dup disasm-op opc-tab-entry @ execute ;
   
 : disasm-dump ( addr u -- ) \ gforth  : disasm ( addr u -- ) \ gforth
     \G disassemble u aus starting at addr      \G disassemble u aus starting at addr
     bounds u+do      bounds u+do
         cr ." ( " i hex. ." ) " i i @ disasm-inst          cr ." ( " i hex. ." ) " i i ul@ disasm-inst
         1 cells +loop ;          4 +loop
       cr ;
   
   ' disasm IS discode
   
   definitions
   
 : disasm-special ( addr w -- )  : disasm-special ( addr w -- )
     \ disassemble inst with opcode special      \ disassemble inst with opcode special
     dup disasm-funct cells funct-table + @ execute ;      dup disasm-funct funct-tab-entry @ execute ;
 ' disasm-special 0 cells opc-table + !  ' disasm-special 0 opc-tab-entry ! \ enter it for opcode special
   
   : disasm-special2 ( addr w -- ) \ todo factor out!
       \ disassemble inst with opcode special2
       dup disasm-funct funct-tab2-entry @ execute ;
   ' disasm-special2 $1C opc-tab-entry ! \ enter it for opcode special
   
 : disasm-regimm ( addr w -- )  : disasm-regimm ( addr w -- )
     \ disassemble regimm inst      \ disassemble regimm inst
     dup disasm-rt cells regimm-table + @ execute ;      dup disasm-rt regimm-tab-entry @ execute ;
 ' disasm-regimm 1 cells opc-table + !  ' disasm-regimm 1 opc-tab-entry ! \ enter it for opcode regimm
   
 : disasm-copz-rs ( addr w -- )  : disasm-copz-rs ( addr w -- )
     \ disassemble inst with opcode COPz      \ disassemble inst with opcode COPz
     dup disasm-rs cells copz-rs-table + @ execute ;      dup disasm-rs copz-rs-tab-entry @ execute ;
 ' disasm-copz-rs $10 cells opc-table + !  ' disasm-copz-rs $10 opc-tab-entry ! \ enter it for opcodes COPz
 ' disasm-copz-rs $11 cells opc-table + !  ' disasm-copz-rs $11 opc-tab-entry !
 ' disasm-copz-rs $12 cells opc-table + !  ' disasm-copz-rs $12 opc-tab-entry !
   
 : disasm-copz-rt ( addr w -- )  : disasm-copz-rt ( addr w -- )
     \ disassemble inst with opcode COPz, rs=BC      \ disassemble inst with opcode COPz, rs=BC
     dup disasm-rt cells copz-rt-table + @ execute ;      dup disasm-rt copz-rt-tab-entry @ execute ;
 ' disasm-copz-rt $08 cells copz-rs-table + !  ' disasm-copz-rt $08 copz-rs-tab-entry ! \ into COPz-table for rs=BC
   
 : disasm-cp0 ( addr w -- )  : disasm-cp0 ( addr w -- )
     \ disassemble inst with opcode COPz, rs=CO      \ disassemble inst with opcode COPz, rs=CO
     dup disasm-funct cells cp0-table + @ execute ;      dup disasm-funct cp0-tab-entry @ execute ;
 ' disasm-cp0 $10 cells copz-rs-table + !  ' disasm-cp0 $10 copz-rs-tab-entry ! \ into COPz-table for rs=CO
   
 \ disassemble various formats  \ dummy words for insts.fs (words with these names are needed by asm.fs)
   
 : asm-op ( -- ) ;  : asm-op ( -- ) ;
   : asm-rs ( -- ) ;
   : asm-rt ( -- ) ;
   
   \ disassemble various formats
   
 : disasm-J-target ( addr w -- )  : disasm-J-target ( addr w -- )
     \ print jump target      \ print jump target
     $3ffffff and swap $fc000000 and or hex. ;      2 lshift $0fffffff and swap $f0000000 and or hex. ;
   
 : asm-J-target ( u "inst" -- ; compiled code: addr w -- )  
     \ disassemble jump inst with opcode u  
     :noname POSTPONE disasm-J-target  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells opc-table + ! ;  
   
 : disasm-I-rs,rt,imm ( addr w -- )  : disasm-I-rs,rt,imm ( addr w -- )
     dup disasm-rs .      dup disasm-rs .
     dup disasm-rt .      dup disasm-rt .
     disasm-imm disasm-relative . ;      disasm-imm disasm-relative . ;
   
 : asm-I-rs,rt,imm ( u "name" -- ; compiled code: addr w -- )  
     :noname POSTPONE disasm-I-rs,rt,imm  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells opc-table + ! ;  
   
 : asm-rt ( -- ) ;  
   
 : disasm-I-rs,imm ( addr w -- )  : disasm-I-rs,imm ( addr w -- )
     \ !! does not check for correctly set rt ( should be 0 )  
     dup disasm-rs .      dup disasm-rs .
     disasm-imm disasm-relative . ;      disasm-imm disasm-relative . ;
   
 : asm-I-rs,imm ( u1 u2 "name" -- ; compiled code: addr w -- )  
     :noname POSTPONE disasm-I-rs,imm  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells opc-table + ! ;  
   
 : disasm-rt,rs,imm ( addr w -- )  : disasm-rt,rs,imm ( addr w -- )
     dup disasm-rt .      dup disasm-rt .
     dup disasm-rs .      dup disasm-rs .
     disasm-imm .      disasm-imm .
     drop ;      drop ;
   
 : asm-I-rt,rs,imm ( u "name" -- ; compiled code: addr w -- )  : disasm-rt,rs,uimm ( addr w -- )
     :noname POSTPONE disasm-rt,rs,imm  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells opc-table + ! ;  
   
 : disasm-rt,imm ( addr w -- )  
     dup disasm-rt .      dup disasm-rt .
     disasm-imm .      dup disasm-rs .
       disasm-uimm hex.
     drop ;      drop ;
   
 : asm-I-rt,imm ( u "name" -- ; compiled code: addr w -- )  : disasm-rt,uimm ( addr w -- )
     :noname POSTPONE disasm-rt,imm      dup disasm-rt .
     name POSTPONE sliteral POSTPONE type POSTPONE ;      disasm-uimm hex.
     swap cells opc-table + ! ;      drop ;
   
 : disasm-rt,imm,rs ( addr w -- )  : disasm-rt,imm,rs ( addr w -- )
     dup disasm-rt .      dup disasm-rt .
Line 169  create cp0-table $40 init-disasm-table \ Line 181  create cp0-table $40 init-disasm-table \
     dup disasm-rs .      dup disasm-rs .
     2drop ;      2drop ;
   
 : asm-I-rt,offset,rs ( u "name" -- ; compiled code: addr w -- )  
     :noname POSTPONE disasm-rt,imm,rs  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells opc-table + ! ;  
   
 : disasm-rd,rt,sa ( addr w -- )  : disasm-rd,rt,sa ( addr w -- )
     dup disasm-rd .      dup disasm-rd .
     dup disasm-rt .      dup disasm-rt .
     dup disasm-shamt .      dup disasm-shamt .
     2drop ;      2drop ;
   
 : asm-special-rd,rt,sa ( u "name" -- ; compiled code: addr w -- )  
     :noname POSTPONE disasm-rd,rt,sa  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells funct-table + ! ;  
   
 : disasm-rd,rt,rs ( addr w -- )  : disasm-rd,rt,rs ( addr w -- )
     dup disasm-rd .      dup disasm-rd .
     dup disasm-rt .      dup disasm-rt .
     dup disasm-rs .      dup disasm-rs .
     2drop ;      2drop ;
   
 : asm-special-rd,rt,rs ( u "name" -- ; compiled code: addr w -- )  
     :noname POSTPONE disasm-rd,rt,rs  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells funct-table + ! ;  
   
 : disasm-rs. ( addr w -- )  : disasm-rs. ( addr w -- )
     dup disasm-rs .      dup disasm-rs .
     2drop ;      2drop ;
   
 : asm-special-rs ( u "name" -- ; compiled code: addr w -- )  
     :noname POSTPONE disasm-rs.  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells funct-table + ! ;  
   
 : disasm-rd,rs ( addr w -- )  : disasm-rd,rs ( addr w -- )
     dup disasm-rd .      dup disasm-rd .
     dup disasm-rs .      dup disasm-rs .
     2drop ;      2drop ;
   
 : asm-special-rd,rs ( u "name" -- ; compiled code: addr w -- )  
     :noname POSTPONE disasm-rd,rs  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells funct-table + ! ;  
   
 : asm-special-nothing ( u "name" -- ; compiled code: addr w -- )  
     :noname POSTPONE 2drop  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells funct-table + ! ;  
   
 : disasm-rd. ( addr w -- )  : disasm-rd. ( addr w -- )
     dup disasm-rd .      dup disasm-rd .
     2drop ;      2drop ;
   
 : asm-special-rd ( u "name" -- ; compiled code: addr w -- )  
     :noname POSTPONE disasm-rd.  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells funct-table + ! ;  
   
 : disasm-rs,rt ( addr w -- )  : disasm-rs,rt ( addr w -- )
     dup disasm-rs .      dup disasm-rs .
     dup disasm-rt .      dup disasm-rt .
     2drop ;      2drop ;
   
 : asm-special-rs,rt ( u "name" -- ; compiled code: addr w -- )  
     :noname POSTPONE disasm-rs,rt  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells funct-table + ! ;  
   
 : disasm-rd,rs,rt ( addr w -- )  : disasm-rd,rs,rt ( addr w -- )
     dup disasm-rd .      dup disasm-rd .
     dup disasm-rs .      dup disasm-rs .
     dup disasm-rt .      dup disasm-rt .
     2drop ;      2drop ;
   
 : asm-special-rd,rs,rt ( u "name" -- ; compiled code: addr w -- )  
     :noname POSTPONE disasm-rd,rs,rt  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells funct-table + ! ;  
   
 : asm-regimm-rs,imm ( u "name" -- )  
     :noname POSTPONE disasm-I-rs,imm  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells regimm-table + ! ;  
   
 : asm-copz-rt,offset,rs ( u "name" -- )  
     \ ignore these insts, we disassemble using  asm-I-rt,offset,rs  
     drop name 2drop ;  
   
 : asm-copz0 ( u "name" -- )  
     :noname POSTPONE 2drop  
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells cp0-table + ! ;  
   
 $00 constant asm-copz-MF  
 $02 constant asm-copz-CF  
 $04 constant asm-copz-MT  
 $06 constant asm-copz-CT  
 $08 constant asm-copz-BC  
 $10 constant asm-copz-C0  
   
 $00 constant asm-copz-BCF  
 $01 constant asm-copz-BCT  
   
 : asm-rs ( -- ) ;  
   
 : disasm-rt,rd,z ( addr w -- )  : disasm-rt,rd,z ( addr w -- )
     dup disasm-rt .      dup disasm-rt .
     dup disasm-rd .      dup disasm-rd .
     dup disasm-copz .      dup disasm-copz .
     2drop ;      2drop ;
   
   : disasm-I-imm,z ( addr w -- )
       tuck disasm-imm disasm-relative .
       disasm-copz . ;
   
   \ meta-defining word for instruction format disassembling definitions
   
   \ The following word defines instruction-format words, which in turn
   \ define anonymous words for disassembling specific instructions and
   \ put them in the appropriate decode table.
   
   : define-format ( disasm-xt table-xt -- )
       \ define an instruction format that uses disasm-xt for
       \ disassembling and enters the defined instructions into table
       \ table-xt
       create 2,
   does> ( u "inst" -- )
       \ defines an anonymous word for disassembling instruction inst,
       \ and enters it as u-th entry into table-xt
       2@ swap here name string, ( u table-xt disasm-xt c-addr ) \ remember string
       noname create 2,      \ define anonymous word
       execute lastxt swap ! \ enter xt of defined word into table-xt
   does> ( addr w -- )
       \ disassemble instruction w at addr
       2@ >r ( addr w disasm-xt R: c-addr )
       execute ( R: c-addr ) \ disassemble operands
       r> count type ; \ print name 
   
   \ all the following words have the stack effect ( u "name" )
   ' disasm-J-target    ' opc-tab-entry     define-format asm-J-target
   ' disasm-I-rs,rt,imm ' opc-tab-entry     define-format asm-I-rs,rt,imm
   ' disasm-I-rs,imm    ' opc-tab-entry     define-format asm-I-rs,imm1
   ' disasm-rt,rs,imm   ' opc-tab-entry     define-format asm-I-rt,rs,imm
   ' disasm-rt,rs,uimm   ' opc-tab-entry    define-format asm-I-rt,rs,uimm
   ' disasm-rt,uimm      ' opc-tab-entry    define-format asm-I-rt,uimm
   ' disasm-rt,imm,rs   ' opc-tab-entry     define-format asm-I-rt,offset,rs
   ' disasm-rd,rt,sa    ' funct-tab-entry   define-format asm-special-rd,rt,sa
   ' disasm-rd,rt,rs    ' funct-tab-entry   define-format asm-special-rd,rt,rs
   ' disasm-rs.         ' funct-tab-entry   define-format asm-special-rs
   ' disasm-rd,rs       ' funct-tab-entry   define-format asm-special-rd,rs
   ' 2drop              ' funct-tab-entry   define-format asm-special-nothing
   ' disasm-rd.         ' funct-tab-entry   define-format asm-special-rd
   ' disasm-rs,rt       ' funct-tab-entry   define-format asm-special-rs,rt
   ' disasm-rd,rs,rt    ' funct-tab-entry   define-format asm-special-rd,rs,rt
   ' disasm-rd,rs       ' funct-tab2-entry  define-format asm-special2-rd,rs
   ' disasm-rs,rt       ' funct-tab2-entry  define-format asm-special2-rs,rt
   ' disasm-rd,rs,rt    ' funct-tab2-entry  define-format asm-special2-rd,rs,rt
   ' disasm-I-rs,imm    ' regimm-tab-entry  define-format asm-regimm-rs,imm
   ' 2drop              ' cp0-tab-entry     define-format asm-copz0
   ' disasm-rt,rd,z     ' copz-rs-tab-entry define-format asm-copz-rt,rd1
   ' disasm-I-imm,z     ' copz-rt-tab-entry define-format asm-copz-imm1
   
   : asm-I-rs,imm ( u1 u2 "name" -- ; compiled code: addr w -- )
       nip asm-I-rs,imm1 ;
   
 : asm-copz-rt,rd ( u1 u2 "name" -- )  : asm-copz-rt,rd ( u1 u2 "name" -- )
     drop :noname POSTPONE disasm-rt,rd,z      drop asm-copz-rt,rd1 ;
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells copz-rs-table + ! ;  
   
 : disasm-I-imm ( addr w -- )  : asm-copz-rt,offset,rs ( u "name" -- )
     disasm-imm disasm-relative . ;      \ ignore these insts, we disassemble using  asm-I-rt,offset,rs
       drop name 2drop ;
   
 : asm-copz-imm ( u1 u2 u3 "name" -- )  : asm-copz-imm ( u1 u2 u3 "name" -- )
     drop nip :noname POSTPONE disasm-I-imm      drop nip asm-copz-imm1 ;
     name POSTPONE sliteral POSTPONE type POSTPONE ;  
     swap cells copz-rt-table + ! ;  
   
 include ./insts.fs  include ./insts.fs
   
   previous set-current

Removed from v.1.3  
changed lines
  Added in v.1.16


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>