OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [gdb-5.0/] [opcodes/] [arm-dis.c] - Blame information for rev 1778

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/* Instruction printing code for the ARM
2
   Copyright (C) 1994, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
3
   Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4
   Modification by James G. Smith (jsmith@cygnus.co.uk)
5
 
6
This file is part of libopcodes.
7
 
8
This program is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 2 of the License, or (at your option)
11
any later version.
12
 
13
This program is distributed in the hope that it will be useful, but WITHOUT
14
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
 
22
#include "sysdep.h"
23
#include "dis-asm.h"
24
#define DEFINE_TABLE
25
#include "arm-opc.h"
26
#include "coff/internal.h"
27
#include "libcoff.h"
28
#include "opintl.h"
29
 
30
/* FIXME: This shouldn't be done here */
31
#include "elf-bfd.h"
32
#include "elf/internal.h"
33
#include "elf/arm.h"
34
 
35
#ifndef streq
36
#define streq(a,b)      (strcmp ((a), (b)) == 0)
37
#endif
38
 
39
#ifndef strneq
40
#define strneq(a,b,n)   (strncmp ((a), (b), (n)) == 0)
41
#endif
42
 
43
#ifndef NUM_ELEM
44
#define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
45
#endif
46
 
47
static char * arm_conditional[] =
48
{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
49
 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
50
 
51
typedef struct
52
{
53
  const char * name;
54
  const char * description;
55
  const char * reg_names[16];
56
}
57
arm_regname;
58
 
59
static arm_regname regnames[] =
60
{
61
  { "raw" , "Select raw register names",
62
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
63
  { "std",  "Select register names used in ARM's ISA documentation",
64
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
65
  { "apcs", "Select register names used in the APCS",
66
    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
67
  { "atpcs", "Select register names used in the ATPCS",
68
    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
69
  { "special-atpcs", "Select special register names used in the ATPCS",
70
    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }}
71
};
72
 
73
/* Default to standard register name set.  */
74
static unsigned int regname_selected = 1;
75
 
76
#define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
77
#define arm_regnames      regnames[regname_selected].reg_names
78
 
79
static boolean force_thumb = false;
80
 
81
static char * arm_fp_const[] =
82
{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
83
 
84
static char * arm_shift[] =
85
{"lsl", "lsr", "asr", "ror"};
86
 
87
/* Forward declarations.  */
88
static void arm_decode_shift PARAMS ((long, fprintf_ftype, void *));
89
static int  print_insn_arm   PARAMS ((bfd_vma, struct disassemble_info *, long));
90
static int  print_insn_thumb PARAMS ((bfd_vma, struct disassemble_info *, long));
91
static void parse_disassembler_options PARAMS ((char *));
92
static int  print_insn       PARAMS ((bfd_vma, struct disassemble_info *, boolean));
93
int get_arm_regname_num_options (void);
94
int set_arm_regname_option (int option);
95
int get_arm_regnames (int option, const char **setname,
96
                      const char **setdescription,
97
                      const char ***register_names);
98
 
99
/* Functions. */
100
int
101
get_arm_regname_num_options (void)
102
{
103
  return NUM_ARM_REGNAMES;
104
}
105
 
106
int
107
set_arm_regname_option (int option)
108
{
109
  int old = regname_selected;
110
  regname_selected = option;
111
  return old;
112
}
113
 
114
int
115
get_arm_regnames (int option, const char **setname,
116
                  const char **setdescription,
117
                  const char ***register_names)
118
{
119
  *setname = regnames[option].name;
120
  *setdescription = regnames[option].description;
121
  *register_names = regnames[option].reg_names;
122
  return 16;
123
}
124
 
125
static void
126
arm_decode_shift (given, func, stream)
127
     long given;
128
     fprintf_ftype func;
129
     void * stream;
130
{
131
  func (stream, "%s", arm_regnames[given & 0xf]);
132
 
133
  if ((given & 0xff0) != 0)
134
    {
135
      if ((given & 0x10) == 0)
136
        {
137
          int amount = (given & 0xf80) >> 7;
138
          int shift = (given & 0x60) >> 5;
139
 
140
          if (amount == 0)
141
            {
142
              if (shift == 3)
143
                {
144
                  func (stream, ", rrx");
145
                  return;
146
                }
147
 
148
              amount = 32;
149
            }
150
 
151
          func (stream, ", %s #%d", arm_shift[shift], amount);
152
        }
153
      else
154
        func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
155
              arm_regnames[(given & 0xf00) >> 8]);
156
    }
157
}
158
 
159
/* Print one instruction from PC on INFO->STREAM.
160
   Return the size of the instruction (always 4 on ARM). */
161
static int
162
print_insn_arm (pc, info, given)
163
     bfd_vma                   pc;
164
     struct disassemble_info * info;
165
     long                      given;
166
{
167
  struct arm_opcode *  insn;
168
  void *               stream = info->stream;
169
  fprintf_ftype        func   = info->fprintf_func;
170
 
171
  for (insn = arm_opcodes; insn->assembler; insn++)
172
    {
173
      if ((given & insn->mask) == insn->value)
174
        {
175
          char * c;
176
 
177
          for (c = insn->assembler; *c; c++)
178
            {
179
              if (*c == '%')
180
                {
181
                  switch (*++c)
182
                    {
183
                    case '%':
184
                      func (stream, "%%");
185
                      break;
186
 
187
                    case 'a':
188
                      if (((given & 0x000f0000) == 0x000f0000)
189
                          && ((given & 0x02000000) == 0))
190
                        {
191
                          int offset = given & 0xfff;
192
 
193
                          func (stream, "[pc");
194
 
195
                          if (given & 0x01000000)
196
                            {
197
                              if ((given & 0x00800000) == 0)
198
                                offset = - offset;
199
 
200
                              /* pre-indexed */
201
                              func (stream, ", #%x]", offset);
202
 
203
                              offset += pc + 8;
204
 
205
                              /* Cope with the possibility of write-back
206
                                 being used.  Probably a very dangerous thing
207
                                 for the programmer to do, but who are we to
208
                                 argue ?  */
209
                              if (given & 0x00200000)
210
                                func (stream, "!");
211
                            }
212
                          else
213
                            {
214
                              /* Post indexed.  */
215
                              func (stream, "], #%x", offset);
216
 
217
                              offset = pc + 8;  /* ie ignore the offset.  */
218
                            }
219
 
220
                          func (stream, "\t; ");
221
                          info->print_address_func (offset, info);
222
                        }
223
                      else
224
                        {
225
                          func (stream, "[%s",
226
                                arm_regnames[(given >> 16) & 0xf]);
227
                          if ((given & 0x01000000) != 0)
228
                            {
229
                              if ((given & 0x02000000) == 0)
230
                                {
231
                                  int offset = given & 0xfff;
232
                                  if (offset)
233
                                    func (stream, ", %s#%d",
234
                                          (((given & 0x00800000) == 0)
235
                                           ? "-" : ""), offset);
236
                                }
237
                              else
238
                                {
239
                                  func (stream, ", %s",
240
                                        (((given & 0x00800000) == 0)
241
                                         ? "-" : ""));
242
                                  arm_decode_shift (given, func, stream);
243
                                }
244
 
245
                              func (stream, "]%s",
246
                                    ((given & 0x00200000) != 0) ? "!" : "");
247
                            }
248
                          else
249
                            {
250
                              if ((given & 0x02000000) == 0)
251
                                {
252
                                  int offset = given & 0xfff;
253
                                  if (offset)
254
                                    func (stream, "], %s#%d",
255
                                          (((given & 0x00800000) == 0)
256
                                           ? "-" : ""), offset);
257
                                  else
258
                                    func (stream, "]");
259
                                }
260
                              else
261
                                {
262
                                  func (stream, "], %s",
263
                                        (((given & 0x00800000) == 0)
264
                                         ? "-" : ""));
265
                                  arm_decode_shift (given, func, stream);
266
                                }
267
                            }
268
                        }
269
                      break;
270
 
271
                    case 's':
272
                      if ((given & 0x004f0000) == 0x004f0000)
273
                        {
274
                          /* PC relative with immediate offset.  */
275
                          int offset = ((given & 0xf00) >> 4) | (given & 0xf);
276
 
277
                          if ((given & 0x00800000) == 0)
278
                            offset = -offset;
279
 
280
                          func (stream, "[pc, #%x]\t; ", offset);
281
 
282
                          (*info->print_address_func)
283
                            (offset + pc + 8, info);
284
                        }
285
                      else
286
                        {
287
                          func (stream, "[%s",
288
                                arm_regnames[(given >> 16) & 0xf]);
289
                          if ((given & 0x01000000) != 0)
290
                            {
291
                              /* Pre-indexed.  */
292
                              if ((given & 0x00400000) == 0x00400000)
293
                                {
294
                                  /* Immediate.  */
295
                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
296
                                  if (offset)
297
                                    func (stream, ", %s#%d",
298
                                          (((given & 0x00800000) == 0)
299
                                           ? "-" : ""), offset);
300
                                }
301
                              else
302
                                {
303
                                  /* Register.  */
304
                                  func (stream, ", %s%s",
305
                                        (((given & 0x00800000) == 0)
306
                                         ? "-" : ""),
307
                                        arm_regnames[given & 0xf]);
308
                                }
309
 
310
                              func (stream, "]%s",
311
                                    ((given & 0x00200000) != 0) ? "!" : "");
312
                            }
313
                          else
314
                            {
315
                              /* Post-indexed.  */
316
                              if ((given & 0x00400000) == 0x00400000)
317
                                {
318
                                  /* Immediate.  */
319
                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
320
                                  if (offset)
321
                                    func (stream, "], %s#%d",
322
                                          (((given & 0x00800000) == 0)
323
                                           ? "-" : ""), offset);
324
                                  else
325
                                    func (stream, "]");
326
                                }
327
                              else
328
                                {
329
                                  /* Register.  */
330
                                  func (stream, "], %s%s",
331
                                        (((given & 0x00800000) == 0)
332
                                         ? "-" : ""),
333
                                        arm_regnames[given & 0xf]);
334
                                }
335
                            }
336
                        }
337
                      break;
338
 
339
                    case 'b':
340
                      (*info->print_address_func)
341
                        (BDISP (given) * 4 + pc + 8, info);
342
                      break;
343
 
344
                    case 'c':
345
                      func (stream, "%s",
346
                            arm_conditional [(given >> 28) & 0xf]);
347
                      break;
348
 
349
                    case 'm':
350
                      {
351
                        int started = 0;
352
                        int reg;
353
 
354
                        func (stream, "{");
355
                        for (reg = 0; reg < 16; reg++)
356
                          if ((given & (1 << reg)) != 0)
357
                            {
358
                              if (started)
359
                                func (stream, ", ");
360
                              started = 1;
361
                              func (stream, "%s", arm_regnames[reg]);
362
                            }
363
                        func (stream, "}");
364
                      }
365
                      break;
366
 
367
                    case 'o':
368
                      if ((given & 0x02000000) != 0)
369
                        {
370
                          int rotate = (given & 0xf00) >> 7;
371
                          int immed = (given & 0xff);
372
                          immed = (((immed << (32 - rotate))
373
                                    | (immed >> rotate)) & 0xffffffff);
374
                          func (stream, "#%d\t; 0x%x", immed, immed);
375
                        }
376
                      else
377
                        arm_decode_shift (given, func, stream);
378
                      break;
379
 
380
                    case 'p':
381
                      if ((given & 0x0000f000) == 0x0000f000)
382
                        func (stream, "p");
383
                      break;
384
 
385
                    case 't':
386
                      if ((given & 0x01200000) == 0x00200000)
387
                        func (stream, "t");
388
                      break;
389
 
390
                    case 'h':
391
                      if ((given & 0x00000020) == 0x00000020)
392
                        func (stream, "h");
393
                      else
394
                        func (stream, "b");
395
                      break;
396
 
397
                    case 'A':
398
                      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
399
                      if ((given & 0x01000000) != 0)
400
                        {
401
                          int offset = given & 0xff;
402
                          if (offset)
403
                            func (stream, ", %s#%d]%s",
404
                                  ((given & 0x00800000) == 0 ? "-" : ""),
405
                                  offset * 4,
406
                                  ((given & 0x00200000) != 0 ? "!" : ""));
407
                          else
408
                            func (stream, "]");
409
                        }
410
                      else
411
                        {
412
                          int offset = given & 0xff;
413
                          if (offset)
414
                            func (stream, "], %s#%d",
415
                                  ((given & 0x00800000) == 0 ? "-" : ""),
416
                                  offset * 4);
417
                          else
418
                            func (stream, "]");
419
                        }
420
                      break;
421
 
422
                    case 'C':
423
                      switch (given & 0x00090000)
424
                        {
425
                        default:
426
                          func (stream, "_???");
427
                          break;
428
                        case 0x90000:
429
                          func (stream, "_all");
430
                          break;
431
                        case 0x10000:
432
                          func (stream, "_ctl");
433
                          break;
434
                        case 0x80000:
435
                          func (stream, "_flg");
436
                          break;
437
                        }
438
                      break;
439
 
440
                    case 'F':
441
                      switch (given & 0x00408000)
442
                        {
443
                        case 0:
444
                          func (stream, "4");
445
                          break;
446
                        case 0x8000:
447
                          func (stream, "1");
448
                          break;
449
                        case 0x00400000:
450
                          func (stream, "2");
451
                          break;
452
                        default:
453
                          func (stream, "3");
454
                        }
455
                      break;
456
 
457
                    case 'P':
458
                      switch (given & 0x00080080)
459
                        {
460
                        case 0:
461
                          func (stream, "s");
462
                          break;
463
                        case 0x80:
464
                          func (stream, "d");
465
                          break;
466
                        case 0x00080000:
467
                          func (stream, "e");
468
                          break;
469
                        default:
470
                          func (stream, _("<illegal precision>"));
471
                          break;
472
                        }
473
                      break;
474
                    case 'Q':
475
                      switch (given & 0x00408000)
476
                        {
477
                        case 0:
478
                          func (stream, "s");
479
                          break;
480
                        case 0x8000:
481
                          func (stream, "d");
482
                          break;
483
                        case 0x00400000:
484
                          func (stream, "e");
485
                          break;
486
                        default:
487
                          func (stream, "p");
488
                          break;
489
                        }
490
                      break;
491
                    case 'R':
492
                      switch (given & 0x60)
493
                        {
494
                        case 0:
495
                          break;
496
                        case 0x20:
497
                          func (stream, "p");
498
                          break;
499
                        case 0x40:
500
                          func (stream, "m");
501
                          break;
502
                        default:
503
                          func (stream, "z");
504
                          break;
505
                        }
506
                      break;
507
 
508
                    case '0': case '1': case '2': case '3': case '4':
509
                    case '5': case '6': case '7': case '8': case '9':
510
                      {
511
                        int bitstart = *c++ - '0';
512
                        int bitend = 0;
513
                        while (*c >= '0' && *c <= '9')
514
                          bitstart = (bitstart * 10) + *c++ - '0';
515
 
516
                        switch (*c)
517
                          {
518
                          case '-':
519
                            c++;
520
 
521
                            while (*c >= '0' && *c <= '9')
522
                              bitend = (bitend * 10) + *c++ - '0';
523
 
524
                            if (!bitend)
525
                              abort ();
526
 
527
                            switch (*c)
528
                              {
529
                              case 'r':
530
                                {
531
                                  long reg;
532
 
533
                                  reg = given >> bitstart;
534
                                  reg &= (2 << (bitend - bitstart)) - 1;
535
 
536
                                  func (stream, "%s", arm_regnames[reg]);
537
                                }
538
                                break;
539
                              case 'd':
540
                                {
541
                                  long reg;
542
 
543
                                  reg = given >> bitstart;
544
                                  reg &= (2 << (bitend - bitstart)) - 1;
545
 
546
                                  func (stream, "%d", reg);
547
                                }
548
                                break;
549
                              case 'x':
550
                                {
551
                                  long reg;
552
 
553
                                  reg = given >> bitstart;
554
                                  reg &= (2 << (bitend - bitstart)) - 1;
555
 
556
                                  func (stream, "0x%08x", reg);
557
 
558
                                  /* Some SWI instructions have special
559
                                     meanings.  */
560
                                  if ((given & 0x0fffffff) == 0x0FF00000)
561
                                    func (stream, "\t; IMB");
562
                                  else if ((given & 0x0fffffff) == 0x0FF00001)
563
                                    func (stream, "\t; IMBRange");
564
                                }
565
                                break;
566
                              case 'X':
567
                                {
568
                                  long reg;
569
 
570
                                  reg = given >> bitstart;
571
                                  reg &= (2 << (bitend - bitstart)) - 1;
572
 
573
                                  func (stream, "%01x", reg & 0xf);
574
                                }
575
                                break;
576
                              case 'f':
577
                                {
578
                                  long reg;
579
 
580
                                  reg = given >> bitstart;
581
                                  reg &= (2 << (bitend - bitstart)) - 1;
582
 
583
                                  if (reg > 7)
584
                                    func (stream, "#%s",
585
                                          arm_fp_const[reg & 7]);
586
                                  else
587
                                    func (stream, "f%d", reg);
588
                                }
589
                                break;
590
                              default:
591
                                abort ();
592
                              }
593
                            break;
594
 
595
                          case '`':
596
                            c++;
597
                            if ((given & (1 << bitstart)) == 0)
598
                              func (stream, "%c", *c);
599
                            break;
600
                          case '\'':
601
                            c++;
602
                            if ((given & (1 << bitstart)) != 0)
603
                              func (stream, "%c", *c);
604
                            break;
605
                          case '?':
606
                            ++c;
607
                            if ((given & (1 << bitstart)) != 0)
608
                              func (stream, "%c", *c++);
609
                            else
610
                              func (stream, "%c", *++c);
611
                            break;
612
                          default:
613
                            abort ();
614
                          }
615
                        break;
616
 
617
                      default:
618
                        abort ();
619
                      }
620
                    }
621
                }
622
              else
623
                func (stream, "%c", *c);
624
            }
625
          return 4;
626
        }
627
    }
628
  abort ();
629
}
630
 
631
/* Print one instruction from PC on INFO->STREAM.
632
   Return the size of the instruction. */
633
static int
634
print_insn_thumb (pc, info, given)
635
     bfd_vma                   pc;
636
     struct disassemble_info * info;
637
     long                      given;
638
{
639
  struct thumb_opcode * insn;
640
  void *                stream = info->stream;
641
  fprintf_ftype         func = info->fprintf_func;
642
 
643
  for (insn = thumb_opcodes; insn->assembler; insn++)
644
    {
645
      if ((given & insn->mask) == insn->value)
646
        {
647
          char * c = insn->assembler;
648
 
649
          /* Special processing for Thumb 2 instruction BL sequence:  */
650
          if (!*c) /* Check for empty (not NULL) assembler string.  */
651
            {
652
              info->bytes_per_chunk = 4;
653
              info->bytes_per_line  = 4;
654
 
655
                func (stream, "bl\t");
656
 
657
              info->print_address_func (BDISP23 (given) * 2 + pc + 4, info);
658
              return 4;
659
            }
660
          else
661
            {
662
              info->bytes_per_chunk = 2;
663
              info->bytes_per_line  = 4;
664
 
665
              given &= 0xffff;
666
 
667
              for (; *c; c++)
668
                {
669
                  if (*c == '%')
670
                    {
671
                      int domaskpc = 0;
672
                      int domasklr = 0;
673
 
674
                      switch (*++c)
675
                        {
676
                        case '%':
677
                          func (stream, "%%");
678
                          break;
679
 
680
                        case 'S':
681
                          {
682
                            long reg;
683
 
684
                            reg = (given >> 3) & 0x7;
685
                            if (given & (1 << 6))
686
                              reg += 8;
687
 
688
                            func (stream, "%s", arm_regnames[reg]);
689
                          }
690
                          break;
691
 
692
                        case 'D':
693
                          {
694
                            long reg;
695
 
696
                            reg = given & 0x7;
697
                            if (given & (1 << 7))
698
                             reg += 8;
699
 
700
                            func (stream, "%s", arm_regnames[reg]);
701
                          }
702
                          break;
703
 
704
                        case 'T':
705
                          func (stream, "%s",
706
                                arm_conditional [(given >> 8) & 0xf]);
707
                          break;
708
 
709
                        case 'N':
710
                          if (given & (1 << 8))
711
                            domasklr = 1;
712
                          /* Fall through.  */
713
                        case 'O':
714
                          if (*c == 'O' && (given & (1 << 8)))
715
                            domaskpc = 1;
716
                          /* Fall through.  */
717
                        case 'M':
718
                          {
719
                            int started = 0;
720
                            int reg;
721
 
722
                            func (stream, "{");
723
 
724
                            /* It would be nice if we could spot
725
                               ranges, and generate the rS-rE format: */
726
                            for (reg = 0; (reg < 8); reg++)
727
                              if ((given & (1 << reg)) != 0)
728
                                {
729
                                  if (started)
730
                                    func (stream, ", ");
731
                                  started = 1;
732
                                  func (stream, "%s", arm_regnames[reg]);
733
                                }
734
 
735
                            if (domasklr)
736
                              {
737
                                if (started)
738
                                  func (stream, ", ");
739
                                started = 1;
740
                                func (stream, arm_regnames[14] /* "lr" */);
741
                              }
742
 
743
                            if (domaskpc)
744
                              {
745
                                if (started)
746
                                  func (stream, ", ");
747
                                func (stream, arm_regnames[15] /* "pc" */);
748
                              }
749
 
750
                            func (stream, "}");
751
                          }
752
                          break;
753
 
754
 
755
                        case '0': case '1': case '2': case '3': case '4':
756
                        case '5': case '6': case '7': case '8': case '9':
757
                          {
758
                            int bitstart = *c++ - '0';
759
                            int bitend = 0;
760
 
761
                            while (*c >= '0' && *c <= '9')
762
                              bitstart = (bitstart * 10) + *c++ - '0';
763
 
764
                            switch (*c)
765
                              {
766
                              case '-':
767
                                {
768
                                  long reg;
769
 
770
                                  c++;
771
                                  while (*c >= '0' && *c <= '9')
772
                                    bitend = (bitend * 10) + *c++ - '0';
773
                                  if (!bitend)
774
                                    abort ();
775
                                  reg = given >> bitstart;
776
                                  reg &= (2 << (bitend - bitstart)) - 1;
777
                                  switch (*c)
778
                                    {
779
                                    case 'r':
780
                                      func (stream, "%s", arm_regnames[reg]);
781
                                      break;
782
 
783
                                    case 'd':
784
                                      func (stream, "%d", reg);
785
                                      break;
786
 
787
                                    case 'H':
788
                                      func (stream, "%d", reg << 1);
789
                                      break;
790
 
791
                                    case 'W':
792
                                      func (stream, "%d", reg << 2);
793
                                      break;
794
 
795
                                    case 'a':
796
                                      /* PC-relative address -- the bottom two
797
                                         bits of the address are dropped
798
                                         before the calculation.  */
799
                                      info->print_address_func
800
                                        (((pc + 4) & ~3) + (reg << 2), info);
801
                                      break;
802
 
803
                                    case 'x':
804
                                      func (stream, "0x%04x", reg);
805
                                      break;
806
 
807
                                    case 'I':
808
                                      reg = ((reg ^ (1 << bitend)) - (1 << bitend));
809
                                      func (stream, "%d", reg);
810
                                      break;
811
 
812
                                    case 'B':
813
                                      reg = ((reg ^ (1 << bitend)) - (1 << bitend));
814
                                      (*info->print_address_func)
815
                                        (reg * 2 + pc + 4, info);
816
                                      break;
817
 
818
                                    default:
819
                                      abort ();
820
                                    }
821
                                }
822
                                break;
823
 
824
                              case '\'':
825
                                c++;
826
                                if ((given & (1 << bitstart)) != 0)
827
                                  func (stream, "%c", *c);
828
                                break;
829
 
830
                              case '?':
831
                                ++c;
832
                                if ((given & (1 << bitstart)) != 0)
833
                                  func (stream, "%c", *c++);
834
                                else
835
                                  func (stream, "%c", *++c);
836
                                break;
837
 
838
                              default:
839
                                 abort ();
840
                              }
841
                          }
842
                          break;
843
 
844
                        default:
845
                          abort ();
846
                        }
847
                    }
848
                  else
849
                    func (stream, "%c", *c);
850
                }
851
             }
852
          return 2;
853
       }
854
    }
855
 
856
  /* No match.  */
857
  abort ();
858
}
859
 
860
/* Parse an individual disassembler option.  */
861
void
862
parse_arm_disassembler_option (option)
863
     char * option;
864
{
865
  if (option == NULL)
866
    return;
867
 
868
  if (strneq (option, "reg-names-", 10))
869
    {
870
      int i;
871
 
872
      option += 10;
873
 
874
      for (i = NUM_ARM_REGNAMES; i--;)
875
        if (streq (option, regnames[i].name))
876
          {
877
            regname_selected = i;
878
            break;
879
          }
880
 
881
      if (i < 0)
882
        fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
883
    }
884
  else if (streq (option, "force-thumb"))
885
    force_thumb = 1;
886
  else if (streq (option, "no-force-thumb"))
887
    force_thumb = 0;
888
  else
889
    fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
890
 
891
  return;
892
}
893
 
894
/* Parse the string of disassembler options, spliting it at whitespaces.  */
895
static void
896
parse_disassembler_options (options)
897
     char * options;
898
{
899
  char * space;
900
 
901
  if (options == NULL)
902
    return;
903
 
904
  do
905
    {
906
      space = strchr (options, ' ');
907
 
908
      if (space)
909
        {
910
          * space = '\0';
911
          parse_arm_disassembler_option (options);
912
          * space = ' ';
913
          options = space + 1;
914
        }
915
      else
916
        parse_arm_disassembler_option (options);
917
    }
918
  while (space);
919
}
920
 
921
/* NOTE: There are no checks in these routines that
922
   the relevant number of data bytes exist.  */
923
static int
924
print_insn (pc, info, little)
925
     bfd_vma pc;
926
     struct disassemble_info * info;
927
     boolean little;
928
{
929
  unsigned char      b[4];
930
  long               given;
931
  int                status;
932
  int                is_thumb;
933
 
934
  if (info->disassembler_options)
935
    {
936
      parse_disassembler_options (info->disassembler_options);
937
 
938
      /* To avoid repeated parsing of these options, we remove them here.  */
939
      info->disassembler_options = NULL;
940
    }
941
 
942
  is_thumb = force_thumb;
943
 
944
  if (!is_thumb && info->symbols != NULL)
945
    {
946
      if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
947
        {
948
          coff_symbol_type * cs;
949
 
950
          cs = coffsymbol (*info->symbols);
951
          is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
952
                      || cs->native->u.syment.n_sclass == C_THUMBSTAT
953
                      || cs->native->u.syment.n_sclass == C_THUMBLABEL
954
                      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
955
                      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
956
        }
957
      else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
958
        {
959
          elf_symbol_type *  es;
960
          unsigned int       type;
961
 
962
          es = *(elf_symbol_type **)(info->symbols);
963
          type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
964
 
965
          is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
966
        }
967
    }
968
 
969
  info->bytes_per_chunk = 4;
970
  info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
971
 
972
  if (little)
973
    {
974
      status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
975
      if (status != 0 && is_thumb)
976
        {
977
          info->bytes_per_chunk = 2;
978
 
979
          status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
980
          b[3] = b[2] = 0;
981
        }
982
 
983
      if (status != 0)
984
        {
985
          info->memory_error_func (status, pc, info);
986
          return -1;
987
        }
988
 
989
      given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
990
    }
991
  else
992
    {
993
      status = info->read_memory_func
994
        (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
995
      if (status != 0)
996
        {
997
          info->memory_error_func (status, pc, info);
998
          return -1;
999
        }
1000
 
1001
      if (is_thumb)
1002
        {
1003
          if (pc & 0x2)
1004
            {
1005
              given = (b[2] << 8) | b[3];
1006
 
1007
              status = info->read_memory_func
1008
                ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
1009
              if (status != 0)
1010
                {
1011
                  info->memory_error_func (status, pc + 4, info);
1012
                  return -1;
1013
                }
1014
 
1015
              given |= (b[0] << 24) | (b[1] << 16);
1016
            }
1017
          else
1018
            given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1019
        }
1020
      else
1021
        given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
1022
    }
1023
 
1024
  if (is_thumb)
1025
    status = print_insn_thumb (pc, info, given);
1026
  else
1027
    status = print_insn_arm (pc, info, given);
1028
 
1029
  return status;
1030
}
1031
 
1032
int
1033
print_insn_big_arm (pc, info)
1034
     bfd_vma pc;
1035
     struct disassemble_info * info;
1036
{
1037
  return print_insn (pc, info, false);
1038
}
1039
 
1040
int
1041
print_insn_little_arm (pc, info)
1042
     bfd_vma pc;
1043
     struct disassemble_info * info;
1044
{
1045
  return print_insn (pc, info, true);
1046
}
1047
 
1048
void
1049
print_arm_disassembler_options (FILE * stream)
1050
{
1051
  int i;
1052
 
1053
  fprintf (stream, _("\n\
1054
The following ARM specific disassembler options are supported for use with\n\
1055
the -M switch:\n"));
1056
 
1057
  for (i = NUM_ARM_REGNAMES; i--;)
1058
    fprintf (stream, "  reg-names-%s %*c%s\n",
1059
             regnames[i].name,
1060
             14 - strlen (regnames[i].name), ' ',
1061
             regnames[i].description);
1062
 
1063
  fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
1064
  fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
1065
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.