S390 gdbserver: Mark local funcs/vars as static
[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 {
560 case bfd_mach_arc_nps400:
4eb6f892
AB
561 if (major_opcode == 0xb)
562 {
563 bfd_byte minor_opcode = lsb & 0x1f;
564
565 if (minor_opcode < 4)
566 return 2;
567 }
cb040366
AB
568 case bfd_mach_arc_arc700:
569 case bfd_mach_arc_arc600:
570 return (major_opcode > 0xb) ? 2 : 4;
571 break;
572
573 case bfd_mach_arc_arcv2:
574 return (major_opcode > 0x7) ? 2 : 4;
575 break;
576
577 default:
578 abort ();
579 }
580}
581
4eb6f892
AB
582/* Extract and return the value of OPERAND from the instruction whose value
583 is held in the array INSN. */
584
585static int
586extract_operand_value (const struct arc_operand *operand, unsigned *insn)
587{
588 int value;
589
590 /* Read the limm operand, if required. */
591 if (operand->flags & ARC_OPERAND_LIMM)
592 /* The second part of the instruction value will have been loaded as
593 part of the find_format call made earlier. */
594 value = insn[1];
595 else
596 {
597 if (operand->extract)
598 value = (*operand->extract) (insn[0], (int *) NULL);
599 else
600 {
601 if (operand->flags & ARC_OPERAND_ALIGNED32)
602 {
603 value = (insn[0] >> operand->shift)
604 & ((1 << (operand->bits - 2)) - 1);
605 value = value << 2;
606 }
607 else
608 {
609 value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
610 }
611 if (operand->flags & ARC_OPERAND_SIGNED)
612 {
613 int signbit = 1 << (operand->bits - 1);
614 value = (value ^ signbit) - signbit;
615 }
616 }
617 }
618
619 return value;
620}
621
622/* Find the next operand, and the operands value from ITER. Return TRUE if
623 there is another operand, otherwise return FALSE. If there is an
624 operand returned then the operand is placed into OPERAND, and the value
625 into VALUE. If there is no operand returned then OPERAND and VALUE are
626 unchanged. */
627
628static bfd_boolean
629operand_iterator_next (struct arc_operand_iterator *iter,
630 const struct arc_operand **operand,
631 int *value)
632{
633 if (iter->mode == OPERAND_ITERATOR_STANDARD)
634 {
635 if (*iter->state.standard.opidx == 0)
636 {
637 *operand = NULL;
638 return FALSE;
639 }
640
641 *operand = &arc_operands[*iter->state.standard.opidx];
642 *value = extract_operand_value (*operand, iter->insn);
643 iter->state.standard.opidx++;
644 }
645 else
646 {
647 const struct arc_operand *operand_base, *operand_limm;
648 int value_base, value_limm;
649
650 if (*iter->state.long_insn.opidx_limm == 0)
651 {
652 *operand = NULL;
653 return FALSE;
654 }
655
656 operand_base = &arc_operands[*iter->state.long_insn.opidx_base];
657 operand_limm = &arc_operands[*iter->state.long_insn.opidx_limm];
658
659 if (operand_base->flags & ARC_OPERAND_LIMM)
660 {
661 /* We've reached the end of the operand list. */
662 *operand = NULL;
663 return FALSE;
664 }
665
666 value_base = value_limm = 0;
667 if (!(operand_limm->flags & ARC_OPERAND_IGNORE))
668 {
669 /* This should never happen. If it does then the use of
670 extract_operand_value below will access memory beyond
671 the insn array. */
672 assert ((operand_limm->flags & ARC_OPERAND_LIMM) == 0);
673
674 *operand = operand_limm;
675 value_limm = extract_operand_value (*operand, &iter->insn[1]);
676 }
677
678 if (!(operand_base->flags & ARC_OPERAND_IGNORE))
679 {
680 *operand = operand_base;
681 value_base = extract_operand_value (*operand, iter->insn);
682 }
683
684 /* This is a bit of a fudge. There's no reason why simply ORing
685 together the two values is the right thing to do, however, for all
686 the cases we currently have, it is the right thing, so, for now,
687 I've put off solving the more complex problem. */
688 *value = value_base | value_limm;
689
690 iter->state.long_insn.opidx_base++;
691 iter->state.long_insn.opidx_limm++;
692 }
693 return TRUE;
694}
695
886a2506 696/* Disassemble ARC instructions. */
0d2bcfaf 697
886a2506
NC
698static int
699print_insn_arc (bfd_vma memaddr,
700 struct disassemble_info *info)
0d2bcfaf 701{
886a2506
NC
702 bfd_byte buffer[4];
703 unsigned int lowbyte, highbyte;
704 int status;
4eb6f892 705 unsigned int insn_len;
3f94e60d
NC
706 unsigned insn[2] = { 0, 0 };
707 unsigned isa_mask;
886a2506 708 const struct arc_opcode *opcode;
886a2506
NC
709 bfd_boolean need_comma;
710 bfd_boolean open_braket;
24b368f8 711 int size;
4eb6f892
AB
712 const struct arc_operand *operand;
713 int value;
714 struct arc_operand_iterator iter;
0d2bcfaf 715
4eb6f892 716 memset (&iter, 0, sizeof (iter));
886a2506
NC
717 lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
718 highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
0d2bcfaf 719
886a2506
NC
720 switch (info->mach)
721 {
8699fc3e
AB
722 case bfd_mach_arc_nps400:
723 isa_mask = ARC_OPCODE_ARC700 | ARC_OPCODE_NPS400;
724 break;
725
886a2506
NC
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.806472 seconds and 4 git commands to generate.