Coverage Report

Created: 2024-05-21 06:29

/src/binutils-gdb/opcodes/v850-dis.c
Line
Count
Source (jump to first uncovered line)
1
/* Disassemble V850 instructions.
2
   Copyright (C) 1996-2024 Free Software Foundation, Inc.
3
4
   This file is part of the GNU opcodes library.
5
6
   This library is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3, or (at your option)
9
   any later version.
10
11
   It is distributed in the hope that it will be useful, but WITHOUT
12
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14
   License for more details.
15
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
   MA 02110-1301, USA.  */
20
21
22
#include "sysdep.h"
23
#include <stdio.h>
24
#include <string.h>
25
#include "opcode/v850.h"
26
#include "disassemble.h"
27
#include "opintl.h"
28
#include "libiberty.h"
29
30
static const int v850_cacheop_codes[] =
31
{
32
  0x00, 0x20, 0x40, 0x60, 0x61, 0x04, 0x06,
33
  0x07, 0x24, 0x26, 0x27, 0x44, 0x64, 0x65, -1
34
};
35
36
static const int v850_prefop_codes[] =
37
{ 0x00, 0x04, -1};
38
39
static void
40
print_value (int flags,
41
       bfd_vma memaddr,
42
       struct disassemble_info *info,
43
       long value)
44
176k
{
45
176k
  if (flags & V850_PCREL)
46
19.6k
    {
47
19.6k
      bfd_vma addr = value + memaddr;
48
49
19.6k
      if (flags & V850_INVERSE_PCREL)
50
135
  addr = memaddr - value;
51
19.6k
      info->print_address_func (addr, info);
52
19.6k
    }
53
156k
  else if (flags & V850_OPERAND_DISP)
54
102k
    {
55
102k
      if (flags & V850_OPERAND_SIGNED)
56
34.2k
        {
57
34.2k
          info->fprintf_func (info->stream, "%ld", value);
58
34.2k
        }
59
67.8k
      else
60
67.8k
        {
61
67.8k
          info->fprintf_func (info->stream, "%lu", value);
62
67.8k
        }
63
102k
    }
64
54.4k
  else if ((flags & V850E_IMMEDIATE32)
65
54.4k
     || (flags & V850E_IMMEDIATE16HI))
66
355
    {
67
355
      info->fprintf_func (info->stream, "0x%lx", value);
68
355
    }
69
54.0k
  else
70
54.0k
    {
71
54.0k
      if (flags & V850_OPERAND_SIGNED)
72
31.8k
  {
73
31.8k
    info->fprintf_func (info->stream, "%ld", value);
74
31.8k
  }
75
22.2k
      else
76
22.2k
  {
77
22.2k
    info->fprintf_func (info->stream, "%lu", value);
78
22.2k
  }
79
54.0k
    }
80
176k
}
81
82
static long
83
get_operand_value (const struct v850_operand *operand,
84
       unsigned long insn,
85
       int bytes_read,
86
       bfd_vma memaddr,
87
       struct disassemble_info * info,
88
       bool noerror,
89
       int *invalid)
90
1.28M
{
91
1.28M
  unsigned long value;
92
1.28M
  bfd_byte buffer[4];
93
94
1.28M
  if ((operand->flags & V850E_IMMEDIATE16)
95
1.28M
      || (operand->flags & V850E_IMMEDIATE16HI))
96
438
    {
97
438
      int status = info->read_memory_func (memaddr + bytes_read, buffer, 2, info);
98
99
438
      if (status == 0)
100
438
  {
101
438
    value = bfd_getl16 (buffer);
102
103
438
    if (operand->flags & V850E_IMMEDIATE16HI)
104
6
      value <<= 16;
105
432
    else if (value & 0x8000)
106
316
      value |= (-1UL << 16);
107
108
438
    return value;
109
438
  }
110
111
0
      if (!noerror)
112
0
  info->memory_error_func (status, memaddr + bytes_read, info);
113
114
0
      return 0;
115
438
    }
116
117
1.28M
  if (operand->flags & V850E_IMMEDIATE23)
118
3.08k
    {
119
3.08k
      int status = info->read_memory_func (memaddr + 2, buffer, 4, info);
120
121
3.08k
      if (status == 0)
122
3.08k
  {
123
3.08k
    value = bfd_getl32 (buffer);
124
125
3.08k
    value = (operand->extract) (value, invalid);
126
127
3.08k
    return value;
128
3.08k
  }
129
130
0
      if (!noerror)
131
0
  info->memory_error_func (status, memaddr + bytes_read, info);
132
133
0
      return 0;
134
3.08k
    }
135
136
1.28M
  if (operand->flags & V850E_IMMEDIATE32)
137
2.34k
    {
138
2.34k
      int status = info->read_memory_func (memaddr + bytes_read, buffer, 4, info);
139
140
2.34k
      if (status == 0)
141
2.34k
  {
142
2.34k
    bytes_read += 4;
143
2.34k
    value = bfd_getl32 (buffer);
144
145
2.34k
    return value;
146
2.34k
  }
147
148
2
      if (!noerror)
149
1
  info->memory_error_func (status, memaddr + bytes_read, info);
150
151
2
      return 0;
152
2.34k
    }
153
154
1.28M
  if (operand->extract)
155
163k
    value = (operand->extract) (insn, invalid);
156
1.11M
  else
157
1.11M
    {
158
1.11M
      if (operand->bits == -1)
159
3.60k
  value = (insn & operand->shift);
160
1.11M
      else
161
1.11M
  value = (insn >> operand->shift) & ((1ul << operand->bits) - 1);
162
163
1.11M
      if (operand->flags & V850_OPERAND_SIGNED)
164
87.2k
  {
165
87.2k
    unsigned long sign = 1ul << (operand->bits - 1);
166
87.2k
    value = (value ^ sign) - sign;
167
87.2k
  }
168
1.11M
    }
169
170
1.28M
  return value;
171
1.28M
}
172
173
static const char *
174
get_v850_sreg_name (unsigned int reg)
175
448
{
176
448
  static const char *const v850_sreg_names[] =
177
448
    {
178
448
     "eipc/vip/mpm", "eipsw/mpc", "fepc/tid", "fepsw/ppa", "ecr/vmecr", "psw/vmtid",
179
448
     "sr6/fpsr/vmadr/dcc", "sr7/fpepc/dc0",
180
448
     "sr8/fpst/vpecr/dcv1", "sr9/fpcc/vptid", "sr10/fpcfg/vpadr/spal", "sr11/spau",
181
448
     "sr12/vdecr/ipa0l", "eiic/vdtid/ipa0u", "feic/ipa1l", "dbic/ipa1u",
182
448
     "ctpc/ipa2l", "ctpsw/ipa2u", "dbpc/ipa3l", "dbpsw/ipa3u", "ctbp/dpa0l",
183
448
     "dir/dpa0u", "bpc/dpa0u", "asid/dpa1l",
184
448
     "bpav/dpa1u", "bpam/dpa2l", "bpdv/dpa2u", "bpdm/dpa3l", "eiwr/dpa3u",
185
448
     "fewr", "dbwr", "bsel"
186
448
    };
187
188
448
  if (reg < ARRAY_SIZE (v850_sreg_names))
189
135
    return v850_sreg_names[reg];
190
313
  return _("<invalid s-reg number>");
191
448
}
192
193
static const char *
194
get_v850_reg_name (unsigned int reg)
195
347k
{
196
347k
  static const char *const v850_reg_names[] =
197
347k
    {
198
347k
     "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7",
199
347k
     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
200
347k
     "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
201
347k
     "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp"
202
347k
    };
203
204
347k
  if (reg < ARRAY_SIZE (v850_reg_names))
205
347k
    return v850_reg_names[reg];
206
0
  return _("<invalid reg number>");
207
347k
}
208
209
static const char *
210
get_v850_vreg_name (unsigned int reg)
211
350
{
212
350
  static const char *const v850_vreg_names[] =
213
350
    {
214
350
     "vr0", "vr1", "vr2", "vr3", "vr4", "vr5", "vr6", "vr7", "vr8", "vr9",
215
350
     "vr10", "vr11", "vr12", "vr13", "vr14", "vr15", "vr16", "vr17", "vr18",
216
350
     "vr19", "vr20", "vr21", "vr22", "vr23", "vr24", "vr25", "vr26", "vr27",
217
350
     "vr28", "vr29", "vr30", "vr31"
218
350
    };
219
220
350
  if (reg < ARRAY_SIZE (v850_vreg_names))
221
350
    return v850_vreg_names[reg];
222
0
  return _("<invalid v-reg number>");
223
350
}
224
225
static const char *
226
get_v850_cc_name (unsigned int reg)
227
413
{
228
413
  static const char *const v850_cc_names[] =
229
413
    {
230
413
     "v", "c/l", "z", "nh", "s/n", "t", "lt", "le",
231
413
     "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt"
232
413
    };
233
234
413
  if (reg < ARRAY_SIZE (v850_cc_names))
235
413
    return v850_cc_names[reg];
236
0
  return _("<invalid CC-reg number>");
237
413
}
238
239
static const char *
240
get_v850_float_cc_name (unsigned int reg)
241
29
{
242
29
  static const char *const v850_float_cc_names[] =
243
29
    {
244
29
     "f/t", "un/or", "eq/neq", "ueq/ogl", "olt/uge", "ult/oge", "ole/ugt", "ule/ogt",
245
29
     "sf/st", "ngle/gle", "seq/sne", "ngl/gl", "lt/nlt", "nge/ge", "le/nle", "ngt/gt"
246
29
    };
247
248
29
  if (reg < ARRAY_SIZE (v850_float_cc_names))
249
29
    return v850_float_cc_names[reg];
250
0
  return _("<invalid float-CC-reg number>");
251
29
}
252
253
static const char *
254
get_v850_cacheop_name (unsigned int reg)
255
94
{
256
94
  static const char *const v850_cacheop_names[] =
257
94
    {
258
94
     "chbii", "cibii", "cfali", "cisti", "cildi", "chbid", "chbiwbd",
259
94
     "chbwbd", "cibid", "cibiwbd", "cibwbd", "cfald", "cistd", "cildd"
260
94
    };
261
262
94
  if (reg < ARRAY_SIZE (v850_cacheop_names))
263
94
    return v850_cacheop_names[reg];
264
0
  return _("<invalid cacheop number>");
265
94
}
266
267
static const char *
268
get_v850_prefop_name (unsigned int reg)
269
188
{
270
188
  static const char *const v850_prefop_names[] =
271
188
    { "prefi", "prefd" };
272
273
188
  if (reg < ARRAY_SIZE (v850_prefop_names))
274
188
    return v850_prefop_names[reg];
275
0
  return _("<invalid prefop number>");
276
188
}
277
278
static int
279
disassemble (bfd_vma memaddr,
280
       struct disassemble_info *info,
281
       int bytes_read,
282
       unsigned long insn)
283
292k
{
284
292k
  struct v850_opcode *op = (struct v850_opcode *) v850_opcodes;
285
292k
  const struct v850_operand *operand;
286
292k
  int match = 0;
287
292k
  int target_processor;
288
289
292k
  switch (info->mach)
290
292k
    {
291
10.0k
    case 0:
292
10.0k
    default:
293
10.0k
      target_processor = PROCESSOR_V850;
294
10.0k
      break;
295
296
463
    case bfd_mach_v850e:
297
463
      target_processor = PROCESSOR_V850E;
298
463
      break;
299
300
176
    case bfd_mach_v850e1:
301
176
      target_processor = PROCESSOR_V850E;
302
176
      break;
303
304
13.9k
    case bfd_mach_v850e2:
305
13.9k
      target_processor = PROCESSOR_V850E2;
306
13.9k
      break;
307
308
56.3k
    case bfd_mach_v850e2v3:
309
56.3k
      target_processor = PROCESSOR_V850E2V3;
310
56.3k
      break;
311
312
211k
    case bfd_mach_v850e3v5:
313
211k
      target_processor = PROCESSOR_V850E3V5;
314
211k
      break;
315
292k
    }
316
317
  /* If this is a two byte insn, then mask off the high bits.  */
318
292k
  if (bytes_read == 2)
319
225k
    insn &= 0xffff;
320
321
  /* Find the opcode.  */
322
59.4M
  while (op->name)
323
59.4M
    {
324
59.4M
      if ((op->mask & insn) == op->opcode
325
59.4M
    && (op->processors & target_processor)
326
59.4M
    && !(op->processors & PROCESSOR_OPTION_ALIAS))
327
339k
  {
328
    /* Code check start.  */
329
339k
    const unsigned char *opindex_ptr;
330
339k
    unsigned int opnum;
331
339k
    unsigned int memop;
332
333
339k
    for (opindex_ptr = op->operands, opnum = 1;
334
984k
         *opindex_ptr != 0;
335
644k
         opindex_ptr++, opnum++)
336
700k
      {
337
700k
        int invalid = 0;
338
700k
        long value;
339
340
700k
        operand = &v850_operands[*opindex_ptr];
341
342
700k
        value = get_operand_value (operand, insn, bytes_read, memaddr,
343
700k
           info, 1, &invalid);
344
345
700k
        if (invalid)
346
36
    goto next_opcode;
347
348
700k
              if ((operand->flags & V850_NOT_R0) && value == 0 && (op->memop) <=2)
349
55.8k
    goto next_opcode;
350
351
644k
        if ((operand->flags & V850_NOT_SA) && value == 0xd)
352
29
    goto next_opcode;
353
354
644k
        if ((operand->flags & V850_NOT_IMM0) && value == 0)
355
83
    goto next_opcode;
356
644k
      }
357
358
    /* Code check end.  */
359
360
283k
    match = 1;
361
283k
    (*info->fprintf_func) (info->stream, "%s\t", op->name);
362
#if 0
363
    fprintf (stderr, "match: insn: %lx, mask: %lx, opcode: %lx, name: %s\n",
364
       insn, op->mask, op->opcode, op->name );
365
#endif
366
367
283k
    memop = op->memop;
368
    /* Now print the operands.
369
370
       MEMOP is the operand number at which a memory
371
       address specification starts, or zero if this
372
       instruction has no memory addresses.
373
374
       A memory address is always two arguments.
375
376
       This information allows us to determine when to
377
       insert commas into the output stream as well as
378
       when to insert disp[reg] expressions onto the
379
       output stream.  */
380
381
283k
    for (opindex_ptr = op->operands, opnum = 1;
382
871k
         *opindex_ptr != 0;
383
587k
         opindex_ptr++, opnum++)
384
587k
      {
385
587k
        bool square = false;
386
587k
        long value;
387
587k
        int flag;
388
587k
        char *prefix;
389
390
587k
        operand = &v850_operands[*opindex_ptr];
391
392
587k
        value = get_operand_value (operand, insn, bytes_read, memaddr,
393
587k
           info, 0, 0);
394
395
        /* The first operand is always output without any
396
     special handling.
397
398
     For the following arguments:
399
400
       If memop && opnum == memop + 1, then we need '[' since
401
       we're about to output the register used in a memory
402
       reference.
403
404
       If memop && opnum == memop + 2, then we need ']' since
405
       we just finished the register in a memory reference.  We
406
       also need a ',' before this operand.
407
408
       Else we just need a comma.
409
410
       We may need to output a trailing ']' if the last operand
411
       in an instruction is the register for a memory address.
412
413
       The exception (and there's always an exception) are the
414
       "jmp" insn which needs square brackets around it's only
415
       register argument, and the clr1/not1/set1/tst1 insns
416
       which [...] around their second register argument.  */
417
418
587k
        prefix = "";
419
587k
        if (operand->flags & V850_OPERAND_BANG)
420
0
    {
421
0
      prefix = "!";
422
0
    }
423
587k
        else if (operand->flags & V850_OPERAND_PERCENT)
424
0
    {
425
0
      prefix = "%";
426
0
    }
427
428
587k
        if (opnum == 1 && opnum == memop)
429
1.70k
    {
430
1.70k
      info->fprintf_func (info->stream, "%s[", prefix);
431
1.70k
      square = true;
432
1.70k
    }
433
586k
        else if (   (strcmp ("stc.w", op->name) == 0
434
586k
      || strcmp ("cache", op->name) == 0
435
586k
      || strcmp ("pref",  op->name) == 0)
436
586k
           && opnum == 2 && opnum == memop)
437
693
    {
438
693
      info->fprintf_func (info->stream, ", [");
439
693
      square = true;
440
693
    }
441
585k
        else if (   (strcmp (op->name, "pushsp") == 0
442
585k
      || strcmp (op->name, "popsp") == 0
443
585k
      || strcmp (op->name, "dbpush" ) == 0)
444
585k
           && opnum == 2)
445
62
    {
446
62
      info->fprintf_func (info->stream, "-");
447
62
    }
448
585k
        else if (opnum > 1
449
585k
           && (v850_operands[*(opindex_ptr - 1)].flags
450
343k
         & V850_OPERAND_DISP) != 0
451
585k
           && opnum == memop)
452
102k
    {
453
102k
      info->fprintf_func (info->stream, "%s[", prefix);
454
102k
      square = true;
455
102k
    }
456
483k
        else if (opnum == 2
457
483k
           && (   op->opcode == 0x00e407e0 /* clr1 */
458
150k
         || op->opcode == 0x00e207e0 /* not1 */
459
150k
         || op->opcode == 0x00e007e0 /* set1 */
460
150k
         || op->opcode == 0x00e607e0 /* tst1 */
461
150k
         ))
462
262
    {
463
262
      info->fprintf_func (info->stream, ", %s[", prefix);
464
262
      square = true;
465
262
    }
466
482k
        else if (opnum > 1)
467
240k
    info->fprintf_func (info->stream, ", %s", prefix);
468
469
        /* Extract the flags, ignoring ones which do not
470
     effect disassembly output.  */
471
587k
        flag = operand->flags & (V850_OPERAND_REG
472
587k
               | V850_REG_EVEN
473
587k
               | V850_OPERAND_EP
474
587k
               | V850_OPERAND_SRG
475
587k
               | V850E_OPERAND_REG_LIST
476
587k
               | V850_OPERAND_CC
477
587k
               | V850_OPERAND_VREG
478
587k
               | V850_OPERAND_CACHEOP
479
587k
               | V850_OPERAND_PREFOP
480
587k
               | V850_OPERAND_FLOAT_CC);
481
482
587k
        switch (flag)
483
587k
    {
484
339k
    case V850_OPERAND_REG:
485
339k
      info->fprintf_func (info->stream, "%s", get_v850_reg_name (value));
486
339k
      break;
487
126
    case (V850_OPERAND_REG|V850_REG_EVEN):
488
126
      info->fprintf_func (info->stream, "%s", get_v850_reg_name (value * 2));
489
126
      break;
490
67.8k
    case V850_OPERAND_EP:
491
67.8k
      info->fprintf_func (info->stream, "ep");
492
67.8k
      break;
493
448
    case V850_OPERAND_SRG:
494
448
      info->fprintf_func (info->stream, "%s", get_v850_sreg_name (value));
495
448
      break;
496
1.80k
    case V850E_OPERAND_REG_LIST:
497
1.80k
      {
498
1.80k
        static int list12_regs[32]   = { 30, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
499
1.80k
                 0,  0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
500
1.80k
        int *regs;
501
1.80k
        int i;
502
1.80k
        unsigned int mask = 0;
503
1.80k
        int pc = 0;
504
505
1.80k
        switch (operand->shift)
506
1.80k
          {
507
1.80k
          case 0xffe00001: regs = list12_regs; break;
508
0
          default:
509
      /* xgettext:c-format */
510
0
      opcodes_error_handler (_("unknown operand shift: %x"),
511
0
                 operand->shift);
512
0
      abort ();
513
1.80k
          }
514
515
59.4k
        for (i = 0; i < 32; i++)
516
57.6k
          {
517
57.6k
      if (value & (1u << i))
518
9.20k
        {
519
9.20k
          switch (regs[ i ])
520
9.20k
            {
521
9.20k
            default:
522
9.20k
        mask |= (1u << regs[ i ]);
523
9.20k
        break;
524
0
            case 0:
525
        /* xgettext:c-format */
526
0
        opcodes_error_handler (_("unknown reg: %d"), i);
527
0
        abort ();
528
0
        break;
529
0
            case -1:
530
0
        pc = 1;
531
0
        break;
532
9.20k
            }
533
9.20k
        }
534
57.6k
          }
535
536
1.80k
        info->fprintf_func (info->stream, "{");
537
538
1.80k
        if (mask || pc)
539
1.74k
          {
540
1.74k
      if (mask)
541
1.74k
        {
542
1.74k
          unsigned int bit;
543
1.74k
          int shown_one = 0;
544
545
49.0k
          for (bit = 0; bit < 32; bit++)
546
47.3k
            if (mask & (1u << bit))
547
5.20k
        {
548
5.20k
          unsigned int first = bit;
549
5.20k
          unsigned int last;
550
551
5.20k
          if (shown_one)
552
3.46k
            info->fprintf_func (info->stream, ", ");
553
1.74k
          else
554
1.74k
            shown_one = 1;
555
556
5.20k
          info->fprintf_func (info->stream, "%s", get_v850_reg_name (first));
557
558
9.20k
          for (bit++; bit < 32; bit++)
559
8.43k
            if ((mask & (1u << bit)) == 0)
560
4.44k
              break;
561
562
5.20k
          last = bit;
563
564
5.20k
          if (last > first + 1)
565
2.07k
            {
566
2.07k
              info->fprintf_func (info->stream, " - %s", get_v850_reg_name (last - 1));
567
2.07k
            }
568
5.20k
        }
569
1.74k
        }
570
571
1.74k
      if (pc)
572
0
        info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
573
1.74k
          }
574
575
1.80k
        info->fprintf_func (info->stream, "}");
576
1.80k
      }
577
0
      break;
578
579
413
    case V850_OPERAND_CC:
580
413
      info->fprintf_func (info->stream, "%s", get_v850_cc_name (value));
581
413
      break;
582
583
29
    case V850_OPERAND_FLOAT_CC:
584
29
      info->fprintf_func (info->stream, "%s", get_v850_float_cc_name (value));
585
29
      break;
586
587
180
    case V850_OPERAND_CACHEOP:
588
180
      {
589
180
        int idx;
590
591
2.21k
        for (idx = 0; v850_cacheop_codes[idx] != -1; idx++)
592
2.12k
          {
593
2.12k
      if (value == v850_cacheop_codes[idx])
594
94
        {
595
94
          info->fprintf_func (info->stream, "%s",
596
94
            get_v850_cacheop_name (idx));
597
94
          goto MATCH_CACHEOP_CODE;
598
94
        }
599
2.12k
          }
600
86
        info->fprintf_func (info->stream, "%d", (int) value);
601
86
      }
602
180
    MATCH_CACHEOP_CODE:
603
180
      break;
604
605
513
    case V850_OPERAND_PREFOP:
606
513
      {
607
513
        int idx;
608
609
1.21k
        for (idx = 0; v850_prefop_codes[idx] != -1; idx++)
610
888
          {
611
888
      if (value == v850_prefop_codes[idx])
612
188
        {
613
188
          info->fprintf_func (info->stream, "%s",
614
188
            get_v850_prefop_name (idx));
615
188
          goto MATCH_PREFOP_CODE;
616
188
        }
617
888
          }
618
325
        info->fprintf_func (info->stream, "%d", (int) value);
619
325
      }
620
513
    MATCH_PREFOP_CODE:
621
513
      break;
622
623
350
    case V850_OPERAND_VREG:
624
350
      info->fprintf_func (info->stream, "%s", get_v850_vreg_name (value));
625
350
      break;
626
627
176k
    default:
628
176k
      print_value (operand->flags, memaddr, info, value);
629
176k
      break;
630
587k
    }
631
632
587k
        if (square)
633
104k
    (*info->fprintf_func) (info->stream, "]");
634
587k
      }
635
636
    /* All done. */
637
283k
    break;
638
283k
  }
639
59.1M
    next_opcode:
640
59.1M
      op++;
641
59.1M
    }
642
643
292k
  return match;
644
292k
}
645
646
int
647
print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
648
292k
{
649
292k
  int status, status2, match;
650
292k
  bfd_byte buffer[8];
651
292k
  int length = 0, code_length = 0;
652
292k
  unsigned long insn = 0, insn2 = 0;
653
292k
  int target_processor;
654
655
292k
  switch (info->mach)
656
292k
    {
657
10.0k
    case 0:
658
10.0k
    default:
659
10.0k
      target_processor = PROCESSOR_V850;
660
10.0k
      break;
661
662
466
    case bfd_mach_v850e:
663
466
      target_processor = PROCESSOR_V850E;
664
466
      break;
665
666
178
    case bfd_mach_v850e1:
667
178
      target_processor = PROCESSOR_V850E;
668
178
      break;
669
670
13.9k
    case bfd_mach_v850e2:
671
13.9k
      target_processor = PROCESSOR_V850E2;
672
13.9k
      break;
673
674
56.3k
    case bfd_mach_v850e2v3:
675
56.3k
      target_processor = PROCESSOR_V850E2V3;
676
56.3k
      break;
677
678
211k
    case bfd_mach_v850e3v5:
679
211k
      target_processor = PROCESSOR_V850E3V5;
680
211k
      break;
681
292k
    }
682
683
292k
  status = info->read_memory_func (memaddr, buffer, 2, info);
684
685
292k
  if (status)
686
97
    {
687
97
      info->memory_error_func (status, memaddr, info);
688
97
      return -1;
689
97
    }
690
691
292k
  insn = bfd_getl16 (buffer);
692
693
292k
  status2 = info->read_memory_func (memaddr+2, buffer, 2 , info);
694
695
292k
  if (!status2)
696
292k
    {
697
292k
      insn2 = bfd_getl16 (buffer);
698
      /* fprintf (stderr, "insn2 0x%08lx\n", insn2); */
699
292k
    }
700
701
  /* Special case.  */
702
292k
  if (length == 0
703
292k
      && ((target_processor & PROCESSOR_V850E2_UP) != 0))
704
281k
    {
705
281k
      if ((insn & 0xffff) == 0x02e0    /* jr 32bit */
706
281k
    && !status2 && (insn2 & 0x1) == 0)
707
0
  {
708
0
    length = 2;
709
0
    code_length = 6;
710
0
  }
711
281k
      else if ((insn & 0xffe0) == 0x02e0  /* jarl 32bit */
712
281k
         && !status2 && (insn2 & 0x1) == 0)
713
203
  {
714
203
    length = 2;
715
203
    code_length = 6;
716
203
  }
717
281k
      else if ((insn & 0xffe0) == 0x06e0  /* jmp 32bit */
718
281k
         && !status2 && (insn2 & 0x1) == 0)
719
536
  {
720
536
    length = 2;
721
536
    code_length = 6;
722
536
  }
723
281k
    }
724
725
292k
  if (length == 0
726
292k
      && ((target_processor & PROCESSOR_V850E3V5_UP) != 0))
727
211k
    {
728
211k
      if (   ((insn & 0xffe0) == 0x07a0    /* ld.dw 23bit (v850e3v5) */
729
211k
        && !status2 && (insn2 & 0x000f) == 0x0009)
730
211k
    || ((insn & 0xffe0) == 0x07a0    /* st.dw 23bit (v850e3v5) */
731
211k
        && !status2 && (insn2 & 0x000f) == 0x000f))
732
404
  {
733
404
    length = 4;
734
404
    code_length = 6;
735
404
  }
736
211k
    }
737
738
292k
  if (length == 0
739
292k
      && ((target_processor & PROCESSOR_V850E2V3_UP) != 0))
740
266k
    {
741
266k
      if (((insn & 0xffe0) == 0x0780    /* ld.b 23bit */
742
266k
     && !status2 && (insn2 & 0x000f) == 0x0005)
743
266k
    || ((insn & 0xffe0) == 0x07a0    /* ld.bu 23bit */
744
266k
        && !status2 && (insn2 & 0x000f) == 0x0005)
745
266k
    || ((insn & 0xffe0) == 0x0780    /* ld.h 23bit */
746
266k
        && !status2 && (insn2 & 0x000f) == 0x0007)
747
266k
    || ((insn & 0xffe0) == 0x07a0    /* ld.hu 23bit */
748
266k
        && !status2 && (insn2 & 0x000f) == 0x0007)
749
266k
    || ((insn & 0xffe0) == 0x0780    /* ld.w 23bit */
750
265k
        && !status2 && (insn2 & 0x000f) == 0x0009))
751
830
  {
752
830
    length = 4;
753
830
    code_length = 6;
754
830
  }
755
265k
      else if (((insn & 0xffe0) == 0x0780  /* st.b 23bit */
756
265k
         && !status2 && (insn2 & 0x000f) == 0x000d)
757
265k
        || ((insn & 0xffe0) == 0x07a0  /* st.h 23bit */
758
265k
      && !status2 && (insn2 & 0x000f) == 0x000d)
759
265k
        || ((insn & 0xffe0) == 0x0780  /* st.w 23bit */
760
265k
      && !status2 && (insn2 & 0x000f) == 0x000f))
761
659
  {
762
659
    length = 4;
763
659
    code_length = 6;
764
659
  }
765
266k
    }
766
767
292k
  if (length == 0
768
292k
      && target_processor != PROCESSOR_V850)
769
279k
    {
770
279k
      if ((insn & 0xffe0) == 0x0620)    /* 32 bit MOV */
771
312
  {
772
312
    length = 2;
773
312
    code_length = 6;
774
312
  }
775
279k
      else if ((insn & 0xffc0) == 0x0780  /* prepare {list}, imm5, imm16<<16 */
776
279k
         && !status2 && (insn2 & 0x001f) == 0x0013)
777
3
  {
778
3
    length = 4;
779
3
    code_length = 6;
780
3
  }
781
279k
      else if ((insn & 0xffc0) == 0x0780  /* prepare {list}, imm5, imm16 */
782
279k
         && !status2 && (insn2 & 0x001f) == 0x000b)
783
216
  {
784
216
    length = 4;
785
216
    code_length = 6;
786
216
  }
787
279k
      else if ((insn & 0xffc0) == 0x0780  /* prepare {list}, imm5, imm32 */
788
279k
         && !status2 && (insn2 & 0x001f) == 0x001b)
789
45
  {
790
45
    length = 4;
791
45
    code_length = 8;
792
45
  }
793
279k
    }
794
795
292k
  if (length == 4
796
292k
      || (length == 0
797
290k
    && (insn & 0x0600) == 0x0600))
798
67.2k
    {
799
      /* This is a 4 byte insn.  */
800
67.2k
      status = info->read_memory_func (memaddr, buffer, 4, info);
801
67.2k
      if (!status)
802
67.2k
  {
803
67.2k
    insn = bfd_getl32 (buffer);
804
805
67.2k
    if (!length)
806
65.0k
      length = code_length = 4;
807
67.2k
  }
808
67.2k
    }
809
810
292k
  if (code_length > length)
811
3.20k
    {
812
3.20k
      status = info->read_memory_func (memaddr + length, buffer, code_length - length, info);
813
3.20k
      if (status)
814
5
  length = 0;
815
3.20k
    }
816
817
292k
  if (length == 0 && !status)
818
224k
    length = code_length = 2;
819
820
292k
  if (length == 2)
821
225k
    insn &= 0xffff;
822
823
  /* when the last 2 bytes of section is 0xffff, length will be 0 and cause infinitive loop */
824
292k
  if (length == 0)
825
17
    return -1;
826
827
292k
  match = disassemble (memaddr, info, length, insn);
828
829
292k
  if (!match)
830
8.97k
    {
831
8.97k
      int l = 0;
832
833
8.97k
      status = info->read_memory_func (memaddr, buffer, code_length, info);
834
835
18.3k
      while (l < code_length)
836
9.36k
  {
837
9.36k
    if (code_length - l == 2)
838
5.82k
      {
839
5.82k
        insn = bfd_getl16 (buffer + l) & 0xffff;
840
5.82k
        info->fprintf_func (info->stream, ".short\t0x%04lx", insn);
841
5.82k
        l += 2;
842
5.82k
      }
843
3.54k
    else
844
3.54k
      {
845
3.54k
        insn = bfd_getl32 (buffer + l);
846
3.54k
        info->fprintf_func (info->stream, ".long\t0x%08lx", insn);
847
3.54k
        l += 4;
848
3.54k
      }
849
9.36k
  }
850
8.97k
    }
851
852
292k
  return code_length;
853
292k
}