Annotation of gforth/arch/mips/disasm.fs, revision 1.4

1.1       anton       1: \ disasm.fs    disassembler file (for MIPS R3000)
                      2: \
                      3: \ Copyright (C) 1995-97 Martin Anton Ertl, Christian Pirker
                      4: \
                      5: \ This file is part of RAFTS.
                      6: \
                      7: \      RAFTS is free software; you can redistribute it and/or
                      8: \      modify it under the terms of the GNU General Public License
                      9: \      as published by the Free Software Foundation; either version 2
                     10: \      of the License, or (at your option) any later version.
                     11: \
                     12: \      This program is distributed in the hope that it will be useful,
                     13: \      but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14: \      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15: \      GNU General Public License for more details.
                     16: \
                     17: \      You should have received a copy of the GNU General Public License
                     18: \      along with this program; if not, write to the Free Software
                     19: \      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     20: 
1.4     ! anton      21: \ this disassembler is based on data from the R4400 manual
        !            22: \ http://www.mips.com/Documentation/R4400_Uman_book_Ed2.pdf, in
        !            23: \ particular pages A3,A181,A182 (offset 468 pages in xpdf).
        !            24: \ it is limited to the R3000 (MIPS-I) architecture, though.
1.2       anton      25: 
1.4     ! anton      26: \ instruction fields
1.3       anton      27: 
                     28: : disasm-op ( w -- u )
                     29:     26 rshift ;
                     30: 
                     31: : disasm-rs ( w -- u )
                     32:     21 rshift $1F and ;
                     33: 
                     34: : disasm-rt ( w -- u )
                     35:     16 rshift $1f and ;
                     36: 
                     37: : disasm-rd ( w -- u )
                     38:     11 rshift $1f and ;
                     39: 
                     40: : disasm-shamt ( w -- u )
                     41:     \ shift amount field
                     42:     6 rshift $1f and ;
                     43: 
                     44: : disasm-funct ( w -- u )
                     45:     $3f and ;
                     46: 
                     47: : disasm-copz ( w -- u )
                     48:     disasm-op 3 and ;
                     49: 
                     50: : disasm-imm ( w -- n )
                     51:     $ffff and dup 15 rshift negate 15 lshift or ;
                     52: 
                     53: : disasm-relative ( addr n -- w )
                     54:     \ compute printable form of relative address n relative to addr
                     55:     nip ( + ) ;
                     56: 
1.4     ! anton      57: \ decode tables
        !            58: 
        !            59: : disasm-illegal ( addr w -- )
        !            60:     \ disassemble illegal/unknown instruction w at addr
        !            61:     hex. ." , ( illegal inst ) " drop ;
        !            62: 
        !            63: : disasm-table ( n "name" -- )
        !            64:     \ initialize table with n entries with disasm-illegal
        !            65:     create 0 ?do
        !            66:        ['] disasm-illegal ,
        !            67:     loop
        !            68: does> ( u -- addr )
        !            69:     swap cells + ;
        !            70: 
        !            71: $40 disasm-table opc-tab-entry     \ top-level decode table
        !            72: $40 disasm-table funct-tab-entry   \ special function table
        !            73: $20 disasm-table regimm-tab-entry  \ regim instructions rt table
        !            74: $20 disasm-table copz-rs-tab-entry \ COPz instructions rs table
        !            75: $20 disasm-table copz-rt-tab-entry \ COPz BC instructions rt table
        !            76: $40 disasm-table cp0-tab-entry     \ COP0 CO instructions funct table
        !            77: 
1.3       anton      78: \ disassembler central decode cascade
                     79: 
                     80: : disasm-inst ( addr w -- )
                     81:     \G disassemble instruction w at addr (addr is used for computing
                     82:     \G branch targets)
1.4     ! anton      83:     dup disasm-op opc-tab-entry @ execute ;
1.3       anton      84: 
                     85: : disasm-dump ( addr u -- ) \ gforth
                     86:     \G disassemble u aus starting at addr
                     87:     bounds u+do
                     88:        cr ." ( " i hex. ." ) " i i @ disasm-inst
                     89:        1 cells +loop ;
                     90: 
                     91: : disasm-special ( addr w -- )
                     92:     \ disassemble inst with opcode special
1.4     ! anton      93:     dup disasm-funct funct-tab-entry @ execute ;
        !            94: ' disasm-special 0 opc-tab-entry ! \ enter it for opcode special
1.3       anton      95: 
                     96: : disasm-regimm ( addr w -- )
                     97:     \ disassemble regimm inst
1.4     ! anton      98:     dup disasm-rt regimm-tab-entry @ execute ;
        !            99: ' disasm-regimm 1 opc-tab-entry ! \ enter it for opcode regimm
1.3       anton     100: 
                    101: : disasm-copz-rs ( addr w -- )
                    102:     \ disassemble inst with opcode COPz
1.4     ! anton     103:     dup disasm-rs copz-rs-tab-entry @ execute ;
        !           104: ' disasm-copz-rs $10 opc-tab-entry ! \ enter it for opcodes COPz
        !           105: ' disasm-copz-rs $11 opc-tab-entry !
        !           106: ' disasm-copz-rs $12 opc-tab-entry !
1.3       anton     107: 
                    108: : disasm-copz-rt ( addr w -- )
                    109:     \ disassemble inst with opcode COPz, rs=BC
1.4     ! anton     110:     dup disasm-rt copz-rt-tab-entry @ execute ;
        !           111: ' disasm-copz-rt $08 copz-rs-tab-entry ! \ into COPz-table for rs=BC
1.3       anton     112: 
                    113: : disasm-cp0 ( addr w -- )
                    114:     \ disassemble inst with opcode COPz, rs=CO
1.4     ! anton     115:     dup disasm-funct cp0-tab-entry @ execute ;
        !           116: ' disasm-cp0 $10 copz-rs-tab-entry ! \ into COPz-table for rs=CO
1.3       anton     117: 
1.4     ! anton     118: \ dummy words for insts.fs (words with these names are needed by asm.fs)
1.3       anton     119: 
                    120: : asm-op ( -- ) ;
1.4     ! anton     121: : asm-rs ( -- ) ;
        !           122: : asm-rt ( -- ) ;
        !           123: 
        !           124: \ disassemble various formats
1.3       anton     125: 
                    126: : disasm-J-target ( addr w -- )
                    127:     \ print jump target
                    128:     $3ffffff and swap $fc000000 and or hex. ;
                    129: 
                    130: : disasm-I-rs,rt,imm ( addr w -- )
                    131:     dup disasm-rs .
                    132:     dup disasm-rt .
                    133:     disasm-imm disasm-relative . ;
                    134: 
                    135: : disasm-I-rs,imm ( addr w -- )
                    136:     dup disasm-rs .
                    137:     disasm-imm disasm-relative . ;
                    138: 
                    139: : disasm-rt,rs,imm ( addr w -- )
                    140:     dup disasm-rt .
                    141:     dup disasm-rs .
                    142:     disasm-imm .
                    143:     drop ;
1.1       anton     144: 
1.3       anton     145: : disasm-rt,imm ( addr w -- )
                    146:     dup disasm-rt .
                    147:     disasm-imm .
1.1       anton     148:     drop ;
                    149: 
1.3       anton     150: : disasm-rt,imm,rs ( addr w -- )
                    151:     dup disasm-rt .
                    152:     dup disasm-imm .
                    153:     dup disasm-rs .
                    154:     2drop ;
                    155: 
                    156: : disasm-rd,rt,sa ( addr w -- )
                    157:     dup disasm-rd .
                    158:     dup disasm-rt .
                    159:     dup disasm-shamt .
                    160:     2drop ;
                    161: 
                    162: : disasm-rd,rt,rs ( addr w -- )
                    163:     dup disasm-rd .
                    164:     dup disasm-rt .
                    165:     dup disasm-rs .
                    166:     2drop ;
                    167: 
                    168: : disasm-rs. ( addr w -- )
                    169:     dup disasm-rs .
                    170:     2drop ;
                    171: 
                    172: : disasm-rd,rs ( addr w -- )
                    173:     dup disasm-rd .
                    174:     dup disasm-rs .
                    175:     2drop ;
                    176: 
                    177: : disasm-rd. ( addr w -- )
                    178:     dup disasm-rd .
                    179:     2drop ;
                    180: 
                    181: : disasm-rs,rt ( addr w -- )
                    182:     dup disasm-rs .
                    183:     dup disasm-rt .
                    184:     2drop ;
                    185: 
                    186: : disasm-rd,rs,rt ( addr w -- )
                    187:     dup disasm-rd .
                    188:     dup disasm-rs .
                    189:     dup disasm-rt .
                    190:     2drop ;
                    191: 
                    192: : disasm-rt,rd,z ( addr w -- )
                    193:     dup disasm-rt .
                    194:     dup disasm-rd .
                    195:     dup disasm-copz .
                    196:     2drop ;
                    197: 
1.4     ! anton     198: : disasm-I-imm ( addr w -- )
        !           199:     disasm-imm disasm-relative . ;
        !           200: 
        !           201: \ meta-defining word for instruction format disassembling definitions
        !           202: 
        !           203: \ The following word defines instruction-format words, which in turn
        !           204: \ define anonymous words for disassembling specific instructions and
        !           205: \ put them in the appropriate decode table.
        !           206: 
        !           207: : define-format ( disasm-xt table-xt -- )
        !           208:     \ define an instruction format that uses disasm-xt for
        !           209:     \ disassembling and enters the defined instructions into table
        !           210:     \ table-xt
        !           211:     create 2,
        !           212: does> ( u "inst" -- )
        !           213:     \ defines an anonymous word for disassembling instruction inst,
        !           214:     \ and enters it as u-th entry into table-xt
        !           215:     2@ swap here name string, ( u table-xt disasm-xt c-addr ) \ remember string
        !           216:     noname create 2,      \ define anonymous word
        !           217:     execute lastxt swap ! \ enter xt of defined word into table-xt
        !           218: does> ( addr w -- )
        !           219:     \ disassemble instruction w at addr
        !           220:     2@ >r ( addr w disasm-xt R: c-addr )
        !           221:     execute ( R: c-addr ) \ disassemble operands
        !           222:     r> count type ; \ print name 
        !           223: 
        !           224: \ all the following words have the stack effect ( u "name" )
        !           225: ' disasm-J-target    ' opc-tab-entry    define-format asm-J-target
        !           226: ' disasm-I-rs,rt,imm ' opc-tab-entry    define-format asm-I-rs,rt,imm
        !           227: ' disasm-I-rs,imm    ' opc-tab-entry    define-format asm-I-rs,imm1
        !           228: ' disasm-rt,rs,imm   ' opc-tab-entry    define-format asm-I-rt,rs,imm
        !           229: ' disasm-rt,imm      ' opc-tab-entry    define-format asm-I-rt,imm
        !           230: ' disasm-rt,imm,rs   ' opc-tab-entry    define-format asm-I-rt,offset,rs
        !           231: ' disasm-rd,rt,sa    ' funct-tab-entry          define-format asm-special-rd,rt,sa
        !           232: ' disasm-rd,rt,rs    ' funct-tab-entry          define-format asm-special-rd,rt,rs
        !           233: ' disasm-rs.         ' funct-tab-entry          define-format asm-special-rs
        !           234: ' disasm-rd,rs       ' funct-tab-entry          define-format asm-special-rd,rs
        !           235: ' 2drop              ' funct-tab-entry          define-format asm-special-nothing
        !           236: ' disasm-rd.         ' funct-tab-entry          define-format asm-special-rd
        !           237: ' disasm-rs,rt       ' funct-tab-entry          define-format asm-special-rs,rt
        !           238: ' disasm-rd,rs,rt    ' funct-tab-entry          define-format asm-special-rd,rs,rt
        !           239: ' disasm-I-rs,imm    ' regimm-tab-entry  define-format asm-regimm-rs,imm
        !           240: ' 2drop              ' cp0-tab-entry     define-format asm-copz0
        !           241: ' disasm-rt,rd,z     ' copz-rs-tab-entry define-format asm-copz-rt,rd1
        !           242: ' disasm-I-imm       ' copz-rt-tab-entry define-format asm-copz-imm1
        !           243: 
        !           244: : asm-I-rs,imm ( u1 u2 "name" -- ; compiled code: addr w -- )
        !           245:     nip asm-I-rs,imm1 ;
        !           246: 
1.3       anton     247: : asm-copz-rt,rd ( u1 u2 "name" -- )
1.4     ! anton     248:     drop asm-copz-rt,rd1 ;
1.3       anton     249: 
1.4     ! anton     250: : asm-copz-rt,offset,rs ( u "name" -- )
        !           251:     \ ignore these insts, we disassemble using  asm-I-rt,offset,rs
        !           252:     drop name 2drop ;
1.3       anton     253: 
                    254: : asm-copz-imm ( u1 u2 u3 "name" -- )
1.4     ! anton     255:     drop nip asm-copz-imm1 ;
1.1       anton     256: 
1.3       anton     257: include ./insts.fs

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