1 /* $NetBSD: db_disasm.c,v 1.19 2021/04/06 15:55:26 simonb Exp $ */
2
3 /*
4 * Copyright (c) 1994 David S. Miller, davem@nadzieja.rutgers.edu
5 * Copyright (c) 1995 Paul Kranenburg
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by David Miller.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.19 2021/04/06 15:55:26 simonb Exp $");
36
37 #include <sys/param.h>
38 #include <machine/db_machdep.h>
39 #include <machine/instr.h>
40 #include <ddb/db_sym.h>
41 #include <ddb/db_interface.h>
42 #include <ddb/db_user.h>
43 #include <ddb/db_extern.h>
44 #include <ddb/db_output.h>
45 #include <ddb/db_access.h>
46
47 #ifndef _KERNEL
48 #include <stdlib.h>
49 #endif
50
51 #ifndef V9
52 #define V9
53 #endif
54
55 /* Sign extend values */
56 #ifdef V9
57 #define SIGNEX(v,width) ((((long long)(v))<<(64-width))>>(64-width))
58 #else
59 #define SIGNEX(v,width) ((((int)(v))<<(32-width))>>(32-width))
60 #endif
61 #define SIGN(v) (((v)<0)?"-":"")
62
63 /*
64 * All Sparc instructions are 32-bits, with the one exception being
65 * the set instruction which is actually a macro which expands into
66 * two instructions...
67 *
68 * There are 5 different fields that can be used to identify which
69 * operation is encoded into a particular 32-bit insn. There are 3
70 * formats for instructions, which one being used is determined by
71 * bits 30-31 of the insn. Here are the bit fields and their names:
72 *
73 * 1100 0000 0000 0000 0000 0000 0000 0000 op field, determines format
74 * 0000 0001 1100 0000 0000 0000 0000 0000 op2 field, format 2 only
75 * 0000 0001 1111 1000 0000 0000 0000 0000 op3 field, format 3 only
76 * 0000 0000 0000 0000 0010 0000 0000 0000 f3i bit, format 3 only
77 * 0000 0000 0000 0000 0001 0000 0000 0000 X bit, format 3 only
78 */
79
80 #define OP(x) (((x) & 0x3) << 30)
81 #define OP2(x) (((x) & 0x7) << 22)
82 #define OP3(x) (((x) & 0x3f) << 19)
83 #define OPF(x) (((x) & 0x1ff) << 5)
84 #define F3I(x) (((x) & 0x1) << 13)
85
86 /* various other fields */
87
88 #define A(x) (((x) & 0x1) << 29)
89 #define P(x) (((x) & 0x1) << 19)
90 #define X(x) (((x) & 0x1) << 12)
91 #define FCN(x) (((x) & 0x1f) << 25)
92 #define RCOND2(x) (((x) & 0x7) << 25)
93 #define RCOND34(x) (((x) & 0x7) << 10)
94 #define COND(x) (((x) & 0xf) << 25)
95 #define SW_TRAP(x) ((x) & 0x7f)
96 #define SHCNT32(x) ((x) & 0x1f)
97 #define SHCNT64(x) ((x) & 0x3f)
98 #define IMM11(x) ((x) & 0x7ff)
99 #define IMM22(x) ((x) & 0x3fffff)
100 #define DISP19(x) ((x) & 0x7ffff)
101 #define DISP22(x) ((x) & 0x3fffff)
102 #define DISP30(x) ((x) & 0x3fffffffL)
103
104 /* Register Operand Fields */
105 #define RS1(x) (((x) & 0x1f) << 14)
106 #define RS2(x) ((x) & 0x1f)
107 #define RD(x) (((x) & 0x1f) << 25)
108
109 /* FORMAT macros used in sparc_i table to decode each opcode */
110 #define FORMAT1(a) (OP(a))
111 #define FORMAT2(a,b) (OP(a) | OP2(b))
112 #define FORMAT3(a,b,c) (OP(a) | OP3(b) | F3I(c))
113 #define FORMAT3F(a,b,c) (OP(a) | OP3(b) | OPF(c))
114
115 /* Helper macros to construct OP3 & OPF */
116 #define OP3_X(x,y) ((((x) & 3) << 4) | ((y) & 0xf))
117 #define OPF_X(x,y) ((((x) & 0x1f) << 4) | ((y) & 0xf))
118
119 /* COND condition codes field... */
120 #define COND2(y,x) (((((y)<<4) & 1)|((x) & 0xf)) << 14)
121
122 struct sparc_insn {
123 unsigned int match;
124 const char* name;
125 const char* format;
126 };
127
128 const char* regs[] = {
129 "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
130 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
131 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
132 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7"
133 };
134
135 const char* priv_regs[] = {
136 "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
137 "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
138 "wstate", "fq",
139 "", "", "", "", "", "", "", "",
140 "", "", "", "", "", "", "", "ver"
141 };
142
143 const char* state_regs[] = {
144 "y", "", "ccr", "asi", "tick", "pc", "fprs", "asr",
145 "", "", "", "", "", "", "", "",
146 "pcr", "pic", "dcr", "gsr", "set_softint", "clr_softint", "softint", "tick_cmpr", "",
147 "", "", "", "", "", "", "", ""
148 };
149
150 const char* ccodes[] = {
151 "fcc0", "fcc1", "fcc2", "fcc3", "icc", "", "xcc", ""
152 };
153
154 const char* prefetch[] = {
155 "n_reads", "one_read", "n_writes", "one_write", "page"
156 };
157
158
159 /* The sparc instruction table has a format field which tells what
160 the operand structure for this instruction is. Here are the codes:
161
162 Modifiers (nust be first):
163 a -- opcode has annul bit
164 p -- opcode has branch prediction bit
165
166 Codes:
167 1 -- source register operand stored in rs1
168 2 -- source register operand stored in rs2
169 d -- destination register operand stored in rd
170 3 -- floating source register in rs1
171 4 -- floating source register in rs2
172 e -- floating destination register in rd
173 i -- 13-bit immediate value stored in simm13
174 j -- 11-bit immediate value stored in simm11
175 l -- displacement using d16lo and d16hi
176 m -- 22-bit fcc displacement value
177 n -- 30-bit displacement used in call insns
178 o -- %fcc number specified in cc1 and cc0 fields
179 p -- address computed by the contents of rs1+rs2
180 q -- address computed by the contents of rs1+simm13
181 r -- prefetch
182 s -- %asi is implicit in the insn, rs1 value not used
183 t -- immediate 8-bit asi value
184 u -- 19-bit fcc displacement value
185 5 -- hard register, %fsr lower-half
186 6 -- hard register, %fsr all
187 7 -- [reg_addr rs1+rs2] imm_asi
188 8 -- [reg_addr rs1+simm13] %asi
189 9 -- logical or of the cmask and mmask fields (membar insn)
190 0 -- icc or xcc condition codes register
191 . -- %fcc, %icc, or %xcc in opf_cc field
192 r -- prefection function stored in fcn field
193 A -- privileged register encoded in rs1
194 B -- state register encoded in rs1
195 C -- %hi(value) where value is stored in imm22 field
196 D -- 32-bit shift count in shcnt32
197 E -- 64-bit shift count in shcnt64
198 F -- software trap number stored in sw_trap
199 G -- privileged register encoded in rd
200 H -- state register encoded in rd
201
202 V8 only:
203 Y -- write y register
204 P -- write psr register
205 T -- write tbr register
206 W -- write wim register
207 */
208
209
210 struct sparc_insn sparc_i[] = {
211
212 /*
213 * Format 1: Call
214 */
215 {(FORMAT1(1)), "call", "n"},
216
217 /*
218 * Format 0: Sethi & Branches
219 */
220 /* Illegal Instruction Trap */
221 {(FORMAT2(0, 0)), "illtrap", "m"},
222
223 /* Note: if imm22 is zero then this is actually a "nop" grrr... */
224 {(FORMAT2(0, 0x4)), "sethi", "Cd"},
225
226 /* Branch on Integer Condition Codes "Bicc" */
227 {(FORMAT2(0, 2) | COND(8)), "ba", "a,m"},
228 {(FORMAT2(0, 2) | COND(0)), "bn", "a,m"},
229 {(FORMAT2(0, 2) | COND(9)), "bne", "a,m"},
230 {(FORMAT2(0, 2) | COND(1)), "be", "a,m"},
231 {(FORMAT2(0, 2) | COND(10)), "bg", "a,m"},
232 {(FORMAT2(0, 2) | COND(2)), "ble", "a,m"},
233 {(FORMAT2(0, 2) | COND(11)), "bge", "a,m"},
234 {(FORMAT2(0, 2) | COND(3)), "bl", "a,m"},
235 {(FORMAT2(0, 2) | COND(12)), "bgu", "a,m"},
236 {(FORMAT2(0, 2) | COND(4)), "bleu", "a,m"},
237 {(FORMAT2(0, 2) | COND(13)), "bcc", "a,m"},
238 {(FORMAT2(0, 2) | COND(5)), "bcs", "a,m"},
239 {(FORMAT2(0, 2) | COND(14)), "bpos", "a,m"},
240 {(FORMAT2(0, 2) | COND(6)), "bneg", "a,m"},
241 {(FORMAT2(0, 2) | COND(15)), "bvc", "a,m"},
242 {(FORMAT2(0, 2) | COND(7)), "bvs", "a,m"},
243
244 /* Branch on Integer Condition Codes with Prediction "BPcc" */
245 {(FORMAT2(0, 1) | COND(8)), "ba", "ap,u"},
246 {(FORMAT2(0, 1) | COND(0)), "bn", "ap,u"},
247 {(FORMAT2(0, 1) | COND(9)), "bne", "ap,u"},
248 {(FORMAT2(0, 1) | COND(1)), "be", "ap,u"},
249 {(FORMAT2(0, 1) | COND(10)), "bg", "ap,u"},
250 {(FORMAT2(0, 1) | COND(2)), "ble", "ap,u"},
251 {(FORMAT2(0, 1) | COND(11)), "bge", "ap,u"},
252 {(FORMAT2(0, 1) | COND(3)), "bl", "ap,u"},
253 {(FORMAT2(0, 1) | COND(12)), "bgu", "ap,u"},
254 {(FORMAT2(0, 1) | COND(4)), "bleu", "ap,u"},
255 {(FORMAT2(0, 1) | COND(13)), "bcc", "ap,u"},
256 {(FORMAT2(0, 1) | COND(5)), "bcs", "ap,u"},
257 {(FORMAT2(0, 1) | COND(14)), "bpos", "ap,u"},
258 {(FORMAT2(0, 1) | COND(6)), "bneg", "ap,u"},
259 {(FORMAT2(0, 1) | COND(15)), "bvc", "ap,u"},
260 {(FORMAT2(0, 1) | COND(7)), "bvs", "ap,u"},
261
262 /* Branch on Integer Register with Prediction "BPr" */
263 {(FORMAT2(0, 3) | RCOND2(1)), "brz", "ap,1l"},
264 {(FORMAT2(0, 3) | A(1) | P(1) | RCOND2(2)), "brlex", "ap,1l"},
265 {(FORMAT2(0, 3) | RCOND2(3)), "brlz", "ap,1l"},
266 {(FORMAT2(0, 3) | RCOND2(5)), "brnz", "ap,1l"},
267 {(FORMAT2(0, 3) | RCOND2(6)), "brgz", "ap,1l"},
268 {(FORMAT2(0, 3) | RCOND2(7)), "brgez", "ap,1l"},
269
270 /* Branch on Floating-Point Condition Codes with Prediction "FBPfcc" */
271 {(FORMAT2(0, 5) | COND(8)), "fba", "ap,m"},
272 {(FORMAT2(0, 5) | COND(0)), "fbn", "ap,m"},
273 {(FORMAT2(0, 5) | COND(7)), "fbu", "ap,m"},
274 {(FORMAT2(0, 5) | COND(6)), "fbg", "ap,m"},
275 {(FORMAT2(0, 5) | COND(5)), "fbug", "ap,m"},
276 {(FORMAT2(0, 5) | COND(4)), "fbl", "ap,m"},
277 {(FORMAT2(0, 5) | COND(3)), "fbul", "ap,m"},
278 {(FORMAT2(0, 5) | COND(2)), "fblg", "ap,m"},
279 {(FORMAT2(0, 5) | COND(1)), "fbne", "ap,m"},
280 {(FORMAT2(0, 5) | COND(9)), "fbe", "ap,m"},
281 {(FORMAT2(0, 5) | COND(10)), "fbue", "ap,m"},
282 {(FORMAT2(0, 5) | COND(11)), "fbge", "ap,m"},
283 {(FORMAT2(0, 5) | COND(12)), "fbuge", "ap,m"},
284 {(FORMAT2(0, 5) | COND(13)), "fble", "ap,m"},
285 {(FORMAT2(0, 5) | COND(14)), "fbule", "ap,m"},
286 {(FORMAT2(0, 5) | COND(15)), "fbo", "ap,m"},
287
288 /* Branch on Floating-Point Condition Codes "FBfcc" */
289 {(FORMAT2(0, 6) | COND(8)), "fba", "a,m"},
290 {(FORMAT2(0, 6) | COND(0)), "fbn", "a,m"},
291 {(FORMAT2(0, 6) | COND(7)), "fbu", "a,m"},
292 {(FORMAT2(0, 6) | COND(6)), "fbg", "a,m"},
293 {(FORMAT2(0, 6) | COND(5)), "fbug", "a,m"},
294 {(FORMAT2(0, 6) | COND(4)), "fbl", "a,m"},
295 {(FORMAT2(0, 6) | COND(3)), "fbul", "a,m"},
296 {(FORMAT2(0, 6) | COND(2)), "fblg", "a,m"},
297 {(FORMAT2(0, 6) | COND(1)), "fbne", "a,m"},
298 {(FORMAT2(0, 6) | COND(9)), "fbe", "a,m"},
299 {(FORMAT2(0, 6) | COND(10)), "fbue", "a,m"},
300 {(FORMAT2(0, 6) | COND(11)), "fbge", "a,m"},
301 {(FORMAT2(0, 6) | COND(12)), "fbuge", "a,m"},
302 {(FORMAT2(0, 6) | COND(13)), "fble", "a,m"},
303 {(FORMAT2(0, 6) | COND(14)), "fbule", "a,m"},
304 {(FORMAT2(0, 6) | COND(15)), "fbo", "a,m"},
305
306
307
308 /*
309 * Format 3/2: Arithmetic & misc (table 32, appendix E)
310 */
311 {FORMAT3(2, OP3_X(0,0), 0), "add", "12d"},
312 {FORMAT3(2, OP3_X(0,0), 1), "add", "1id"},
313 {FORMAT3(2, OP3_X(1,0), 0), "addcc", "12d"},
314 {FORMAT3(2, OP3_X(1,0), 1), "addcc", "1id"},
315 {FORMAT3(2, OP3_X(2,0), 0), "taddcc", "12d"},
316 {FORMAT3(2, OP3_X(2,0), 1), "taddcc", "1id"},
317 #ifdef V9
318 {(FORMAT3(2, 0x30, 1) | RD(0xf)), "sir", "i"},
319 {FORMAT3(2, OP3_X(3,0), 0), "wr", "12H"},
320 {FORMAT3(2, OP3_X(3,0), 1), "wr", "1iH"},
321 #else
322 {FORMAT3(2, OP3_X(3,0), 0), "wr", "12Y"}, /* wr 1, 2, %y */
323 {FORMAT3(2, OP3_X(3,0), 1), "wr", "1iY"}, /* wr 1, i, %y */
324 #endif
325
326 {FORMAT3(2, OP3_X(0,1), 0), "and", "12d"},
327 {FORMAT3(2, OP3_X(0,1), 1), "and", "1id"},
328 {FORMAT3(2, OP3_X(1,1), 0), "andcc", "12d"},
329 {FORMAT3(2, OP3_X(1,1), 1), "andcc", "1id"},
330 {FORMAT3(2, OP3_X(2,1), 0), "tsubcc", "12d"},
331 {FORMAT3(2, OP3_X(2,1), 1), "tsubcc", "1id"},
332 #ifdef V9
333 {FORMAT3(2, OP3_X(3,1), 0), "saved", ""},
334 {FORMAT3(2, OP3_X(3,1), 0)|FCN(1), "restored", ""},
335 #else
336 {FORMAT3(2, OP3_X(3,1), 0), "wr", "12P"}, /* wr 1, 2, %psr */
337 {FORMAT3(2, OP3_X(3,1), 1), "wr", "1iP"}, /* wr 1, i, %psr */
338 #endif
339
340 {FORMAT3(2, OP3_X(0,2), 0), "or", "12d"},
341 {FORMAT3(2, OP3_X(0,2), 1), "or", "1id"},
342 {FORMAT3(2, OP3_X(1,2), 0), "orcc", "12d"},
343 {FORMAT3(2, OP3_X(1,2), 1), "orcc", "1id"},
344 {FORMAT3(2, OP3_X(2,2), 0), "taddcctv", "12d"},
345 {FORMAT3(2, OP3_X(2,2), 1), "taddcctv", "1id"},
346 #ifdef V9
347 {FORMAT3(2, OP3_X(3,2), 0), "wrpr", "12G"},
348 {FORMAT3(2, OP3_X(3,2), 1), "wrpr", "1iG"},
349 #else
350 {FORMAT3(2, OP3_X(3,2), 0), "wr", "12W"}, /* wr 1, 2, %wim */
351 {FORMAT3(2, OP3_X(3,2), 1), "wr", "1iW"}, /* wr 1, i, %wim */
352 #endif
353
354 {FORMAT3(2, OP3_X(0,3), 0), "xor", "12d"},
355 {FORMAT3(2, OP3_X(0,3), 1), "xor", "1id"},
356 {FORMAT3(2, OP3_X(1,3), 0), "xorcc", "12d"},
357 {FORMAT3(2, OP3_X(1,3), 1), "xorcc", "1id"},
358 {FORMAT3(2, OP3_X(2,3), 0), "tsubcctv", "12d"},
359 {FORMAT3(2, OP3_X(2,3), 1), "tsubcctv", "1id"},
360 #ifdef V9
361 {FORMAT3(2, OP3_X(3,3), 0), "UNDEFINED", ""},
362 #else
363 {FORMAT3(2, OP3_X(3,3), 0), "wr", "12T"}, /* wr 1, 2, %tbr */
364 {FORMAT3(2, OP3_X(3,3), 1), "wr", "1iT"}, /* wr 1, i, %tbr */
365 #endif
366
367 {FORMAT3(2, OP3_X(0,4), 0), "sub", "12d"},
368 {FORMAT3(2, OP3_X(0,4), 1), "sub", "1id"},
369 {FORMAT3(2, OP3_X(1,4), 0), "subcc", "12d"},
370 {FORMAT3(2, OP3_X(1,4), 1), "subcc", "1id"},
371 {FORMAT3(2, OP3_X(2,4), 0), "mulscc", "12d"},
372 {FORMAT3(2, OP3_X(2,4), 1), "mulscc", "1id"},
373 {FORMAT3(2, OP3_X(3,4), 1), "FPop1", ""}, /* see below */
374
375 {FORMAT3(2, OP3_X(0,5), 0), "andn", "12d"},
376 {FORMAT3(2, OP3_X(0,5), 1), "andn", "1id"},
377 {FORMAT3(2, OP3_X(1,5), 0), "andncc", "12d"},
378 {FORMAT3(2, OP3_X(1,5), 1), "andncc", "1id"},
379 {FORMAT3(2, OP3_X(2,5), 0), "sll", "12d"},
380 {FORMAT3(2, OP3_X(2,5), 1), "sll", "1Dd"},
381 {FORMAT3(2, OP3_X(2,5), 0)|X(1), "sllx", "12d"},
382 {FORMAT3(2, OP3_X(2,5), 1)|X(1), "sllx", "1Ed"},
383 {FORMAT3(2, OP3_X(3,5), 1), "FPop2", ""}, /* see below */
384
385 {FORMAT3(2, OP3_X(0,6), 0), "orn", "12d"},
386 {FORMAT3(2, OP3_X(0,6), 1), "orn", "1id"},
387 {FORMAT3(2, OP3_X(1,6), 0), "orncc", "12d"},
388 {FORMAT3(2, OP3_X(1,6), 1), "orncc", "1id"},
389 {FORMAT3(2, OP3_X(2,6), 0), "srl", "12d"},
390 {FORMAT3(2, OP3_X(2,6), 1), "srl", "1Dd"},
391 {FORMAT3(2, OP3_X(2,6), 0)|X(1), "srlx", "12d"},
392 {FORMAT3(2, OP3_X(2,6), 1)|X(1), "srlx", "1Ed"},
393 {FORMAT3(2, OP3_X(3,6), 1), "impdep1", ""},
394
395 {FORMAT3(2, OP3_X(0,7), 0), "xorn", "12d"},
396 {FORMAT3(2, OP3_X(0,7), 1), "xorn", "1id"},
397 {FORMAT3(2, OP3_X(1,7), 0), "xorncc", "12d"},
398 {FORMAT3(2, OP3_X(1,7), 1), "xorncc", "1id"},
399 {FORMAT3(2, OP3_X(2,7), 0), "sra", "12d"},
400 {FORMAT3(2, OP3_X(2,7), 1), "sra", "1Dd"},
401 {FORMAT3(2, OP3_X(2,7), 0)|X(1), "srax", "12d"},
402 {FORMAT3(2, OP3_X(2,7), 1)|X(1), "srax", "1Ed"},
403 {FORMAT3(2, OP3_X(3,7), 1), "impdep2", ""},
404
405 {FORMAT3(2, OP3_X(0,8), 0), "addc", "12d"},
406 {FORMAT3(2, OP3_X(0,8), 1), "addc", "1id"},
407 {FORMAT3(2, OP3_X(1,8), 0), "addccc", "12d"},
408 {FORMAT3(2, OP3_X(1,8), 1), "addccc", "1id"},
409 #ifdef V9
410 {(FORMAT3(2, 0x28, 1) | RS1(15)), "membar", "9"},
411 {(FORMAT3(2, 0x28, 0) | RS1(15)), "stbar", ""},
412 {FORMAT3(2, OP3_X(2,8), 0), "rd", "Bd"},
413 #else
414 {FORMAT3(2, OP3_X(2,8), 0), "rd", "Yd"},
415 #endif
416
417 {FORMAT3(2, OP3_X(3,8), 0), "jmpl", "pd"},
418 {FORMAT3(2, OP3_X(3,8), 1), "jmpl", "qd"},
419
420 {FORMAT3(2, OP3_X(0,9), 0), "mulx", "12d"},
421 {FORMAT3(2, OP3_X(0,9), 1), "mulx", "1id"},
422 {FORMAT3(2, OP3_X(1,9), 0), "UNDEFINED", ""},
423 #ifdef V9
424 {FORMAT3(2, OP3_X(2,9), 0), "UNDEFINED", ""},
425 #else
426 {FORMAT3(2, OP3_X(2,9), 0), "rd", "Pd"},
427 #endif
428 {FORMAT3(2, OP3_X(3,9), 0), "return", "p"},
429 {FORMAT3(2, OP3_X(3,9), 1), "return", "q"},
430
431 {FORMAT3(2, OP3_X(0,10), 0), "umul", "12d"},
432 {FORMAT3(2, OP3_X(0,10), 1), "umul", "1id"},
433 {FORMAT3(2, OP3_X(1,10), 0), "umulcc", "12d"},
434 {FORMAT3(2, OP3_X(1,10), 1), "umulcc", "1id"},
435 #ifdef V9
436 {FORMAT3(2, OP3_X(2,10), 0), "rdpr", "Ad"},
437 #else
438 {FORMAT3(2, OP3_X(2,10), 0), "rd", "Wd"},
439 #endif
440 /*
441 * OP3 = (3,10): TCC: Trap on Integer Condition Codes
442 */
443 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0x8)), "ta", "12F"},
444 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0x8)), "ta", "0F"},
445 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0x0)), "tn", "12F"},
446 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0x0)), "tn", "0F"},
447 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0x9)), "tne", "12F"},
448 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0x9)), "tne", "0F"},
449 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0x1)), "te", "12F"},
450 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0x1)), "te", "0F"},
451 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0xa)), "tg", "12F"},
452 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0xa)), "tg", "0F"},
453 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0x2)), "tle", "12F"},
454 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0x2)), "tle", "0F"},
455 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0xb)), "tge", "12F"},
456 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0xb)), "tge", "0F"},
457 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0x3)), "tl", "12F"},
458 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0x3)), "tl", "0F"},
459 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0xc)), "tgu", "12F"},
460 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0xc)), "tgu", "0F"},
461 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0x4)), "tleu", "12F"},
462 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0x4)), "tleu", "0F"},
463 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0xd)), "tcc", "12F"},
464 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0xd)), "tcc", "0F"},
465 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0x5)), "tcs", "12F"},
466 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0x5)), "tcs", "0F"},
467 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0xe)), "tpos", "12F"},
468 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0xe)), "tpos", "0F"},
469 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0x6)), "tneg", "12F"},
470 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0x6)), "tneg", "0F"},
471 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0xf)), "tvc", "12F"},
472 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0xf)), "tvc", "0F"},
473 {(FORMAT3(2, OP3_X(3,10), 0) | COND(0x7)), "tvs", "12F"},
474 {(FORMAT3(2, OP3_X(3,10), 1) | COND(0x7)), "tvs", "0F"},
475
476 {FORMAT3(2, OP3_X(0,11), 0), "smul", "12d"},
477 {FORMAT3(2, OP3_X(0,11), 1), "smul", "1id"},
478 {FORMAT3(2, OP3_X(1,11), 0), "smulcc", "12d"},
479 {FORMAT3(2, OP3_X(1,11), 1), "smulcc", "1id"},
480 #ifdef V9
481 {FORMAT3(2, OP3_X(2,11), 0), "flushw", ""},
482 #else
483 {FORMAT3(2, OP3_X(2,11), 0), "rd", "Td"},
484 #endif
485 {FORMAT3(2, OP3_X(3,11), 0), "flush", "p"},
486 {FORMAT3(2, OP3_X(3,11), 1), "flush", "q"},
487
488 {FORMAT3(2, OP3_X(0,12), 0), "subc", "12d"},
489 {FORMAT3(2, OP3_X(0,12), 1), "subc", "1id"},
490 {FORMAT3(2, OP3_X(1,12), 0), "subccc", "12d"},
491 {FORMAT3(2, OP3_X(1,12), 1), "subccc", "1id"},
492 /*
493 * OP3 = (2,12): MOVcc, Move Integer Register on Condition
494 */
495 /* For Integer Condition Codes */
496 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,8)), "mova", "0jd"},
497 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,8)), "mova", "02d"},
498 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,0)), "movn", "0jd"},
499 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,0)), "movn", "02d"},
500 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,9)), "movne", "0jd"},
501 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,9)), "movne", "02d"},
502 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,1)), "move", "0jd"},
503 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,1)), "move", "02d"},
504 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,10)), "movg", "0jd"},
505 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,10)), "movg", "02d"},
506 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,2)), "movle", "0jd"},
507 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,2)), "movle", "02d"},
508 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,11)), "movge", "0jd"},
509 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,11)), "movge", "02d"},
510 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,3)), "movl", "0jd"},
511 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,3)), "movl", "02d"},
512 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,12)), "movgu", "0jd"},
513 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,12)), "movgu", "02d"},
514 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,4)), "movleu", "0jd"},
515 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,4)), "movleu", "02d"},
516 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,13)), "movcc", "0jd"},
517 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,13)), "movcc", "02d"},
518 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,5)), "movcs", "0jd"},
519 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,5)), "movcs", "02d"},
520 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,14)), "movpos", "0jd"},
521 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,14)), "movpos", "02d"},
522 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,6)), "movneg", "0jd"},
523 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,6)), "movneg", "02d"},
524 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,15)), "movvc", "0jd"},
525 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,15)), "movvc", "02d"},
526 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,7)), "movvs", "0jd"},
527 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,7)), "movvs", "02d"},
528
529 /* For Floating-Point Condition Codes */
530 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,8)), "mova", "ojd"},
531 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,8)), "mova", "o2d"},
532 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,0)), "movn", "ojd"},
533 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,0)), "movn", "o2d"},
534 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,7)), "movu", "ojd"},
535 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,7)), "movu", "o2d"},
536 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,6)), "movg", "ojd"},
537 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,6)), "movg", "o2d"},
538 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,5)), "movug", "ojd"},
539 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,5)), "movug", "o2d"},
540 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,4)), "movl", "ojd"},
541 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,4)), "movl", "o2d"},
542 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,3)), "movul", "ojd"},
543 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,3)), "movul", "o2d"},
544 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,2)), "movlg", "ojd"},
545 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,2)), "movlg", "o2d"},
546 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,1)), "movne", "ojd"},
547 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,1)), "movne", "o2d"},
548 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,9)), "move", "ojd"},
549 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,9)), "move", "o2d"},
550 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,10)), "movue", "ojd"},
551 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,10)), "movue", "o2d"},
552 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,11)), "movge", "ojd"},
553 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,11)), "movge", "o2d"},
554 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,12)), "movuge", "ojd"},
555 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,12)), "movuge", "o2d"},
556 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,13)), "movle", "ojd"},
557 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,13)), "movle", "o2d"},
558 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,14)), "movule", "ojd"},
559 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,14)), "movule", "o2d"},
560 {(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,15)), "movo", "ojd"},
561 {(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,15)), "movo", "o2d"},
562
563 {FORMAT3(2, OP3_X(3,12), 0), "save", "12d"},
564 {FORMAT3(2, OP3_X(3,12), 1), "save", "1id"},
565
566 {FORMAT3(2, OP3_X(0,13), 0), "udivx", "12d"},
567 {FORMAT3(2, OP3_X(0,13), 1), "udivx", "1id"},
568 {FORMAT3(2, OP3_X(1,13), 0), "UNDEFINED", ""},
569 {FORMAT3(2, OP3_X(2,13), 0), "sdivx", "12d"},
570 {FORMAT3(2, OP3_X(2,13), 1), "sdivx", "1id"},
571 {FORMAT3(2, OP3_X(3,13), 0), "restore", "12d"},
572 {FORMAT3(2, OP3_X(3,13), 1), "restore", "1id"},
573
574 {FORMAT3(2, OP3_X(0,14), 0), "udiv", "12d"},
575 {FORMAT3(2, OP3_X(0,14), 1), "udiv", "1id"},
576 {FORMAT3(2, OP3_X(1,14), 0), "udivcc", "12d"},
577 {FORMAT3(2, OP3_X(1,14), 1), "udivcc", "1id"},
578 {FORMAT3(2, OP3_X(2,14), 0), "popc", "2d"},
579 {FORMAT3(2, OP3_X(2,14), 1), "popc", "id"},
580
581 {FORMAT3(2, OP3_X(3,14), 0), "done", ""},
582 {FORMAT3(2, OP3_X(3,14)|FCN(1), 1), "retry", ""},
583
584 {FORMAT3(2, OP3_X(0,15), 0), "sdiv", "12d"},
585 {FORMAT3(2, OP3_X(0,15), 1), "sdiv", "1id"},
586 {FORMAT3(2, OP3_X(1,15), 0), "sdivcc", "12d"},
587 {FORMAT3(2, OP3_X(1,15), 1), "sdivcc", "1id"},
588 /*
589 * OP3 = (2,15): MOVr:
590 * Move Integer Register on Register Condition
591 */
592 {(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(1)), "movrz", "1jd"},
593 {(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(1)), "movrz", "12d"},
594 {(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(2)), "movrlez", "1jd"},
595 {(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(2)), "movrlez", "12d"},
596 {(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(3)), "movrlz", "1jd"},
597 {(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(3)), "movrlz", "12d"},
598 {(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(5)), "movrnz", "1jd"},
599 {(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(5)), "movrnz", "12d"},
600 {(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(6)), "movrgz", "1jd"},
601 {(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(6)), "movrgz", "12d"},
602 {(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(7)), "movrgez", "1jd"},
603 {(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(7)), "movrgez", "12d"},
604
605 {FORMAT3(2, OP3_X(3,15), 0), "UNDEFINED", ""},
606
607
608 /*
609 * Format 3/3: Load and store (appendix E, table 33)
610 */
611
612 /* Loads */
613 {(FORMAT3(3, OP3_X(0,0), 0)), "ld", "pd"}, /* officially: lduw */
614 {(FORMAT3(3, OP3_X(0,0), 1)), "ld", "qd"},
615 {(FORMAT3(3, OP3_X(1,0), 0)), "lda", "7d"}, /* officially: lduwa */
616 {(FORMAT3(3, OP3_X(1,0), 1)), "lda", "8d"},
617 {(FORMAT3(3, OP3_X(2,0), 0)), "ldf", "pe"},
618 {(FORMAT3(3, OP3_X(2,0), 1)), "ldf", "qe"},
619 {(FORMAT3(3, OP3_X(3,0), 0)), "ldfa", "7e"},
620 {(FORMAT3(3, OP3_X(3,0), 1)), "ldfa", "8e"},
621
622 {(FORMAT3(3, OP3_X(0,1), 0)), "ldub", "pd"},
623 {(FORMAT3(3, OP3_X(0,1), 1)), "ldub", "qd"},
624 {(FORMAT3(3, OP3_X(1,1), 0)), "lduba", "7d"},
625 {(FORMAT3(3, OP3_X(1,1), 1)), "lduba", "8d"},
626 {(FORMAT3(3, OP3_X(2,1), 0) | RD(0)), "ld", "p5"},
627 {(FORMAT3(3, OP3_X(2,1), 1) | RD(0)), "ld", "q5"},
628 {(FORMAT3(3, OP3_X(2,1), 0) | RD(1)), "ldx", "p6"},
629 {(FORMAT3(3, OP3_X(2,1), 1) | RD(1)), "ldx", "q6"},
630
631 {(FORMAT3(3, OP3_X(0,2), 0)), "lduh", "pd"},
632 {(FORMAT3(3, OP3_X(0,2), 1)), "lduh", "qd"},
633 {(FORMAT3(3, OP3_X(1,2), 0)), "lduha", "7d"},
634 {(FORMAT3(3, OP3_X(1,2), 1)), "lduha", "8d"},
635 {(FORMAT3(3, OP3_X(2,2), 0)), "ldq", "pe"},
636 {(FORMAT3(3, OP3_X(2,2), 1)), "ldq", "qe"},
637 {(FORMAT3(3, OP3_X(3,2), 0)), "ldqa", "7e"},
638 {(FORMAT3(3, OP3_X(3,2), 1)), "ldqa", "8e"},
639
640 {(FORMAT3(3, OP3_X(0,3), 0)), "ldd", "pd"},
641 {(FORMAT3(3, OP3_X(0,3), 1)), "ldd", "qd"},
642 {(FORMAT3(3, OP3_X(1,3), 0)), "ldda", "7d"},
643 {(FORMAT3(3, OP3_X(1,3), 1)), "ldda", "8d"},
644 {(FORMAT3(3, OP3_X(2,3), 0)), "ldd", "pe"},
645 {(FORMAT3(3, OP3_X(2,3), 1)), "ldd", "qe"},
646 {(FORMAT3(3, OP3_X(3,3), 0)), "ldda", "7e"},
647 {(FORMAT3(3, OP3_X(3,3), 1)), "ldda", "8e"},
648
649 {(FORMAT3(3, OP3_X(0,4), 0)), "st", "dp"}, /* officially: stw */
650 {(FORMAT3(3, OP3_X(0,4), 1)), "st", "dq"},
651 {(FORMAT3(3, OP3_X(1,4), 0)), "sta", "d7"}, /* officially: stwa */
652 {(FORMAT3(3, OP3_X(1,4), 1)), "sta", "d8"},
653 {(FORMAT3(3, OP3_X(2,4), 0)), "st", "ep"},
654 {(FORMAT3(3, OP3_X(2,4), 1)), "st", "eq"},
655 {(FORMAT3(3, OP3_X(3,4), 0)), "sta", "e7"},
656 {(FORMAT3(3, OP3_X(3,4), 1)), "sta", "e8"},
657
658 {(FORMAT3(3, OP3_X(0,5), 0)), "stb", "dp"},
659 {(FORMAT3(3, OP3_X(0,5), 1)), "stb", "dq"},
660 {(FORMAT3(3, OP3_X(1,5), 0)), "stba", "d7"},
661 {(FORMAT3(3, OP3_X(1,5), 1)), "stba", "d8"},
662 {(FORMAT3(3, OP3_X(2,5), 0)), "st", "5p"},
663 {(FORMAT3(3, OP3_X(2,5), 1)), "st", "5q"},
664 {(FORMAT3(3, OP3_X(2,5), 0)|RD(1)), "stx", "6p"},
665 {(FORMAT3(3, OP3_X(2,5), 1)|RD(1)), "stx", "6q"},
666
667 {(FORMAT3(3, OP3_X(0,6), 0)), "sth", "dp"},
668 {(FORMAT3(3, OP3_X(0,6), 1)), "sth", "dq"},
669 {(FORMAT3(3, OP3_X(1,6), 0)), "stha", "d7"},
670 {(FORMAT3(3, OP3_X(1,6), 1)), "stha", "d8"},
671 {(FORMAT3(3, OP3_X(2,6), 0)), "stq", "ep"},
672 {(FORMAT3(3, OP3_X(2,6), 1)), "stq", "eq"},
673 {(FORMAT3(3, OP3_X(3,6), 0)), "stqa", "e7"},
674 {(FORMAT3(3, OP3_X(3,6), 1)), "stqa", "e8"},
675
676 {(FORMAT3(3, OP3_X(0,7), 0)), "std", "dp"},
677 {(FORMAT3(3, OP3_X(0,7), 1)), "std", "dq"},
678 {(FORMAT3(3, OP3_X(1,7), 0)), "stda", "d7"},
679 {(FORMAT3(3, OP3_X(1,7), 1)), "stda", "d8"},
680 {(FORMAT3(3, OP3_X(2,7), 0)), "std", "ep"},
681 {(FORMAT3(3, OP3_X(2,7), 1)), "std", "eq"},
682 {(FORMAT3(3, OP3_X(3,7), 0)), "stda", "e7"},
683 {(FORMAT3(3, OP3_X(3,7), 1)), "stda", "e8"},
684
685 {(FORMAT3(3, OP3_X(0,8), 0)), "ldsw", "pd"},
686 {(FORMAT3(3, OP3_X(0,8), 1)), "ldsw", "qd"},
687 {(FORMAT3(3, OP3_X(1,8), 0)), "ldswa", "7d"},
688 {(FORMAT3(3, OP3_X(1,8), 1)), "ldswa", "8d"},
689
690 {(FORMAT3(3, OP3_X(0,9), 0)), "ldsb", "pd"},
691 {(FORMAT3(3, OP3_X(0,9), 1)), "ldsb", "qd"},
692 {(FORMAT3(3, OP3_X(1,9), 0)), "ldsba", "7d"},
693 {(FORMAT3(3, OP3_X(1,9), 1)), "ldsba", "8d"},
694
695 {(FORMAT3(3, OP3_X(0,10), 0)), "ldsh", "pd"},
696 {(FORMAT3(3, OP3_X(0,10), 1)), "ldsh", "qd"},
697 {(FORMAT3(3, OP3_X(1,10), 0)), "ldsha", "7d"},
698 {(FORMAT3(3, OP3_X(1,10), 1)), "ldsha", "8d"},
699
700 {(FORMAT3(3, OP3_X(0,11), 0)), "ldx", "pd"},
701 {(FORMAT3(3, OP3_X(0,11), 1)), "ldx", "qd"},
702 {(FORMAT3(3, OP3_X(1,11), 0)), "ldxa", "7d"},
703 {(FORMAT3(3, OP3_X(1,11), 1)), "ldxa", "8d"},
704
705 {(FORMAT3(3, OP3_X(3,12), 1)), "casa", "s2d"},
706 {(FORMAT3(3, OP3_X(3,12), 0)), "casa", "t2d"},
707
708 {(FORMAT3(3, OP3_X(0,13), 0)), "ldstub", "7d"},
709 {(FORMAT3(3, OP3_X(0,13), 1)), "ldstub", "8d"},
710 {(FORMAT3(3, OP3_X(1,13), 0)), "ldstuba", "pd"},
711 {(FORMAT3(3, OP3_X(1,13), 1)), "ldstuba", "qd"},
712 {(FORMAT3(3, OP3_X(2,13), 0)), "prefetch", "pr"},
713 {(FORMAT3(3, OP3_X(2,13), 1)), "prefetch", "qr"},
714 {(FORMAT3(3, OP3_X(3,13), 0)), "prefetcha", "7r"},
715 {(FORMAT3(3, OP3_X(3,13), 1)), "prefetcha", "8r"},
716
717 {(FORMAT3(3, OP3_X(0,14), 0)), "stx", "dp"},
718 {(FORMAT3(3, OP3_X(0,14), 1)), "stx", "dq"},
719 {(FORMAT3(3, OP3_X(1,14), 0)), "stwa", "d7"},
720 {(FORMAT3(3, OP3_X(1,14), 1)), "stwa", "d8"},
721 {(FORMAT3(3, OP3_X(3,14), 0)), "casxa", "t2d"},
722 {(FORMAT3(3, OP3_X(3,14), 1)), "casxa", "s2d"},
723
724 /* Swap Register */
725 {(FORMAT3(3, OP3_X(0,15), 0)), "swap", "pd"},
726 {(FORMAT3(3, OP3_X(0,15), 1)), "swap", "qd"},
727 {(FORMAT3(3, OP3_X(1,15), 0)), "swapa", "7d"},
728 {(FORMAT3(3, OP3_X(1,15), 1)), "swapa", "8d"},
729
730
731 /*
732 * OP3 = (3,4): FPop1 (table 34)
733 */
734 {(FORMAT3F(2, OP3_X(3,4), OPF_X(0,1))), "fmovs", ".4e"},
735 {(FORMAT3F(2, OP3_X(3,4), OPF_X(0,2))), "fmovd", ".4e"},
736 {(FORMAT3F(2, OP3_X(3,4), OPF_X(0,3))), "fmovq", ".4e"},
737 {(FORMAT3F(2, OP3_X(3,4), OPF_X(0,5))), "fnegs", "4e"},
738 {(FORMAT3F(2, OP3_X(3,4), OPF_X(0,6))), "fnegd", "4e"},
739 {(FORMAT3F(2, OP3_X(3,4), OPF_X(0,7))), "fnegq", "4e"},
740 {(FORMAT3F(2, OP3_X(3,4), OPF_X(0,9))), "fabss", "4e"},
741 {(FORMAT3F(2, OP3_X(3,4), OPF_X(0,10))), "fabsd", "4e"},
742 {(FORMAT3F(2, OP3_X(3,4), OPF_X(0,11))), "fabsq", "4e"},
743
744 {(FORMAT3F(2, OP3_X(3,4), OPF_X(2,9))), "fsqrts", "4e"},
745 {(FORMAT3F(2, OP3_X(3,4), OPF_X(2,10))), "fsqrtd", "4e"},
746 {(FORMAT3F(2, OP3_X(3,4), OPF_X(2,11))), "fsqrtq", "4e"},
747
748 {(FORMAT3F(2, OP3_X(3,4), OPF_X(4,1))), "fadds", "34e"},
749 {(FORMAT3F(2, OP3_X(3,4), OPF_X(4,2))), "faddd", "34e"},
750 {(FORMAT3F(2, OP3_X(3,4), OPF_X(4,3))), "faddq", "34e"},
751 {(FORMAT3F(2, OP3_X(3,4), OPF_X(4,5))), "fsubs", "34e"},
752 {(FORMAT3F(2, OP3_X(3,4), OPF_X(4,6))), "fsubd", "34e"},
753 {(FORMAT3F(2, OP3_X(3,4), OPF_X(4,7))), "fsubq", "34e"},
754 {(FORMAT3F(2, OP3_X(3,4), OPF_X(4,9))), "fmuls", "34e"},
755 {(FORMAT3F(2, OP3_X(3,4), OPF_X(4,10))), "fmuld", "34e"},
756 {(FORMAT3F(2, OP3_X(3,4), OPF_X(4,11))), "fmulq", "34e"},
757 {(FORMAT3F(2, OP3_X(3,4), OPF_X(4,13))), "fdivs", "34e"},
758 {(FORMAT3F(2, OP3_X(3,4), OPF_X(4,14))), "fdivd", "34e"},
759 {(FORMAT3F(2, OP3_X(3,4), OPF_X(4,15))), "fdivq", "34e"},
760
761 {(FORMAT3F(2, OP3_X(3,4), OPF_X(6,9))), "fsmuld", "34e"},
762 {(FORMAT3F(2, OP3_X(3,4), OPF_X(6,14))), "fdmulq", "34e"},
763
764 {(FORMAT3F(2, OP3_X(3,4), OPF_X(8,1))), "fstox", "4e"},
765 {(FORMAT3F(2, OP3_X(3,4), OPF_X(8,2))), "fdtox", "4e"},
766 {(FORMAT3F(2, OP3_X(3,4), OPF_X(8,3))), "fqtox", "4e"},
767 {(FORMAT3F(2, OP3_X(3,4), OPF_X(8,4))), "fxtos", "4e"},
768 {(FORMAT3F(2, OP3_X(3,4), OPF_X(8,8))), "fxtod", "4e"},
769 {(FORMAT3F(2, OP3_X(3,4), OPF_X(8,12))), "fxtoq", "4e"},
770
771 {(FORMAT3F(2, OP3_X(3,4), OPF_X(12,4))), "fitos", "4e"},
772 {(FORMAT3F(2, OP3_X(3,4), OPF_X(12,6))), "fdtos", "4e"},
773 {(FORMAT3F(2, OP3_X(3,4), OPF_X(12,7))), "fqtos", "4e"},
774 {(FORMAT3F(2, OP3_X(3,4), OPF_X(12,8))), "fitod", "4e"},
775 {(FORMAT3F(2, OP3_X(3,4), OPF_X(12,9))), "fstod", "4e"},
776 {(FORMAT3F(2, OP3_X(3,4), OPF_X(12,11))), "fqtod", "4e"},
777 {(FORMAT3F(2, OP3_X(3,4), OPF_X(12,12))), "fitoq", "4e"},
778 {(FORMAT3F(2, OP3_X(3,4), OPF_X(12,13))), "fstoq", "4e"},
779 {(FORMAT3F(2, OP3_X(3,4), OPF_X(12,14))), "fdtoq", "4e"},
780
781 {(FORMAT3F(2, OP3_X(3,4), OPF_X(13,1))), "fstoi", "4e"},
782 {(FORMAT3F(2, OP3_X(3,4), OPF_X(13,2))), "fdtoi", "4e"},
783 {(FORMAT3F(2, OP3_X(3,4), OPF_X(13,3))), "fqtoi", "4e"},
784
785
786 #ifdef xxx
787 /*
788 * OP3 =(3,5): FPop2 (table 35)
789 */
790 {(FORMAT3F(2, OP3_X(3,5), 81)), "fcmps", "o34"},
791 {(FORMAT3F(2, OP3_X(3,5), 82)), "fcmpd", "o34"},
792 {(FORMAT3F(2, OP3_X(3,5), 83)), "fcmpq", "o34"},
793 {(FORMAT3F(2, OP3_X(3,5), 85)), "fcmpes", "o34"},
794 {(FORMAT3F(2, OP3_X(3,5), 86)), "fcmped", "o34"},
795 {(FORMAT3F(2, OP3_X(3,5), 87)), "fcmpeq", "o34"},
796
797 /* Move Floating-Point Register on Condition "FMOVcc" */
798 /* FIXME should check for single, double, and quad movements */
799 /* Integer Condition Codes */
800 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,8)), "fmova", "04e"},
801 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,0)), "fmovn", "04e"},
802 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,9)), "fmovne", "04e"},
803 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,1)), "fmove", "04e"},
804 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,10)), "fmovg", "04e"},
805 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,2)), "fmovle", "04e"},
806 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,11)), "fmovge", "04e"},
807 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,3)), "fmovl", "04e"},
808 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,12)), "fmovgu", "04e"},
809 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,4)), "fmovleu", "04e"},
810 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,13)), "fmovcc", "04e"},
811 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,5)), "fmovcs", "04e"},
812 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,14)), "fmovpos", "04e"},
813 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,6)), "fmovneg", "04e"},
814 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,15)), "fmovvc", "04e"},
815 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,7)), "fmovvs", "04e"},
816
817 /* Floating-Point Condition Codes */
818 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,8)), "fmova", "o4e"},
819 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,0)), "fmovn", "o4e"},
820 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,7)), "fmovu", "o4e"},
821 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,6)), "fmovg", "o4e"},
822 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,5)), "fmovug", "o4e"},
823 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,4)), "fmovk", "o4e"},
824 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,3)), "fmovul", "o4e"},
825 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,2)), "fmovlg", "o4e"},
826 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,1)), "fmovne", "o4e"},
827 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,9)), "fmove", "o4e"},
828 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,10)), "fmovue", "o4e"},
829 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,11)), "fmovge", "o4e"},
830 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,12)), "fmovuge", "o4e"},
831 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,13)), "fmovle", "o4e"},
832 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,14)), "fmovule", "o4e"},
833 {(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,15)), "fmovo", "o4e"},
834
835 /* Move F-P Register on Integer Register Condition "FMOVr" */
836 /* FIXME: check for short, double, and quad's */
837 {(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(1)), "fmovre", "14e"},
838 {(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(2)), "fmovrlez", "14e"},
839 {(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(3)), "fmovrlz", "14e"},
840 {(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(5)), "fmovrne", "14e"},
841 {(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(6)), "fmovrgz", "14e"},
842 {(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(7)), "fmovrgez", "14e"},
843 #endif
844 /* FP logical insns -- UltraSPARC extens */
845 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,0))), "fzero", "e"},
846 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,1))), "fzeros", "e"},
847 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,14))), "fone", "e"},
848 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,15))), "fones", "e"},
849 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,4))), "fsrc1", "3e"},
850 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,5))), "fsrc1s", "3e"},
851 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,8))), "fsrc2", "4e"},
852 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,9))), "fsrc2s", "4e"},
853 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,10))), "fnot1", "3e"},
854 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,11))), "fnot1s", "3e"},
855 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,6))), "fnot2", "4e"},
856 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,7))), "fnot2s", "4e"},
857 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,12))), "for", "34e"},
858 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,13))), "fors", "34e"},
859 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,2))), "fnor", "34e"},
860 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,3))), "fnors", "34e"},
861 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,0))), "fand", "34e"},
862 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,1))), "fands", "34e"},
863 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,14))), "fnand", "34e"},
864 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,15))), "fnands", "34e"},
865 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,12))), "fxor", "34e"},
866 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,13))), "fxors", "34e"},
867 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,2))), "fxnor", "34e"},
868 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,3))), "fxnors", "34e"},
869 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,10))), "fornot1", "34e"},
870 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,11))), "fornot1s", "34e"},
871 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,6))), "fornot2", "34e"},
872 {(FORMAT3F(2, OP3_X(3,6), OPF_X(7,7))), "fornot2s", "34e"},
873 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,8))), "fandnot1", "34e"},
874 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,9))), "fandnot1s", "34e"},
875 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,4))), "fandnot2", "34e"},
876 {(FORMAT3F(2, OP3_X(3,6), OPF_X(6,5))), "fandnot2s", "34e"},
877
878 /* grrrr.... */
879 {0, 0, 0}
880
881 };
882
883 db_addr_t
db_disasm(db_addr_t loc,bool altfmt)884 db_disasm(db_addr_t loc, bool altfmt)
885 {
886 struct sparc_insn* i_ptr = (struct sparc_insn *)&sparc_i;
887
888 unsigned int insn, you_lose, bitmask;
889 int matchp;
890 const char *f_ptr, *cp;
891
892 you_lose = 0;
893 matchp = 0;
894 insn = db_get_value(loc, 4, 0);
895
896 if (insn == 0x01000000) {
897 db_printf("nop\n");
898 return loc + 4;
899 }
900
901 while (i_ptr->name) {
902 /* calculate YOU_LOSE value */
903 bitmask= (i_ptr->match);
904 you_lose = (~bitmask);
905
906 if (((bitmask>>30) & 0x3) == 0x1) {
907 /* Call */
908 you_lose = ((~0x1U)<<30);
909 } else if (((bitmask>>30) & 0x3) == 0x0) {
910 if (((bitmask>>22) & 0x7) == 0x4) {
911 /* Sethi */
912 you_lose &= (FORMAT2(0x3,0x7));
913 } else {
914 /* Branches */
915 you_lose &= (FORMAT2(0x3,0x7)|COND(0xf));
916 }
917 } else if (((bitmask>>30) & 0x3) == 0x2 &&
918 ((bitmask>>19) & 0x3f) == 0x34) /* XXX */ {
919 /* FPop1 */
920 you_lose &= (FORMAT3(0x3,0x3f,0x1) | OPF(0x1ff));
921 } else if (((bitmask>>30) & 0x3) == 0x2 &&
922 ((bitmask>>19) & 0x3f) == 0x3a) /* XXX */ {
923 /* Tcc */
924 you_lose &= (FORMAT3(0x3,0x3f,0x1) | COND(0xf));
925 } else if (((bitmask>>30) & 0x3) == 0x2 &&
926 ((bitmask>>21) & 0xf) == 0x9 &&
927 ((bitmask>>19) & 0x3) != 0) /* XXX */ {
928 /* shifts */
929 you_lose &= (FORMAT3(0x3,0x3f,0x1))|X(1);
930 } else if (((bitmask>>30) & 0x3) == 0x2 &&
931 ((bitmask>>19) & 0x3f) == 0x2c) /* XXX */ {
932 /* cmov */
933 you_lose &= (FORMAT3(0x3,0x3f,0x1) | COND2(1,0xf));
934 } else if (((bitmask>>30) & 0x3) == 0x2 &&
935 ((bitmask>>19) & 0x3f) == 0x35) /* XXX */ {
936 /* fmov */
937 you_lose &= (FORMAT3(0x3,0x3f,0x1) | COND2(1,0xf));
938 } else {
939 you_lose &= (FORMAT3(0x3,0x3f,0x1));
940 }
941
942 if (((bitmask & insn) == bitmask) && ((you_lose & insn) == 0)) {
943 matchp = 1;
944 break;
945 }
946 i_ptr++;
947 };
948
949 if (!matchp) {
950 db_printf("undefined\n");
951 return loc + 4;
952 }
953
954 db_printf("%s", i_ptr->name);
955
956 f_ptr = i_ptr->format;
957
958 for (cp = f_ptr; *cp; cp++) {
959 if (*cp == ',') {
960 for (;f_ptr < cp; f_ptr++)
961 switch (*f_ptr) {
962 case 'a':
963 if (insn & A(1))
964 db_printf(",a");
965 break;
966 case 'p':
967 if (insn & P(1))
968 db_printf(",pt");
969 else
970 db_printf(",pn");
971 break;
972 }
973 f_ptr++;
974 break;
975 }
976 }
977 db_printf(" \t");
978
979 while (*f_ptr) {
980 switch (*f_ptr) {
981 int64_t val;
982 case '1':
983 db_printf("%%%s", regs[((insn >> 14) & 0x1f)]);
984 break;
985 case '2':
986 db_printf("%%%s", regs[(insn & 0x1f)]);
987 break;
988 case 'd':
989 db_printf("%%%s", regs[((insn >> 25) & 0x1f)]);
990 break;
991 case '3':
992 db_printf("%%f%d", ((insn >> 14) & 0x1f));
993 break;
994 case '4':
995 db_printf("%%f%d", (insn & 0x1f));
996 break;
997 case 'e':
998 db_printf("%%f%d", ((insn >> 25) & 0x1f));
999 break;
1000 case 'i':
1001 /* simm13 -- signed */
1002 val = SIGNEX(insn, 13);
1003 db_printf("%s0x%x", SIGN(val), abs((int)val));
1004 break;
1005 case 'j':
1006 /* simm11 -- signed */
1007 val = SIGNEX(insn, 11);
1008 db_printf("%s0x%x", SIGN(val), abs((int)val));
1009 break;
1010 case 'l':
1011 val = (((insn>>20)&0x3)<<13)|(insn & 0x1fff);
1012 val = SIGNEX(val, 16);
1013 db_printsym((db_addr_t)(loc + (4 * val)),
1014 DB_STGY_ANY, db_printf);
1015 break;
1016 case 'm':
1017 db_printsym((db_addr_t)(loc + (4 * SIGNEX(insn, 22))),
1018 DB_STGY_ANY, db_printf);
1019 break;
1020 case 'u':
1021 db_printsym((db_addr_t)(loc + (4 * SIGNEX(insn, 19))),
1022 DB_STGY_ANY, db_printf);
1023 break;
1024 case 'n':
1025 db_printsym((db_addr_t)(loc + (4 * SIGNEX(insn, 30))),
1026 DB_STGY_PROC, db_printf);
1027 break;
1028 case 's':
1029 db_printf("%%asi");
1030 break;
1031 case 't':
1032 db_printf("0x%-2.2x", ((insn >> 5) & 0xff));
1033 break;
1034 case 'o':
1035 db_printf("%%fcc%d", ((insn >> 25) & 0x3));
1036 break;
1037 case 'p':
1038 case '7':
1039 db_printf("[%%%s + %%%s]",
1040 regs[((insn >> 14) & 0x1f)],
1041 regs[(insn & 0x1f)]);
1042 if (*f_ptr == '7')
1043 db_printf(" %d", ((insn >> 5) & 0xff));
1044 break;
1045 case 'q':
1046 case '8':
1047 val = SIGNEX(insn, 13);
1048 db_printf("[%%%s %c 0x%x]",
1049 regs[((insn >> 14) & 0x1f)],
1050 (int)((val<0)?'-':'+'),
1051 abs((int)val));
1052 if (*f_ptr == '8')
1053 db_printf(" %%asi");
1054 break;
1055 case '5':
1056 db_printf("%%fsr");
1057 break;
1058 case '6':
1059 db_printf("%%fsr");
1060 break;
1061 case '9':
1062 db_printf("0x%xl",
1063 ((insn & 0xf) | ((insn >> 4) & 0x7)));
1064 break;
1065 case '0':
1066 db_printf("%%%s", ccodes[((insn >> 11) & 0x3) + 4]);
1067 break;
1068 case '.':
1069 db_printf("%%%s", ccodes[((insn >> 11) & 0x7)]);
1070 break;
1071 case 'r':
1072 db_printf("#%s", prefetch[((insn >> 25) & 0x1f)]);
1073 break;
1074 case 'A':
1075 db_printf("%%%s", priv_regs[((insn >> 14) & 0x1f)]);
1076 break;
1077 case 'B':
1078 db_printf("%%%s", state_regs[((insn >> 14) & 0x1f)]);
1079 break;
1080 case 'C':
1081 db_printf("%%hi(0x%x)", ((insn & 0x3fffff) << 10));
1082 break;
1083 case 'D':
1084 db_printf("0x%x", (insn & 0x1f));
1085 break;
1086 case 'E':
1087 db_printf("%d", (insn & 0x3f));
1088 break;
1089 case 'F':
1090 db_printf("%d", (insn & 0x3f));
1091 break;
1092 case 'G':
1093 db_printf("%%%s", priv_regs[((insn >> 25) & 0x1f)]);
1094 break;
1095 case 'H':
1096 db_printf("%%%s", state_regs[((insn >> 25) & 0x1f)]);
1097 break;
1098 #ifndef V9
1099 case 'P':
1100 db_printf("%%psr");
1101 break;
1102 case 'T':
1103 db_printf("%%tbr");
1104 break;
1105 case 'W':
1106 db_printf("%%wim");
1107 break;
1108 case 'Y':
1109 db_printf("%%y");
1110 break;
1111 #endif
1112 default:
1113 db_printf("(UNKNOWN)");
1114 break;
1115 }
1116 if (*(++f_ptr))
1117 db_printf(", ");
1118 };
1119
1120 db_printf("\n");
1121
1122 return (loc + 4);
1123 }
1124