opcodes,gas: adjust sparc insns and make GAS aware of it
[deliverable/binutils-gdb.git] / opcodes / sparc-dis.c
CommitLineData
252b5132 1/* Print SPARC instructions.
6f2750fe 2 Copyright (C) 1989-2016 Free Software Foundation, Inc.
252b5132 3
9b201bb5
NC
4 This file is part of the GNU opcodes library.
5
6 This library is free software; you can redistribute it and/or modify
0f6ab988 7 it under the terms of the GNU General Public License as published by
9b201bb5
NC
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
252b5132 10
9b201bb5
NC
11 It is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
252b5132 15
0f6ab988
NC
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
47b0e7ad
NC
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
252b5132 20
252b5132 21#include "sysdep.h"
df7b86aa 22#include <stdio.h>
252b5132
RH
23#include "opcode/sparc.h"
24#include "dis-asm.h"
25#include "libiberty.h"
26#include "opintl.h"
27
28/* Bitmask of v9 architectures. */
29#define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \
19f7b010 30 | (1 << SPARC_OPCODE_ARCH_V9A) \
4f26fb3a
JM
31 | (1 << SPARC_OPCODE_ARCH_V9B) \
32 | (1 << SPARC_OPCODE_ARCH_V9C) \
33 | (1 << SPARC_OPCODE_ARCH_V9D) \
34 | (1 << SPARC_OPCODE_ARCH_V9E) \
35 | (1 << SPARC_OPCODE_ARCH_V9V) \
36 | (1 << SPARC_OPCODE_ARCH_V9M))
252b5132
RH
37/* 1 if INSN is for v9 only. */
38#define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9))
39/* 1 if INSN is for v9. */
40#define V9_P(insn) (((insn)->architecture & MASK_V9) != 0)
41
42/* The sorted opcode table. */
47b0e7ad 43static const sparc_opcode **sorted_opcodes;
252b5132
RH
44
45/* For faster lookup, after insns are sorted they are hashed. */
46/* ??? I think there is room for even more improvement. */
47
48#define HASH_SIZE 256
49/* It is important that we only look at insn code bits as that is how the
50 opcode table is hashed. OPCODE_BITS is a table of valid bits for each
51 of the main types (0,1,2,3). */
52static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
53#define HASH_INSN(INSN) \
54 ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
47b0e7ad 55typedef struct sparc_opcode_hash
0f6ab988 56{
47b0e7ad
NC
57 struct sparc_opcode_hash *next;
58 const sparc_opcode *opcode;
59} sparc_opcode_hash;
252b5132 60
47b0e7ad 61static sparc_opcode_hash *opcode_hash_table[HASH_SIZE];
252b5132
RH
62
63/* Sign-extend a value which is N bits long. */
64#define SEX(value, bits) \
65 ((((int)(value)) << ((8 * sizeof (int)) - bits)) \
66 >> ((8 * sizeof (int)) - bits) )
67
68static char *reg_names[] =
47b0e7ad
NC
69{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
70 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
71 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
72 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
73 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
74 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
252b5132
RH
75 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
76 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
47b0e7ad
NC
77 "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
78 "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
252b5132
RH
79 "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
80 "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
81/* psr, wim, tbr, fpsr, cpsr are v8 only. */
82 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
83};
84
85#define freg_names (&reg_names[4 * 8])
86
87/* These are ordered according to there register number in
88 rdpr and wrpr insns. */
89static char *v9_priv_reg_names[] =
90{
91 "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
92 "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
ff3f9d5b 93 "wstate", "fq", "gl"
38074311 94 /* "ver" and "pmcdper" - special cased */
252b5132
RH
95};
96
ff3f9d5b
DM
97/* These are ordered according to there register number in
98 rdhpr and wrhpr insns. */
99static char *v9_hpriv_reg_names[] =
100{
101 "hpstate", "htstate", "resv2", "hintp", "resv4", "htba", "hver",
43e65147 102 "resv7", "resv8", "resv9", "resv10", "resv11", "resv12", "resv13",
ff3f9d5b
DM
103 "resv14", "resv15", "resv16", "resv17", "resv18", "resv19", "resv20",
104 "resv21", "resv22", "resv23", "resv24", "resv25", "resv26", "resv27",
ec92c392 105 "hstick_offset", "hstick_enable", "resv30", "hstick_cmpr"
ff3f9d5b
DM
106};
107
252b5132
RH
108/* These are ordered according to there register number in
109 rd and wr insns (-16). */
110static char *v9a_asr_reg_names[] =
111{
112 "pcr", "pic", "dcr", "gsr", "set_softint", "clear_softint",
2e52845b 113 "softint", "tick_cmpr", "stick", "stick_cmpr", "cfr",
3d68f91c 114 "pause", "mwait"
252b5132
RH
115};
116
117/* Macros used to extract instruction fields. Not all fields have
118 macros defined here, only those which are actually used. */
119
47b0e7ad
NC
120#define X_RD(i) (((i) >> 25) & 0x1f)
121#define X_RS1(i) (((i) >> 14) & 0x1f)
122#define X_LDST_I(i) (((i) >> 13) & 1)
123#define X_ASI(i) (((i) >> 5) & 0xff)
124#define X_RS2(i) (((i) >> 0) & 0x1f)
ea783ef3 125#define X_RS3(i) (((i) >> 9) & 0x1f)
47b0e7ad
NC
126#define X_IMM(i,n) (((i) >> 0) & ((1 << (n)) - 1))
127#define X_SIMM(i,n) SEX (X_IMM ((i), (n)), (n))
128#define X_DISP22(i) (((i) >> 0) & 0x3fffff)
129#define X_IMM22(i) X_DISP22 (i)
130#define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
252b5132
RH
131
132/* These are for v9. */
47b0e7ad 133#define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
2615994e 134#define X_DISP10(i) (((((i) >> 19) & 3) << 8) | (((i) >> 5) & 0xff))
47b0e7ad
NC
135#define X_DISP19(i) (((i) >> 0) & 0x7ffff)
136#define X_MEMBAR(i) ((i) & 0x7f)
252b5132
RH
137
138/* Here is the union which was used to extract instruction fields
139 before the shift and mask macros were written.
140
141 union sparc_insn
142 {
143 unsigned long int code;
144 struct
145 {
146 unsigned int anop:2;
147 #define op ldst.anop
148 unsigned int anrd:5;
149 #define rd ldst.anrd
150 unsigned int op3:6;
151 unsigned int anrs1:5;
152 #define rs1 ldst.anrs1
153 unsigned int i:1;
154 unsigned int anasi:8;
155 #define asi ldst.anasi
156 unsigned int anrs2:5;
157 #define rs2 ldst.anrs2
158 #define shcnt rs2
159 } ldst;
160 struct
161 {
162 unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
163 unsigned int IMM13:13;
164 #define imm13 IMM13.IMM13
165 } IMM13;
166 struct
167 {
168 unsigned int anop:2;
169 unsigned int a:1;
170 unsigned int cond:4;
171 unsigned int op2:3;
172 unsigned int DISP22:22;
173 #define disp22 branch.DISP22
174 #define imm22 disp22
175 } branch;
176 struct
177 {
178 unsigned int anop:2;
179 unsigned int a:1;
180 unsigned int z:1;
181 unsigned int rcond:3;
182 unsigned int op2:3;
183 unsigned int DISP16HI:2;
184 unsigned int p:1;
185 unsigned int _rs1:5;
186 unsigned int DISP16LO:14;
187 } branch16;
188 struct
189 {
190 unsigned int anop:2;
191 unsigned int adisp30:30;
192 #define disp30 call.adisp30
193 } call;
47b0e7ad 194 }; */
252b5132
RH
195
196/* Nonzero if INSN is the opcode for a delayed branch. */
47b0e7ad 197
252b5132 198static int
47b0e7ad 199is_delayed_branch (unsigned long insn)
252b5132 200{
47b0e7ad 201 sparc_opcode_hash *op;
252b5132
RH
202
203 for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
204 {
47b0e7ad
NC
205 const sparc_opcode *opcode = op->opcode;
206
252b5132
RH
207 if ((opcode->match & insn) == opcode->match
208 && (opcode->lose & insn) == 0)
47b0e7ad 209 return opcode->flags & F_DELAYED;
252b5132
RH
210 }
211 return 0;
212}
213
214/* extern void qsort (); */
215
216/* Records current mask of SPARC_OPCODE_ARCH_FOO values, used to pass value
217 to compare_opcodes. */
218static unsigned int current_arch_mask;
219
47b0e7ad
NC
220/* Given BFD mach number, return a mask of SPARC_OPCODE_ARCH_FOO values. */
221
222static int
223compute_arch_mask (unsigned long mach)
224{
225 switch (mach)
226 {
227 case 0 :
228 case bfd_mach_sparc :
d6787ef9
EB
229 return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8)
230 | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_LEON));
47b0e7ad
NC
231 case bfd_mach_sparc_sparclet :
232 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET);
233 case bfd_mach_sparc_sparclite :
234 case bfd_mach_sparc_sparclite_le :
235 /* sparclites insns are recognized by default (because that's how
236 they've always been treated, for better or worse). Kludge this by
237 indicating generic v8 is also selected. */
238 return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE)
239 | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8));
240 case bfd_mach_sparc_v8plus :
241 case bfd_mach_sparc_v9 :
242 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9);
243 case bfd_mach_sparc_v8plusa :
244 case bfd_mach_sparc_v9a :
245 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A);
246 case bfd_mach_sparc_v8plusb :
247 case bfd_mach_sparc_v9b :
248 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9B);
4f26fb3a
JM
249 case bfd_mach_sparc_v8plusc :
250 case bfd_mach_sparc_v9c :
251 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9C);
252 case bfd_mach_sparc_v8plusd :
253 case bfd_mach_sparc_v9d :
254 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9D);
255 case bfd_mach_sparc_v8pluse :
256 case bfd_mach_sparc_v9e :
257 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9E);
258 case bfd_mach_sparc_v8plusv :
259 case bfd_mach_sparc_v9v :
260 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9V);
261 case bfd_mach_sparc_v8plusm :
262 case bfd_mach_sparc_v9m :
263 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9M);
47b0e7ad
NC
264 }
265 abort ();
266}
267
268/* Compare opcodes A and B. */
269
270static int
271compare_opcodes (const void * a, const void * b)
272{
273 sparc_opcode *op0 = * (sparc_opcode **) a;
274 sparc_opcode *op1 = * (sparc_opcode **) b;
275 unsigned long int match0 = op0->match, match1 = op1->match;
276 unsigned long int lose0 = op0->lose, lose1 = op1->lose;
277 register unsigned int i;
278
279 /* If one (and only one) insn isn't supported by the current architecture,
280 prefer the one that is. If neither are supported, but they're both for
281 the same architecture, continue processing. Otherwise (both unsupported
282 and for different architectures), prefer lower numbered arch's (fudged
283 by comparing the bitmasks). */
284 if (op0->architecture & current_arch_mask)
285 {
286 if (! (op1->architecture & current_arch_mask))
287 return -1;
288 }
289 else
290 {
291 if (op1->architecture & current_arch_mask)
292 return 1;
293 else if (op0->architecture != op1->architecture)
294 return op0->architecture - op1->architecture;
295 }
296
297 /* If a bit is set in both match and lose, there is something
298 wrong with the opcode table. */
299 if (match0 & lose0)
300 {
301 fprintf
302 (stderr,
303 /* xgettext:c-format */
304 _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
305 op0->name, match0, lose0);
306 op0->lose &= ~op0->match;
307 lose0 = op0->lose;
308 }
309
310 if (match1 & lose1)
311 {
312 fprintf
313 (stderr,
314 /* xgettext:c-format */
315 _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
316 op1->name, match1, lose1);
317 op1->lose &= ~op1->match;
318 lose1 = op1->lose;
319 }
320
321 /* Because the bits that are variable in one opcode are constant in
322 another, it is important to order the opcodes in the right order. */
323 for (i = 0; i < 32; ++i)
324 {
325 unsigned long int x = 1 << i;
326 int x0 = (match0 & x) != 0;
327 int x1 = (match1 & x) != 0;
328
329 if (x0 != x1)
330 return x1 - x0;
331 }
332
333 for (i = 0; i < 32; ++i)
334 {
335 unsigned long int x = 1 << i;
336 int x0 = (lose0 & x) != 0;
337 int x1 = (lose1 & x) != 0;
338
339 if (x0 != x1)
340 return x1 - x0;
341 }
342
343 /* They are functionally equal. So as long as the opcode table is
344 valid, we can put whichever one first we want, on aesthetic grounds. */
345
346 /* Our first aesthetic ground is that aliases defer to real insns. */
347 {
348 int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
349
350 if (alias_diff != 0)
351 /* Put the one that isn't an alias first. */
352 return alias_diff;
353 }
354
355 /* Except for aliases, two "identical" instructions had
356 better have the same opcode. This is a sanity check on the table. */
357 i = strcmp (op0->name, op1->name);
358 if (i)
359 {
0afd1215
DM
360 if (op0->flags & F_ALIAS)
361 {
362 if (op0->flags & F_PREFERRED)
363 return -1;
364 if (op1->flags & F_PREFERRED)
365 return 1;
366
367 /* If they're both aliases, and neither is marked as preferred,
368 be arbitrary. */
369 return i;
370 }
47b0e7ad
NC
371 else
372 fprintf (stderr,
373 /* xgettext:c-format */
374 _("Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n"),
375 op0->name, op1->name);
376 }
377
378 /* Fewer arguments are preferred. */
379 {
380 int length_diff = strlen (op0->args) - strlen (op1->args);
381
382 if (length_diff != 0)
383 /* Put the one with fewer arguments first. */
384 return length_diff;
385 }
386
387 /* Put 1+i before i+1. */
388 {
389 char *p0 = (char *) strchr (op0->args, '+');
390 char *p1 = (char *) strchr (op1->args, '+');
391
392 if (p0 && p1)
393 {
394 /* There is a plus in both operands. Note that a plus
395 sign cannot be the first character in args,
396 so the following [-1]'s are valid. */
397 if (p0[-1] == 'i' && p1[1] == 'i')
398 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
399 return 1;
400 if (p0[1] == 'i' && p1[-1] == 'i')
401 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
402 return -1;
403 }
404 }
405
406 /* Put 1,i before i,1. */
407 {
408 int i0 = strncmp (op0->args, "i,1", 3) == 0;
409 int i1 = strncmp (op1->args, "i,1", 3) == 0;
410
411 if (i0 ^ i1)
412 return i0 - i1;
413 }
414
415 /* They are, as far as we can tell, identical.
416 Since qsort may have rearranged the table partially, there is
417 no way to tell which one was first in the opcode table as
418 written, so just say there are equal. */
419 /* ??? This is no longer true now that we sort a vector of pointers,
420 not the table itself. */
421 return 0;
422}
423
424/* Build a hash table from the opcode table.
425 OPCODE_TABLE is a sorted list of pointers into the opcode table. */
426
427static void
428build_hash_table (const sparc_opcode **opcode_table,
429 sparc_opcode_hash **hash_table,
430 int num_opcodes)
431{
432 int i;
433 int hash_count[HASH_SIZE];
434 static sparc_opcode_hash *hash_buf = NULL;
435
436 /* Start at the end of the table and work backwards so that each
437 chain is sorted. */
438
439 memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
440 memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
441 if (hash_buf != NULL)
442 free (hash_buf);
443 hash_buf = xmalloc (sizeof (* hash_buf) * num_opcodes);
444 for (i = num_opcodes - 1; i >= 0; --i)
445 {
446 int hash = HASH_INSN (opcode_table[i]->match);
447 sparc_opcode_hash *h = &hash_buf[i];
448
449 h->next = hash_table[hash];
450 h->opcode = opcode_table[i];
451 hash_table[hash] = h;
452 ++hash_count[hash];
453 }
454
455#if 0 /* for debugging */
456 {
457 int min_count = num_opcodes, max_count = 0;
458 int total;
459
460 for (i = 0; i < HASH_SIZE; ++i)
461 {
462 if (hash_count[i] < min_count)
463 min_count = hash_count[i];
464 if (hash_count[i] > max_count)
465 max_count = hash_count[i];
466 total += hash_count[i];
467 }
468
469 printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
470 min_count, max_count, (double) total / HASH_SIZE);
471 }
472#endif
473}
474
252b5132
RH
475/* Print one instruction from MEMADDR on INFO->STREAM.
476
477 We suffix the instruction with a comment that gives the absolute
478 address involved, as well as its symbolic form, if the instruction
479 is preceded by a findable `sethi' and it either adds an immediate
480 displacement to that register, or it is an `add' or `or' instruction
481 on that register. */
482
483int
47b0e7ad 484print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
252b5132
RH
485{
486 FILE *stream = info->stream;
487 bfd_byte buffer[4];
488 unsigned long insn;
47b0e7ad 489 sparc_opcode_hash *op;
252b5132
RH
490 /* Nonzero of opcode table has been initialized. */
491 static int opcodes_initialized = 0;
492 /* bfd mach number of last call. */
493 static unsigned long current_mach = 0;
7bfeee7b 494 bfd_vma (*getword) (const void *);
252b5132
RH
495
496 if (!opcodes_initialized
497 || info->mach != current_mach)
498 {
499 int i;
500
501 current_arch_mask = compute_arch_mask (info->mach);
502
503 if (!opcodes_initialized)
47b0e7ad
NC
504 sorted_opcodes =
505 xmalloc (sparc_num_opcodes * sizeof (sparc_opcode *));
252b5132
RH
506 /* Reset the sorted table so we can resort it. */
507 for (i = 0; i < sparc_num_opcodes; ++i)
508 sorted_opcodes[i] = &sparc_opcodes[i];
509 qsort ((char *) sorted_opcodes, sparc_num_opcodes,
510 sizeof (sorted_opcodes[0]), compare_opcodes);
511
512 build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes);
513 current_mach = info->mach;
514 opcodes_initialized = 1;
515 }
516
517 {
518 int status =
519 (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
47b0e7ad 520
252b5132
RH
521 if (status != 0)
522 {
523 (*info->memory_error_func) (status, memaddr, info);
524 return -1;
525 }
526 }
527
528 /* On SPARClite variants such as DANlite (sparc86x), instructions
0f6ab988 529 are always big-endian even when the machine is in little-endian mode. */
252b5132
RH
530 if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite)
531 getword = bfd_getb32;
532 else
533 getword = bfd_getl32;
534
535 insn = getword (buffer);
536
0f6ab988
NC
537 info->insn_info_valid = 1; /* We do return this info. */
538 info->insn_type = dis_nonbranch; /* Assume non branch insn. */
539 info->branch_delay_insns = 0; /* Assume no delay. */
540 info->target = 0; /* Assume no target known. */
252b5132
RH
541
542 for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
543 {
47b0e7ad 544 const sparc_opcode *opcode = op->opcode;
252b5132
RH
545
546 /* If the insn isn't supported by the current architecture, skip it. */
547 if (! (opcode->architecture & current_arch_mask))
548 continue;
549
550 if ((opcode->match & insn) == opcode->match
551 && (opcode->lose & insn) == 0)
552 {
553 /* Nonzero means that we have found an instruction which has
554 the effect of adding or or'ing the imm13 field to rs1. */
555 int imm_added_to_rs1 = 0;
9df31319 556 int imm_ored_to_rs1 = 0;
252b5132
RH
557
558 /* Nonzero means that we have found a plus sign in the args
559 field of the opcode table. */
560 int found_plus = 0;
47b0e7ad 561
252b5132
RH
562 /* Nonzero means we have an annulled branch. */
563 int is_annulled = 0;
564
565 /* Do we have an `add' or `or' instruction combining an
566 immediate with rs1? */
9df31319
RH
567 if (opcode->match == 0x80102000) /* or */
568 imm_ored_to_rs1 = 1;
569 if (opcode->match == 0x80002000) /* add */
252b5132
RH
570 imm_added_to_rs1 = 1;
571
572 if (X_RS1 (insn) != X_RD (insn)
573 && strchr (opcode->args, 'r') != 0)
574 /* Can't do simple format if source and dest are different. */
575 continue;
576 if (X_RS2 (insn) != X_RD (insn)
577 && strchr (opcode->args, 'O') != 0)
578 /* Can't do simple format if source and dest are different. */
579 continue;
580
d908c8af 581 (*info->fprintf_func) (stream, "%s", opcode->name);
252b5132
RH
582
583 {
47b0e7ad 584 const char *s;
252b5132
RH
585
586 if (opcode->args[0] != ',')
587 (*info->fprintf_func) (stream, " ");
0f6ab988 588
252b5132
RH
589 for (s = opcode->args; *s != '\0'; ++s)
590 {
591 while (*s == ',')
592 {
593 (*info->fprintf_func) (stream, ",");
594 ++s;
0f6ab988
NC
595 switch (*s)
596 {
597 case 'a':
598 (*info->fprintf_func) (stream, "a");
599 is_annulled = 1;
600 ++s;
601 continue;
602 case 'N':
603 (*info->fprintf_func) (stream, "pn");
604 ++s;
605 continue;
606
607 case 'T':
608 (*info->fprintf_func) (stream, "pt");
609 ++s;
610 continue;
611
612 default:
613 break;
614 }
615 }
252b5132
RH
616
617 (*info->fprintf_func) (stream, " ");
47b0e7ad 618
252b5132
RH
619 switch (*s)
620 {
621 case '+':
622 found_plus = 1;
47b0e7ad 623 /* Fall through. */
252b5132 624
252b5132
RH
625 default:
626 (*info->fprintf_func) (stream, "%c", *s);
627 break;
628
629 case '#':
630 (*info->fprintf_func) (stream, "0");
631 break;
632
633#define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
634 case '1':
635 case 'r':
636 reg (X_RS1 (insn));
637 break;
638
639 case '2':
640 case 'O':
641 reg (X_RS2 (insn));
642 break;
643
644 case 'd':
645 reg (X_RD (insn));
646 break;
647#undef reg
648
649#define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
650#define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
651 case 'e':
652 freg (X_RS1 (insn));
653 break;
47b0e7ad
NC
654 case 'v': /* Double/even. */
655 case 'V': /* Quad/multiple of 4. */
252b5132
RH
656 fregx (X_RS1 (insn));
657 break;
658
659 case 'f':
660 freg (X_RS2 (insn));
661 break;
47b0e7ad
NC
662 case 'B': /* Double/even. */
663 case 'R': /* Quad/multiple of 4. */
252b5132
RH
664 fregx (X_RS2 (insn));
665 break;
666
ea783ef3
DM
667 case '4':
668 freg (X_RS3 (insn));
669 break;
670 case '5': /* Double/even. */
671 fregx (X_RS3 (insn));
672 break;
673
252b5132
RH
674 case 'g':
675 freg (X_RD (insn));
676 break;
47b0e7ad
NC
677 case 'H': /* Double/even. */
678 case 'J': /* Quad/multiple of 4. */
3d68f91c 679 case '}': /* Double/even. */
252b5132
RH
680 fregx (X_RD (insn));
681 break;
682#undef freg
683#undef fregx
684
685#define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
686 case 'b':
687 creg (X_RS1 (insn));
688 break;
689
690 case 'c':
691 creg (X_RS2 (insn));
692 break;
693
694 case 'D':
695 creg (X_RD (insn));
696 break;
697#undef creg
698
699 case 'h':
700 (*info->fprintf_func) (stream, "%%hi(%#x)",
56930d37 701 ((unsigned) 0xFFFFFFFF
252b5132
RH
702 & ((int) X_IMM22 (insn) << 10)));
703 break;
704
47b0e7ad
NC
705 case 'i': /* 13 bit immediate. */
706 case 'I': /* 11 bit immediate. */
707 case 'j': /* 10 bit immediate. */
252b5132
RH
708 {
709 int imm;
710
711 if (*s == 'i')
712 imm = X_SIMM (insn, 13);
713 else if (*s == 'I')
714 imm = X_SIMM (insn, 11);
715 else
716 imm = X_SIMM (insn, 10);
717
718 /* Check to see whether we have a 1+i, and take
719 note of that fact.
720
721 Note: because of the way we sort the table,
722 we will be matching 1+i rather than i+1,
723 so it is OK to assume that i is after +,
724 not before it. */
725 if (found_plus)
726 imm_added_to_rs1 = 1;
47b0e7ad 727
252b5132
RH
728 if (imm <= 9)
729 (*info->fprintf_func) (stream, "%d", imm);
730 else
731 (*info->fprintf_func) (stream, "%#x", imm);
732 }
733 break;
734
6cda1326 735 case ')': /* 5 bit unsigned immediate from RS3. */
d908c8af 736 (info->fprintf_func) (stream, "%#x", (unsigned int) X_RS3 (insn));
6cda1326
DM
737 break;
738
47b0e7ad
NC
739 case 'X': /* 5 bit unsigned immediate. */
740 case 'Y': /* 6 bit unsigned immediate. */
252b5132
RH
741 {
742 int imm = X_IMM (insn, *s == 'X' ? 5 : 6);
743
744 if (imm <= 9)
745 (info->fprintf_func) (stream, "%d", imm);
746 else
747 (info->fprintf_func) (stream, "%#x", (unsigned) imm);
748 }
749 break;
750
19f7b010 751 case '3':
0fd3a477 752 (info->fprintf_func) (stream, "%ld", X_IMM (insn, 3));
19f7b010
JJ
753 break;
754
252b5132
RH
755 case 'K':
756 {
757 int mask = X_MEMBAR (insn);
758 int bit = 0x40, printed_one = 0;
759 const char *name;
760
761 if (mask == 0)
762 (info->fprintf_func) (stream, "0");
763 else
764 while (bit)
765 {
766 if (mask & bit)
767 {
768 if (printed_one)
769 (info->fprintf_func) (stream, "|");
770 name = sparc_decode_membar (bit);
771 (info->fprintf_func) (stream, "%s", name);
772 printed_one = 1;
773 }
774 bit >>= 1;
775 }
776 break;
777 }
778
2615994e
DM
779 case '=':
780 info->target = memaddr + SEX (X_DISP10 (insn), 10) * 4;
781 (*info->print_address_func) (info->target, info);
782 break;
783
252b5132
RH
784 case 'k':
785 info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
786 (*info->print_address_func) (info->target, info);
787 break;
788
789 case 'G':
790 info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;
791 (*info->print_address_func) (info->target, info);
792 break;
793
794 case '6':
795 case '7':
796 case '8':
797 case '9':
798 (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
799 break;
800
801 case 'z':
802 (*info->fprintf_func) (stream, "%%icc");
803 break;
804
805 case 'Z':
806 (*info->fprintf_func) (stream, "%%xcc");
807 break;
808
809 case 'E':
810 (*info->fprintf_func) (stream, "%%ccr");
811 break;
812
813 case 's':
814 (*info->fprintf_func) (stream, "%%fprs");
815 break;
816
3d68f91c
JM
817 case '{':
818 (*info->fprintf_func) (stream, "%%mcdper");
819 break;
820
252b5132
RH
821 case 'o':
822 (*info->fprintf_func) (stream, "%%asi");
823 break;
47b0e7ad 824
252b5132
RH
825 case 'W':
826 (*info->fprintf_func) (stream, "%%tick");
827 break;
828
829 case 'P':
830 (*info->fprintf_func) (stream, "%%pc");
831 break;
832
833 case '?':
834 if (X_RS1 (insn) == 31)
835 (*info->fprintf_func) (stream, "%%ver");
38074311
JM
836 else if (X_RS1 (insn) == 23)
837 (*info->fprintf_func) (stream, "%%pmcdper");
ff3f9d5b 838 else if ((unsigned) X_RS1 (insn) < 17)
252b5132
RH
839 (*info->fprintf_func) (stream, "%%%s",
840 v9_priv_reg_names[X_RS1 (insn)]);
841 else
842 (*info->fprintf_func) (stream, "%%reserved");
843 break;
844
845 case '!':
38074311
JM
846 if (X_RD (insn) == 23)
847 (*info->fprintf_func) (stream, "%%pmcdper");
848 else if ((unsigned) X_RD (insn) < 17)
252b5132
RH
849 (*info->fprintf_func) (stream, "%%%s",
850 v9_priv_reg_names[X_RD (insn)]);
851 else
852 (*info->fprintf_func) (stream, "%%reserved");
853 break;
854
ff3f9d5b
DM
855 case '$':
856 if ((unsigned) X_RS1 (insn) < 32)
857 (*info->fprintf_func) (stream, "%%%s",
858 v9_hpriv_reg_names[X_RS1 (insn)]);
859 else
860 (*info->fprintf_func) (stream, "%%reserved");
861 break;
862
863 case '%':
864 if ((unsigned) X_RD (insn) < 32)
865 (*info->fprintf_func) (stream, "%%%s",
866 v9_hpriv_reg_names[X_RD (insn)]);
867 else
868 (*info->fprintf_func) (stream, "%%reserved");
869 break;
870
252b5132 871 case '/':
ea783ef3 872 if (X_RS1 (insn) < 16 || X_RS1 (insn) > 28)
252b5132
RH
873 (*info->fprintf_func) (stream, "%%reserved");
874 else
875 (*info->fprintf_func) (stream, "%%%s",
876 v9a_asr_reg_names[X_RS1 (insn)-16]);
877 break;
878
879 case '_':
ea783ef3 880 if (X_RD (insn) < 16 || X_RD (insn) > 28)
252b5132
RH
881 (*info->fprintf_func) (stream, "%%reserved");
882 else
883 (*info->fprintf_func) (stream, "%%%s",
884 v9a_asr_reg_names[X_RD (insn)-16]);
885 break;
886
887 case '*':
888 {
889 const char *name = sparc_decode_prefetch (X_RD (insn));
890
891 if (name)
892 (*info->fprintf_func) (stream, "%s", name);
893 else
0fd3a477 894 (*info->fprintf_func) (stream, "%ld", X_RD (insn));
252b5132
RH
895 break;
896 }
47b0e7ad 897
252b5132 898 case 'M':
0fd3a477 899 (*info->fprintf_func) (stream, "%%asr%ld", X_RS1 (insn));
252b5132 900 break;
47b0e7ad 901
252b5132 902 case 'm':
0fd3a477 903 (*info->fprintf_func) (stream, "%%asr%ld", X_RD (insn));
252b5132 904 break;
47b0e7ad 905
252b5132
RH
906 case 'L':
907 info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
908 (*info->print_address_func) (info->target, info);
909 break;
910
911 case 'n':
912 (*info->fprintf_func)
913 (stream, "%#x", SEX (X_DISP22 (insn), 22));
914 break;
915
916 case 'l':
917 info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;
918 (*info->print_address_func) (info->target, info);
919 break;
920
921 case 'A':
922 {
923 const char *name = sparc_decode_asi (X_ASI (insn));
924
925 if (name)
926 (*info->fprintf_func) (stream, "%s", name);
927 else
0fd3a477 928 (*info->fprintf_func) (stream, "(%ld)", X_ASI (insn));
252b5132
RH
929 break;
930 }
931
932 case 'C':
933 (*info->fprintf_func) (stream, "%%csr");
934 break;
935
936 case 'F':
937 (*info->fprintf_func) (stream, "%%fsr");
938 break;
939
ea783ef3
DM
940 case '(':
941 (*info->fprintf_func) (stream, "%%efsr");
942 break;
943
252b5132
RH
944 case 'p':
945 (*info->fprintf_func) (stream, "%%psr");
946 break;
947
948 case 'q':
949 (*info->fprintf_func) (stream, "%%fq");
950 break;
951
952 case 'Q':
953 (*info->fprintf_func) (stream, "%%cq");
954 break;
955
956 case 't':
957 (*info->fprintf_func) (stream, "%%tbr");
958 break;
959
960 case 'w':
961 (*info->fprintf_func) (stream, "%%wim");
962 break;
963
964 case 'x':
0fd3a477 965 (*info->fprintf_func) (stream, "%ld",
252b5132
RH
966 ((X_LDST_I (insn) << 8)
967 + X_ASI (insn)));
968 break;
969
970 case 'y':
971 (*info->fprintf_func) (stream, "%%y");
972 break;
973
974 case 'u':
975 case 'U':
976 {
977 int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);
978 const char *name = sparc_decode_sparclet_cpreg (val);
979
980 if (name)
981 (*info->fprintf_func) (stream, "%s", name);
982 else
983 (*info->fprintf_func) (stream, "%%cpreg(%d)", val);
984 break;
985 }
986 }
987 }
988 }
989
990 /* If we are adding or or'ing something to rs1, then
991 check to see whether the previous instruction was
992 a sethi to the same register as in the sethi.
993 If so, attempt to print the result of the add or
994 or (in this context add and or do the same thing)
995 and its symbolic value. */
9df31319 996 if (imm_ored_to_rs1 || imm_added_to_rs1)
252b5132
RH
997 {
998 unsigned long prev_insn;
999 int errcode;
1000
0f6ab988
NC
1001 if (memaddr >= 4)
1002 errcode =
1003 (*info->read_memory_func)
252b5132 1004 (memaddr - 4, buffer, sizeof (buffer), info);
0f6ab988
NC
1005 else
1006 errcode = 1;
1007
252b5132
RH
1008 prev_insn = getword (buffer);
1009
1010 if (errcode == 0)
1011 {
1012 /* If it is a delayed branch, we need to look at the
1013 instruction before the delayed branch. This handles
0f6ab988 1014 sequences such as:
252b5132
RH
1015
1016 sethi %o1, %hi(_foo), %o1
1017 call _printf
0f6ab988 1018 or %o1, %lo(_foo), %o1 */
252b5132
RH
1019
1020 if (is_delayed_branch (prev_insn))
1021 {
0f6ab988
NC
1022 if (memaddr >= 8)
1023 errcode = (*info->read_memory_func)
1024 (memaddr - 8, buffer, sizeof (buffer), info);
1025 else
1026 errcode = 1;
1027
252b5132
RH
1028 prev_insn = getword (buffer);
1029 }
1030 }
1031
1032 /* If there was a problem reading memory, then assume
1033 the previous instruction was not sethi. */
1034 if (errcode == 0)
1035 {
1036 /* Is it sethi to the same register? */
1037 if ((prev_insn & 0xc1c00000) == 0x01000000
1038 && X_RD (prev_insn) == X_RS1 (insn))
1039 {
1040 (*info->fprintf_func) (stream, "\t! ");
47b0e7ad 1041 info->target =
56930d37
AO
1042 ((unsigned) 0xFFFFFFFF
1043 & ((int) X_IMM22 (prev_insn) << 10));
9df31319
RH
1044 if (imm_added_to_rs1)
1045 info->target += X_SIMM (insn, 13);
1046 else
1047 info->target |= X_SIMM (insn, 13);
252b5132
RH
1048 (*info->print_address_func) (info->target, info);
1049 info->insn_type = dis_dref;
1050 info->data_size = 4; /* FIXME!!! */
1051 }
1052 }
1053 }
1054
1055 if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
1056 {
c7e2358a
AM
1057 /* FIXME -- check is_annulled flag. */
1058 (void) is_annulled;
252b5132
RH
1059 if (opcode->flags & F_UNBR)
1060 info->insn_type = dis_branch;
1061 if (opcode->flags & F_CONDBR)
1062 info->insn_type = dis_condbranch;
1063 if (opcode->flags & F_JSR)
1064 info->insn_type = dis_jsr;
1065 if (opcode->flags & F_DELAYED)
1066 info->branch_delay_insns = 1;
1067 }
1068
1069 return sizeof (buffer);
1070 }
1071 }
1072
0f6ab988 1073 info->insn_type = dis_noninsn; /* Mark as non-valid instruction. */
252b5132
RH
1074 (*info->fprintf_func) (stream, _("unknown"));
1075 return sizeof (buffer);
1076}
This page took 0.845307 seconds and 4 git commands to generate.