Add support store ddr param in flash.
[xloong.git] / dump / disassemble.c
blobcf3ead5c3525a2630bf3559f3ec2db91001a54ad
1 /* $Id: disassemble.c,v 1.1.1.1 2006/09/14 01:59:08 root Exp $ */
3 /*
4 * Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com)
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Opsycon AB, Sweden.
17 * 4. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
21 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include "frame.h"
37 /* regsize states */
38 #define REGSZ_32 0
39 #define REGSZ_64 1
41 #define LINESZ 200
42 #define whatcpu 0
44 typedef enum {
45 RD_RS_RT, RT_RS_IMM, OFF, RS_RT_OFF, RS_OFF,
46 NONE, RT_RD, COFUN, RD_RT,
47 RS_RT, TARGET, JALR, RS, RD_RT_SFT, LOAD_STORE,
48 RT_IMM, RD, RD_RT_RS, RD_RS,
49 RT_RS_SIMM, RS_SIMM, RT_SIMM, JR, RT_C0, RT_C1,
50 RT_CN, RT_CC1, LDSTC0, LDSTC1,
51 LDSTCN, WORD, RT_C2, RT_CC2, BPCODE, CACHE_OP,
52 CP_OFF, STORE, STOREC1, STORECN,
53 FT_FS_FD_D, FT_FS_FD_S, FS_FD_D, FS_FD_S, FS_FD_W,
54 FS_FD_L, FT_FS_D, FT_FS_S,
55 RT_RD_TO, RT_CC1_TO, RT_CN_TO, RT_C0_TO, RT_C1_TO
56 } TYPE;
58 typedef struct {
59 const char *str;
60 long mask, code;
61 TYPE type;
62 } DISTBL;
63 struct trapframe *cpuinfotab[8];
64 #define REGREG ((u_int32_t *)cpuinfotab[whatcpu])
65 #define load_byte(adr) (*(u_int8_t *)(adr))
66 #define load_word(adr) (*(u_int32_t *)(adr))
67 #define getfield(w,s,p) ((((unsigned long)w)&(((1<<s)-1)<<p))>>p)
69 #define FS_(x) (((x) >> 11) & ((1L << 5) - 1))
70 #define FT_(x) (((x) >> 16) & ((1L << 5) - 1))
71 #define FD_(x) (((x) >> 6) & ((1L << 5) - 1))
72 #define RS_(x) (((x) >> 21) & ((1L << 5) - 1))
73 #define RT_(x) (((x) >> 16) & ((1L << 5) - 1))
74 #define RD_(x) (((x) >> 11) & ((1L << 5) - 1))
75 #define IMM_(x) (((x) >> 0) & ((1L << 16) - 1))
76 #define TARGET_(x) (((x) >> 0) & ((1L << 26) - 1))
77 #define SHAMT_(x) (((x) >> 6) & ((1L << 5) - 1))
80 #define comma() strcat(dest,",")
81 #define rd() strcat(dest,regname[(int)RD_(inst)])
82 #define rs() strcat(dest,regname[(int)RS_(inst)])
83 #define rt() strcat(dest,regname[(int)RT_(inst)])
84 #define fd() strcat(dest,c1reg[(int)FD_(inst)])
85 #define fs() strcat(dest,c1reg[(int)FS_(inst)])
86 #define ft() strcat(dest,c1reg[(int)FT_(inst)])
87 #define c0() strcat(dest,c0reg[(int)RD_(inst)])
88 #define c1() strcat(dest,c1reg[(int)RD_(inst)])
89 #define c2() strcat(dest,regs_hw[(int)RD_(inst)])
90 #define cn() strcat(dest,regs_hw[(int)RD_(inst)])
91 #define c0ft() strcat(dest,c0reg[(int)RT_(inst)])
92 #define c1ft() strcat(dest,c1reg[(int)RT_(inst)])
93 #define cnft() strcat(dest,regs_hw[(int)RT_(inst)])
94 #define cc1() strcat(dest,regs_hw[(int)RD_(inst)])
95 #define cc2() strcat(dest,regs_hw[(int)RD_(inst)])
97 long inst, cur_loc;
98 static char *searching = "searching.. ";
100 const char * const *regname; /* pointer to either regs_sw or regs_hw */
102 /* software register names */
103 const char * const regs_sw[] =
105 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
106 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
107 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
108 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
111 /* hardware register names */
112 const char * const regs_hw[] =
114 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
115 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
116 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
117 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
120 const char * const * c0reg; /* pointer to either regs_c0 or c1reg */
122 const char * const regs_c0[] =
124 "C0_INX", "C0_RAND", "C0_TLBLO0", "C0_TLBLO1",
125 "C0_CTEXT", "C0_PGMASK", "C0_WIRED", "$7",
126 "C0_BADADDR", "C0_COUNT", "C0_TLBHI", "C0_COMPARE",
127 "C0_SR", "C0_CAUSE", "C0_EPC", "C0_PRID",
128 "C0_CONFIG", "C0_LLADDR", "C0_WATCHLO", "C0_WATCHHI",
129 "C0_XCTEXT", "$21", "$22", "$23", "$24", "$25",
130 "C0_ECC", "C0_CACHERR", "C0_TAGLO", "C0_TAGHI", "C0_ERRPC", "$31"
133 const char * const c1reg[] =
135 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
136 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
137 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
138 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
141 const DISTBL distbl[] =
143 /* special aliases for certain instructions */
144 {"nop", 0xffffffffL, 0x00000000L, NONE}, /* sll 0,0,0 */
145 {"li", 0xffe00000L, 0x24000000L, RT_SIMM}, /* addiu rd,0,simm */
146 {"li", 0xffe00000L, 0x34000000L, RT_IMM}, /* ori rd,0,imm*/
147 {"move", 0xfc1f07ffL, 0x00000021L, RD_RS}, /* addu rd,0,rs */
148 {"move", 0xfc1f07ffL, 0x00000025L, RD_RS}, /* or rd,0,rs */
149 {"neg", 0xffe007ffL, 0x00000022L, RD_RT}, /* sub rd,rt,0 */
150 {"negu", 0xffe007ffL, 0x00000023L, RD_RT}, /* subu rd,rt,0 */
151 {"dmove", 0xfc1f07ffL, 0x0000002dL, RD_RS}, /* daddu rd,0,rs */
152 {"dneg", 0xffe007ffL, 0x0000002eL, RD_RT}, /* dsub rd,rt,0 */
153 {"dnegu", 0xffe007ffL, 0x0000002fL, RD_RT}, /* dsubu rd,rt,0 */
154 {"not", 0xfc1f07ffL, 0x00000027L, RD_RS}, /* nor rd,0,rs */
155 {"b", 0xffff0000L, 0x10000000L, OFF}, /* beq 0,0 */
156 {"b", 0xffff0000L, 0x04010000L, OFF}, /* bgez 0 */
157 {"bal", 0xffff0000L, 0x04110000L, OFF}, /* bgezal 0 */
159 /* machine insns */
160 {"add", 0xfc0007ffL, 0x00000020L, RD_RS_RT},
161 {"addi", 0xfc000000L, 0x20000000L, RT_RS_SIMM},
162 {"addiu", 0xfc000000L, 0x24000000L, RT_RS_SIMM},
163 {"addu", 0xfc0007ffL, 0x00000021L, RD_RS_RT},
165 {"dadd", 0xfc0007ffL, 0x0000002cL, RD_RS_RT},
166 {"daddi", 0xfc000000L, 0x60000000L, RT_RS_SIMM},
167 {"daddiu", 0xfc000000L, 0x64000000L, RT_RS_SIMM},
168 {"daddu", 0xfc0007ffL, 0x0000002dL, RD_RS_RT},
170 {"and", 0xfc0007ffL, 0x00000024L, RD_RS_RT},
171 {"andi", 0xfc000000L, 0x30000000L, RT_RS_IMM},
173 {"bc0f", 0xffff0000L, 0x41000000L, CP_OFF},
174 {"bc1f", 0xffff0000L, 0x45000000L, CP_OFF},
175 {"bc2f", 0xffff0000L, 0x49000000L, CP_OFF},
176 {"bc3f", 0xffff0000L, 0x4d000000L, CP_OFF},
177 {"bc0t", 0xffff0000L, 0x41010000L, CP_OFF},
178 {"bc1t", 0xffff0000L, 0x45010000L, CP_OFF},
179 {"bc2t", 0xffff0000L, 0x49010000L, CP_OFF},
180 {"bc3t", 0xffff0000L, 0x4d010000L, CP_OFF},
182 {"bc0fl", 0xffff0000L, 0x41020000L, CP_OFF},
183 {"bc1fl", 0xffff0000L, 0x45020000L, CP_OFF},
184 {"bc2fl", 0xffff0000L, 0x49020000L, CP_OFF},
185 {"bc3fl", 0xffff0000L, 0x4d020000L, CP_OFF},
186 {"bc0tl", 0xffff0000L, 0x41030000L, CP_OFF},
187 {"bc1tl", 0xffff0000L, 0x45030000L, CP_OFF},
188 {"bc2tl", 0xffff0000L, 0x49030000L, CP_OFF},
189 {"bc3tl", 0xffff0000L, 0x4d030000L, CP_OFF},
191 {"beq", 0xfc000000L, 0x10000000L, RS_RT_OFF},
192 {"bne", 0xfc000000L, 0x14000000L, RS_RT_OFF},
193 {"blez", 0xfc1f0000L, 0x18000000L, RS_OFF},
194 {"bgtz", 0xfc1f0000L, 0x1c000000L, RS_OFF},
196 {"beql", 0xfc000000L, 0x50000000L, RS_RT_OFF},
197 {"bnel", 0xfc000000L, 0x54000000L, RS_RT_OFF},
198 {"blezl", 0xfc1f0000L, 0x58000000L, RS_OFF},
199 {"bgtzl", 0xfc1f0000L, 0x5c000000L, RS_OFF},
201 {"bltz", 0xfc1f0000L, 0x04000000L, RS_OFF},
202 {"bgez", 0xfc1f0000L, 0x04010000L, RS_OFF},
204 {"bltzl", 0xfc1f0000L, 0x04020000L, RS_OFF},
205 {"bgezl", 0xfc1f0000L, 0x04030000L, RS_OFF},
207 {"bltzal", 0xfc1f0000L, 0x04100000L, RS_OFF},
208 {"bgezal", 0xfc1f0000L, 0x04110000L, RS_OFF},
210 {"bltzall",0xfc1f0000L, 0x04120000L, RS_OFF},
211 {"bgezall",0xfc1f0000L, 0x04130000L, RS_OFF},
213 {"break", 0xfc00003fL, 0x0000000dL, BPCODE},
215 {"cache", 0xfc000000L, 0xbc000000L, CACHE_OP},
217 {"cfc0", 0xffe007ffL, 0x40400000L, RT_RD},
218 {"cfc1", 0xffe007ffL, 0x44400000L, RT_CC1},
219 {"cfc2", 0xffe007ffL, 0x48400000L, RT_CN},
220 {"cfc3", 0xffe007ffL, 0x4c400000L, RT_CN},
221 {"tlbp", 0xffffffffL, 0x42000008L, NONE},
222 {"tlbr", 0xffffffffL, 0x42000001L, NONE},
223 {"tlbwi", 0xffffffffL, 0x42000002L, NONE},
224 {"tlbwr", 0xffffffffL, 0x42000006L, NONE},
225 {"rfe", 0xffffffffL, 0x42000010L, NONE},
226 {"eret", 0xffffffffL, 0x42000018L, NONE},
227 {"cop0", 0xfe000000L, 0x42000000L, COFUN},
229 {"add.s", 0xfee0003fL, 0x46000000L, FT_FS_FD_S},
230 {"add.d", 0xfee0003fL, 0x46200000L, FT_FS_FD_D},
231 {"sub.s", 0xfee0003fL, 0x46000001L, FT_FS_FD_S},
232 {"sub.d", 0xfee0003fL, 0x46200001L, FT_FS_FD_D},
233 {"mul.s", 0xfee0003fL, 0x46000002L, FT_FS_FD_S},
234 {"mul.d", 0xfee0003fL, 0x46200002L, FT_FS_FD_D},
235 {"div.s", 0xfee0003fL, 0x46000003L, FT_FS_FD_S},
236 {"div.d", 0xfee0003fL, 0x46200003L, FT_FS_FD_D},
237 {"abs.s", 0xfee0003fL, 0x46000005L, FS_FD_S},
238 {"abs.d", 0xfee0003fL, 0x46200005L, FS_FD_D},
239 {"mov.s", 0xfee0003fL, 0x46000006L, FS_FD_S},
240 {"mov.d", 0xfee0003fL, 0x46200006L, FS_FD_D},
241 {"neg.s", 0xfee0003fL, 0x46000007L, FS_FD_S},
242 {"neg.d", 0xfee0003fL, 0x46200007L, FS_FD_D},
243 {"sqrt.d", 0xfee0003fL, 0x46200004, FS_FD_D},
244 {"sqrt.s", 0xfee0003fL, 0x46000004, FS_FD_S},
246 {"c.f.s", 0xfee0003fL, 0x46000030L, FT_FS_S},
247 {"c.f.d", 0xfee0003fL, 0x46200030L, FT_FS_D},
248 {"c.un.s", 0xfee0003fL, 0x46000031L, FT_FS_S},
249 {"c.un.d", 0xfee0003fL, 0x46200031L, FT_FS_D},
250 {"c.eq.s", 0xfee0003fL, 0x46000032L, FT_FS_S},
251 {"c.eq.d", 0xfee0003fL, 0x46200032L, FT_FS_D},
252 {"c.ueq.s", 0xfee0003fL, 0x46000033L, FT_FS_S},
253 {"c.ueq.d", 0xfee0003fL, 0x46200033L, FT_FS_D},
254 {"c.olt.s", 0xfee0003fL, 0x46000034L, FT_FS_S},
255 {"c.olt.d", 0xfee0003fL, 0x46200034L, FT_FS_D},
256 {"c.ult.s", 0xfee0003fL, 0x46000035L, FT_FS_S},
257 {"c.ult.d", 0xfee0003fL, 0x46200035L, FT_FS_D},
258 {"c.ole.s", 0xfee0003fL, 0x46000036L, FT_FS_S},
259 {"c.ole.d", 0xfee0003fL, 0x46200036L, FT_FS_D},
260 {"c.ule.s", 0xfee0003fL, 0x46000037L, FT_FS_S},
261 {"c.ule.d", 0xfee0003fL, 0x46200037L, FT_FS_D},
262 {"c.sf.s", 0xfee0003fL, 0x46000038L, FT_FS_S},
263 {"c.sf.d", 0xfee0003fL, 0x46200038L, FT_FS_D},
264 {"c.ngle.s", 0xfee0003fL, 0x46000039L, FT_FS_S},
265 {"c.ngle.d", 0xfee0003fL, 0x46200039L, FT_FS_D},
266 {"c.seq.s", 0xfee0003fL, 0x4600003aL, FT_FS_S},
267 {"c.seq.d", 0xfee0003fL, 0x4620003aL, FT_FS_D},
268 {"c.ngl.s", 0xfee0003fL, 0x4600003bL, FT_FS_S},
269 {"c.ngl.d", 0xfee0003fL, 0x4620003bL, FT_FS_D},
270 {"c.lt.s", 0xfee0003fL, 0x4600003cL, FT_FS_S},
271 {"c.lt.d", 0xfee0003fL, 0x4620003cL, FT_FS_D},
272 {"c.nge.s", 0xfee0003fL, 0x4600003dL, FT_FS_S},
273 {"c.nge.d", 0xfee0003fL, 0x4620003dL, FT_FS_D},
274 {"c.le.s", 0xfee0003fL, 0x4600003eL, FT_FS_S},
275 {"c.le.d", 0xfee0003fL, 0x4620003eL, FT_FS_D},
276 {"c.ngt.s", 0xfee0003fL, 0x4600003fL, FT_FS_S},
277 {"c.ngt.d", 0xfee0003fL, 0x4620003fL, FT_FS_D},
279 {"cvt.s.w", 0xfee0003fL, 0x46800020L, FS_FD_W},
280 {"cvt.s.l", 0xfee0003fL, 0x46a00020L, FS_FD_L},
281 {"cvt.s.d", 0xfee0003fL, 0x46200020L, FS_FD_D},
282 {"cvt.d.s", 0xfee0003fL, 0x46000021L, FS_FD_S},
283 {"cvt.d.w", 0xfee0003fL, 0x46800021L, FS_FD_W},
284 {"cvt.d.l", 0xfee0003fL, 0x46a00021L, FS_FD_L},
285 {"cvt.w.d", 0xfee0003fL, 0x46200024L, FS_FD_D},
286 {"cvt.w.s", 0xfee0003fL, 0x46000024L, FS_FD_S},
287 {"cvt.l.d", 0xfee0003fL, 0x46200025L, FS_FD_D},
288 {"cvt.l.s", 0xfee0003fL, 0x46000025L, FS_FD_S},
290 {"ceil.l.d", 0xffff003fL, 0x4620000aL, FS_FD_L},
291 {"ceil.l.s", 0xffff003fL, 0x4600000aL, FS_FD_L},
292 {"ceil.w.d", 0xffff003fL, 0x4620000eL, FS_FD_W},
293 {"ceil.w.s", 0xffff003fL, 0x4600000eL, FS_FD_W},
294 {"floor.l.d", 0xffff003fL, 0x4620000bL, FS_FD_L},
295 {"floor.l.s", 0xffff003fL, 0x4600000bL, FS_FD_L},
296 {"floor.w.d", 0xffff003fL, 0x4620000fL, FS_FD_W},
297 {"floor.w.s", 0xffff003fL, 0x4600000fL, FS_FD_W},
298 {"round.l.d", 0xffff003fL, 0x46200008L, FS_FD_L},
299 {"round.l.s", 0xffff003fL, 0x46000008L, FS_FD_L},
300 {"round.w.d", 0xffff003fL, 0x4620000cL, FS_FD_W},
301 {"round.w.s", 0xffff003fL, 0x4600000cL, FS_FD_W},
302 {"trunc.l.d", 0xffff003fL, 0x46200009L, FS_FD_L},
303 {"trunc.l.s", 0xffff003fL, 0x46000009L, FS_FD_L},
304 {"trunc.w.d", 0xffff003fL, 0x4620000dL, FS_FD_W},
305 {"trunc.w.s", 0xffff003fL, 0x4600000dL, FS_FD_W},
307 {"cop1", 0xfe000000L, 0x46000000L, COFUN},
309 {"cop2", 0xfe000000L, 0x4a000000L, COFUN},
310 {"cop3", 0xfe000000L, 0x4e000000L, COFUN},
312 {"ctc0", 0xffe007ffL, 0x40c00000L, RT_RD_TO},
313 {"ctc1", 0xffe007ffL, 0x44c00000L, RT_CC1_TO},
314 {"ctc2", 0xffe007ffL, 0x48c00000L, RT_CN_TO},
315 {"ctc3", 0xffe007ffL, 0x4cc00000L, RT_CN_TO},
317 {"div", 0xfc00ffffL, 0x0000001aL, RS_RT},
318 {"divu", 0xfc00ffffL, 0x0000001bL, RS_RT},
319 {"ddiv", 0xfc00ffffL, 0x0000001eL, RS_RT},
320 {"ddivu", 0xfc00ffffL, 0x0000001fL, RS_RT},
322 {"j", 0xfc000000L, 0x08000000L, TARGET},
323 {"jal", 0xfc000000L, 0x0c000000L, TARGET},
324 {"jalr", 0xfc1f07ffL, 0x00000009L, JALR},
325 {"jr", 0xfc1fffffL, 0x00000008L, JR},
327 {"lui", 0xfc000000L, 0x3c000000L, RT_IMM},
329 {"lb", 0xfc000000L, 0x80000000L, LOAD_STORE},
330 {"lbu", 0xfc000000L, 0x90000000L, LOAD_STORE},
331 {"lh", 0xfc000000L, 0x84000000L, LOAD_STORE},
332 {"lhu", 0xfc000000L, 0x94000000L, LOAD_STORE},
333 {"lw", 0xfc000000L, 0x8c000000L, LOAD_STORE},
334 {"lwl", 0xfc000000L, 0x88000000L, LOAD_STORE},
335 {"lwr", 0xfc000000L, 0x98000000L, LOAD_STORE},
336 {"lwu", 0xfc000000L, 0x9c000000L, LOAD_STORE},
337 {"ldl", 0xfc000000L, 0x68000000L, LOAD_STORE},
338 {"ldr", 0xfc000000L, 0x6c000000L, LOAD_STORE},
340 {"ll", 0xfc000000L, 0xc0000000L, LOAD_STORE},
341 {"lwc1", 0xfc000000L, 0xc4000000L, LDSTC1},
342 {"lwc2", 0xfc000000L, 0xc8000000L, LDSTCN},
343 {"lwc3", 0xfc000000L, 0xcc000000L, LDSTCN},
345 {"lld", 0xfc000000L, 0xd0000000L, LOAD_STORE},
346 {"ldc1", 0xfc000000L, 0xd4000000L, LDSTC1},
347 {"ldc2", 0xfc000000L, 0xd8000000L, LDSTCN},
348 {"ld", 0xfc000000L, 0xdc000000L, LOAD_STORE},
350 {"mfc0", 0xffe007ffL, 0x40000000L, RT_C0},
351 {"mfc1", 0xffe007ffL, 0x44000000L, RT_C1},
352 {"mfc2", 0xffe007ffL, 0x48000000L, RT_CN},
353 {"mfc3", 0xffe007ffL, 0x4c000000L, RT_CN},
355 {"dmfc0", 0xffe007ffL, 0x40200000L, RT_C0},
356 {"dmfc1", 0xffe007ffL, 0x44200000L, RT_C1},
357 {"dmfc2", 0xffe007ffL, 0x48200000L, RT_CN},
358 {"dmfc3", 0xffe007ffL, 0x4c200000L, RT_CN},
360 {"mtc0", 0xffe007ffL, 0x40800000L, RT_C0_TO},
361 {"mtc1", 0xffe007ffL, 0x44800000L, RT_C1_TO},
362 {"mtc2", 0xffe007ffL, 0x48800000L, RT_CN_TO},
363 {"mtc3", 0xffe007ffL, 0x4c800000L, RT_CN_TO},
365 {"dmtc0", 0xffe007ffL, 0x40a00000L, RT_C0_TO},
366 {"dmtc1", 0xffe007ffL, 0x44a00000L, RT_C1_TO},
367 {"dmtc2", 0xffe007ffL, 0x48a00000L, RT_CN_TO},
368 {"dmtc3", 0xffe007ffL, 0x4ca00000L, RT_CN_TO},
370 {"mfhi", 0xffff07ffL, 0x00000010L, RD},
371 {"mflo", 0xffff07ffL, 0x00000012L, RD},
372 {"mthi", 0xfc1fffffL, 0x00000011L, RS},
373 {"mtlo", 0xfc1fffffL, 0x00000013L, RS},
375 {"mult", 0xfc00ffffL, 0x00000018L, RS_RT},
376 {"multu", 0xfc00ffffL, 0x00000019L, RS_RT},
377 {"dmult", 0xfc00ffffL, 0x0000001cL, RS_RT},
378 {"dmultu", 0xfc00ffffL, 0x0000001dL, RS_RT},
380 /* R4100: */
381 {"madd16", 0xfc00ffff, 0x00000028, RS_RT},
382 {"dmadd16", 0xfc00ffff, 0x00000020, RS_RT},
383 {"standby", ~0, 0x42000021, NONE},
384 {"suspend", ~0, 0x42000022, NONE},
385 {"hibernate", ~0, 0x42000023, NONE},
387 {"nor", 0xfc0007ffL, 0x00000027L, RD_RS_RT},
388 {"or", 0xfc0007ffL, 0x00000025L, RD_RS_RT},
389 {"ori", 0xfc000000L, 0x34000000L, RT_RS_IMM},
391 {"sb", 0xfc000000L, 0xa0000000L, STORE},
392 {"sh", 0xfc000000L, 0xa4000000L, STORE},
393 {"swl", 0xfc000000L, 0xa8000000L, STORE},
394 {"sw", 0xfc000000L, 0xac000000L, STORE},
395 {"sdl", 0xfc000000L, 0xb0000000L, STORE},
396 {"sdr", 0xfc000000L, 0xb4000000L, STORE},
397 {"swr", 0xfc000000L, 0xb8000000L, STORE},
399 {"sc", 0xfc000000L, 0xe0000000L, STORE},
400 {"swc1", 0xfc000000L, 0xe4000000L, STOREC1},
401 {"swc2", 0xfc000000L, 0xe8000000L, STORECN},
402 {"swc3", 0xfc000000L, 0xec000000L, STORECN},
404 {"scd", 0xfc000000L, 0xf0000000L, STORE},
405 {"sdc1", 0xfc000000L, 0xf4000000L, STOREC1},
406 {"sdc2", 0xfc000000L, 0xf8000000L, STORECN},
407 {"sd", 0xfc000000L, 0xfc000000L, STORE},
409 {"sll", 0xffe0003fL, 0x00000000L, RD_RT_SFT},
410 {"sllv", 0xfc0007ffL, 0x00000004L, RD_RT_RS},
411 {"dsll", 0xffe0003fL, 0x00000038L, RD_RT_SFT},
412 {"dsllv", 0xfc0007ffL, 0x00000014L, RD_RT_RS},
413 // {"dsll32", 0xfc0007ffL, 0x0000003cL, RD_RT_RS},
414 {"dsll32", 0xffe0003fL, 0x0000003cL, RD_RT_SFT},
416 {"slt", 0xfc0007ffL, 0x0000002aL, RD_RS_RT},
417 {"slti", 0xfc000000L, 0x28000000L, RT_RS_SIMM},
418 {"sltiu", 0xfc000000L, 0x2c000000L, RT_RS_SIMM},
419 {"sltu", 0xfc0007ffL, 0x0000002bL, RD_RS_RT},
421 {"sra", 0xffe0003fL, 0x00000003L, RD_RT_SFT},
422 {"srav", 0xfc0007ffL, 0x00000007L, RD_RT_RS},
423 {"dsra", 0xffe0003fL, 0x0000003bL, RD_RT_SFT},
424 {"dsrav", 0xfc0007ffL, 0x00000017L, RD_RT_RS},
425 // {"dsra32", 0xfc0007ffL, 0x0000003fL, RD_RT_RS},
426 {"dsra32", 0xffe0003fL, 0x0000003fL, RD_RT_SFT},
428 {"srl", 0xffe0003fL, 0x00000002L, RD_RT_SFT},
429 {"srlv", 0xfc0007ffL, 0x00000006L, RD_RT_RS},
430 {"dsrl", 0xffe0003fL, 0x0000003aL, RD_RT_SFT},
431 {"dsrlv", 0xfc0007ffL, 0x00000016L, RD_RT_RS},
432 // {"dsrl32", 0xfc0007ffL, 0x0000003eL, RD_RT_RS},
433 {"dsrl32", 0xffe0003fL, 0x0000003eL, RD_RT_SFT},
435 {"sub", 0xfc0007ffL, 0x00000022L, RD_RS_RT},
436 {"subu", 0xfc0007ffL, 0x00000023L, RD_RS_RT},
437 {"dsub", 0xfc0007ffL, 0x0000002eL, RD_RS_RT},
438 {"dsubu", 0xfc0007ffL, 0x0000002fL, RD_RS_RT},
440 {"teqi", 0xfc1f0000L, 0x040c0000L, RS_SIMM},
441 {"teq", 0xfc00003fL, 0x00000034L, RS_RT},
442 {"tgei", 0xfc1f0000L, 0x04080000L, RS_SIMM},
443 {"tge", 0xfc00003fL, 0x00000030L, RS_RT},
444 {"tgeiu", 0xfc1f0000L, 0x04090000L, RS_SIMM},
445 {"tgeu", 0xfc00003fL, 0x00000031L, RS_RT},
446 {"tlti", 0xfc1f0000L, 0x040a0000L, RS_SIMM},
447 {"tlt", 0xfc00003fL, 0x00000032L, RS_RT},
448 {"tltiu", 0xfc1f0000L, 0x040b0000L, RS_SIMM},
449 {"tltu", 0xfc00003fL, 0x00000033L, RS_RT},
450 {"tnei", 0xfc1f0000L, 0x040e0000L, RS_SIMM},
451 {"tne", 0xfc00003fL, 0x00000036L, RS_RT},
453 {"sync", 0xffffffffL, 0x0000000fL, NONE},
454 {"syscall", 0xffffffffL, 0x0000000cL, NONE},
455 {"xor", 0xfc0007ffL, 0x00000026L, RD_RS_RT},
456 {"xori", 0xfc000000L, 0x38000000L, RT_RS_IMM},
458 /* must be last !! never be move/remove */
459 {".word", 0x00000000L, 0x00000000L, WORD}
462 static char *
463 _getbase(char *p, int *basep)
465 if (p[0] == '0') {
466 switch (p[1]) {
467 case 'x':
468 *basep = 16;
469 break;
470 case 't': case 'n':
471 *basep = 10;
472 break;
473 case 'o':
474 *basep = 8;
475 break;
476 default:
477 *basep = 10;
478 return (p);
480 return (p + 2);
482 *basep = 10;
483 return (p);
488 * _atob(vp,p,base)
490 static int
491 _atob (unsigned long *vp, char *p, int base)
493 u_long value, v1, v2;
494 char *q, tmp[20];
495 int digit;
497 if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
498 base = 16;
499 p += 2;
502 if (base == 16 && (q = strchr (p, '.')) != 0) {
503 if (q - p > sizeof(tmp) - 1)
504 return (0);
506 strncpy (tmp, p, q - p);
507 tmp[q - p] = '\0';
508 if (!_atob (&v1, tmp, 16))
509 return (0);
511 q++;
512 if (strchr (q, '.'))
513 return (0);
515 if (!_atob (&v2, q, 16))
516 return (0);
517 *vp = (v1 << 16) + v2;
518 return (1);
521 value = *vp = 0;
522 for (; *p; p++) {
523 if (*p >= '0' && *p <= '9')
524 digit = *p - '0';
525 else if (*p >= 'a' && *p <= 'f')
526 digit = *p - 'a' + 10;
527 else if (*p >= 'A' && *p <= 'F')
528 digit = *p - 'A' + 10;
529 else
530 return (0);
532 if (digit >= base)
533 return (0);
534 value *= base;
535 value += digit;
537 *vp = value;
538 return (1);
542 * atob(vp,p,base)
543 * converts p to binary result in vp, rtn 1 on success
546 atob(u_int32_t *vp, char *p, int base)
548 u_long v;
550 if (base == 0)
551 p = _getbase (p, &base);
552 if (_atob (&v, p, base)) {
553 *vp = v;
554 return (1);
556 return (0);
559 char * strccat(char *dst, int c)
561 int len;
563 if (!dst)
564 return (dst);
565 len = strlen (dst);
566 dst[len] = c;
567 dst[len + 1] = 0;
568 return (dst);
570 int md_ator(u_int32_t *vp, char *p, int base)
572 return(atob(vp,p,base));
575 /** char *strrpset(str,set) like strrset except ignores inner parens */
577 char *
578 strrpset(const char *str, const char *set)
580 int n;
581 const char *p;
583 n = 0;
584 for (p = &str[strlen (str) - 1]; p > str; p--) {
585 if (*p == '(')
586 n++;
587 else if (*p == ')')
588 n--;
589 else if (strchr (set, *p) && n == 0)
590 return ((char *)p);
592 return (0);
594 char *
595 strbalp(const char *p)
597 char b, e;
598 char *ol = "({[<";
599 char *cl = ")}]>";
600 int i, n;
602 b = *p;
603 for (i = 0; ol[i] != 0; i++) {
604 if (ol[i] == b)
605 break;
607 if (ol[i] == 0)
608 return (0);
609 e = cl[i];
611 n = 0;
612 for (; *p; p++) {
613 if (*p == b)
614 n++;
615 else if (*p == e) {
616 n--;
617 if (n == 0)
618 return ((char *)p);
621 return (0);
623 char *
624 strdchr(char *p)
626 char *t;
628 if(p != NULL) {
629 for (t = p; *t; t++) {
630 *t = *(t + 1);
633 return (p);
636 * Scan and input a value.
638 * Note: The vp arg (dest) must be able to receive a value
639 * of 'u_int32_t' size. Assumption here is that this
640 * type will be the largets we deal with for non
641 * register type values.
644 get_rsa(u_int32_t *vp, char *p)
646 u_int32_t val;
648 if(get_rsa_reg (&val, p)) {
649 *vp = val;
650 return (1);
652 return (0);
656 * Scan and input a value of largest size (processor register width).
658 * Note: The vp arg (dest) must be able to receive a value
659 * of 'regsiter_t' size. Assumption here is that this
660 * type will be the largets we deal with.
663 get_rsa_reg(u_int32_t *vp, char *p)
665 int r, inbase;
666 u_int32_t v1, v2;
667 char *q, subexpr[LINESZ];
669 /* strip enclosing parens */
670 while (*p == '(' && strbalp (p) == p + strlen (p) - 1) {
671 strdchr (p);
672 p[strlen (p) - 1] = 0;
675 if ((q = strrpset (p, "+-")) != 0) { /* is compound */
676 strncpy (subexpr, p, q - p);
677 subexpr[q - p] = '\0';
678 r = get_rsa_reg (&v1, subexpr);
679 if (r == 0) {
680 return (r);
682 r = get_rsa_reg (&v2, q + 1);
683 if (r == 0) {
684 return (r);
686 if (*q == '+') {
687 *vp = v1 + v2;
689 else {
690 *vp = v1 - v2;
692 return (1);
695 if ((q = strrpset (p, "*/")) != 0) {
696 strncpy (subexpr, p, q - p);
697 subexpr[q - p] = '\0';
698 r = get_rsa_reg (&v1, subexpr);
699 if (r == 0) {
700 return (r);
702 r = get_rsa_reg (&v2, q + 1);
703 if (r == 0) {
704 return (r);
706 if (*q == '*') {
707 *vp = v1 * v2;
709 else {
710 if (v2 == 0) {
711 printf ("divide by zero\n");
712 return (0);
714 *vp = v1 / v2;
716 return (1);
719 if (*p == '^') {
720 r = get_rsa_reg (&v2, &p[1]);
721 if (r == 0) {
722 printf ("%s: bad indirect address\n", &p[1]);
724 else {
725 *vp = load_word ((int32_t)v2);
727 } else if (isdigit (*p)) {
729 r = md_ator (vp, p, 16);
731 if (r == 0) {
732 r = md_ator (vp, p, 0);
733 if (r == 0) {
734 printf ("%s: bad base value\n", p);
738 return (r);
741 const DISTBL * get_distbl (u_int32_t bits)
743 const DISTBL *pt = distbl;
744 static const DISTBL *lastpt = 0;
745 static u_int32_t lastbits;
747 /* simple cache for repeated lookups */
748 if (lastpt && bits == lastbits)
749 return lastpt;
751 while ((bits & pt->mask) != pt->code)
752 ++pt;
753 lastpt = pt;
754 lastbits = bits;
755 return (pt);
760 /*************************************************************
761 * mkcomment(p,fmt,v)
762 * generate an appropriate comment
764 void mkcomment (char *p, char *fmt, long v)
766 char tmp[20];
767 int n;
769 for (n = 50 - strlen (p); n > 0; n--)
770 strcat (p, " ");
771 sprintf (tmp, fmt, v);
772 strcat (p, tmp);
775 /*************************************************************
776 * simm(dest)
777 * signed immediate value
779 void simm (char *dest)
781 char tmp[20];
782 long v;
784 v = IMM_ (inst);
785 sprintf (tmp, "0x%x", v);
786 strcat (dest, tmp);
787 if (v & (1L << 15))
788 v |= 0xffff0000L;
789 mkcomment (dest, "# %d", v);
792 /*************************************************************
793 * imm(dest)
794 * unsigned immediate value
796 void imm (char *dest)
798 char tmp[20];
799 long v;
801 v = IMM_ (inst);
802 sprintf (tmp, "0x%x", v);
803 strcat (dest, tmp);
804 mkcomment (dest, "# %d", v);
807 int md_is_branch(void *adr)
809 const DISTBL *pt;
810 u_int32_t inst;
812 inst = load_word (adr);
813 pt = get_distbl (inst);
814 switch (pt->type) {
815 case OFF:
816 case RS_RT_OFF:
817 case RS_OFF:
818 case CP_OFF:
819 case TARGET:
820 case JALR:
821 case JR:
822 return (1);
823 default:
824 return (0);
828 int md_is_cond_branch(void *adr)
830 const DISTBL *pt;
831 u_int32_t inst;
833 inst = load_word (adr);
834 pt = get_distbl (inst);
835 switch (pt->type) {
836 case RS_RT_OFF:
837 case RS_OFF:
838 case CP_OFF:
839 return (1);
840 default:
841 return (0);
845 int md_is_jr (void *adr)
847 const DISTBL *pt;
848 u_int32_t inst;
850 inst = load_word (adr);
851 pt = get_distbl (inst);
852 return (pt->type == JR);
855 int md_is_call (void *adr)
857 u_int32_t inst;
859 inst = load_word(adr);
860 switch (getfield(inst, 6, 26)) {
861 case 0:
862 /* special: jalr */
863 return (getfield (inst, 6, 0) == 9);
864 case 1:
865 /* regimm: bal */
866 return (getfield (inst, 2, 19) == 2);
867 case 3:
868 /* jal */
869 return (1);
871 return (0);
874 /*************************************************************
875 * dis(ac,av)
876 * the 'l' (disassemble) command
878 int rflag; /* Wanting effective addresses for load/store instructions */
879 int rsvalue; /* Computed by rs() macro for displaying load/store effective addrs */
880 int rtvalue;
881 int do_rt;
882 int do_rs;
885 /**************************************************************/
886 void * md_disasm (char *dest, void *addr)
888 const DISTBL *pt;
889 char tmp[40];
890 long v, v1, w;
891 int i;
892 #ifdef FLOATINGPT
893 float *s_fs; /* For getting at FS argument via float */
894 float *s_ft; /* For getting at FT argument via float */
895 double *d_fs; /* For getting at FS argument via double */
896 double *d_ft; /* For getting at FT argument via double */
897 int *w_fs; /* For getting at FS argument via binary fixed single */
898 long long *l_fs; /* For getting at FS argument via binary fixed long */
899 int fpdis; /* Actually show the floating point values switch */
900 #endif /* FLOATINGPT */
902 inst = load_word(addr);;
903 if (regname == 0)
904 regname = regs_sw;
906 // if (!adr2symoff (dest, (int)addr, 12))
907 // sprintf (dest, "%08x", addr);
908 sprintf (tmp, " %08x ", inst);
909 strcat (dest, tmp);
910 memset(tmp, 0, 40);
912 pt = get_distbl (inst);
913 i = strlen (pt->str);
914 strcat (dest, pt->str);
915 do_rt = 0;
916 do_rs = 0;
918 #ifdef FLOATINGPT
920 * It is possible the floating point values are bogus for printing
921 * so give user a way to not show them.
924 fpdis = matchenv ("fpdis");
927 * Get pointers to various ways of looking at floating point operands
928 * as part of the rflag display rather than having do do these casts
929 * over and over
932 d_fs = (double *)&Fpr[(int)FS_(inst)];
933 d_ft = (double *)&Fpr[(int)FT_(inst)];
934 l_fs = (long long *)d_fs;
935 s_fs = (float *)(((int *)d_fs)+1);
936 s_ft = (float *)(((int *)d_ft)+1);
937 w_fs = (int *)s_fs;
938 #endif /* FLOATINGPT */
940 while (i++ < 8)
941 strcat (dest, " ");
942 switch (pt->type) {
943 case FT_FS_FD_D:
944 fd (); comma (); fs (); comma (); ft ();
945 #ifdef FLOATINGPT
946 if (rflag )
948 mkcomment( dest, "#", 0);
949 if (fpdis )
951 if (dpdenorm( (struct IEEEdp *)d_fs ) )
952 sprintf (tmp, " fs=0.0 (dp denorm)");
953 else if (dpnan( (struct IEEEdp *)d_fs ) )
954 sprintf (tmp, " fs=Nan");
955 else
956 sprintf (tmp, " fs=%e", *d_fs);
957 strcat (dest, tmp);
958 if (dpdenorm( (struct IEEEdp *)d_ft ) )
959 sprintf (tmp, " ft=0.0 (dp denorm)");
960 else if (dpnan( (struct IEEEdp *)d_ft ) )
961 sprintf (tmp, " ft=Nan");
962 else
963 sprintf (tmp, " ft=%e", *d_ft);
965 else
966 sprintf (tmp, " fs=%llx ft=%llx", *d_fs, *d_ft);
967 strcat (dest, tmp);
969 #endif /* FLOATINGPT */
970 break;
971 case FT_FS_FD_S:
972 fd (); comma (); fs (); comma (); ft ();
973 #ifdef FLOATINGPT
974 if (rflag )
976 mkcomment( dest, "#", 0);
977 if (fpdis )
979 if (spdenorm( (struct IEEEsp *)s_fs ) )
980 sprintf (tmp, " fs=0.0 (sp denorm)");
981 else if (spnan( (struct IEEEsp *)s_fs ) )
982 sprintf (tmp, " fs=Nan");
983 else
984 sprintf (tmp, " fs=%e", *s_fs);
985 strcat (dest, tmp);
986 if (spdenorm( (struct IEEEsp *)s_ft ) )
987 sprintf (tmp, " ft=0.0 (sp denorm)");
988 if (spnan( (struct IEEEsp *)s_ft ) )
989 sprintf (tmp, " ft=Nan");
990 else
991 sprintf (tmp, " ft=%e", *s_ft);
993 else
994 sprintf (tmp, " fs=0x%x ft=0x%x", *s_fs, *s_ft);
995 strcat (dest, tmp);
997 #endif /* FLOATINGPT */
998 break;
999 case FS_FD_D:
1000 fd (); comma (); fs ();
1001 #ifdef FLOATINGPT
1002 if (rflag )
1004 mkcomment( dest, "#", 0);
1005 if (fpdis )
1006 if (dpdenorm( (struct IEEEdp *)d_fs ) )
1007 sprintf (tmp, " fs=0.0 (dp denorm)");
1008 else if (dpnan( (struct IEEEdp *)d_fs ) )
1009 sprintf (tmp, " fs=Nan");
1010 else
1011 sprintf (tmp, " fs=%e", *d_fs);
1012 else
1013 sprintf (tmp, " fs=%llx", *d_fs);
1014 strcat (dest, tmp);
1016 #endif /* FLOATINGPT */
1017 break;
1018 case FS_FD_S:
1019 fd (); comma (); fs ();
1020 #ifdef FLOATINGPT
1021 if (rflag )
1023 mkcomment( dest, "#", 0);
1024 if (fpdis )
1025 if (spdenorm( (struct IEEEsp *)s_fs ) )
1026 sprintf (tmp, " fs=0.0 (sp denorm)");
1027 else if (spnan( (struct IEEEsp *)s_fs ) )
1028 sprintf (tmp, " fs=Nan");
1029 else
1030 sprintf (tmp, " fs=%e", *s_fs);
1031 else
1032 sprintf (tmp, " fs=0x%x", *s_fs);
1033 strcat (dest, tmp);
1035 #endif /* FLOATINGPT */
1036 break;
1037 case FS_FD_W:
1038 fd (); comma (); fs ();
1039 #ifdef FLOATINGPT
1040 if (rflag )
1042 mkcomment( dest, "# ", 0);
1043 sprintf (tmp, "fs=0x%x", *w_fs);
1044 strcat (dest, tmp);
1046 #endif /* FLOATINGPT */
1047 break;
1048 case FS_FD_L:
1049 fd (); comma (); fs ();
1050 #ifdef FLOATINGPT
1051 if (rflag )
1053 mkcomment( dest, "# ", 0);
1054 sprintf (tmp, "fs=%llx", *l_fs);
1055 strcat (dest, tmp);
1057 #endif /* FLOATINGPT */
1058 break;
1059 case FT_FS_D:
1060 fs (); comma (); ft ();
1061 #ifdef FLOATINGPT
1062 if (rflag )
1064 mkcomment( dest, "#", 0);
1065 if (fpdis )
1067 if (dpdenorm( (struct IEEEdp *)d_fs ) )
1068 sprintf (tmp, " fs=0.0 (dp denorm)");
1069 else if (dpnan( (struct IEEEdp *)d_fs ) )
1070 sprintf (tmp, " fs=Nan");
1071 else
1072 sprintf (tmp, " fs=%e", *d_fs);
1073 strcat (dest, tmp);
1074 if (dpdenorm( (struct IEEEdp *)d_ft ) )
1075 sprintf (tmp, " ft=0.0 (dp denorm)");
1076 else if (dpnan( (struct IEEEdp *)d_ft ) )
1077 sprintf (tmp, " ft=Nan");
1078 else
1079 sprintf (tmp, " ft=%e", *d_ft);
1081 else
1082 sprintf (tmp, " fs=%llx ft=%llx", *d_fs, *d_ft);
1083 strcat (dest, tmp);
1085 #endif /* FLOATINGPT */
1086 break;
1087 case FT_FS_S:
1088 fs (); comma (); ft ();
1089 #ifdef FLOATINGPT
1090 if (rflag )
1092 mkcomment( dest, "#", 0);
1093 if (fpdis )
1095 if (spdenorm( (struct IEEEsp *)s_fs ) )
1096 sprintf (tmp, " fs=0.0 (sp denorm)");
1097 if (spnan( (struct IEEEsp *)s_fs ) )
1098 sprintf (tmp, " fs=Nan");
1099 else
1100 sprintf (tmp, " fs=%e", *s_fs);
1101 strcat (dest, tmp);
1102 if (spdenorm( (struct IEEEsp *)s_ft ) )
1103 sprintf (tmp, " ft=0.0 (sp denorm)");
1104 else if (spnan( (struct IEEEsp *)s_ft ) )
1105 sprintf (tmp, " ft=Nan");
1106 else
1107 sprintf (tmp, " ft=%e", *s_ft);
1109 else
1110 sprintf (tmp, " fs=0x%x ft=0x%x", *s_fs, *s_ft);
1111 strcat (dest, tmp);
1113 #endif /* FLOATINGPT */
1114 break;
1115 case RT_RS_IMM:
1116 rt (); comma (); rs (); comma (); imm (dest);
1117 if (rflag )
1119 sprintf (tmp, " rs=0x%x", rsvalue);
1120 strcat (dest, tmp);
1122 break;
1123 case RT_RS_SIMM:
1124 rt (); comma (); rs (); comma (); simm (dest);
1125 if (rflag )
1127 sprintf (tmp, " rs=0x%x", rsvalue);
1128 strcat (dest, tmp);
1130 break;
1131 case RT_IMM:
1132 rt (); comma (); imm (dest);
1133 break;
1134 case RT_SIMM:
1135 rt (); comma (); simm (dest);
1136 break;
1137 case RS_SIMM:
1138 rs (); comma (); simm (dest);
1139 if (rflag )
1141 sprintf (tmp, " rs=0x%x", rsvalue);
1142 strcat (dest, tmp);
1144 break;
1145 case RT_RD:
1146 rt (); comma (); rd();
1147 break;
1148 case RT_RD_TO:
1149 rt (); comma (); rd();
1150 if (rflag )
1151 mkcomment( dest, "# rt=0x%x", rtvalue);
1152 break;
1153 case RD:
1154 rd ();
1155 break;
1156 case RD_RS:
1157 rd (); comma (); rs ();
1158 if (rflag )
1159 mkcomment( dest, "# rs=0x%x", rsvalue);
1160 break;
1161 case RT_C0:
1162 rt (); comma (); c0 ();
1163 break;
1164 case RT_C0_TO:
1165 rt (); comma (); c0 ();
1166 if (rflag )
1167 mkcomment( dest, "# rt=0x%x", rtvalue);
1168 break;
1169 case RT_C1:
1170 rt (); comma (); c1 ();
1171 break;
1172 case RT_C1_TO:
1173 rt (); comma (); c1 ();
1174 if (rflag )
1175 mkcomment( dest, "# rt=0x%x", rtvalue);
1176 break;
1177 case RT_C2:
1178 rt (); comma (); c2 ();
1179 break;
1180 case RT_CN:
1181 rt (); comma (); cn ();
1182 break;
1183 case RT_CN_TO:
1184 rt (); comma (); cn ();
1185 if (rflag )
1186 mkcomment( dest, "# rt=0x%x", rtvalue);
1187 break;
1188 case RT_CC1:
1189 rt (); comma (); cc1 ();
1190 break;
1191 case RT_CC1_TO:
1192 rt (); comma (); cc1 ();
1193 if (rflag )
1194 mkcomment( dest, "# rt=0x%x", rtvalue);
1195 break;
1196 case RT_CC2:
1197 rt (); comma (); cc2 ();
1198 break;
1199 case RD_RT_RS:
1200 rd (); comma (); rt (); comma (); rs();
1201 if (rflag )
1203 mkcomment( dest, "# rt=0x%x", rtvalue);
1204 sprintf (tmp, " rs=0x%x", rsvalue);
1205 strcat (dest, tmp);
1207 break;
1208 case JR:
1209 case RS:
1210 rs ();
1211 if (rflag )
1212 mkcomment( dest, "# rs=0x%x", rsvalue);
1213 break;
1214 case RD_RS_RT:
1215 rd (); comma ();
1216 case RS_RT:
1217 rs (); comma (); rt ();
1218 if (rflag )
1220 mkcomment( dest, "# rs=0x%x ", rsvalue);
1221 sprintf (tmp, " rt=0x%x", rtvalue);
1222 strcat (dest, tmp);
1224 break;
1225 case RD_RT:
1226 rd (); comma (); rt ();
1227 if (rflag )
1228 mkcomment( dest, "# rt=0x%x", rtvalue);
1229 break;
1230 case RD_RT_SFT:
1231 rd (); comma (); rt (); comma ();
1232 sprintf (tmp, "0x%x", SHAMT_ (inst));
1233 strcat (dest, tmp);
1234 mkcomment (dest, "# %d", SHAMT_ (inst));
1235 if (rflag )
1237 sprintf (tmp, " rt=0x%x", rtvalue);
1238 strcat (dest, tmp);
1240 break;
1241 case RS_RT_OFF:
1242 case RS_OFF:
1243 rs (); comma ();
1244 do_rs = 1;
1245 if (pt->type == RS_RT_OFF)
1247 rt (); comma ();
1248 if (rflag )
1249 do_rt = 1;
1251 case CP_OFF:
1252 case OFF:
1253 v = IMM_ (inst);
1254 if (v & (1L << 15))
1255 v |= 0xffff0000L;
1256 v1 = (long)4 + (v << 2);
1257 // if (!adr2symoff (tmp, v1, 0))
1258 // sprintf (tmp, "%x", v1);
1259 // strcat (dest, tmp);
1260 if (v & (1L << 15))
1262 sprintf(tmp, "-0x%x(PC)", -v1);
1263 strcat (dest, tmp);
1264 mkcomment (dest, "#pc - 0x%08x", -v1);
1266 else
1268 sprintf(tmp, "0x%x(PC)", v1);
1269 strcat (dest, tmp);
1270 mkcomment (dest, "#pc + 0x%08x", v1);
1272 if (rflag && do_rs )
1274 sprintf (tmp, " rs=0x%x", rsvalue);
1275 strcat (dest, tmp);
1276 do_rs = 0;
1278 if (rflag && do_rt )
1280 sprintf (tmp, " rt=0x%x", rtvalue);
1281 strcat (dest, tmp);
1282 do_rt = 0;
1284 break;
1285 case BPCODE:
1286 sprintf (tmp, "%d", (inst >> 16) & 0x3ff);
1287 strcat (dest, tmp);
1288 break;
1289 case COFUN:
1290 sprintf (tmp, "0x%x", inst & 0x01ffffffL);
1291 strcat (dest, tmp);
1292 break;
1293 case NONE:
1294 break;
1295 case TARGET:
1296 v = (inst & 0x03ffffff) << 2;
1297 // v |= ((int)addr & 0xf0000000);
1298 // if (!adr2symoff (tmp, v, 0))
1299 // sprintf (tmp, "%x", v);
1300 // strcat (dest, tmp);
1301 mkcomment (dest, "#. 0x**%06x", v);
1302 break;
1303 case JALR:
1304 if (RD_ (inst) != 31L)
1305 rd (); comma ();
1306 rs ();
1307 if (rflag )
1308 mkcomment( dest, "# rs=0x%x", rsvalue);
1309 break;
1310 case LDSTC0:
1311 v = IMM_ (inst);
1312 if (v & (1L << 15))
1313 v |= 0xffff0000L;
1314 c0ft (); comma ();
1315 sprintf (tmp, "%d", v);
1316 strcat (dest, tmp);
1317 strcat (dest, "(");
1318 rs ();
1319 strcat (dest, ")");
1320 mkcomment (dest, "# 0x%x", v);
1321 if (rflag )
1323 /* If wanting register contents, then add this too */
1324 sprintf (tmp, " addr=0x%x", (int)(v + rsvalue));
1325 strcat (dest, tmp);
1327 break;
1328 case LDSTC1:
1329 case STOREC1:
1330 v = IMM_ (inst);
1331 if (v & (1L << 15))
1332 v |= 0xffff0000L;
1333 c1ft (); comma ();
1334 sprintf (tmp, "%d", v);
1335 strcat (dest, tmp);
1336 strcat (dest, "(");
1337 rs ();
1338 strcat (dest, ")");
1339 mkcomment (dest, "# 0x%x", v);
1340 if (rflag )
1342 /* If wanting register contents, then add this too */
1343 sprintf (tmp, " addr=0x%x", (int)(v + rsvalue));
1344 strcat (dest, tmp);
1345 #ifdef FLOATINGPT
1346 if (pt->type == STOREC1 )
1348 if (fpdis) {
1349 if (dpdenorm( (struct IEEEdp *)d_ft ))
1350 sprintf (tmp, " ft=0.0 (dp denorm)");
1351 else if (dpnan ((struct IEEEdp *)d_ft))
1352 sprintf (tmp, " ft=Nan");
1353 else
1354 sprintf (tmp, " ft=%e", *d_ft);
1356 else
1357 sprintf (tmp, " rt=0x%llx", Fpr[(int)RT_(inst)]);
1358 strcat (dest, tmp);
1360 #endif /* FLOATINGPT */
1362 break;
1363 case LDSTCN:
1364 case STORECN:
1365 v = IMM_ (inst);
1366 if (v & (1L << 15))
1367 v |= 0xffff0000L;
1368 cnft (); comma ();
1369 sprintf (tmp, "%d", v);
1370 strcat (dest, tmp);
1371 strcat (dest, "(");
1372 rs ();
1373 strcat (dest, ")");
1374 mkcomment (dest, "# 0x%x", v);
1375 if (rflag )
1377 /* If wanting register contents, then add this too */
1378 sprintf (tmp, " addr=0x%x", (int)(v + rsvalue));
1379 strcat (dest, tmp);
1381 break;
1382 case LOAD_STORE:
1383 case STORE:
1384 rt (); comma ();
1385 load_store:
1386 v = IMM_ (inst);
1387 if (v & (1L << 15))
1388 v |= 0xffff0000L;
1389 sprintf (tmp, "%d", v);
1390 strcat (dest, tmp);
1391 strcat (dest, "(");
1392 rs ();
1393 strcat (dest, ")");
1394 if (rflag )
1396 /* If wanting register contents, then add this too */
1397 mkcomment( dest, "# addr=0x%x", (int)(v + rsvalue));
1398 if (pt->type == STORE )
1400 sprintf (tmp, " rt=0x%x", (int)rtvalue);
1401 strcat (dest, tmp);
1404 else
1405 mkcomment (dest, "# 0x%x", v);
1406 break;
1407 case CACHE_OP:
1408 sprintf (tmp, "%d,", RT_(inst));
1409 strcat (dest, tmp);
1410 goto load_store;
1411 case WORD:
1412 sprintf (tmp, "%08x", inst);
1413 strcat (dest, tmp);
1414 strcat (dest, " # ");
1415 w = (long)addr;
1416 for (i = 0; i < 4; i++) {
1417 v = load_byte ((u_int8_t *)w);
1418 w++;
1419 if (isprint (v))
1420 strccat (dest, v);
1421 else
1422 strccat (dest, '.');
1424 break;
1426 return (addr + 4L);
1429 int main(int ac, char *av[])
1431 int32_t adr;
1432 char buf[1024];
1433 char prnbuf[LINESZ + 8]; /* commonly used print buffer */
1434 FILE* fp;
1435 char *p, *q;
1437 if(ac != 2)
1439 printf("Pls use :dump file\n");
1440 return 1;
1442 fp = fopen(av[1], "r");
1443 if(NULL == fp)
1445 printf("file %s open error\n", av[1]);
1446 return 1;
1449 regname = regs_sw;
1450 c0reg = regs_c0;
1452 while (!feof(fp)) {
1453 memset(prnbuf, 0, LINESZ + 8);
1454 /* Enable this if you want a 'label' at the start of each
1455 * procedure.
1457 fgets(buf, 1024, fp);
1458 p = strstr(buf, ".word");
1459 if(!p)
1461 printf ("%s\n", buf);
1463 else{
1465 *p = '\0';
1466 p += 6;
1467 printf ("%s", buf);
1468 q = strstr(p, "\r");
1469 if(q)
1470 *q = '\0';
1471 get_rsa (&adr, p);
1472 // printf ("%8x\n", adr);
1473 // printf ("%s\n", p);
1474 md_disasm (prnbuf, &adr);
1475 printf ("%s\n", prnbuf);
1478 fclose(fp);
1479 return (0);