Arc assembler: Convert nps400 from a machine type to an extension.
[deliverable/binutils-gdb.git] / opcodes / arc-dis.c
CommitLineData
252b5132 1/* Instruction printing code for the ARC.
6f2750fe 2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
886a2506
NC
3
4 Contributed by Claudiu Zissulescu (claziss@synopsys.com)
252b5132 5
9b201bb5
NC
6 This file is part of libopcodes.
7
8 This library is free software; you can redistribute it and/or modify
0d2bcfaf 9 it under the terms of the GNU General Public License as published by
9b201bb5
NC
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
252b5132 12
9b201bb5
NC
13 It is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
252b5132 17
0d2bcfaf
NC
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
47b0e7ad
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
252b5132 22
5eb3690e 23#include "sysdep.h"
886a2506
NC
24#include <stdio.h>
25#include <assert.h>
252b5132
RH
26#include "dis-asm.h"
27#include "opcode/arc.h"
0d2bcfaf
NC
28#include "arc-dis.h"
29#include "arc-ext.h"
252b5132 30
4eb6f892
AB
31/* Structure used to iterate over, and extract the values for, operands of
32 an opcode. */
33
34struct arc_operand_iterator
35{
36 enum
37 {
38 OPERAND_ITERATOR_STANDARD,
39 OPERAND_ITERATOR_LONG
40 } mode;
41
42 /* The array of 32-bit values that make up this instruction. All
43 required values have been pre-loaded into this array during the
44 find_format call. */
45 unsigned *insn;
46
47 union
48 {
49 struct
50 {
51 /* The opcode this iterator is operating on. */
52 const struct arc_opcode *opcode;
53
54 /* The index into the opcodes operand index list. */
55 const unsigned char *opidx;
56 } standard;
57
58 struct
59 {
60 /* The long instruction opcode this iterator is operating on. */
61 const struct arc_long_opcode *long_opcode;
62
63 /* Two indexes into the opcodes operand index lists. */
64 const unsigned char *opidx_base, *opidx_limm;
65 } long_insn;
66 } state;
67};
252b5132 68
886a2506 69/* Globals variables. */
82b829a7 70
886a2506 71static const char * const regnames[64] =
47b0e7ad 72{
886a2506
NC
73 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
74 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
75 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
76 "r24", "r25", "gp", "fp", "sp", "ilink", "r30", "blink",
77
78 "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
79 "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
80 "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
81 "r56", "r57", "ACCL", "ACCH", "lp_count", "rezerved", "LIMM", "pcl"
82};
83
84/* Macros section. */
85
86#ifdef DEBUG
87# define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
88#else
89# define pr_debug(fmt, args...)
90#endif
91
92#define ARRANGE_ENDIAN(info, buf) \
93 (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf)) \
94 : bfd_getb32 (buf))
95
96#define BITS(word,s,e) (((word) << (sizeof (word) * 8 - 1 - e)) >> \
97 (s + (sizeof (word) * 8 - 1 - e)))
279a96ca 98#define OPCODE(word) (BITS ((word), 27, 31))
252b5132 99
886a2506 100#define OPCODE_AC(word) (BITS ((word), 11, 15))
252b5132 101
886a2506 102/* Functions implementation. */
252b5132 103
886a2506
NC
104static bfd_vma
105bfd_getm32 (unsigned int data)
0d2bcfaf 106{
886a2506 107 bfd_vma value = 0;
0d2bcfaf 108
886a2506
NC
109 value = ((data & 0xff00) | (data & 0xff)) << 16;
110 value |= ((data & 0xff0000) | (data & 0xff000000)) >> 16;
111 return value;
0d2bcfaf
NC
112}
113
886a2506
NC
114static int
115special_flag_p (const char *opname,
116 const char *flgname)
0d2bcfaf 117{
886a2506 118 const struct arc_flag_special *flg_spec;
886a2506 119 unsigned i, j, flgidx;
0d2bcfaf 120
886a2506 121 for (i = 0; i < arc_num_flag_special; i++)
252b5132 122 {
886a2506 123 flg_spec = &arc_flag_special_cases[i];
279a96ca 124
24b368f8 125 if (strcmp (opname, flg_spec->name))
886a2506 126 continue;
279a96ca 127
886a2506
NC
128 /* Found potential special case instruction. */
129 for (j=0;; ++j)
0d2bcfaf 130 {
886a2506
NC
131 flgidx = flg_spec->flags[j];
132 if (flgidx == 0)
133 break; /* End of the array. */
0d2bcfaf 134
886a2506
NC
135 if (strcmp (flgname, arc_flag_operands[flgidx].name) == 0)
136 return 1;
252b5132 137 }
0d2bcfaf 138 }
886a2506 139 return 0;
0d2bcfaf 140}
252b5132 141
4eb6f892
AB
142/* Find opcode from ARC_TABLE given the instruction described by INSN and
143 INSNLEN. The ISA_MASK restricts the possible matches in ARC_TABLE. */
144
b99747ae 145static const struct arc_opcode *
4eb6f892
AB
146find_format_from_table (const struct arc_opcode *arc_table,
147 unsigned *insn, unsigned int insn_len,
148 unsigned isa_mask, bfd_boolean *has_limm)
b99747ae
CZ
149{
150 unsigned int i = 0;
151 const struct arc_opcode *opcode = NULL;
152 const unsigned char *opidx;
153 const unsigned char *flgidx;
154
155 do {
156 bfd_boolean invalid = FALSE;
157
158 opcode = &arc_table[i++];
159
4eb6f892 160 if (ARC_SHORT (opcode->mask) && (insn_len == 2))
b99747ae
CZ
161 {
162 if (OPCODE_AC (opcode->opcode) != OPCODE_AC (insn[0]))
163 continue;
164 }
4eb6f892 165 else if (!ARC_SHORT (opcode->mask) && (insn_len == 4))
b99747ae
CZ
166 {
167 if (OPCODE (opcode->opcode) != OPCODE (insn[0]))
168 continue;
169 }
170 else
171 continue;
172
173 if ((insn[0] ^ opcode->opcode) & opcode->mask)
174 continue;
175
176 if (!(opcode->cpu & isa_mask))
177 continue;
178
4eb6f892
AB
179 *has_limm = FALSE;
180
b99747ae
CZ
181 /* Possible candidate, check the operands. */
182 for (opidx = opcode->operands; *opidx; opidx++)
183 {
184 int value;
185 const struct arc_operand *operand = &arc_operands[*opidx];
186
187 if (operand->flags & ARC_OPERAND_FAKE)
188 continue;
189
190 if (operand->extract)
191 value = (*operand->extract) (insn[0], &invalid);
192 else
193 value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
194
195 /* Check for LIMM indicator. If it is there, then make sure
196 we pick the right format. */
197 if (operand->flags & ARC_OPERAND_IR
198 && !(operand->flags & ARC_OPERAND_LIMM))
199 {
4eb6f892
AB
200 if ((value == 0x3E && insn_len == 4)
201 || (value == 0x1E && insn_len == 2))
b99747ae
CZ
202 {
203 invalid = TRUE;
204 break;
205 }
206 }
4eb6f892
AB
207
208 if (operand->flags & ARC_OPERAND_LIMM
209 && !(operand->flags & ARC_OPERAND_DUPLICATE))
210 *has_limm = TRUE;
b99747ae
CZ
211 }
212
213 /* Check the flags. */
214 for (flgidx = opcode->flags; *flgidx; flgidx++)
215 {
216 /* Get a valid flag class. */
217 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
218 const unsigned *flgopridx;
219 int foundA = 0, foundB = 0;
f36e33da 220 unsigned int value;
b99747ae 221
f36e33da 222 /* Check first the extensions. */
c810e0b8 223 if (cl_flags->flag_class & F_CLASS_EXTEND)
f36e33da
CZ
224 {
225 value = (insn[0] & 0x1F);
226 if (arcExtMap_condCodeName (value))
227 continue;
228 }
b99747ae
CZ
229 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
230 {
231 const struct arc_flag_operand *flg_operand =
232 &arc_flag_operands[*flgopridx];
b99747ae
CZ
233
234 value = (insn[0] >> flg_operand->shift)
235 & ((1 << flg_operand->bits) - 1);
236 if (value == flg_operand->code)
237 foundA = 1;
238 if (value)
239 foundB = 1;
240 }
241 if (!foundA && foundB)
242 {
243 invalid = TRUE;
244 break;
245 }
246 }
247
248 if (invalid)
249 continue;
250
251 /* The instruction is valid. */
252 return opcode;
253 } while (opcode->mask);
254
255 return NULL;
256}
257
4eb6f892
AB
258/* Find long instructions matching values in INSN array. */
259
260static const struct arc_long_opcode *
261find_format_long_instructions (unsigned *insn,
262 unsigned int *insn_len,
263 unsigned isa_mask,
264 bfd_vma memaddr,
265 struct disassemble_info *info)
266{
267 unsigned int i;
268 unsigned limm = 0;
269 bfd_boolean limm_loaded = FALSE;
270
271 for (i = 0; i < arc_num_long_opcodes; ++i)
272 {
273 bfd_byte buffer[4];
274 int status;
275 const struct arc_opcode *opcode;
276
277 opcode = &arc_long_opcodes[i].base_opcode;
278
279 if (ARC_SHORT (opcode->mask) && (*insn_len == 2))
280 {
281 if (OPCODE_AC (opcode->opcode) != OPCODE_AC (insn[0]))
282 continue;
283 }
284 else if (!ARC_SHORT (opcode->mask) && (*insn_len == 4))
285 {
286 if (OPCODE (opcode->opcode) != OPCODE (insn[0]))
287 continue;
288 }
289 else
290 continue;
291
292 if ((insn[0] ^ opcode->opcode) & opcode->mask)
293 continue;
294
295 if (!(opcode->cpu & isa_mask))
296 continue;
297
298 if (!limm_loaded)
299 {
300 status = (*info->read_memory_func) (memaddr + *insn_len, buffer,
301 4, info);
302 if (status != 0)
303 return NULL;
304
305 limm = ARRANGE_ENDIAN (info, buffer);
306 limm_loaded = TRUE;
307 }
308
309 /* Check the second word using the mask and template. */
310 if ((limm & arc_long_opcodes[i].limm_mask)
311 != arc_long_opcodes[i].limm_template)
312 continue;
313
314 (*insn_len) += 4;
315 insn[1] = limm;
316 return &arc_long_opcodes[i];
317 }
318
319 return NULL;
320}
321
322/* Find opcode for INSN, trying various different sources. The instruction
323 length in INSN_LEN will be updated if the instruction requires a LIMM
324 extension, and the additional values loaded into the INSN array (which
325 must be big enough).
326
327 A pointer to the opcode is placed into OPCODE_RESULT, and ITER is
328 initialised, ready to iterate over the operands of the found opcode.
329
330 This function returns TRUE in almost all cases, FALSE is reserved to
331 indicate an error (failing to find an opcode is not an error) a
332 returned result of FALSE would indicate that the disassembler can't
333 continue.
334
335 If no matching opcode is found then the returned result will be TRUE,
336 the value placed into OPCODE_RESULT will be NULL, ITER will be
337 undefined, and INSN_LEN will be unchanged.
338
339 If a matching opcode is found, then the returned result will be TRUE,
340 the opcode pointer is placed into OPCODE_RESULT, INSN_LEN will be
341 increased by 4 if the instruction requires a LIMM, and the LIMM value
342 will have been loaded into the INSN[1]. Finally, ITER will have been
343 initialised so that calls to OPERAND_ITERATOR_NEXT will iterate over
344 the opcode's operands. */
345
346static bfd_boolean
347find_format (bfd_vma memaddr, unsigned *insn, unsigned int *insn_len,
348 unsigned isa_mask, struct disassemble_info *info,
349 const struct arc_opcode **opcode_result,
350 struct arc_operand_iterator *iter)
351{
352 const struct arc_opcode *opcode;
353 bfd_boolean needs_limm;
354
355 /* Find the first match in the opcode table. */
356 opcode = find_format_from_table (arc_opcodes, insn, *insn_len,
357 isa_mask, &needs_limm);
358
359 if (opcode == NULL)
360 {
361 const extInstruction_t *einsn;
362
363 /* No instruction found. Try the extensions. */
364 einsn = arcExtMap_insn (OPCODE (insn[0]), insn[0]);
365 if (einsn != NULL)
366 {
367 const char *errmsg = NULL;
368 opcode = arcExtMap_genOpcode (einsn, isa_mask, &errmsg);
369 if (opcode == NULL)
370 {
371 (*info->fprintf_func) (info->stream,
372 "An error occured while "
373 "generating the extension instruction "
374 "operations");
375 *opcode_result = NULL;
376 return FALSE;
377 }
378
379 opcode = find_format_from_table (opcode, insn, *insn_len,
380 isa_mask, &needs_limm);
381 assert (opcode != NULL);
382 }
383 }
384
385 if (needs_limm && opcode != NULL)
386 {
387 bfd_byte buffer[4];
388 int status;
389
390 status = (*info->read_memory_func) (memaddr + *insn_len, buffer,
391 4, info);
392 if (status != 0)
393 {
394 opcode = NULL;
395 }
396 else
397 {
398 insn[1] = ARRANGE_ENDIAN (info, buffer);
399 *insn_len += 4;
400 }
401 }
402
403 if (opcode == NULL)
404 {
405 const struct arc_long_opcode *long_opcode;
406
407 /* No instruction found yet, try the long instructions. */
408 long_opcode =
409 find_format_long_instructions (insn, insn_len, isa_mask,
410 memaddr, info);
411
412 if (long_opcode != NULL)
413 {
414 iter->mode = OPERAND_ITERATOR_LONG;
415 iter->insn = insn;
416 iter->state.long_insn.long_opcode = long_opcode;
417 iter->state.long_insn.opidx_base =
418 long_opcode->base_opcode.operands;
419 iter->state.long_insn.opidx_limm =
420 long_opcode->operands;
421 opcode = &long_opcode->base_opcode;
422 }
423 }
424 else
425 {
426 iter->mode = OPERAND_ITERATOR_STANDARD;
427 iter->insn = insn;
428 iter->state.standard.opcode = opcode;
429 iter->state.standard.opidx = opcode->operands;
430 }
431
432 *opcode_result = opcode;
433 return TRUE;
434}
435
f36e33da
CZ
436static void
437print_flags (const struct arc_opcode *opcode,
438 unsigned *insn,
439 struct disassemble_info *info)
440{
441 const unsigned char *flgidx;
442 unsigned int value;
443
444 /* Now extract and print the flags. */
445 for (flgidx = opcode->flags; *flgidx; flgidx++)
446 {
447 /* Get a valid flag class. */
448 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
449 const unsigned *flgopridx;
450
451 /* Check first the extensions. */
c810e0b8 452 if (cl_flags->flag_class & F_CLASS_EXTEND)
f36e33da
CZ
453 {
454 const char *name;
455 value = (insn[0] & 0x1F);
456
457 name = arcExtMap_condCodeName (value);
458 if (name)
459 {
460 (*info->fprintf_func) (info->stream, ".%s", name);
461 continue;
462 }
463 }
464
465 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
466 {
467 const struct arc_flag_operand *flg_operand =
468 &arc_flag_operands[*flgopridx];
469
470 if (!flg_operand->favail)
471 continue;
472
473 value = (insn[0] >> flg_operand->shift)
474 & ((1 << flg_operand->bits) - 1);
475 if (value == flg_operand->code)
476 {
477 /* FIXME!: print correctly nt/t flag. */
478 if (!special_flag_p (opcode->name, flg_operand->name))
479 (*info->fprintf_func) (info->stream, ".");
480 else if (info->insn_type == dis_dref)
481 {
482 switch (flg_operand->name[0])
483 {
484 case 'b':
485 info->data_size = 1;
486 break;
487 case 'h':
488 case 'w':
489 info->data_size = 2;
490 break;
491 default:
492 info->data_size = 4;
493 break;
494 }
495 }
d9eca1df
CZ
496 if (flg_operand->name[0] == 'd'
497 && flg_operand->name[1] == 0)
498 info->branch_delay_insns = 1;
499
500 /* Check if it is a conditional flag. */
501 if (cl_flags->flag_class & F_CLASS_COND)
502 {
503 if (info->insn_type == dis_jsr)
504 info->insn_type = dis_condjsr;
505 else if (info->insn_type == dis_branch)
506 info->insn_type = dis_condbranch;
507 }
508
f36e33da
CZ
509 (*info->fprintf_func) (info->stream, "%s", flg_operand->name);
510 }
f36e33da
CZ
511 }
512 }
513}
514
515static const char *
516get_auxreg (const struct arc_opcode *opcode,
517 int value,
518 unsigned isa_mask)
519{
520 const char *name;
521 unsigned int i;
522 const struct arc_aux_reg *auxr = &arc_aux_regs[0];
523
c810e0b8 524 if (opcode->insn_class != AUXREG)
f36e33da
CZ
525 return NULL;
526
527 name = arcExtMap_auxRegName (value);
528 if (name)
529 return name;
530
531 for (i = 0; i < arc_num_aux_regs; i++, auxr++)
532 {
533 if (!(auxr->cpu & isa_mask))
534 continue;
535
536 if (auxr->subclass != NONE)
537 return NULL;
538
539 if (auxr->address == value)
540 return auxr->name;
541 }
542 return NULL;
543}
cb040366
AB
544
545/* Calculate the instruction length for an instruction starting with MSB
546 and LSB, the most and least significant byte. The ISA_MASK is used to
547 filter the instructions considered to only those that are part of the
548 current architecture.
549
550 The instruction lengths are calculated from the ARC_OPCODE table, and
551 cached for later use. */
552
553static unsigned int
4eb6f892 554arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
cb040366
AB
555{
556 bfd_byte major_opcode = msb >> 3;
557
558 switch (info->mach)
559 {
bdd582db
GM
560 case bfd_mach_arc_arc700:
561 /* The nps400 extension set requires this special casing of the
562 instruction length calculation. Right now this is not causing any
563 problems as none of the known extensions overlap in opcode space,
564 but, if they ever do then we might need to start carrying
565 information around in the elf about which extensions are in use. */
4eb6f892
AB
566 if (major_opcode == 0xb)
567 {
568 bfd_byte minor_opcode = lsb & 0x1f;
569
570 if (minor_opcode < 4)
571 return 2;
572 }
cb040366
AB
573 case bfd_mach_arc_arc600:
574 return (major_opcode > 0xb) ? 2 : 4;
575 break;
576
577 case bfd_mach_arc_arcv2:
578 return (major_opcode > 0x7) ? 2 : 4;
579 break;
580
581 default:
582 abort ();
583 }
584}
585
4eb6f892
AB
586/* Extract and return the value of OPERAND from the instruction whose value
587 is held in the array INSN. */
588
589static int
590extract_operand_value (const struct arc_operand *operand, unsigned *insn)
591{
592 int value;
593
594 /* Read the limm operand, if required. */
595 if (operand->flags & ARC_OPERAND_LIMM)
596 /* The second part of the instruction value will have been loaded as
597 part of the find_format call made earlier. */
598 value = insn[1];
599 else
600 {
601 if (operand->extract)
602 value = (*operand->extract) (insn[0], (int *) NULL);
603 else
604 {
605 if (operand->flags & ARC_OPERAND_ALIGNED32)
606 {
607 value = (insn[0] >> operand->shift)
608 & ((1 << (operand->bits - 2)) - 1);
609 value = value << 2;
610 }
611 else
612 {
613 value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
614 }
615 if (operand->flags & ARC_OPERAND_SIGNED)
616 {
617 int signbit = 1 << (operand->bits - 1);
618 value = (value ^ signbit) - signbit;
619 }
620 }
621 }
622
623 return value;
624}
625
626/* Find the next operand, and the operands value from ITER. Return TRUE if
627 there is another operand, otherwise return FALSE. If there is an
628 operand returned then the operand is placed into OPERAND, and the value
629 into VALUE. If there is no operand returned then OPERAND and VALUE are
630 unchanged. */
631
632static bfd_boolean
633operand_iterator_next (struct arc_operand_iterator *iter,
634 const struct arc_operand **operand,
635 int *value)
636{
637 if (iter->mode == OPERAND_ITERATOR_STANDARD)
638 {
639 if (*iter->state.standard.opidx == 0)
640 {
641 *operand = NULL;
642 return FALSE;
643 }
644
645 *operand = &arc_operands[*iter->state.standard.opidx];
646 *value = extract_operand_value (*operand, iter->insn);
647 iter->state.standard.opidx++;
648 }
649 else
650 {
651 const struct arc_operand *operand_base, *operand_limm;
652 int value_base, value_limm;
653
654 if (*iter->state.long_insn.opidx_limm == 0)
655 {
656 *operand = NULL;
657 return FALSE;
658 }
659
660 operand_base = &arc_operands[*iter->state.long_insn.opidx_base];
661 operand_limm = &arc_operands[*iter->state.long_insn.opidx_limm];
662
663 if (operand_base->flags & ARC_OPERAND_LIMM)
664 {
665 /* We've reached the end of the operand list. */
666 *operand = NULL;
667 return FALSE;
668 }
669
670 value_base = value_limm = 0;
671 if (!(operand_limm->flags & ARC_OPERAND_IGNORE))
672 {
673 /* This should never happen. If it does then the use of
674 extract_operand_value below will access memory beyond
675 the insn array. */
676 assert ((operand_limm->flags & ARC_OPERAND_LIMM) == 0);
677
678 *operand = operand_limm;
679 value_limm = extract_operand_value (*operand, &iter->insn[1]);
680 }
681
682 if (!(operand_base->flags & ARC_OPERAND_IGNORE))
683 {
684 *operand = operand_base;
685 value_base = extract_operand_value (*operand, iter->insn);
686 }
687
688 /* This is a bit of a fudge. There's no reason why simply ORing
689 together the two values is the right thing to do, however, for all
690 the cases we currently have, it is the right thing, so, for now,
691 I've put off solving the more complex problem. */
692 *value = value_base | value_limm;
693
694 iter->state.long_insn.opidx_base++;
695 iter->state.long_insn.opidx_limm++;
696 }
697 return TRUE;
698}
699
886a2506 700/* Disassemble ARC instructions. */
0d2bcfaf 701
886a2506
NC
702static int
703print_insn_arc (bfd_vma memaddr,
704 struct disassemble_info *info)
0d2bcfaf 705{
886a2506
NC
706 bfd_byte buffer[4];
707 unsigned int lowbyte, highbyte;
708 int status;
4eb6f892 709 unsigned int insn_len;
3f94e60d
NC
710 unsigned insn[2] = { 0, 0 };
711 unsigned isa_mask;
886a2506 712 const struct arc_opcode *opcode;
886a2506
NC
713 bfd_boolean need_comma;
714 bfd_boolean open_braket;
24b368f8 715 int size;
4eb6f892
AB
716 const struct arc_operand *operand;
717 int value;
718 struct arc_operand_iterator iter;
0d2bcfaf 719
4eb6f892 720 memset (&iter, 0, sizeof (iter));
886a2506
NC
721 lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
722 highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
0d2bcfaf 723
886a2506
NC
724 switch (info->mach)
725 {
726 case bfd_mach_arc_arc700:
727 isa_mask = ARC_OPCODE_ARC700;
728 break;
0d2bcfaf 729
886a2506
NC
730 case bfd_mach_arc_arc600:
731 isa_mask = ARC_OPCODE_ARC600;
732 break;
0d2bcfaf 733
886a2506
NC
734 case bfd_mach_arc_arcv2:
735 default:
736 isa_mask = ARC_OPCODE_ARCv2HS | ARC_OPCODE_ARCv2EM;
737 break;
0d2bcfaf
NC
738 }
739
24b368f8
CZ
740 /* This variable may be set by the instruction decoder. It suggests
741 the number of bytes objdump should display on a single line. If
742 the instruction decoder sets this, it should always set it to
743 the same value in order to get reasonable looking output. */
744
745 info->bytes_per_line = 8;
746
747 /* In the next lines, we set two info variables control the way
748 objdump displays the raw data. For example, if bytes_per_line is
749 8 and bytes_per_chunk is 4, the output will look like this:
750 00: 00000000 00000000
751 with the chunks displayed according to "display_endian". */
752
753 if (info->section
754 && !(info->section->flags & SEC_CODE))
755 {
756 /* This is not a CODE section. */
757 switch (info->section->size)
758 {
759 case 1:
760 case 2:
761 case 4:
762 size = info->section->size;
763 break;
764 default:
765 size = (info->section->size & 0x01) ? 1 : 4;
766 break;
767 }
768 info->bytes_per_chunk = 1;
769 info->display_endian = info->endian;
770 }
771 else
772 {
773 size = 2;
774 info->bytes_per_chunk = 2;
775 info->display_endian = info->endian;
776 }
777
886a2506 778 /* Read the insn into a host word. */
24b368f8 779 status = (*info->read_memory_func) (memaddr, buffer, size, info);
886a2506 780 if (status != 0)
0d2bcfaf 781 {
886a2506
NC
782 (*info->memory_error_func) (status, memaddr, info);
783 return -1;
0d2bcfaf
NC
784 }
785
886a2506
NC
786 if (info->section
787 && !(info->section->flags & SEC_CODE))
0d2bcfaf 788 {
24b368f8
CZ
789 /* Data section. */
790 unsigned long data;
791
792 data = bfd_get_bits (buffer, size * 8,
793 info->display_endian == BFD_ENDIAN_BIG);
794 switch (size)
0d2bcfaf 795 {
24b368f8
CZ
796 case 1:
797 (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data);
798 break;
799 case 2:
800 (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data);
801 break;
802 case 4:
803 (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data);
804 break;
805 default:
806 abort ();
0d2bcfaf 807 }
24b368f8 808 return size;
886a2506 809 }
279a96ca 810
4eb6f892
AB
811 insn_len = arc_insn_length (buffer[lowbyte], buffer[highbyte], info);
812 pr_debug ("instruction length = %d bytes\n", insn_len);
813 switch (insn_len)
886a2506 814 {
cb040366 815 case 2:
886a2506 816 insn[0] = (buffer[lowbyte] << 8) | buffer[highbyte];
cb040366 817 break;
886a2506 818
cb040366
AB
819 default:
820 /* An unknown instruction is treated as being length 4. This is
821 possibly not the best solution, but matches the behaviour that was
822 in place before the table based instruction length look-up was
823 introduced. */
824 case 4:
886a2506
NC
825 /* This is a long instruction: Read the remaning 2 bytes. */
826 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
827 if (status != 0)
0d2bcfaf 828 {
886a2506
NC
829 (*info->memory_error_func) (status, memaddr + 2, info);
830 return -1;
0d2bcfaf 831 }
886a2506 832 insn[0] = ARRANGE_ENDIAN (info, buffer);
cb040366 833 break;
886a2506
NC
834 }
835
886a2506
NC
836 /* Set some defaults for the insn info. */
837 info->insn_info_valid = 1;
838 info->branch_delay_insns = 0;
839 info->data_size = 0;
840 info->insn_type = dis_nonbranch;
841 info->target = 0;
842 info->target2 = 0;
843
844 /* FIXME to be moved in dissasemble_init_for_target. */
845 info->disassembler_needs_relocs = TRUE;
846
847 /* Find the first match in the opcode table. */
4eb6f892
AB
848 if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
849 return -1;
886a2506 850
b99747ae
CZ
851 if (!opcode)
852 {
4eb6f892
AB
853 if (insn_len == 2)
854 (*info->fprintf_func) (info->stream, ".long %#04x", insn[0]);
b99747ae 855 else
4eb6f892 856 (*info->fprintf_func) (info->stream, ".long %#08x", insn[0]);
886a2506 857
4eb6f892
AB
858 info->insn_type = dis_noninsn;
859 return insn_len;
886a2506 860 }
279a96ca 861
886a2506
NC
862 /* Print the mnemonic. */
863 (*info->fprintf_func) (info->stream, "%s", opcode->name);
864
865 /* Preselect the insn class. */
c810e0b8 866 switch (opcode->insn_class)
886a2506
NC
867 {
868 case BRANCH:
869 case JUMP:
870 if (!strncmp (opcode->name, "bl", 2)
871 || !strncmp (opcode->name, "jl", 2))
d9eca1df
CZ
872 {
873 if (opcode->subclass == COND)
874 info->insn_type = dis_condjsr;
875 else
876 info->insn_type = dis_jsr;
877 }
279a96ca 878 else
d9eca1df
CZ
879 {
880 if (opcode->subclass == COND)
881 info->insn_type = dis_condbranch;
882 else
883 info->insn_type = dis_branch;
884 }
886a2506
NC
885 break;
886 case MEMORY:
887 info->insn_type = dis_dref; /* FIXME! DB indicates mov as memory! */
0d2bcfaf 888 break;
0d2bcfaf 889 default:
886a2506 890 info->insn_type = dis_nonbranch;
0d2bcfaf
NC
891 break;
892 }
279a96ca 893
886a2506 894 pr_debug ("%s: 0x%08x\n", opcode->name, opcode->opcode);
279a96ca 895
f36e33da 896 print_flags (opcode, insn, info);
279a96ca 897
886a2506
NC
898 if (opcode->operands[0] != 0)
899 (*info->fprintf_func) (info->stream, "\t");
279a96ca 900
886a2506
NC
901 need_comma = FALSE;
902 open_braket = FALSE;
279a96ca 903
886a2506 904 /* Now extract and print the operands. */
4eb6f892
AB
905 operand = NULL;
906 while (operand_iterator_next (&iter, &operand, &value))
886a2506 907 {
886a2506 908 if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
0d2bcfaf 909 {
886a2506
NC
910 (*info->fprintf_func) (info->stream, "]");
911 open_braket = FALSE;
912 continue;
0d2bcfaf 913 }
279a96ca 914
886a2506
NC
915 /* Only take input from real operands. */
916 if ((operand->flags & ARC_OPERAND_FAKE)
917 && !(operand->flags & ARC_OPERAND_BRAKET))
918 continue;
279a96ca 919
4eb6f892
AB
920 if ((operand->flags & ARC_OPERAND_IGNORE)
921 && (operand->flags & ARC_OPERAND_IR)
922 && value == -1)
886a2506 923 continue;
279a96ca 924
886a2506
NC
925 if (need_comma)
926 (*info->fprintf_func) (info->stream, ",");
279a96ca 927
886a2506 928 if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
0d2bcfaf 929 {
886a2506
NC
930 (*info->fprintf_func) (info->stream, "[");
931 open_braket = TRUE;
932 need_comma = FALSE;
933 continue;
0d2bcfaf 934 }
886a2506 935
886a2506
NC
936 /* Print the operand as directed by the flags. */
937 if (operand->flags & ARC_OPERAND_IR)
938 {
f36e33da
CZ
939 const char *rname;
940
886a2506 941 assert (value >=0 && value < 64);
f36e33da
CZ
942 rname = arcExtMap_coreRegName (value);
943 if (!rname)
944 rname = regnames[value];
945 (*info->fprintf_func) (info->stream, "%s", rname);
886a2506 946 if (operand->flags & ARC_OPERAND_TRUNCATE)
f36e33da
CZ
947 {
948 rname = arcExtMap_coreRegName (value + 1);
949 if (!rname)
950 rname = regnames[value + 1];
951 (*info->fprintf_func) (info->stream, "%s", rname);
952 }
886a2506
NC
953 }
954 else if (operand->flags & ARC_OPERAND_LIMM)
955 {
4eb6f892 956 const char *rname = get_auxreg (opcode, value, isa_mask);
f36e33da
CZ
957 if (rname && open_braket)
958 (*info->fprintf_func) (info->stream, "%s", rname);
959 else
960 {
4eb6f892 961 (*info->fprintf_func) (info->stream, "%#x", value);
f36e33da
CZ
962 if (info->insn_type == dis_branch
963 || info->insn_type == dis_jsr)
4eb6f892 964 info->target = (bfd_vma) value;
f36e33da 965 }
886a2506
NC
966 }
967 else if (operand->flags & ARC_OPERAND_PCREL)
968 {
969 /* PCL relative. */
970 if (info->flags & INSN_HAS_RELOC)
971 memaddr = 0;
972 (*info->print_address_func) ((memaddr & ~3) + value, info);
279a96ca 973
886a2506
NC
974 info->target = (bfd_vma) (memaddr & ~3) + value;
975 }
976 else if (operand->flags & ARC_OPERAND_SIGNED)
f36e33da
CZ
977 {
978 const char *rname = get_auxreg (opcode, value, isa_mask);
979 if (rname && open_braket)
980 (*info->fprintf_func) (info->stream, "%s", rname);
981 else
982 (*info->fprintf_func) (info->stream, "%d", value);
983 }
886a2506 984 else
f36e33da
CZ
985 {
986 if (operand->flags & ARC_OPERAND_TRUNCATE
987 && !(operand->flags & ARC_OPERAND_ALIGNED32)
988 && !(operand->flags & ARC_OPERAND_ALIGNED16)
989 && value > 0 && value <= 14)
990 (*info->fprintf_func) (info->stream, "r13-%s",
991 regnames[13 + value - 1]);
992 else
993 {
994 const char *rname = get_auxreg (opcode, value, isa_mask);
995 if (rname && open_braket)
996 (*info->fprintf_func) (info->stream, "%s", rname);
997 else
998 (*info->fprintf_func) (info->stream, "%#x", value);
999 }
1000 }
886a2506
NC
1001
1002 need_comma = TRUE;
252b5132 1003 }
279a96ca 1004
4eb6f892 1005 return insn_len;
252b5132
RH
1006}
1007
47b0e7ad 1008
886a2506
NC
1009disassembler_ftype
1010arc_get_disassembler (bfd *abfd)
252b5132 1011{
886a2506
NC
1012 /* Read the extenssion insns and registers, if any. */
1013 build_ARC_extmap (abfd);
b99747ae 1014#ifdef DEBUG
886a2506 1015 dump_ARC_extmap ();
b99747ae 1016#endif
252b5132 1017
886a2506 1018 return print_insn_arc;
252b5132
RH
1019}
1020
886a2506 1021/* Disassemble ARC instructions. Used by debugger. */
47b0e7ad 1022
886a2506
NC
1023struct arcDisState
1024arcAnalyzeInstr (bfd_vma memaddr,
1025 struct disassemble_info *info)
0d2bcfaf 1026{
886a2506
NC
1027 struct arcDisState ret;
1028 memset (&ret, 0, sizeof (struct arcDisState));
1029
1030 ret.instructionLen = print_insn_arc (memaddr, info);
1031
1032#if 0
1033 ret.words[0] = insn[0];
1034 ret.words[1] = insn[1];
1035 ret._this = &ret;
1036 ret.coreRegName = _coreRegName;
1037 ret.auxRegName = _auxRegName;
1038 ret.condCodeName = _condCodeName;
1039 ret.instName = _instName;
1040#endif
47b0e7ad 1041
886a2506 1042 return ret;
0d2bcfaf
NC
1043}
1044
886a2506
NC
1045/* Local variables:
1046 eval: (c-set-style "gnu")
1047 indent-tabs-mode: t
1048 End: */
This page took 0.754918 seconds and 4 git commands to generate.