Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * Hypervisor Software File: dis.c | |
5 | * | |
6 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
7 | * | |
8 | * - Do no alter or remove copyright notices | |
9 | * | |
10 | * - Redistribution and use of this software in source and binary forms, with | |
11 | * or without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistribution of source code must retain the above copyright notice, | |
15 | * this list of conditions and the following disclaimer. | |
16 | * | |
17 | * - Redistribution in binary form must reproduce the above copyright notice, | |
18 | * this list of conditions and the following disclaimer in the | |
19 | * documentation and/or other materials provided with the distribution. | |
20 | * | |
21 | * Neither the name of Sun Microsystems, Inc. or the names of contributors | |
22 | * may be used to endorse or promote products derived from this software | |
23 | * without specific prior written permission. | |
24 | * | |
25 | * This software is provided "AS IS," without a warranty of any kind. | |
26 | * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
27 | * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
28 | * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
29 | * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
30 | * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
31 | * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
32 | * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
33 | * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
34 | * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
35 | * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
36 | * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
37 | * | |
38 | * You acknowledge that this software is not designed, licensed or | |
39 | * intended for use in the design, construction, operation or maintenance of | |
40 | * any nuclear facility. | |
41 | * | |
42 | * ========== Copyright Header End ============================================ | |
43 | */ | |
44 | /* | |
45 | * Copyright 2003 Sun Microsystems, Inc. All rights reserved. | |
46 | * Use is subject to license terms. | |
47 | */ | |
48 | ||
49 | #pragma ident "@(#)dis.c 1.2 03/11/10 SMI" | |
50 | ||
51 | #include <stdio.h> | |
52 | #include <sys/types.h> | |
53 | ||
54 | #define RD(inst) (((inst) >> 25) & 0x1f) | |
55 | #define RS1(inst) (((inst) >> 14) & 0x1f) | |
56 | #define RS2(inst) (((inst) ) & 0x1f) | |
57 | #define OP(inst) (((inst) >> 30) & 0x3) | |
58 | #define OP2(inst) (((inst) >> 22) & 0x7) | |
59 | #define OP3(inst) (((inst) >> 19) & 0x3f) | |
60 | #define IMM22(inst) (((inst) << 10) >> 10) | |
61 | #define IMM(inst) (((inst) >> 13) & 1) | |
62 | #define SIMM13(inst) (int64_t)(((((int32_t)(inst) << 19)) >> 19)) | |
63 | #define X(inst) (((inst) >> 12) & 1) | |
64 | #define SHIFT32(inst) ((inst) & 0x1f) | |
65 | #define SHIFT64(inst) ((inst) & 0x3f) | |
66 | #define CMASK(inst) (((inst) >> 4) & 0x7) | |
67 | #define MMASK(inst) ((inst) & 0xf) | |
68 | #define A(inst) (((inst) >> 29) & 1) | |
69 | #define CC(inst) (((inst) >> 20) & 3) | |
70 | #define TCC(inst) (((inst) >> 10) & 3) | |
71 | #define DISP19(inst) (int64_t)(((((int32_t)(inst) << 13)) >> 11)) | |
72 | #define DISP22(inst) (int64_t)(((((int32_t)(inst) << 10)) >> 8)) | |
73 | #define COND(inst) (((inst) >> 25) & 0xf) | |
74 | #define PT(inst) (((inst) >> 19) & 1) | |
75 | #define FCN(inst) (((inst) >> 25) & 0x1f) | |
76 | #define IMMASI(inst) (((inst) >> 5) & 0xff) | |
77 | #define SWTRAP(inst) ((inst) & 0x3f) | |
78 | #define HT(inst) (((inst) >> 7) & 0x1) | |
79 | #define ILLEGAL \ | |
80 | (void)printf("%p:\tIllegal instruction %08x\n", (void *)pc, inst);\ | |
81 | return 0 | |
82 | #define OK 0 | |
83 | #define ERR -1 | |
84 | #define DELAY 1 | |
85 | ||
86 | static char *sregs[] = { | |
87 | "%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7", | |
88 | "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%o6", "%i7", | |
89 | "%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7", | |
90 | "%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%i6", "%i7" | |
91 | }; | |
92 | static int dis_format2(uint32_t *, uint32_t); | |
93 | static int dis_class2(uint32_t *, uint32_t); | |
94 | static int dis_class3(uint32_t *, uint32_t); | |
95 | static int dis_bpcc(uint32_t *, uint32_t); | |
96 | static int dis_bpr(uint32_t *, uint32_t); | |
97 | static int dis_tcc(uint32_t *, uint32_t); | |
98 | static int dis_fbfcc(uint32_t *, uint32_t); | |
99 | static int dis_fbpfcc(uint32_t *, uint32_t); | |
100 | static int dis_bicc(uint32_t *, uint32_t); | |
101 | static int dis_rdasr(uint32_t *, uint32_t); | |
102 | static int dis_rdpr(uint32_t *, uint32_t); | |
103 | static int dis_wrasr(uint32_t *, uint32_t); | |
104 | static int dis_wrpr(uint32_t *, uint32_t); | |
105 | ||
106 | int | |
107 | disasm(uint32_t *pc) | |
108 | { | |
109 | uint32_t inst = *pc; | |
110 | int op = OP(inst); | |
111 | ||
112 | switch(op) { | |
113 | case 0: | |
114 | return dis_format2(pc, inst); | |
115 | case 1: { | |
116 | int64_t label = (inst << 2) + (int64_t) pc; | |
117 | (void)printf("%p:\tcall\t0x%lx\n", (void *)pc, label); | |
118 | return DELAY; | |
119 | } | |
120 | case 2: | |
121 | return dis_class2(pc, inst); | |
122 | case 3: | |
123 | return dis_class3(pc, inst); | |
124 | } | |
125 | return ERR; | |
126 | } | |
127 | ||
128 | static int | |
129 | dis_format2(uint32_t *pc, uint32_t inst) | |
130 | { | |
131 | int op2 = OP2(inst); | |
132 | switch(op2) { | |
133 | case 0: | |
134 | (void)printf("%p:\tilltrap\n", (void *)pc); | |
135 | return OK; | |
136 | case 1: | |
137 | return dis_bpcc(pc, inst); | |
138 | case 2: | |
139 | return dis_bicc(pc, inst); | |
140 | case 3: | |
141 | return dis_bpr(pc, inst); | |
142 | case 4: | |
143 | if ((RD(inst) == 0) && (IMM22(inst) == 0)) { | |
144 | (void)printf("%p:\tnop\n", (void *)pc); | |
145 | return OK; | |
146 | } | |
147 | (void)printf("%p:\tsethi\t0x%x, %s\n", (void *)pc, | |
148 | IMM22(inst) << 10, sregs[RD(inst)]); | |
149 | return OK; | |
150 | case 5: | |
151 | return dis_fbpfcc(pc, inst); | |
152 | case 6: | |
153 | return dis_fbfcc(pc, inst); | |
154 | case 7: | |
155 | ILLEGAL; | |
156 | } | |
157 | return ERR; | |
158 | } | |
159 | static int | |
160 | dis_class2(uint32_t *pc, uint32_t inst) | |
161 | { | |
162 | int op3 = OP3(inst); | |
163 | char *opc[] = { | |
164 | "add", "and", "or", "xor", | |
165 | "sub", "andn", "orn", "xnor", | |
166 | "addc", "mulx", "umul", "smul", | |
167 | "subc", "udivx", "udiv", "sdiv", | |
168 | "addcc", "andcc", "orcc", "xorcc", | |
169 | "subcc", "andncc", "orncc", "xnorcc", | |
170 | "addccc", "-", "umulcc", "smulcc", | |
171 | "subccc", "-", "udivcc", "sdivcc", | |
172 | "taddcc", "tsubcc", "taddcctv", "tsubcctv", | |
173 | "mulscc", "sll", "srl", "sra", | |
174 | "rdy", "-", "rdpr", "flushw", | |
175 | "movcc", "sdivx", "popc", "movr", | |
176 | "wry", "saved", "wrpr", "-", | |
177 | "fpop1", "fpop2", "impldep1", "impldep2", | |
178 | "jmpl", "return", "tcc", "flush", | |
179 | "save", "restore", "done", "-" | |
180 | }; | |
181 | ||
182 | switch(op3) { | |
183 | case 0x00: /* ADD */ | |
184 | case 0x01: /* AND */ | |
185 | case 0x02: /* OR */ | |
186 | case 0x03: /* XOR */ | |
187 | case 0x04: /* SUB */ | |
188 | case 0x05: /* ANDN */ | |
189 | case 0x06: /* ORN */ | |
190 | case 0x07: /* XNOR */ | |
191 | case 0x08: /* ADDC */ | |
192 | case 0x09: /* MULX */ | |
193 | case 0x0a: /* UMUL */ | |
194 | case 0x0b: /* SMUL */ | |
195 | case 0x0c: /* SUBC */ | |
196 | case 0x0d: /* UDIVX */ | |
197 | case 0x0e: /* UDIV */ | |
198 | case 0x0f: /* SDIV */ | |
199 | ||
200 | case 0x10: /* ADDcc */ | |
201 | case 0x11: /* ANDcc */ | |
202 | case 0x12: /* ORcc */ | |
203 | case 0x13: /* XORcc */ | |
204 | case 0x14: /* SUBcc */ | |
205 | case 0x15: /* ANDNcc */ | |
206 | case 0x16: /* ORNcc */ | |
207 | case 0x17: /* XNORcc */ | |
208 | case 0x18: /* ANDCcc */ | |
209 | case 0x1a: /* UMULcc */ | |
210 | case 0x1b: /* SMULcc */ | |
211 | case 0x1c: /* SUBCcc */ | |
212 | case 0x1e: /* UDIVcc */ | |
213 | case 0x1f: /* SDIVcc */ | |
214 | ||
215 | case 0x20: /* TADDcc */ | |
216 | case 0x21: /* TSUBcc */ | |
217 | case 0x22: /* TADDccTV */ | |
218 | case 0x23: /* TSUBccTV */ | |
219 | case 0x24: /* MULScc */ | |
220 | case 0x2c: /* MOVcc */ | |
221 | case 0x2d: /* SDIVX */ | |
222 | case 0x2f: /* MOVr */ | |
223 | case 0x38: /* JMPL */ | |
224 | case 0x3c: /* SAVE */ | |
225 | case 0x3d: /* RESTORE */ | |
226 | (void)printf("%p:\t%s\t%s, ", (void *)pc, | |
227 | opc[op3], sregs[RS1(inst)]); | |
228 | if (IMM(inst)) | |
229 | (void)printf("%ld, ", SIMM13(inst)); | |
230 | else | |
231 | (void)printf("%s, ", sregs[RS2(inst)]); | |
232 | (void)printf("%s\n", sregs[RD(inst)]); | |
233 | return (op3 == 0x38) ? DELAY : OK; | |
234 | ||
235 | case 0x2b: /* FLUSHW */ | |
236 | if ((RD(inst) == 0) && (RS1(inst) == 0) | |
237 | && (IMM(inst) == 0) && (SIMM13(inst) == 0)) { | |
238 | (void)printf("%p:\t%s\n", (void *)pc, opc[op3]); | |
239 | return OK; | |
240 | } | |
241 | ILLEGAL; | |
242 | case 0x39: /* RETURN */ | |
243 | case 0x3b: /* FLUSH */ | |
244 | if (RD(inst)) { | |
245 | ILLEGAL; | |
246 | } | |
247 | (void)printf("%p:\t%s\t%s + ", (void *)pc, opc[op3], sregs[RS1(inst)]); | |
248 | if (IMM(inst)) | |
249 | (void)printf("%ld\n", SIMM13(inst)); | |
250 | else | |
251 | (void)printf("%s\n", sregs[RS2(inst)]); | |
252 | return OK; | |
253 | case 0x19: | |
254 | case 0x1d: | |
255 | case 0x29: | |
256 | case 0x33: | |
257 | case 0x3f: | |
258 | ILLEGAL; | |
259 | case 0x25: /* SLL/SLLX */ | |
260 | case 0x26: /* SRL/SRLX */ | |
261 | case 0x27: /* SRA/SRAX */ | |
262 | (void)printf("%p:\t%s%s\t%s, ", (void *)pc, | |
263 | opc[op3], X(inst) ? "x" : "", sregs[RS1(inst)]); | |
264 | if (IMM(inst)) | |
265 | (void)printf("%d, ", | |
266 | X(inst) ? SHIFT64(inst) : SHIFT32(inst)); | |
267 | else | |
268 | (void)printf("%s, ", sregs[RS2(inst)]); | |
269 | (void)printf("%s\n", sregs[RD(inst)]); | |
270 | return OK; | |
271 | case 0x28: /* RDASR */ | |
272 | return dis_rdasr(pc, inst); | |
273 | case 0x2a: /* RDPR */ | |
274 | return dis_rdpr(pc, inst); | |
275 | case 0x30: /* WRASR */ | |
276 | return dis_wrasr(pc, inst); | |
277 | case 0x31: /* SAVED/RESTORED */ | |
278 | if(FCN(inst) == 0) { | |
279 | (void)printf("%p:\tsaved\n", (void *)pc); | |
280 | return OK; | |
281 | } | |
282 | if(FCN(inst) == 1) { | |
283 | (void)printf("%p:\trestored\n", (void *)pc); | |
284 | return OK; | |
285 | } | |
286 | ILLEGAL; | |
287 | case 0x32: /* WRPR */ | |
288 | return dis_wrpr(pc, inst); | |
289 | case 0x3a: /* Tcc */ | |
290 | return dis_tcc(pc, inst); | |
291 | case 0x3e: /* DONE/RETRY */ | |
292 | if(FCN(inst) == 0) { | |
293 | (void)printf("%p:\tdone\n", (void *)pc); | |
294 | return OK; | |
295 | } | |
296 | if(FCN(inst) == 1) { | |
297 | (void)printf("%p:\tretry\n", (void *)pc); | |
298 | return OK; | |
299 | } | |
300 | ILLEGAL; | |
301 | case 0x36: /* IMPDEP1 */ | |
302 | (void)printf("XXXX %p:\timpldep1\n", (void *)pc ); | |
303 | return ERR; | |
304 | case 0x37: /* IMPLDEP2 */ | |
305 | (void)printf("XXXX %p:\timpldep2\n", (void *)pc); | |
306 | return ERR; | |
307 | default: | |
308 | (void)printf("XXXX dis_class2 op3=%x\n", op3); | |
309 | return ERR; | |
310 | } | |
311 | } | |
312 | ||
313 | static int dis_rdpr(uint32_t *pc, uint32_t inst) | |
314 | { | |
315 | char *prs[] = { | |
316 | "%tpc", "%tnpc", "%tstate", "%tt", | |
317 | "%tick", "%tba", "%pstate", "%tl", | |
318 | "%pil", "%cwp", "%cansave", "%canrestore", | |
319 | "%cleanwin", "%otherwin", "%wstate", "%fq", | |
320 | "-", "-", "-", "-", | |
321 | "-", "-", "-", "-", | |
322 | "-", "-", "-", "-", | |
323 | "-", "-", "-", "%ver" | |
324 | }; | |
325 | if ((SIMM13(inst)) || (RS1(inst) >= 16 && RS1(inst) <=30)) { | |
326 | ILLEGAL; | |
327 | } | |
328 | (void)printf("%p:\trdpr\t%s,%s\n", (void *)pc, prs[RS1(inst)], sregs[RD(inst)]); | |
329 | return OK; | |
330 | } | |
331 | ||
332 | static int dis_wrpr(uint32_t *pc, uint32_t inst) | |
333 | { | |
334 | char *prs[] = { | |
335 | "%tpc", "%tnpc", "%tstate", "%tt", | |
336 | "%tick", "%tba", "%pstate", "%tl", | |
337 | "%pil", "%cwp", "%cansave", "%canrestore", | |
338 | "%cleanwin", "%otherwin", "%wstate", "%fq", | |
339 | "-", "-", "-", "-", | |
340 | "-", "-", "-", "-", | |
341 | "-", "-", "-", "-", | |
342 | "-", "-", "-", "-" | |
343 | }; | |
344 | if (RD(inst) >= 15) { | |
345 | ILLEGAL; | |
346 | } | |
347 | (void)printf("%p:\twrpr\t%s,%s, ", (void *)pc, prs[RD(inst)], sregs[RS1(inst)]); | |
348 | if (IMM(inst)) | |
349 | (void)printf("%ld, ", SIMM13(inst)); | |
350 | else | |
351 | (void)printf("%s, ", sregs[RS2(inst)]); | |
352 | (void)printf("%s\n", sregs[RD(inst)]); | |
353 | return OK; | |
354 | } | |
355 | ||
356 | static int dis_wrasr(uint32_t *pc, uint32_t inst) | |
357 | { | |
358 | char *asrs[] = { | |
359 | "wry", "-", "wrccr", "wrasi", | |
360 | "wrtick", "-", "wrfprs", "-", | |
361 | "-", "-", "-", "-", | |
362 | "-", "-", "-", "sir", | |
363 | }; | |
364 | ||
365 | if ((RD(inst) == 0xf) && (RS1(inst) != 0) && (IMM(inst) == 0)) { | |
366 | ILLEGAL; | |
367 | } | |
368 | switch(RD(inst)) { | |
369 | case 0x01: | |
370 | ILLEGAL; | |
371 | case 0x0f: /* SIR */ | |
372 | case 0x00: /* WRY */ | |
373 | case 0x02: /* WRCCR */ | |
374 | case 0x03: /* WRASI */ | |
375 | case 0x06: /* WRFPRS */ | |
376 | (void)printf("%p:\t%s\t%s,", (void *)pc, asrs[RD(inst)], sregs[RS1(inst)]); | |
377 | if (IMM(inst)) | |
378 | (void)printf("%ld, ", SIMM13(inst)); | |
379 | else | |
380 | (void)printf("%s, ", sregs[RS2(inst)]); | |
381 | (void)printf("\n"); | |
382 | return OK; | |
383 | case 0x04: | |
384 | case 0x05: | |
385 | case 0x07: | |
386 | case 0x08: | |
387 | case 0x09: | |
388 | case 0x0a: | |
389 | case 0x0b: | |
390 | case 0x0c: | |
391 | case 0x0d: | |
392 | case 0x0e: | |
393 | ILLEGAL; | |
394 | case 0x10: | |
395 | case 0x11: | |
396 | case 0x12: | |
397 | case 0x13: | |
398 | case 0x14: | |
399 | case 0x15: | |
400 | case 0x16: | |
401 | case 0x17: | |
402 | case 0x18: | |
403 | case 0x19: | |
404 | case 0x1a: | |
405 | case 0x1b: | |
406 | case 0x1c: | |
407 | case 0x1d: | |
408 | case 0x1e: | |
409 | case 0x1f: | |
410 | (void)printf("%p:\twr\t%s, ", (void *)pc, sregs[RS1(inst)]); | |
411 | if (IMM(inst)) | |
412 | (void)printf("%ld, ", SIMM13(inst)); | |
413 | else | |
414 | (void)printf("%s, ", sregs[RS2(inst)]); | |
415 | (void)printf("%%asr%d\n", RD(inst)); | |
416 | return ERR; | |
417 | default: | |
418 | (void)printf("XXXX wrasr %d\n", RD(inst)); | |
419 | return ERR; | |
420 | } | |
421 | } | |
422 | ||
423 | static int dis_rdasr(uint32_t *pc, uint32_t inst) | |
424 | { | |
425 | char *asrs[32] = { | |
426 | "rdy", "-", "rdccr", "rdasi", | |
427 | "rdtick", "rdpc", "rdfprs", "-", | |
428 | "-", "-", "-", "-", | |
429 | "-", "-", "-", "-", | |
430 | "-", "-", "-", "-", | |
431 | "-", "-", "-", "-", | |
432 | "-", "-", "-", "-", | |
433 | "-", "-", "-", "-", | |
434 | }; | |
435 | switch(RS1(inst)) { | |
436 | case 0x01: | |
437 | case 0x07: | |
438 | case 0x08: | |
439 | case 0x09: | |
440 | case 0x0a: | |
441 | case 0x0b: | |
442 | case 0x0c: | |
443 | case 0x0d: | |
444 | case 0x0e: | |
445 | ILLEGAL; | |
446 | case 0x0: | |
447 | case 0x2: | |
448 | case 0x3: | |
449 | case 0x4: | |
450 | case 0x5: | |
451 | case 0x6: | |
452 | (void)printf("%p:\t%s\t%s\n", (void *)pc, asrs[RS1(inst)], | |
453 | sregs[RD(inst)]); | |
454 | return OK; | |
455 | case 0xf: /* MEMBAR / STBAR */ | |
456 | if (RD(inst) == 0) { | |
457 | if (IMM(inst)) { | |
458 | (void)printf("%p\tmembar\t", (void *)pc); | |
459 | if ((CMASK(inst) & 1)) | |
460 | (void)printf("#Lookaside "); | |
461 | if ((CMASK(inst) & 2)) | |
462 | (void)printf("#MemIssue "); | |
463 | if ((CMASK(inst) & 4)) | |
464 | (void)printf("#Sync "); | |
465 | if ((MMASK(inst) & 1)) | |
466 | (void)printf("#LoadLoad "); | |
467 | if ((MMASK(inst) & 2)) | |
468 | (void)printf("#StoreLoad "); | |
469 | if ((MMASK(inst) & 4)) | |
470 | (void)printf("#LoadStore "); | |
471 | if ((MMASK(inst) & 8)) | |
472 | (void)printf("#StoreStore"); | |
473 | (void)printf("\n"); | |
474 | } else { | |
475 | (void)printf("%p:\tstbar\n", (void *)pc); | |
476 | } | |
477 | return OK; | |
478 | } else { | |
479 | ILLEGAL; | |
480 | } | |
481 | case 0x10: | |
482 | case 0x11: | |
483 | case 0x12: | |
484 | case 0x13: | |
485 | case 0x14: | |
486 | case 0x15: | |
487 | case 0x16: | |
488 | case 0x17: | |
489 | case 0x18: | |
490 | case 0x19: | |
491 | case 0x1a: | |
492 | case 0x1b: | |
493 | case 0x1c: | |
494 | case 0x1d: | |
495 | case 0x1e: | |
496 | case 0x1f: | |
497 | default: | |
498 | (void)printf("%p:\trd\t%%asr%d, %s\n", (void *)pc, RS1(inst), sregs[RD(inst)]); | |
499 | return OK; | |
500 | } | |
501 | } | |
502 | ||
503 | static int | |
504 | dis_class3(uint32_t *pc, uint32_t inst) | |
505 | { | |
506 | int op3 = OP3(inst); | |
507 | char *opc[0x40] = { | |
508 | "lduw", "ldub", "lduh", "ldd", | |
509 | "stw", "stb", "sth", "std", | |
510 | "ldsw", "ldsb", "ldsh", "ldx", | |
511 | "-", "ldstub", "stx", "swap", | |
512 | "lduwa", "lduba", "lduha", "ldda", | |
513 | "stwa", "stba", "stha", "stda", | |
514 | "ldswa", "ldsba", "ldsha", "ldxa", | |
515 | "-", "ldstuba", "stxa", "swapa", | |
516 | "ldf", "ldfsr", "ldqf", "lddf" | |
517 | "stf", "stfsr", "stqf", "stdf", | |
518 | "-", "-", "-", "-", | |
519 | "-", "prefetch", "-", "-", | |
520 | "ldfa", "-", "ldqfa", "lddfa", | |
521 | "stfa", "-", "stqfa", "stdfa", | |
522 | "-", "-", "-", "-", | |
523 | "casa", "prefetcha", "casxa", "-" | |
524 | }; | |
525 | ||
526 | switch(op3) { | |
527 | case 0x0c: | |
528 | case 0x1c: | |
529 | case 0x28: | |
530 | case 0x29: | |
531 | case 0x2a: | |
532 | case 0x2b: | |
533 | case 0x2c: | |
534 | case 0x2e: | |
535 | case 0x31: | |
536 | case 0x35: | |
537 | case 0x38: | |
538 | case 0x39: | |
539 | case 0x3a: | |
540 | case 0x3b: | |
541 | case 0x3f: | |
542 | ILLEGAL; | |
543 | case 0x00: /* LDUW */ | |
544 | case 0x01: /* LDUB */ | |
545 | case 0x02: /* LDUH */ | |
546 | case 0x03: /* LDD */ | |
547 | case 0x08: /* LDSW */ | |
548 | case 0x09: /* LDSB */ | |
549 | case 0x0a: /* LDSH */ | |
550 | case 0x0b: /* LDX */ | |
551 | case 0x0d: /* LDSTUB */ | |
552 | case 0x1f: /* SWAP */ | |
553 | (void)printf("%p:\t%s\t[%s + ", (void *)pc, opc[op3], sregs[RS1(inst)]); | |
554 | if (IMM(inst)) | |
555 | (void)printf("%ld], ", SIMM13(inst)); | |
556 | else | |
557 | (void)printf("%s], ", sregs[RS2(inst)]); | |
558 | (void)printf("%s\n", sregs[RD(inst)]); | |
559 | return OK; | |
560 | case 0x04: /* STW */ | |
561 | case 0x05: /* STB */ | |
562 | case 0x06: /* STH */ | |
563 | case 0x07: /* STD */ | |
564 | case 0x0e: /* STX */ | |
565 | (void)printf("%p:\t%s\t%s, ", (void *)pc, opc[op3], sregs[RD(inst)]); | |
566 | (void)printf("[%s + ", sregs[RS1(inst)]); | |
567 | if (IMM(inst)) | |
568 | (void)printf("%ld]\n", SIMM13(inst)); | |
569 | else | |
570 | (void)printf("%s]\n", sregs[RS2(inst)]); | |
571 | return OK; | |
572 | ||
573 | case 0x10: /* LDUWA */ | |
574 | case 0x11: /* LDUBA */ | |
575 | case 0x12: /* LDUHA */ | |
576 | case 0x13: /* LDDA */ | |
577 | case 0x18: /* LDSWA */ | |
578 | case 0x19: /* LDSBA */ | |
579 | case 0x1a: /* LDSHA */ | |
580 | case 0x1b: /* LDXA */ | |
581 | case 0x1d: /* LDSTUBA */ | |
582 | case 0x2f: /* SWAPA */ | |
583 | case 0x3c: /* CASA */ | |
584 | case 0x3e: /* CASXA */ | |
585 | (void)printf("%p:\t%s\t[%s + ", (void *)pc, opc[op3], sregs[RS1(inst)]); | |
586 | if (IMM(inst)) | |
587 | (void)printf("%ld] %%asi, ", SIMM13(inst)); | |
588 | else | |
589 | (void)printf("%s] 0x%x, ", sregs[RS2(inst)], IMMASI(inst)); | |
590 | (void)printf("%s\n", sregs[RD(inst)]); | |
591 | return OK; | |
592 | ||
593 | case 0x14: /* STWA */ | |
594 | case 0x15: /* STBA */ | |
595 | case 0x16: /* STHA */ | |
596 | case 0x17: /* STDA */ | |
597 | case 0x1e: /* STXA */ | |
598 | (void)printf("%p:\t%s\t%s, ", (void *)pc, opc[op3], sregs[RD(inst)]); | |
599 | (void)printf("[%s + ", sregs[RS1(inst)]); | |
600 | if (IMM(inst)) | |
601 | (void)printf("%ld] %%asi\n", SIMM13(inst)); | |
602 | else | |
603 | (void)printf("%s] 0x%x\n", sregs[RS2(inst)], IMMASI(inst)); | |
604 | return OK; | |
605 | ||
606 | case 0x2d: /* PREFETCH */ | |
607 | if ((RD(inst) >=5) && (RD(inst) <= 15)) { | |
608 | ILLEGAL; | |
609 | } | |
610 | (void)printf("%p:\t%s\t[%s + ", (void *)pc, opc[op3], sregs[RS1(inst)]); | |
611 | if (IMM(inst)) | |
612 | (void)printf("%ld], ", SIMM13(inst)); | |
613 | else | |
614 | (void)printf("%s], ", sregs[RS2(inst)]); | |
615 | (void)printf("%d\n", RD(inst)); | |
616 | return OK; | |
617 | ||
618 | case 0x3d: /* PREFETCHA */ | |
619 | if ((RD(inst) >=5) && (RD(inst) <= 15)) { | |
620 | ILLEGAL; | |
621 | } | |
622 | (void)printf("%p:\t%s\t[%s + ", (void *)pc, opc[op3], sregs[RS1(inst)]); | |
623 | if (IMM(inst)) | |
624 | (void)printf("%ld] %%asi, ", SIMM13(inst)); | |
625 | else | |
626 | (void)printf("%s] 0x%x, ", sregs[RS2(inst)], IMMASI(inst)); | |
627 | (void)printf("%d\n", RD(inst)); | |
628 | return OK; | |
629 | ||
630 | case 0x20: | |
631 | case 0x21: | |
632 | case 0x22: | |
633 | case 0x23: | |
634 | case 0x30: | |
635 | case 0x32: | |
636 | case 0x33: | |
637 | (void)printf("XXXX %p:\tLDF XXX op3=%x\n", (void *)pc, OP3(inst)); | |
638 | return ERR; | |
639 | case 0x24: | |
640 | case 0x25: | |
641 | case 0x26: | |
642 | case 0x27: | |
643 | case 0x34: | |
644 | case 0x36: | |
645 | case 0x37: | |
646 | (void)printf("XXXX %p:\tSTF XXX op3=%x\n", (void *)pc, OP3(inst)); | |
647 | return ERR; | |
648 | default: | |
649 | (void)printf("XXXX dis_class3 op3=%x\n", OP3(inst)); | |
650 | return ERR; | |
651 | } | |
652 | } | |
653 | ||
654 | static int dis_bpcc(uint32_t *pc, uint32_t inst) | |
655 | { | |
656 | char *bpcc[0x10] = { | |
657 | "bpn", "bpe", "bple", "bpl", | |
658 | "bpleu", "bpcs", "bpneg", "bpvs" | |
659 | "bpa", "bpne", "bpg", "bpge", | |
660 | "bpgu", "bpcc", "bppos", "bpvc" | |
661 | }; | |
662 | if ((CC(inst) != 0) && (CC(inst) != 2)) { | |
663 | ILLEGAL; | |
664 | } | |
665 | (void)printf("%p:\t%s%s%s\t%s,0x%lx\n", (void *)pc, | |
666 | bpcc[COND(inst)], | |
667 | A(inst) ? ",a" : "", | |
668 | PT(inst) ? ",pt" : ",pn", | |
669 | CC(inst) ? "%xcc" : "%icc", | |
670 | DISP19(inst) + (int64_t)pc); | |
671 | return DELAY; | |
672 | } | |
673 | ||
674 | static int dis_bpr(uint32_t *pc, uint32_t inst) | |
675 | { | |
676 | (void)printf("%p:\tXXXX dis_bpr 0x%x\n", (void *)pc, inst); | |
677 | return ERR; | |
678 | } | |
679 | ||
680 | static int dis_bicc(uint32_t *pc, uint32_t inst) | |
681 | { | |
682 | char *bcc[0x10] = { | |
683 | "bn", "be", "ble", "bl", | |
684 | "bleu", "bcs", "bneg", "bvs" | |
685 | "ba", "bne", "bg", "bge", | |
686 | "bgu", "bcc", "bpos", "bvc" | |
687 | }; | |
688 | (void)printf("%p:\t%s%s\t0x%lx\n", (void *)pc, | |
689 | bcc[COND(inst)], | |
690 | A(inst) ? ",a" : "", | |
691 | DISP22(inst) + (int64_t)pc); | |
692 | return DELAY; | |
693 | } | |
694 | static int dis_tcc(uint32_t *pc, uint32_t inst) | |
695 | { | |
696 | char *tcc[0x10] = { | |
697 | "tn", "te", "tle", "tl", | |
698 | "tleu", "tcs", "tneg", "tvs", | |
699 | "ta", "tne", "tg", "tge", | |
700 | "tgu", "tcc", "tpos", "tvc" | |
701 | }; | |
702 | (void)printf("%p:\t%s%s\t%s, ", (void *)pc, HT(inst) ? "h" : "", tcc[COND(inst)], | |
703 | TCC(inst) ? "%xcc" : "%icc"); | |
704 | if (IMM(inst)) | |
705 | (void)printf("0x%x\n", SWTRAP(inst)); | |
706 | else | |
707 | (void)printf("%s\n", sregs[RS2(inst)]); | |
708 | return OK; | |
709 | } | |
710 | ||
711 | static int dis_fbfcc(uint32_t *pc, uint32_t inst) | |
712 | { | |
713 | (void)printf("%p:\tXXXX dis_fbfcc 0x%x\n", (void *)pc, inst); | |
714 | return ERR; | |
715 | } | |
716 | static int dis_fbpfcc(uint32_t *pc, uint32_t inst) | |
717 | { | |
718 | (void)printf("%p:\tXXXX dis_fbpfcc 0x%x\n", (void *)pc, inst); | |
719 | return ERR; | |
720 | } | |
721 |