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