Fix seg fault in linker when performing garbage collection on COFF based targets.
[external/binutils.git] / opcodes / arc-dis.c
1 /* Instruction printing code for the ARC.
2    Copyright (C) 1994-2016 Free Software Foundation, Inc.
3
4    Contributed by Claudiu Zissulescu (claziss@synopsys.com)
5
6    This file is part of libopcodes.
7
8    This library is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3, or (at your option)
11    any later version.
12
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.
17
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
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21    MA 02110-1301, USA.  */
22
23 #include "sysdep.h"
24 #include <stdio.h>
25 #include <assert.h>
26 #include "dis-asm.h"
27 #include "opcode/arc.h"
28 #include "arc-dis.h"
29 #include "arc-ext.h"
30
31 /* Structure used to iterate over, and extract the values for, operands of
32    an opcode.  */
33
34 struct 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 };
68
69 /* Globals variables.  */
70
71 static const char * const regnames[64] =
72 {
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)))
98 #define OPCODE(word)    (BITS ((word), 27, 31))
99
100 #define OPCODE_AC(word)   (BITS ((word), 11, 15))
101
102 /* Functions implementation.  */
103
104 static bfd_vma
105 bfd_getm32 (unsigned int data)
106 {
107   bfd_vma value = 0;
108
109   value = ((data & 0xff00) | (data & 0xff)) << 16;
110   value |= ((data & 0xff0000) | (data & 0xff000000)) >> 16;
111   return value;
112 }
113
114 static int
115 special_flag_p (const char *opname,
116                 const char *flgname)
117 {
118   const struct arc_flag_special *flg_spec;
119   unsigned i, j, flgidx;
120
121   for (i = 0; i < arc_num_flag_special; i++)
122     {
123       flg_spec = &arc_flag_special_cases[i];
124
125       if (strcmp (opname, flg_spec->name))
126         continue;
127
128       /* Found potential special case instruction.  */
129       for (j=0;; ++j)
130         {
131           flgidx = flg_spec->flags[j];
132           if (flgidx == 0)
133             break; /* End of the array.  */
134
135           if (strcmp (flgname, arc_flag_operands[flgidx].name) == 0)
136             return 1;
137         }
138     }
139   return 0;
140 }
141
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
145 static const struct arc_opcode *
146 find_format_from_table (const struct arc_opcode *arc_table,
147                         unsigned *insn, unsigned int insn_len,
148                         unsigned isa_mask, bfd_boolean *has_limm)
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
160     if (ARC_SHORT (opcode->mask) && (insn_len == 2))
161       {
162         if (OPCODE_AC (opcode->opcode) != OPCODE_AC (insn[0]))
163           continue;
164       }
165     else if (!ARC_SHORT (opcode->mask) && (insn_len == 4))
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
179     *has_limm = FALSE;
180
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           {
200             if ((value == 0x3E && insn_len == 4)
201                 || (value == 0x1E && insn_len == 2))
202               {
203                 invalid = TRUE;
204                 break;
205               }
206           }
207
208         if (operand->flags & ARC_OPERAND_LIMM
209             && !(operand->flags & ARC_OPERAND_DUPLICATE))
210           *has_limm = TRUE;
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;
220         unsigned int value;
221
222         /* Check first the extensions.  */
223         if (cl_flags->flag_class & F_CLASS_EXTEND)
224           {
225             value = (insn[0] & 0x1F);
226             if (arcExtMap_condCodeName (value))
227               continue;
228           }
229         for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
230           {
231             const struct arc_flag_operand *flg_operand =
232               &arc_flag_operands[*flgopridx];
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
258 /* Find long instructions matching values in INSN array.  */
259
260 static const struct arc_long_opcode *
261 find_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
346 static bfd_boolean
347 find_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
436 static void
437 print_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.  */
452       if (cl_flags->flag_class & F_CLASS_EXTEND)
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                 }
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
509               (*info->fprintf_func) (info->stream, "%s", flg_operand->name);
510             }
511         }
512     }
513 }
514
515 static const char *
516 get_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
524   if (opcode->insn_class != AUXREG)
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 }
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
553 static unsigned int
554 arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
555 {
556   bfd_byte major_opcode = msb >> 3;
557
558   switch (info->mach)
559     {
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.  */
566       if (major_opcode == 0xb)
567         {
568           bfd_byte minor_opcode = lsb & 0x1f;
569
570           if (minor_opcode < 4)
571             return 2;
572         }
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
586 /* Extract and return the value of OPERAND from the instruction whose value
587    is held in the array INSN.  */
588
589 static int
590 extract_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
632 static bfd_boolean
633 operand_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
700 /* Disassemble ARC instructions.  */
701
702 static int
703 print_insn_arc (bfd_vma memaddr,
704                 struct disassemble_info *info)
705 {
706   bfd_byte buffer[4];
707   unsigned int lowbyte, highbyte;
708   int status;
709   unsigned int insn_len;
710   unsigned insn[2] = { 0, 0 };
711   unsigned isa_mask;
712   const struct arc_opcode *opcode;
713   bfd_boolean need_comma;
714   bfd_boolean open_braket;
715   int size;
716   const struct arc_operand *operand;
717   int value;
718   struct arc_operand_iterator iter;
719
720   memset (&iter, 0, sizeof (iter));
721   lowbyte  = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
722   highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
723
724   switch (info->mach)
725     {
726     case bfd_mach_arc_arc700:
727       isa_mask = ARC_OPCODE_ARC700;
728       break;
729
730     case bfd_mach_arc_arc600:
731       isa_mask = ARC_OPCODE_ARC600;
732       break;
733
734     case bfd_mach_arc_arcv2:
735     default:
736       isa_mask = ARC_OPCODE_ARCv2HS | ARC_OPCODE_ARCv2EM;
737       break;
738     }
739
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
778   /* Read the insn into a host word.  */
779   status = (*info->read_memory_func) (memaddr, buffer, size, info);
780   if (status != 0)
781     {
782       (*info->memory_error_func) (status, memaddr, info);
783       return -1;
784     }
785
786   if (info->section
787       && !(info->section->flags & SEC_CODE))
788     {
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)
795         {
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 ();
807         }
808       return size;
809     }
810
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)
814     {
815     case 2:
816       insn[0] = (buffer[lowbyte] << 8) | buffer[highbyte];
817       break;
818
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:
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)
828         {
829           (*info->memory_error_func) (status, memaddr + 2, info);
830           return -1;
831         }
832       insn[0] = ARRANGE_ENDIAN (info, buffer);
833       break;
834     }
835
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.  */
848   if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
849     return -1;
850
851   if (!opcode)
852     {
853       if (insn_len == 2)
854         (*info->fprintf_func) (info->stream, ".long %#04x", insn[0]);
855       else
856         (*info->fprintf_func) (info->stream, ".long %#08x", insn[0]);
857
858       info->insn_type = dis_noninsn;
859       return insn_len;
860     }
861
862   /* Print the mnemonic.  */
863   (*info->fprintf_func) (info->stream, "%s", opcode->name);
864
865   /* Preselect the insn class.  */
866   switch (opcode->insn_class)
867     {
868     case BRANCH:
869     case JUMP:
870       if (!strncmp (opcode->name, "bl", 2)
871           || !strncmp (opcode->name, "jl", 2))
872         {
873           if (opcode->subclass == COND)
874             info->insn_type = dis_condjsr;
875           else
876             info->insn_type = dis_jsr;
877         }
878       else
879         {
880           if (opcode->subclass == COND)
881             info->insn_type = dis_condbranch;
882           else
883             info->insn_type = dis_branch;
884         }
885       break;
886     case MEMORY:
887       info->insn_type = dis_dref; /* FIXME! DB indicates mov as memory! */
888       break;
889     default:
890       info->insn_type = dis_nonbranch;
891       break;
892     }
893
894   pr_debug ("%s: 0x%08x\n", opcode->name, opcode->opcode);
895
896   print_flags (opcode, insn, info);
897
898   if (opcode->operands[0] != 0)
899     (*info->fprintf_func) (info->stream, "\t");
900
901   need_comma = FALSE;
902   open_braket = FALSE;
903
904   /* Now extract and print the operands.  */
905   operand = NULL;
906   while (operand_iterator_next (&iter, &operand, &value))
907     {
908       if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
909         {
910           (*info->fprintf_func) (info->stream, "]");
911           open_braket = FALSE;
912           continue;
913         }
914
915       /* Only take input from real operands.  */
916       if ((operand->flags & ARC_OPERAND_FAKE)
917           && !(operand->flags & ARC_OPERAND_BRAKET))
918         continue;
919
920       if ((operand->flags & ARC_OPERAND_IGNORE)
921           && (operand->flags & ARC_OPERAND_IR)
922           && value == -1)
923         continue;
924
925       if (need_comma)
926         (*info->fprintf_func) (info->stream, ",");
927
928       if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
929         {
930           (*info->fprintf_func) (info->stream, "[");
931           open_braket = TRUE;
932           need_comma = FALSE;
933           continue;
934         }
935
936       /* Print the operand as directed by the flags.  */
937       if (operand->flags & ARC_OPERAND_IR)
938         {
939           const char *rname;
940
941           assert (value >=0 && value < 64);
942           rname = arcExtMap_coreRegName (value);
943           if (!rname)
944             rname = regnames[value];
945           (*info->fprintf_func) (info->stream, "%s", rname);
946           if (operand->flags & ARC_OPERAND_TRUNCATE)
947             {
948               rname = arcExtMap_coreRegName (value + 1);
949               if (!rname)
950                 rname = regnames[value + 1];
951               (*info->fprintf_func) (info->stream, "%s", rname);
952             }
953         }
954       else if (operand->flags & ARC_OPERAND_LIMM)
955         {
956           const char *rname = get_auxreg (opcode, value, isa_mask);
957           if (rname && open_braket)
958             (*info->fprintf_func) (info->stream, "%s", rname);
959           else
960             {
961               (*info->fprintf_func) (info->stream, "%#x", value);
962               if (info->insn_type == dis_branch
963                   || info->insn_type == dis_jsr)
964                 info->target = (bfd_vma) value;
965             }
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);
973
974           info->target = (bfd_vma) (memaddr & ~3) + value;
975         }
976       else if (operand->flags & ARC_OPERAND_SIGNED)
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         }
984       else
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         }
1001
1002       need_comma = TRUE;
1003     }
1004
1005   return insn_len;
1006 }
1007
1008
1009 disassembler_ftype
1010 arc_get_disassembler (bfd *abfd)
1011 {
1012   /* Read the extenssion insns and registers, if any.  */
1013   build_ARC_extmap (abfd);
1014 #ifdef DEBUG
1015   dump_ARC_extmap ();
1016 #endif
1017
1018   return print_insn_arc;
1019 }
1020
1021 /* Disassemble ARC instructions.  Used by debugger.  */
1022
1023 struct arcDisState
1024 arcAnalyzeInstr (bfd_vma memaddr,
1025                  struct disassemble_info *info)
1026 {
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
1041
1042   return ret;
1043 }
1044
1045 /* Local variables:
1046    eval: (c-set-style "gnu")
1047    indent-tabs-mode: t
1048    End:  */