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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [opcodes/] [sh-dis.c] - Blame information for rev 280

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

Line No. Rev Author Line
1 205 julius
/* Disassemble SH instructions.
2
   Copyright 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
3
   2006, 2007  Free Software Foundation, Inc.
4
 
5
   This file is part of the GNU opcodes library.
6
 
7
   This library is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
 
12
   It is distributed in the hope that it will be useful, but WITHOUT
13
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15
   License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this file; see the file COPYING.  If not, write to the
19
   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#include <stdio.h>
23
#include "sysdep.h"
24
#define STATIC_TABLE
25
#define DEFINE_TABLE
26
 
27
#include "sh-opc.h"
28
#include "dis-asm.h"
29
 
30
#ifdef ARCH_all
31
#define INCLUDE_SHMEDIA
32
#endif
33
 
34
static void
35
print_movxy (const sh_opcode_info *op,
36
             int rn,
37
             int rm,
38
             fprintf_ftype fprintf_fn,
39
             void *stream)
40
{
41
  int n;
42
 
43
  fprintf_fn (stream, "%s\t", op->name);
44
  for (n = 0; n < 2; n++)
45
    {
46
      switch (op->arg[n])
47
        {
48
        case A_IND_N:
49
        case AX_IND_N:
50
        case AXY_IND_N:
51
        case AY_IND_N:
52
        case AYX_IND_N:
53
          fprintf_fn (stream, "@r%d", rn);
54
          break;
55
        case A_INC_N:
56
        case AX_INC_N:
57
        case AXY_INC_N:
58
        case AY_INC_N:
59
        case AYX_INC_N:
60
          fprintf_fn (stream, "@r%d+", rn);
61
          break;
62
        case AX_PMOD_N:
63
        case AXY_PMOD_N:
64
          fprintf_fn (stream, "@r%d+r8", rn);
65
          break;
66
        case AY_PMOD_N:
67
        case AYX_PMOD_N:
68
          fprintf_fn (stream, "@r%d+r9", rn);
69
          break;
70
        case DSP_REG_A_M:
71
          fprintf_fn (stream, "a%c", '0' + rm);
72
          break;
73
        case DSP_REG_X:
74
          fprintf_fn (stream, "x%c", '0' + rm);
75
          break;
76
        case DSP_REG_Y:
77
          fprintf_fn (stream, "y%c", '0' + rm);
78
          break;
79
        case DSP_REG_AX:
80
          fprintf_fn (stream, "%c%c",
81
                      (rm & 1) ? 'x' : 'a',
82
                      (rm & 2) ? '1' : '0');
83
          break;
84
        case DSP_REG_XY:
85
          fprintf_fn (stream, "%c%c",
86
                      (rm & 1) ? 'y' : 'x',
87
                      (rm & 2) ? '1' : '0');
88
          break;
89
        case DSP_REG_AY:
90
          fprintf_fn (stream, "%c%c",
91
                      (rm & 2) ? 'y' : 'a',
92
                      (rm & 1) ? '1' : '0');
93
          break;
94
        case DSP_REG_YX:
95
          fprintf_fn (stream, "%c%c",
96
                      (rm & 2) ? 'x' : 'y',
97
                      (rm & 1) ? '1' : '0');
98
          break;
99
        default:
100
          abort ();
101
        }
102
      if (n == 0)
103
        fprintf_fn (stream, ",");
104
    }
105
}
106
 
107
/* Print a double data transfer insn.  INSN is just the lower three
108
   nibbles of the insn, i.e. field a and the bit that indicates if
109
   a parallel processing insn follows.
110
   Return nonzero if a field b of a parallel processing insns follows.  */
111
 
112
static void
113
print_insn_ddt (int insn, struct disassemble_info *info)
114
{
115
  fprintf_ftype fprintf_fn = info->fprintf_func;
116
  void *stream = info->stream;
117
 
118
  /* If this is just a nop, make sure to emit something.  */
119
  if (insn == 0x000)
120
    fprintf_fn (stream, "nopx\tnopy");
121
 
122
  /* If a parallel processing insn was printed before,
123
     and we got a non-nop, emit a tab.  */
124
  if ((insn & 0x800) && (insn & 0x3ff))
125
    fprintf_fn (stream, "\t");
126
 
127
  /* Check if either the x or y part is invalid.  */
128
  if (((insn & 0xc) == 0 && (insn & 0x2a0))
129
      || ((insn & 3) == 0 && (insn & 0x150)))
130
    if (info->mach != bfd_mach_sh_dsp
131
        && info->mach != bfd_mach_sh3_dsp)
132
      {
133
        static const sh_opcode_info *first_movx, *first_movy;
134
        const sh_opcode_info *op;
135
        int is_movy;
136
 
137
        if (! first_movx)
138
          {
139
            for (first_movx = sh_table; first_movx->nibbles[1] != MOVX_NOPY;)
140
              first_movx++;
141
            for (first_movy = first_movx; first_movy->nibbles[1] != MOVY_NOPX;)
142
              first_movy++;
143
          }
144
 
145
        is_movy = ((insn & 3) != 0);
146
 
147
        if (is_movy)
148
          op = first_movy;
149
        else
150
          op = first_movx;
151
 
152
        while (op->nibbles[2] != (unsigned) ((insn >> 4) & 3)
153
               || op->nibbles[3] != (unsigned) (insn & 0xf))
154
          op++;
155
 
156
        print_movxy (op,
157
                     (4 * ((insn & (is_movy ? 0x200 : 0x100)) == 0)
158
                      + 2 * is_movy
159
                      + 1 * ((insn & (is_movy ? 0x100 : 0x200)) != 0)),
160
                     (insn >> 6) & 3,
161
                     fprintf_fn, stream);
162
      }
163
    else
164
      fprintf_fn (stream, ".word 0x%x", insn);
165
  else
166
    {
167
      static const sh_opcode_info *first_movx, *first_movy;
168
      const sh_opcode_info *opx, *opy;
169
      unsigned int insn_x, insn_y;
170
 
171
      if (! first_movx)
172
        {
173
          for (first_movx = sh_table; first_movx->nibbles[1] != MOVX;)
174
            first_movx++;
175
          for (first_movy = first_movx; first_movy->nibbles[1] != MOVY;)
176
            first_movy++;
177
        }
178
      insn_x = (insn >> 2) & 0xb;
179
      if (insn_x)
180
        {
181
          for (opx = first_movx; opx->nibbles[2] != insn_x;)
182
            opx++;
183
          print_movxy (opx, ((insn >> 9) & 1) + 4, (insn >> 7) & 1,
184
                       fprintf_fn, stream);
185
        }
186
      insn_y = (insn & 3) | ((insn >> 1) & 8);
187
      if (insn_y)
188
        {
189
          if (insn_x)
190
            fprintf_fn (stream, "\t");
191
          for (opy = first_movy; opy->nibbles[2] != insn_y;)
192
            opy++;
193
          print_movxy (opy, ((insn >> 8) & 1) + 6, (insn >> 6) & 1,
194
                       fprintf_fn, stream);
195
        }
196
    }
197
}
198
 
199
static void
200
print_dsp_reg (int rm, fprintf_ftype fprintf_fn, void *stream)
201
{
202
  switch (rm)
203
    {
204
    case A_A1_NUM:
205
      fprintf_fn (stream, "a1");
206
      break;
207
    case A_A0_NUM:
208
      fprintf_fn (stream, "a0");
209
      break;
210
    case A_X0_NUM:
211
      fprintf_fn (stream, "x0");
212
      break;
213
    case A_X1_NUM:
214
      fprintf_fn (stream, "x1");
215
      break;
216
    case A_Y0_NUM:
217
      fprintf_fn (stream, "y0");
218
      break;
219
    case A_Y1_NUM:
220
      fprintf_fn (stream, "y1");
221
      break;
222
    case A_M0_NUM:
223
      fprintf_fn (stream, "m0");
224
      break;
225
    case A_A1G_NUM:
226
      fprintf_fn (stream, "a1g");
227
      break;
228
    case A_M1_NUM:
229
      fprintf_fn (stream, "m1");
230
      break;
231
    case A_A0G_NUM:
232
      fprintf_fn (stream, "a0g");
233
      break;
234
    default:
235
      fprintf_fn (stream, "0x%x", rm);
236
      break;
237
    }
238
}
239
 
240
static void
241
print_insn_ppi (int field_b, struct disassemble_info *info)
242
{
243
  static char *sx_tab[] = { "x0", "x1", "a0", "a1" };
244
  static char *sy_tab[] = { "y0", "y1", "m0", "m1" };
245
  fprintf_ftype fprintf_fn = info->fprintf_func;
246
  void *stream = info->stream;
247
  unsigned int nib1, nib2, nib3;
248
  unsigned int altnib1, nib4;
249
  char *dc = NULL;
250
  const sh_opcode_info *op;
251
 
252
  if ((field_b & 0xe800) == 0)
253
    {
254
      fprintf_fn (stream, "psh%c\t#%d,",
255
                  field_b & 0x1000 ? 'a' : 'l',
256
                  (field_b >> 4) & 127);
257
      print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
258
      return;
259
    }
260
  if ((field_b & 0xc000) == 0x4000 && (field_b & 0x3000) != 0x1000)
261
    {
262
      static char *du_tab[] = { "x0", "y0", "a0", "a1" };
263
      static char *se_tab[] = { "x0", "x1", "y0", "a1" };
264
      static char *sf_tab[] = { "y0", "y1", "x0", "a1" };
265
      static char *sg_tab[] = { "m0", "m1", "a0", "a1" };
266
 
267
      if (field_b & 0x2000)
268
        fprintf_fn (stream, "p%s %s,%s,%s\t",
269
                    (field_b & 0x1000) ? "add" : "sub",
270
                    sx_tab[(field_b >> 6) & 3],
271
                    sy_tab[(field_b >> 4) & 3],
272
                    du_tab[(field_b >> 0) & 3]);
273
 
274
      else if ((field_b & 0xf0) == 0x10
275
               && info->mach != bfd_mach_sh_dsp
276
               && info->mach != bfd_mach_sh3_dsp)
277
        fprintf_fn (stream, "pclr %s \t", du_tab[(field_b >> 0) & 3]);
278
 
279
      else if ((field_b & 0xf3) != 0)
280
        fprintf_fn (stream, ".word 0x%x\t", field_b);
281
 
282
      fprintf_fn (stream, "pmuls%c%s,%s,%s",
283
                  field_b & 0x2000 ? ' ' : '\t',
284
                  se_tab[(field_b >> 10) & 3],
285
                  sf_tab[(field_b >>  8) & 3],
286
                  sg_tab[(field_b >>  2) & 3]);
287
      return;
288
    }
289
 
290
  nib1 = PPIC;
291
  nib2 = field_b >> 12 & 0xf;
292
  nib3 = field_b >> 8 & 0xf;
293
  nib4 = field_b >> 4 & 0xf;
294
  switch (nib3 & 0x3)
295
    {
296
    case 0:
297
      dc = "";
298
      nib1 = PPI3;
299
      break;
300
    case 1:
301
      dc = "";
302
      break;
303
    case 2:
304
      dc = "dct ";
305
      nib3 -= 1;
306
      break;
307
    case 3:
308
      dc = "dcf ";
309
      nib3 -= 2;
310
      break;
311
    }
312
  if (nib1 == PPI3)
313
    altnib1 = PPI3NC;
314
  else
315
    altnib1 = nib1;
316
  for (op = sh_table; op->name; op++)
317
    {
318
      if ((op->nibbles[1] == nib1 || op->nibbles[1] == altnib1)
319
          && op->nibbles[2] == nib2
320
          && op->nibbles[3] == nib3)
321
        {
322
          int n;
323
 
324
          switch (op->nibbles[4])
325
            {
326
            case HEX_0:
327
              break;
328
            case HEX_XX00:
329
              if ((nib4 & 3) != 0)
330
                continue;
331
              break;
332
            case HEX_1:
333
              if ((nib4 & 3) != 1)
334
                continue;
335
              break;
336
            case HEX_00YY:
337
              if ((nib4 & 0xc) != 0)
338
                continue;
339
              break;
340
            case HEX_4:
341
              if ((nib4 & 0xc) != 4)
342
                continue;
343
              break;
344
            default:
345
              abort ();
346
            }
347
          fprintf_fn (stream, "%s%s\t", dc, op->name);
348
          for (n = 0; n < 3 && op->arg[n] != A_END; n++)
349
            {
350
              if (n && op->arg[1] != A_END)
351
                fprintf_fn (stream, ",");
352
              switch (op->arg[n])
353
                {
354
                case DSP_REG_N:
355
                  print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
356
                  break;
357
                case DSP_REG_X:
358
                  fprintf_fn (stream, sx_tab[(field_b >> 6) & 3]);
359
                  break;
360
                case DSP_REG_Y:
361
                  fprintf_fn (stream, sy_tab[(field_b >> 4) & 3]);
362
                  break;
363
                case A_MACH:
364
                  fprintf_fn (stream, "mach");
365
                  break;
366
                case A_MACL:
367
                  fprintf_fn (stream, "macl");
368
                  break;
369
                default:
370
                  abort ();
371
                }
372
            }
373
          return;
374
        }
375
    }
376
  /* Not found.  */
377
  fprintf_fn (stream, ".word 0x%x", field_b);
378
}
379
 
380
/* FIXME mvs: movx insns print as ".word 0x%03x", insn & 0xfff
381
   (ie. the upper nibble is missing).  */
382
 
383
int
384
print_insn_sh (bfd_vma memaddr, struct disassemble_info *info)
385
{
386
  fprintf_ftype fprintf_fn = info->fprintf_func;
387
  void *stream = info->stream;
388
  unsigned char insn[4];
389
  unsigned char nibs[8];
390
  int status;
391
  bfd_vma relmask = ~(bfd_vma) 0;
392
  const sh_opcode_info *op;
393
  unsigned int target_arch;
394
  int allow_op32;
395
 
396
  switch (info->mach)
397
    {
398
    case bfd_mach_sh:
399
      target_arch = arch_sh1;
400
      /* SH coff object files lack information about the machine type, so
401
         we end up with bfd_mach_sh unless it was set explicitly (which
402
         could have happended if this is a call from gdb or the simulator.)  */
403
      if (info->symbols
404
          && bfd_asymbol_flavour(*info->symbols) == bfd_target_coff_flavour)
405
        target_arch = arch_sh4;
406
      break;
407
    case bfd_mach_sh5:
408
#ifdef INCLUDE_SHMEDIA
409
      status = print_insn_sh64 (memaddr, info);
410
      if (status != -2)
411
        return status;
412
#endif
413
      /* When we get here for sh64, it's because we want to disassemble
414
         SHcompact, i.e. arch_sh4.  */
415
      target_arch = arch_sh4;
416
      break;
417
    default:
418
      target_arch = sh_get_arch_from_bfd_mach (info->mach);
419
    }
420
 
421
  status = info->read_memory_func (memaddr, insn, 2, info);
422
 
423
  if (status != 0)
424
    {
425
      info->memory_error_func (status, memaddr, info);
426
      return -1;
427
    }
428
 
429
  if (info->endian == BFD_ENDIAN_LITTLE)
430
    {
431
      nibs[0] = (insn[1] >> 4) & 0xf;
432
      nibs[1] = insn[1] & 0xf;
433
 
434
      nibs[2] = (insn[0] >> 4) & 0xf;
435
      nibs[3] = insn[0] & 0xf;
436
    }
437
  else
438
    {
439
      nibs[0] = (insn[0] >> 4) & 0xf;
440
      nibs[1] = insn[0] & 0xf;
441
 
442
      nibs[2] = (insn[1] >> 4) & 0xf;
443
      nibs[3] = insn[1] & 0xf;
444
    }
445
  status = info->read_memory_func (memaddr + 2, insn + 2, 2, info);
446
  if (status != 0)
447
    allow_op32 = 0;
448
  else
449
    {
450
      allow_op32 = 1;
451
 
452
      if (info->endian == BFD_ENDIAN_LITTLE)
453
        {
454
          nibs[4] = (insn[3] >> 4) & 0xf;
455
          nibs[5] = insn[3] & 0xf;
456
 
457
          nibs[6] = (insn[2] >> 4) & 0xf;
458
          nibs[7] = insn[2] & 0xf;
459
        }
460
      else
461
        {
462
          nibs[4] = (insn[2] >> 4) & 0xf;
463
          nibs[5] = insn[2] & 0xf;
464
 
465
          nibs[6] = (insn[3] >> 4) & 0xf;
466
          nibs[7] = insn[3] & 0xf;
467
        }
468
    }
469
 
470
  if (nibs[0] == 0xf && (nibs[1] & 4) == 0
471
      && SH_MERGE_ARCH_SET_VALID (target_arch, arch_sh_dsp_up))
472
    {
473
      if (nibs[1] & 8)
474
        {
475
          int field_b;
476
 
477
          status = info->read_memory_func (memaddr + 2, insn, 2, info);
478
 
479
          if (status != 0)
480
            {
481
              info->memory_error_func (status, memaddr + 2, info);
482
              return -1;
483
            }
484
 
485
          if (info->endian == BFD_ENDIAN_LITTLE)
486
            field_b = insn[1] << 8 | insn[0];
487
          else
488
            field_b = insn[0] << 8 | insn[1];
489
 
490
          print_insn_ppi (field_b, info);
491
          print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
492
          return 4;
493
        }
494
      print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
495
      return 2;
496
    }
497
  for (op = sh_table; op->name; op++)
498
    {
499
      int n;
500
      int imm = 0;
501
      int rn = 0;
502
      int rm = 0;
503
      int rb = 0;
504
      int disp_pc;
505
      bfd_vma disp_pc_addr = 0;
506
      int disp = 0;
507
      int has_disp = 0;
508
      int max_n = SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 8 : 4;
509
 
510
      if (!allow_op32
511
          && SH_MERGE_ARCH_SET (op->arch, arch_op32))
512
        goto fail;
513
 
514
      if (!SH_MERGE_ARCH_SET_VALID (op->arch, target_arch))
515
        goto fail;
516
      for (n = 0; n < max_n; n++)
517
        {
518
          int i = op->nibbles[n];
519
 
520
          if (i < 16)
521
            {
522
              if (nibs[n] == i)
523
                continue;
524
              goto fail;
525
            }
526
          switch (i)
527
            {
528
            case BRANCH_8:
529
              imm = (nibs[2] << 4) | (nibs[3]);
530
              if (imm & 0x80)
531
                imm |= ~0xff;
532
              imm = ((char) imm) * 2 + 4;
533
              goto ok;
534
            case BRANCH_12:
535
              imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
536
              if (imm & 0x800)
537
                imm |= ~0xfff;
538
              imm = imm * 2 + 4;
539
              goto ok;
540
            case IMM0_3c:
541
              if (nibs[3] & 0x8)
542
                goto fail;
543
              imm = nibs[3] & 0x7;
544
              break;
545
            case IMM0_3s:
546
              if (!(nibs[3] & 0x8))
547
                goto fail;
548
              imm = nibs[3] & 0x7;
549
              break;
550
            case IMM0_3Uc:
551
              if (nibs[2] & 0x8)
552
                goto fail;
553
              imm = nibs[2] & 0x7;
554
              break;
555
            case IMM0_3Us:
556
              if (!(nibs[2] & 0x8))
557
                goto fail;
558
              imm = nibs[2] & 0x7;
559
              break;
560
            case DISP0_12:
561
            case DISP1_12:
562
              disp = (nibs[5] << 8) | (nibs[6] << 4) | nibs[7];
563
              has_disp = 1;
564
              goto ok;
565
            case DISP0_12BY2:
566
            case DISP1_12BY2:
567
              disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 1;
568
              relmask = ~(bfd_vma) 1;
569
              has_disp = 1;
570
              goto ok;
571
            case DISP0_12BY4:
572
            case DISP1_12BY4:
573
              disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 2;
574
              relmask = ~(bfd_vma) 3;
575
              has_disp = 1;
576
              goto ok;
577
            case DISP0_12BY8:
578
            case DISP1_12BY8:
579
              disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 3;
580
              relmask = ~(bfd_vma) 7;
581
              has_disp = 1;
582
              goto ok;
583
            case IMM0_20_4:
584
              break;
585
            case IMM0_20:
586
              imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
587
                     | (nibs[6] << 4) | nibs[7]);
588
              if (imm & 0x80000)
589
                imm -= 0x100000;
590
              goto ok;
591
            case IMM0_20BY8:
592
              imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
593
                     | (nibs[6] << 4) | nibs[7]);
594
              imm <<= 8;
595
              if (imm & 0x8000000)
596
                imm -= 0x10000000;
597
              goto ok;
598
            case IMM0_4:
599
            case IMM1_4:
600
              imm = nibs[3];
601
              goto ok;
602
            case IMM0_4BY2:
603
            case IMM1_4BY2:
604
              imm = nibs[3] << 1;
605
              goto ok;
606
            case IMM0_4BY4:
607
            case IMM1_4BY4:
608
              imm = nibs[3] << 2;
609
              goto ok;
610
            case IMM0_8:
611
            case IMM1_8:
612
              imm = (nibs[2] << 4) | nibs[3];
613
              disp = imm;
614
              has_disp = 1;
615
              if (imm & 0x80)
616
                imm -= 0x100;
617
              goto ok;
618
            case PCRELIMM_8BY2:
619
              imm = ((nibs[2] << 4) | nibs[3]) << 1;
620
              relmask = ~(bfd_vma) 1;
621
              goto ok;
622
            case PCRELIMM_8BY4:
623
              imm = ((nibs[2] << 4) | nibs[3]) << 2;
624
              relmask = ~(bfd_vma) 3;
625
              goto ok;
626
            case IMM0_8BY2:
627
            case IMM1_8BY2:
628
              imm = ((nibs[2] << 4) | nibs[3]) << 1;
629
              goto ok;
630
            case IMM0_8BY4:
631
            case IMM1_8BY4:
632
              imm = ((nibs[2] << 4) | nibs[3]) << 2;
633
              goto ok;
634
            case REG_N_D:
635
              if ((nibs[n] & 1) != 0)
636
                goto fail;
637
              /* Fall through.  */
638
            case REG_N:
639
              rn = nibs[n];
640
              break;
641
            case REG_M:
642
              rm = nibs[n];
643
              break;
644
            case REG_N_B01:
645
              if ((nibs[n] & 0x3) != 1 /* binary 01 */)
646
                goto fail;
647
              rn = (nibs[n] & 0xc) >> 2;
648
              break;
649
            case REG_NM:
650
              rn = (nibs[n] & 0xc) >> 2;
651
              rm = (nibs[n] & 0x3);
652
              break;
653
            case REG_B:
654
              rb = nibs[n] & 0x07;
655
              break;
656
            case SDT_REG_N:
657
              /* sh-dsp: single data transfer.  */
658
              rn = nibs[n];
659
              if ((rn & 0xc) != 4)
660
                goto fail;
661
              rn = rn & 0x3;
662
              rn |= (!(rn & 2)) << 2;
663
              break;
664
            case PPI:
665
            case REPEAT:
666
              goto fail;
667
            default:
668
              abort ();
669
            }
670
        }
671
 
672
    ok:
673
      /* sh2a has D_REG but not X_REG.  We don't know the pattern
674
         doesn't match unless we check the output args to see if they
675
         make sense.  */
676
      if (target_arch == arch_sh2a
677
          && ((op->arg[0] == DX_REG_M && (rm & 1) != 0)
678
              || (op->arg[1] == DX_REG_N && (rn & 1) != 0)))
679
        goto fail;
680
 
681
      fprintf_fn (stream, "%s\t", op->name);
682
      disp_pc = 0;
683
      for (n = 0; n < 3 && op->arg[n] != A_END; n++)
684
        {
685
          if (n && op->arg[1] != A_END)
686
            fprintf_fn (stream, ",");
687
          switch (op->arg[n])
688
            {
689
            case A_IMM:
690
              fprintf_fn (stream, "#%d", imm);
691
              break;
692
            case A_R0:
693
              fprintf_fn (stream, "r0");
694
              break;
695
            case A_REG_N:
696
              fprintf_fn (stream, "r%d", rn);
697
              break;
698
            case A_INC_N:
699
            case AS_INC_N:
700
              fprintf_fn (stream, "@r%d+", rn);
701
              break;
702
            case A_DEC_N:
703
            case AS_DEC_N:
704
              fprintf_fn (stream, "@-r%d", rn);
705
              break;
706
            case A_IND_N:
707
            case AS_IND_N:
708
              fprintf_fn (stream, "@r%d", rn);
709
              break;
710
            case A_DISP_REG_N:
711
              fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rn);
712
              break;
713
            case AS_PMOD_N:
714
              fprintf_fn (stream, "@r%d+r8", rn);
715
              break;
716
            case A_REG_M:
717
              fprintf_fn (stream, "r%d", rm);
718
              break;
719
            case A_INC_M:
720
              fprintf_fn (stream, "@r%d+", rm);
721
              break;
722
            case A_DEC_M:
723
              fprintf_fn (stream, "@-r%d", rm);
724
              break;
725
            case A_IND_M:
726
              fprintf_fn (stream, "@r%d", rm);
727
              break;
728
            case A_DISP_REG_M:
729
              fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rm);
730
              break;
731
            case A_REG_B:
732
              fprintf_fn (stream, "r%d_bank", rb);
733
              break;
734
            case A_DISP_PC:
735
              disp_pc = 1;
736
              disp_pc_addr = imm + 4 + (memaddr & relmask);
737
              (*info->print_address_func) (disp_pc_addr, info);
738
              break;
739
            case A_IND_R0_REG_N:
740
              fprintf_fn (stream, "@(r0,r%d)", rn);
741
              break;
742
            case A_IND_R0_REG_M:
743
              fprintf_fn (stream, "@(r0,r%d)", rm);
744
              break;
745
            case A_DISP_GBR:
746
              fprintf_fn (stream, "@(%d,gbr)", has_disp?disp:imm);
747
              break;
748
            case A_TBR:
749
              fprintf_fn (stream, "tbr");
750
              break;
751
            case A_DISP2_TBR:
752
              fprintf_fn (stream, "@@(%d,tbr)", has_disp?disp:imm);
753
              break;
754
            case A_INC_R15:
755
              fprintf_fn (stream, "@r15+");
756
              break;
757
            case A_DEC_R15:
758
              fprintf_fn (stream, "@-r15");
759
              break;
760
            case A_R0_GBR:
761
              fprintf_fn (stream, "@(r0,gbr)");
762
              break;
763
            case A_BDISP12:
764
            case A_BDISP8:
765
              (*info->print_address_func) (imm + memaddr, info);
766
              break;
767
            case A_SR:
768
              fprintf_fn (stream, "sr");
769
              break;
770
            case A_GBR:
771
              fprintf_fn (stream, "gbr");
772
              break;
773
            case A_VBR:
774
              fprintf_fn (stream, "vbr");
775
              break;
776
            case A_DSR:
777
              fprintf_fn (stream, "dsr");
778
              break;
779
            case A_MOD:
780
              fprintf_fn (stream, "mod");
781
              break;
782
            case A_RE:
783
              fprintf_fn (stream, "re");
784
              break;
785
            case A_RS:
786
              fprintf_fn (stream, "rs");
787
              break;
788
            case A_A0:
789
              fprintf_fn (stream, "a0");
790
              break;
791
            case A_X0:
792
              fprintf_fn (stream, "x0");
793
              break;
794
            case A_X1:
795
              fprintf_fn (stream, "x1");
796
              break;
797
            case A_Y0:
798
              fprintf_fn (stream, "y0");
799
              break;
800
            case A_Y1:
801
              fprintf_fn (stream, "y1");
802
              break;
803
            case DSP_REG_M:
804
              print_dsp_reg (rm, fprintf_fn, stream);
805
              break;
806
            case A_SSR:
807
              fprintf_fn (stream, "ssr");
808
              break;
809
            case A_SPC:
810
              fprintf_fn (stream, "spc");
811
              break;
812
            case A_MACH:
813
              fprintf_fn (stream, "mach");
814
              break;
815
            case A_MACL:
816
              fprintf_fn (stream, "macl");
817
              break;
818
            case A_PR:
819
              fprintf_fn (stream, "pr");
820
              break;
821
            case A_SGR:
822
              fprintf_fn (stream, "sgr");
823
              break;
824
            case A_DBR:
825
              fprintf_fn (stream, "dbr");
826
              break;
827
            case F_REG_N:
828
              fprintf_fn (stream, "fr%d", rn);
829
              break;
830
            case F_REG_M:
831
              fprintf_fn (stream, "fr%d", rm);
832
              break;
833
            case DX_REG_N:
834
              if (rn & 1)
835
                {
836
                  fprintf_fn (stream, "xd%d", rn & ~1);
837
                  break;
838
                }
839
            case D_REG_N:
840
              fprintf_fn (stream, "dr%d", rn);
841
              break;
842
            case DX_REG_M:
843
              if (rm & 1)
844
                {
845
                  fprintf_fn (stream, "xd%d", rm & ~1);
846
                  break;
847
                }
848
            case D_REG_M:
849
              fprintf_fn (stream, "dr%d", rm);
850
              break;
851
            case FPSCR_M:
852
            case FPSCR_N:
853
              fprintf_fn (stream, "fpscr");
854
              break;
855
            case FPUL_M:
856
            case FPUL_N:
857
              fprintf_fn (stream, "fpul");
858
              break;
859
            case F_FR0:
860
              fprintf_fn (stream, "fr0");
861
              break;
862
            case V_REG_N:
863
              fprintf_fn (stream, "fv%d", rn * 4);
864
              break;
865
            case V_REG_M:
866
              fprintf_fn (stream, "fv%d", rm * 4);
867
              break;
868
            case XMTRX_M4:
869
              fprintf_fn (stream, "xmtrx");
870
              break;
871
            default:
872
              abort ();
873
            }
874
        }
875
 
876
#if 0
877
      /* This code prints instructions in delay slots on the same line
878
         as the instruction which needs the delay slots.  This can be
879
         confusing, since other disassembler don't work this way, and
880
         it means that the instructions are not all in a line.  So I
881
         disabled it.  Ian.  */
882
      if (!(info->flags & 1)
883
          && (op->name[0] == 'j'
884
              || (op->name[0] == 'b'
885
                  && (op->name[1] == 'r'
886
                      || op->name[1] == 's'))
887
              || (op->name[0] == 'r' && op->name[1] == 't')
888
              || (op->name[0] == 'b' && op->name[2] == '.')))
889
        {
890
          info->flags |= 1;
891
          fprintf_fn (stream, "\t(slot ");
892
          print_insn_sh (memaddr + 2, info);
893
          info->flags &= ~1;
894
          fprintf_fn (stream, ")");
895
          return 4;
896
        }
897
#endif
898
 
899
      if (disp_pc && strcmp (op->name, "mova") != 0)
900
        {
901
          int size;
902
          bfd_byte bytes[4];
903
 
904
          if (relmask == ~(bfd_vma) 1)
905
            size = 2;
906
          else
907
            size = 4;
908
          status = info->read_memory_func (disp_pc_addr, bytes, size, info);
909
          if (status == 0)
910
            {
911
              unsigned int val;
912
 
913
              if (size == 2)
914
                {
915
                  if (info->endian == BFD_ENDIAN_LITTLE)
916
                    val = bfd_getl16 (bytes);
917
                  else
918
                    val = bfd_getb16 (bytes);
919
                }
920
              else
921
                {
922
                  if (info->endian == BFD_ENDIAN_LITTLE)
923
                    val = bfd_getl32 (bytes);
924
                  else
925
                    val = bfd_getb32 (bytes);
926
                }
927
              if ((*info->symbol_at_address_func) (val, info))
928
                {
929
                  fprintf_fn (stream, "\t! ");
930
                  (*info->print_address_func) (val, info);
931
                }
932
              else
933
                fprintf_fn (stream, "\t! %x", val);
934
            }
935
        }
936
 
937
      return SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 4 : 2;
938
    fail:
939
      ;
940
 
941
    }
942
  fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
943
  return 2;
944
}

powered by: WebSVN 2.1.0

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