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>