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:
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 (p. 471, 649, 650 in xpdf).
24: \ it is limited to the R3000 (MIPS-I) architecture, though.
25:
26: \ instruction fields
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-uimm ( w -- u )
51: $ffff and ;
52:
53: : disasm-imm ( w -- n )
54: disasm-uimm dup 15 rshift negate 15 lshift or ;
55:
56: : disasm-relative ( addr n -- w )
57: \ compute printable form of relative address n relative to addr
58: 2 lshift nip ( + ) ;
59:
60: \ decode tables
61:
62: : disasm-illegal ( addr w -- )
63: \ disassemble illegal/unknown instruction w at addr
64: hex. ." , ( illegal inst ) " drop ;
65:
66: : disasm-table ( n "name" -- )
67: \ initialize table with n entries with disasm-illegal
68: create 0 ?do
69: ['] disasm-illegal ,
70: loop
71: does> ( u -- addr )
72: swap cells + ;
73:
74: $40 disasm-table opc-tab-entry \ top-level decode table
75: $40 disasm-table funct-tab-entry \ special function table
76: $20 disasm-table regimm-tab-entry \ regim instructions rt table
77: $20 disasm-table copz-rs-tab-entry \ COPz instructions rs table
78: $20 disasm-table copz-rt-tab-entry \ COPz BC instructions rt table
79: $40 disasm-table cp0-tab-entry \ COP0 CO instructions funct table
80:
81: \ disassembler central decode cascade
82:
83: : disasm-inst ( addr w -- )
84: \G disassemble instruction w at addr (addr is used for computing
85: \G branch targets)
86: dup disasm-op opc-tab-entry @ execute ;
87:
88: : disasm-dump ( addr u -- ) \ gforth
89: \G disassemble u aus starting at addr
90: bounds u+do
91: cr ." ( " i hex. ." ) " i i @ disasm-inst
92: 1 cells +loop ;
93:
94: : disasm-special ( addr w -- )
95: \ disassemble inst with opcode special
96: dup disasm-funct funct-tab-entry @ execute ;
97: ' disasm-special 0 opc-tab-entry ! \ enter it for opcode special
98:
99: : disasm-regimm ( addr w -- )
100: \ disassemble regimm inst
101: dup disasm-rt regimm-tab-entry @ execute ;
102: ' disasm-regimm 1 opc-tab-entry ! \ enter it for opcode regimm
103:
104: : disasm-copz-rs ( addr w -- )
105: \ disassemble inst with opcode COPz
106: dup disasm-rs copz-rs-tab-entry @ execute ;
107: ' disasm-copz-rs $10 opc-tab-entry ! \ enter it for opcodes COPz
108: ' disasm-copz-rs $11 opc-tab-entry !
109: ' disasm-copz-rs $12 opc-tab-entry !
110:
111: : disasm-copz-rt ( addr w -- )
112: \ disassemble inst with opcode COPz, rs=BC
113: dup disasm-rt copz-rt-tab-entry @ execute ;
114: ' disasm-copz-rt $08 copz-rs-tab-entry ! \ into COPz-table for rs=BC
115:
116: : disasm-cp0 ( addr w -- )
117: \ disassemble inst with opcode COPz, rs=CO
118: dup disasm-funct cp0-tab-entry @ execute ;
119: ' disasm-cp0 $10 copz-rs-tab-entry ! \ into COPz-table for rs=CO
120:
121: \ dummy words for insts.fs (words with these names are needed by asm.fs)
122:
123: : asm-op ( -- ) ;
124: : asm-rs ( -- ) ;
125: : asm-rt ( -- ) ;
126:
127: \ disassemble various formats
128:
129: : disasm-J-target ( addr w -- )
130: \ print jump target
131: $03ffffff and swap $fc000000 and or 2 lshift hex. ;
132:
133: : disasm-I-rs,rt,imm ( addr w -- )
134: dup disasm-rs .
135: dup disasm-rt .
136: disasm-imm disasm-relative . ;
137:
138: : disasm-I-rs,imm ( addr w -- )
139: dup disasm-rs .
140: disasm-imm disasm-relative . ;
141:
142: : disasm-rt,rs,imm ( addr w -- )
143: dup disasm-rt .
144: dup disasm-rs .
145: disasm-imm .
146: drop ;
147:
148: : disasm-rt,rs,uimm ( addr w -- )
149: dup disasm-rt .
150: dup disasm-rs .
151: disasm-uimm hex.
152: drop ;
153:
154: : disasm-rt,uimm ( addr w -- )
155: dup disasm-rt .
156: disasm-uimm hex.
157: drop ;
158:
159: : disasm-rt,imm,rs ( addr w -- )
160: dup disasm-rt .
161: dup disasm-imm .
162: dup disasm-rs .
163: 2drop ;
164:
165: : disasm-rd,rt,sa ( addr w -- )
166: dup disasm-rd .
167: dup disasm-rt .
168: dup disasm-shamt .
169: 2drop ;
170:
171: : disasm-rd,rt,rs ( addr w -- )
172: dup disasm-rd .
173: dup disasm-rt .
174: dup disasm-rs .
175: 2drop ;
176:
177: : disasm-rs. ( addr w -- )
178: dup disasm-rs .
179: 2drop ;
180:
181: : disasm-rd,rs ( addr w -- )
182: dup disasm-rd .
183: dup disasm-rs .
184: 2drop ;
185:
186: : disasm-rd. ( addr w -- )
187: dup disasm-rd .
188: 2drop ;
189:
190: : disasm-rs,rt ( addr w -- )
191: dup disasm-rs .
192: dup disasm-rt .
193: 2drop ;
194:
195: : disasm-rd,rs,rt ( addr w -- )
196: dup disasm-rd .
197: dup disasm-rs .
198: dup disasm-rt .
199: 2drop ;
200:
201: : disasm-rt,rd,z ( addr w -- )
202: dup disasm-rt .
203: dup disasm-rd .
204: dup disasm-copz .
205: 2drop ;
206:
207: : disasm-I-imm,z ( addr w -- )
208: tuck disasm-imm disasm-relative .
209: disasm-copz . ;
210:
211: \ meta-defining word for instruction format disassembling definitions
212:
213: \ The following word defines instruction-format words, which in turn
214: \ define anonymous words for disassembling specific instructions and
215: \ put them in the appropriate decode table.
216:
217: : define-format ( disasm-xt table-xt -- )
218: \ define an instruction format that uses disasm-xt for
219: \ disassembling and enters the defined instructions into table
220: \ table-xt
221: create 2,
222: does> ( u "inst" -- )
223: \ defines an anonymous word for disassembling instruction inst,
224: \ and enters it as u-th entry into table-xt
225: 2@ swap here name string, ( u table-xt disasm-xt c-addr ) \ remember string
226: noname create 2, \ define anonymous word
227: execute lastxt swap ! \ enter xt of defined word into table-xt
228: does> ( addr w -- )
229: \ disassemble instruction w at addr
230: 2@ >r ( addr w disasm-xt R: c-addr )
231: execute ( R: c-addr ) \ disassemble operands
232: r> count type ; \ print name
233:
234: \ all the following words have the stack effect ( u "name" )
235: ' disasm-J-target ' opc-tab-entry define-format asm-J-target
236: ' disasm-I-rs,rt,imm ' opc-tab-entry define-format asm-I-rs,rt,imm
237: ' disasm-I-rs,imm ' opc-tab-entry define-format asm-I-rs,imm1
238: ' disasm-rt,rs,imm ' opc-tab-entry define-format asm-I-rt,rs,imm
239: ' disasm-rt,rs,uimm ' opc-tab-entry define-format asm-I-rt,rs,uimm
240: ' disasm-rt,uimm ' opc-tab-entry define-format asm-I-rt,uimm
241: ' disasm-rt,imm,rs ' opc-tab-entry define-format asm-I-rt,offset,rs
242: ' disasm-rd,rt,sa ' funct-tab-entry define-format asm-special-rd,rt,sa
243: ' disasm-rd,rt,rs ' funct-tab-entry define-format asm-special-rd,rt,rs
244: ' disasm-rs. ' funct-tab-entry define-format asm-special-rs
245: ' disasm-rd,rs ' funct-tab-entry define-format asm-special-rd,rs
246: ' 2drop ' funct-tab-entry define-format asm-special-nothing
247: ' disasm-rd. ' funct-tab-entry define-format asm-special-rd
248: ' disasm-rs,rt ' funct-tab-entry define-format asm-special-rs,rt
249: ' disasm-rd,rs,rt ' funct-tab-entry define-format asm-special-rd,rs,rt
250: ' disasm-I-rs,imm ' regimm-tab-entry define-format asm-regimm-rs,imm
251: ' 2drop ' cp0-tab-entry define-format asm-copz0
252: ' disasm-rt,rd,z ' copz-rs-tab-entry define-format asm-copz-rt,rd1
253: ' disasm-I-imm,z ' copz-rt-tab-entry define-format asm-copz-imm1
254:
255: : asm-I-rs,imm ( u1 u2 "name" -- ; compiled code: addr w -- )
256: nip asm-I-rs,imm1 ;
257:
258: : asm-copz-rt,rd ( u1 u2 "name" -- )
259: drop asm-copz-rt,rd1 ;
260:
261: : asm-copz-rt,offset,rs ( u "name" -- )
262: \ ignore these insts, we disassemble using asm-I-rt,offset,rs
263: drop name 2drop ;
264:
265: : asm-copz-imm ( u1 u2 u3 "name" -- )
266: drop nip asm-copz-imm1 ;
267:
268: include ./insts.fs
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>