Coverage Report

Created: 2023-06-29 07:13

/src/binutils-gdb/opcodes/v850-dis.c
Line
Count
Source (jump to first uncovered line)
1
/* Disassemble V850 instructions.
2
   Copyright (C) 1996-2023 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
271k
{
45
271k
  if (flags & V850_PCREL)
46
29.4k
    {
47
29.4k
      bfd_vma addr = value + memaddr;
48
49
29.4k
      if (flags & V850_INVERSE_PCREL)
50
105
  addr = memaddr - value;
51
29.4k
      info->print_address_func (addr, info);
52
29.4k
    }
53
241k
  else if (flags & V850_OPERAND_DISP)
54
159k
    {
55
159k
      if (flags & V850_OPERAND_SIGNED)
56
51.2k
        {
57
51.2k
          info->fprintf_func (info->stream, "%ld", value);
58
51.2k
        }
59
108k
      else
60
108k
        {
61
108k
          info->fprintf_func (info->stream, "%lu", value);
62
108k
        }
63
159k
    }
64
82.6k
  else if ((flags & V850E_IMMEDIATE32)
65
82.6k
     || (flags & V850E_IMMEDIATE16HI))
66
213
    {
67
213
      info->fprintf_func (info->stream, "0x%lx", value);
68
213
    }
69
82.4k
  else
70
82.4k
    {
71
82.4k
      if (flags & V850_OPERAND_SIGNED)
72
49.1k
  {
73
49.1k
    info->fprintf_func (info->stream, "%ld", value);
74
49.1k
  }
75
33.3k
      else
76
33.3k
  {
77
33.3k
    info->fprintf_func (info->stream, "%lu", value);
78
33.3k
  }
79
82.4k
    }
80
271k
}
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.96M
{
91
1.96M
  unsigned long value;
92
1.96M
  bfd_byte buffer[4];
93
94
1.96M
  if ((operand->flags & V850E_IMMEDIATE16)
95
1.96M
      || (operand->flags & V850E_IMMEDIATE16HI))
96
766
    {
97
766
      int status = info->read_memory_func (memaddr + bytes_read, buffer, 2, info);
98
99
766
      if (status == 0)
100
766
  {
101
766
    value = bfd_getl16 (buffer);
102
103
766
    if (operand->flags & V850E_IMMEDIATE16HI)
104
20
      value <<= 16;
105
746
    else if (value & 0x8000)
106
528
      value |= (-1UL << 16);
107
108
766
    return value;
109
766
  }
110
111
0
      if (!noerror)
112
0
  info->memory_error_func (status, memaddr + bytes_read, info);
113
114
0
      return 0;
115
766
    }
116
117
1.96M
  if (operand->flags & V850E_IMMEDIATE23)
118
4.41k
    {
119
4.41k
      int status = info->read_memory_func (memaddr + 2, buffer, 4, info);
120
121
4.41k
      if (status == 0)
122
4.41k
  {
123
4.41k
    value = bfd_getl32 (buffer);
124
125
4.41k
    value = (operand->extract) (value, invalid);
126
127
4.41k
    return value;
128
4.41k
  }
129
130
0
      if (!noerror)
131
0
  info->memory_error_func (status, memaddr + bytes_read, info);
132
133
0
      return 0;
134
4.41k
    }
135
136
1.96M
  if (operand->flags & V850E_IMMEDIATE32)
137
2.56k
    {
138
2.56k
      int status = info->read_memory_func (memaddr + bytes_read, buffer, 4, info);
139
140
2.56k
      if (status == 0)
141
2.56k
  {
142
2.56k
    bytes_read += 4;
143
2.56k
    value = bfd_getl32 (buffer);
144
145
2.56k
    return value;
146
2.56k
  }
147
148
2
      if (!noerror)
149
1
  info->memory_error_func (status, memaddr + bytes_read, info);
150
151
2
      return 0;
152
2.56k
    }
153
154
1.96M
  if (operand->extract)
155
252k
    value = (operand->extract) (insn, invalid);
156
1.70M
  else
157
1.70M
    {
158
1.70M
      if (operand->bits == -1)
159
5.26k
  value = (insn & operand->shift);
160
1.70M
      else
161
1.70M
  value = (insn >> operand->shift) & ((1ul << operand->bits) - 1);
162
163
1.70M
      if (operand->flags & V850_OPERAND_SIGNED)
164
132k
  {
165
132k
    unsigned long sign = 1ul << (operand->bits - 1);
166
132k
    value = (value ^ sign) - sign;
167
132k
  }
168
1.70M
    }
169
170
1.96M
  return value;
171
1.96M
}
172
173
static const char *
174
get_v850_sreg_name (unsigned int reg)
175
537
{
176
537
  static const char *const v850_sreg_names[] =
177
537
    {
178
537
     "eipc/vip/mpm", "eipsw/mpc", "fepc/tid", "fepsw/ppa", "ecr/vmecr", "psw/vmtid",
179
537
     "sr6/fpsr/vmadr/dcc", "sr7/fpepc/dc0",
180
537
     "sr8/fpst/vpecr/dcv1", "sr9/fpcc/vptid", "sr10/fpcfg/vpadr/spal", "sr11/spau",
181
537
     "sr12/vdecr/ipa0l", "eiic/vdtid/ipa0u", "feic/ipa1l", "dbic/ipa1u",
182
537
     "ctpc/ipa2l", "ctpsw/ipa2u", "dbpc/ipa3l", "dbpsw/ipa3u", "ctbp/dpa0l",
183
537
     "dir/dpa0u", "bpc/dpa0u", "asid/dpa1l",
184
537
     "bpav/dpa1u", "bpam/dpa2l", "bpdv/dpa2u", "bpdm/dpa3l", "eiwr/dpa3u",
185
537
     "fewr", "dbwr", "bsel"
186
537
    };
187
188
537
  if (reg < ARRAY_SIZE (v850_sreg_names))
189
144
    return v850_sreg_names[reg];
190
393
  return _("<invalid s-reg number>");
191
537
}
192
193
static const char *
194
get_v850_reg_name (unsigned int reg)
195
532k
{
196
532k
  static const char *const v850_reg_names[] =
197
532k
    {
198
532k
     "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7",
199
532k
     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
200
532k
     "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
201
532k
     "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp"
202
532k
    };
203
204
532k
  if (reg < ARRAY_SIZE (v850_reg_names))
205
532k
    return v850_reg_names[reg];
206
0
  return _("<invalid reg number>");
207
532k
}
208
209
static const char *
210
get_v850_vreg_name (unsigned int reg)
211
589
{
212
589
  static const char *const v850_vreg_names[] =
213
589
    {
214
589
     "vr0", "vr1", "vr2", "vr3", "vr4", "vr5", "vr6", "vr7", "vr8", "vr9",
215
589
     "vr10", "vr11", "vr12", "vr13", "vr14", "vr15", "vr16", "vr17", "vr18",
216
589
     "vr19", "vr20", "vr21", "vr22", "vr23", "vr24", "vr25", "vr26", "vr27",
217
589
     "vr28", "vr29", "vr30", "vr31"
218
589
    };
219
220
589
  if (reg < ARRAY_SIZE (v850_vreg_names))
221
589
    return v850_vreg_names[reg];
222
0
  return _("<invalid v-reg number>");
223
589
}
224
225
static const char *
226
get_v850_cc_name (unsigned int reg)
227
661
{
228
661
  static const char *const v850_cc_names[] =
229
661
    {
230
661
     "v", "c/l", "z", "nh", "s/n", "t", "lt", "le",
231
661
     "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt"
232
661
    };
233
234
661
  if (reg < ARRAY_SIZE (v850_cc_names))
235
661
    return v850_cc_names[reg];
236
0
  return _("<invalid CC-reg number>");
237
661
}
238
239
static const char *
240
get_v850_float_cc_name (unsigned int reg)
241
13
{
242
13
  static const char *const v850_float_cc_names[] =
243
13
    {
244
13
     "f/t", "un/or", "eq/neq", "ueq/ogl", "olt/uge", "ult/oge", "ole/ugt", "ule/ogt",
245
13
     "sf/st", "ngle/gle", "seq/sne", "ngl/gl", "lt/nlt", "nge/ge", "le/nle", "ngt/gt"
246
13
    };
247
248
13
  if (reg < ARRAY_SIZE (v850_float_cc_names))
249
13
    return v850_float_cc_names[reg];
250
0
  return _("<invalid float-CC-reg number>");
251
13
}
252
253
static const char *
254
get_v850_cacheop_name (unsigned int reg)
255
211
{
256
211
  static const char *const v850_cacheop_names[] =
257
211
    {
258
211
     "chbii", "cibii", "cfali", "cisti", "cildi", "chbid", "chbiwbd",
259
211
     "chbwbd", "cibid", "cibiwbd", "cibwbd", "cfald", "cistd", "cildd"
260
211
    };
261
262
211
  if (reg < ARRAY_SIZE (v850_cacheop_names))
263
211
    return v850_cacheop_names[reg];
264
0
  return _("<invalid cacheop number>");
265
211
}
266
267
static const char *
268
get_v850_prefop_name (unsigned int reg)
269
322
{
270
322
  static const char *const v850_prefop_names[] =
271
322
    { "prefi", "prefd" };
272
273
322
  if (reg < ARRAY_SIZE (v850_prefop_names))
274
322
    return v850_prefop_names[reg];
275
0
  return _("<invalid prefop number>");
276
322
}
277
278
static int
279
disassemble (bfd_vma memaddr,
280
       struct disassemble_info *info,
281
       int bytes_read,
282
       unsigned long insn)
283
439k
{
284
439k
  struct v850_opcode *op = (struct v850_opcode *) v850_opcodes;
285
439k
  const struct v850_operand *operand;
286
439k
  int match = 0;
287
439k
  int target_processor;
288
289
439k
  switch (info->mach)
290
439k
    {
291
10.4k
    case 0:
292
10.4k
    default:
293
10.4k
      target_processor = PROCESSOR_V850;
294
10.4k
      break;
295
296
3.58k
    case bfd_mach_v850e:
297
3.58k
      target_processor = PROCESSOR_V850E;
298
3.58k
      break;
299
300
1.50k
    case bfd_mach_v850e1:
301
1.50k
      target_processor = PROCESSOR_V850E;
302
1.50k
      break;
303
304
66.9k
    case bfd_mach_v850e2:
305
66.9k
      target_processor = PROCESSOR_V850E2;
306
66.9k
      break;
307
308
48.5k
    case bfd_mach_v850e2v3:
309
48.5k
      target_processor = PROCESSOR_V850E2V3;
310
48.5k
      break;
311
312
308k
    case bfd_mach_v850e3v5:
313
308k
      target_processor = PROCESSOR_V850E3V5;
314
308k
      break;
315
439k
    }
316
317
  /* If this is a two byte insn, then mask off the high bits.  */
318
439k
  if (bytes_read == 2)
319
333k
    insn &= 0xffff;
320
321
  /* Find the opcode.  */
322
90.8M
  while (op->name)
323
90.8M
    {
324
90.8M
      if ((op->mask & insn) == op->opcode
325
90.8M
    && (op->processors & target_processor)
326
90.8M
    && !(op->processors & PROCESSOR_OPTION_ALIAS))
327
502k
  {
328
    /* Code check start.  */
329
502k
    const unsigned char *opindex_ptr;
330
502k
    unsigned int opnum;
331
502k
    unsigned int memop;
332
333
502k
    for (opindex_ptr = op->operands, opnum = 1;
334
1.48M
         *opindex_ptr != 0;
335
984k
         opindex_ptr++, opnum++)
336
1.06M
      {
337
1.06M
        int invalid = 0;
338
1.06M
        long value;
339
340
1.06M
        operand = &v850_operands[*opindex_ptr];
341
342
1.06M
        value = get_operand_value (operand, insn, bytes_read, memaddr,
343
1.06M
           info, 1, &invalid);
344
345
1.06M
        if (invalid)
346
63
    goto next_opcode;
347
348
1.06M
              if ((operand->flags & V850_NOT_R0) && value == 0 && (op->memop) <=2)
349
76.6k
    goto next_opcode;
350
351
985k
        if ((operand->flags & V850_NOT_SA) && value == 0xd)
352
73
    goto next_opcode;
353
354
985k
        if ((operand->flags & V850_NOT_IMM0) && value == 0)
355
219
    goto next_opcode;
356
985k
      }
357
358
    /* Code check end.  */
359
360
425k
    match = 1;
361
425k
    (*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
425k
    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
425k
    for (opindex_ptr = op->operands, opnum = 1;
382
1.33M
         *opindex_ptr != 0;
383
906k
         opindex_ptr++, opnum++)
384
906k
      {
385
906k
        bool square = false;
386
906k
        long value;
387
906k
        int flag;
388
906k
        char *prefix;
389
390
906k
        operand = &v850_operands[*opindex_ptr];
391
392
906k
        value = get_operand_value (operand, insn, bytes_read, memaddr,
393
906k
           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
906k
        prefix = "";
419
906k
        if (operand->flags & V850_OPERAND_BANG)
420
0
    {
421
0
      prefix = "!";
422
0
    }
423
906k
        else if (operand->flags & V850_OPERAND_PERCENT)
424
0
    {
425
0
      prefix = "%";
426
0
    }
427
428
906k
        if (opnum == 1 && opnum == memop)
429
2.89k
    {
430
2.89k
      info->fprintf_func (info->stream, "%s[", prefix);
431
2.89k
      square = true;
432
2.89k
    }
433
903k
        else if (   (strcmp ("stc.w", op->name) == 0
434
903k
      || strcmp ("cache", op->name) == 0
435
903k
      || strcmp ("pref",  op->name) == 0)
436
903k
           && opnum == 2 && opnum == memop)
437
1.31k
    {
438
1.31k
      info->fprintf_func (info->stream, ", [");
439
1.31k
      square = true;
440
1.31k
    }
441
902k
        else if (   (strcmp (op->name, "pushsp") == 0
442
902k
      || strcmp (op->name, "popsp") == 0
443
902k
      || strcmp (op->name, "dbpush" ) == 0)
444
902k
           && opnum == 2)
445
202
    {
446
202
      info->fprintf_func (info->stream, "-");
447
202
    }
448
901k
        else if (opnum > 1
449
901k
           && (v850_operands[*(opindex_ptr - 1)].flags
450
531k
         & V850_OPERAND_DISP) != 0
451
901k
           && opnum == memop)
452
159k
    {
453
159k
      info->fprintf_func (info->stream, "%s[", prefix);
454
159k
      square = true;
455
159k
    }
456
742k
        else if (opnum == 2
457
742k
           && (   op->opcode == 0x00e407e0 /* clr1 */
458
230k
         || op->opcode == 0x00e207e0 /* not1 */
459
230k
         || op->opcode == 0x00e007e0 /* set1 */
460
230k
         || op->opcode == 0x00e607e0 /* tst1 */
461
230k
         ))
462
415
    {
463
415
      info->fprintf_func (info->stream, ", %s[", prefix);
464
415
      square = true;
465
415
    }
466
742k
        else if (opnum > 1)
467
371k
    info->fprintf_func (info->stream, ", %s", prefix);
468
469
        /* Extract the flags, ignoring ones which do not
470
     effect disassembly output.  */
471
906k
        flag = operand->flags & (V850_OPERAND_REG
472
906k
               | V850_REG_EVEN
473
906k
               | V850_OPERAND_EP
474
906k
               | V850_OPERAND_SRG
475
906k
               | V850E_OPERAND_REG_LIST
476
906k
               | V850_OPERAND_CC
477
906k
               | V850_OPERAND_VREG
478
906k
               | V850_OPERAND_CACHEOP
479
906k
               | V850_OPERAND_PREFOP
480
906k
               | V850_OPERAND_FLOAT_CC);
481
482
906k
        switch (flag)
483
906k
    {
484
520k
    case V850_OPERAND_REG:
485
520k
      info->fprintf_func (info->stream, "%s", get_v850_reg_name (value));
486
520k
      break;
487
446
    case (V850_OPERAND_REG|V850_REG_EVEN):
488
446
      info->fprintf_func (info->stream, "%s", get_v850_reg_name (value * 2));
489
446
      break;
490
108k
    case V850_OPERAND_EP:
491
108k
      info->fprintf_func (info->stream, "ep");
492
108k
      break;
493
537
    case V850_OPERAND_SRG:
494
537
      info->fprintf_func (info->stream, "%s", get_v850_sreg_name (value));
495
537
      break;
496
2.63k
    case V850E_OPERAND_REG_LIST:
497
2.63k
      {
498
2.63k
        static int list12_regs[32]   = { 30, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
499
2.63k
                 0,  0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
500
2.63k
        int *regs;
501
2.63k
        int i;
502
2.63k
        unsigned int mask = 0;
503
2.63k
        int pc = 0;
504
505
2.63k
        switch (operand->shift)
506
2.63k
          {
507
2.63k
          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
2.63k
          }
514
515
86.8k
        for (i = 0; i < 32; i++)
516
84.2k
          {
517
84.2k
      if (value & (1u << i))
518
14.5k
        {
519
14.5k
          switch (regs[ i ])
520
14.5k
            {
521
14.5k
            default:
522
14.5k
        mask |= (1u << regs[ i ]);
523
14.5k
        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
14.5k
            }
533
14.5k
        }
534
84.2k
          }
535
536
2.63k
        info->fprintf_func (info->stream, "{");
537
538
2.63k
        if (mask || pc)
539
2.52k
          {
540
2.52k
      if (mask)
541
2.52k
        {
542
2.52k
          unsigned int bit;
543
2.52k
          int shown_one = 0;
544
545
69.8k
          for (bit = 0; bit < 32; bit++)
546
67.2k
            if (mask & (1u << bit))
547
7.67k
        {
548
7.67k
          unsigned int first = bit;
549
7.67k
          unsigned int last;
550
551
7.67k
          if (shown_one)
552
5.14k
            info->fprintf_func (info->stream, ", ");
553
2.52k
          else
554
2.52k
            shown_one = 1;
555
556
7.67k
          info->fprintf_func (info->stream, "%s", get_v850_reg_name (first));
557
558
14.5k
          for (bit++; bit < 32; bit++)
559
13.4k
            if ((mask & (1u << bit)) == 0)
560
6.61k
              break;
561
562
7.67k
          last = bit;
563
564
7.67k
          if (last > first + 1)
565
3.64k
            {
566
3.64k
              info->fprintf_func (info->stream, " - %s", get_v850_reg_name (last - 1));
567
3.64k
            }
568
7.67k
        }
569
2.52k
        }
570
571
2.52k
      if (pc)
572
0
        info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
573
2.52k
          }
574
575
2.63k
        info->fprintf_func (info->stream, "}");
576
2.63k
      }
577
0
      break;
578
579
661
    case V850_OPERAND_CC:
580
661
      info->fprintf_func (info->stream, "%s", get_v850_cc_name (value));
581
661
      break;
582
583
13
    case V850_OPERAND_FLOAT_CC:
584
13
      info->fprintf_func (info->stream, "%s", get_v850_float_cc_name (value));
585
13
      break;
586
587
392
    case V850_OPERAND_CACHEOP:
588
392
      {
589
392
        int idx;
590
591
4.51k
        for (idx = 0; v850_cacheop_codes[idx] != -1; idx++)
592
4.33k
          {
593
4.33k
      if (value == v850_cacheop_codes[idx])
594
211
        {
595
211
          info->fprintf_func (info->stream, "%s",
596
211
            get_v850_cacheop_name (idx));
597
211
          goto MATCH_CACHEOP_CODE;
598
211
        }
599
4.33k
          }
600
181
        info->fprintf_func (info->stream, "%d", (int) value);
601
181
      }
602
392
    MATCH_CACHEOP_CODE:
603
392
      break;
604
605
921
    case V850_OPERAND_PREFOP:
606
921
      {
607
921
        int idx;
608
609
2.17k
        for (idx = 0; v850_prefop_codes[idx] != -1; idx++)
610
1.57k
          {
611
1.57k
      if (value == v850_prefop_codes[idx])
612
322
        {
613
322
          info->fprintf_func (info->stream, "%s",
614
322
            get_v850_prefop_name (idx));
615
322
          goto MATCH_PREFOP_CODE;
616
322
        }
617
1.57k
          }
618
599
        info->fprintf_func (info->stream, "%d", (int) value);
619
599
      }
620
921
    MATCH_PREFOP_CODE:
621
921
      break;
622
623
589
    case V850_OPERAND_VREG:
624
589
      info->fprintf_func (info->stream, "%s", get_v850_vreg_name (value));
625
589
      break;
626
627
271k
    default:
628
271k
      print_value (operand->flags, memaddr, info, value);
629
271k
      break;
630
906k
    }
631
632
906k
        if (square)
633
163k
    (*info->fprintf_func) (info->stream, "]");
634
906k
      }
635
636
    /* All done. */
637
425k
    break;
638
425k
  }
639
90.4M
    next_opcode:
640
90.4M
      op++;
641
90.4M
    }
642
643
439k
  return match;
644
439k
}
645
646
int
647
print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
648
439k
{
649
439k
  int status, status2, match;
650
439k
  bfd_byte buffer[8];
651
439k
  int length = 0, code_length = 0;
652
439k
  unsigned long insn = 0, insn2 = 0;
653
439k
  int target_processor;
654
655
439k
  switch (info->mach)
656
439k
    {
657
10.5k
    case 0:
658
10.5k
    default:
659
10.5k
      target_processor = PROCESSOR_V850;
660
10.5k
      break;
661
662
3.58k
    case bfd_mach_v850e:
663
3.58k
      target_processor = PROCESSOR_V850E;
664
3.58k
      break;
665
666
1.50k
    case bfd_mach_v850e1:
667
1.50k
      target_processor = PROCESSOR_V850E;
668
1.50k
      break;
669
670
66.9k
    case bfd_mach_v850e2:
671
66.9k
      target_processor = PROCESSOR_V850E2;
672
66.9k
      break;
673
674
48.5k
    case bfd_mach_v850e2v3:
675
48.5k
      target_processor = PROCESSOR_V850E2V3;
676
48.5k
      break;
677
678
308k
    case bfd_mach_v850e3v5:
679
308k
      target_processor = PROCESSOR_V850E3V5;
680
308k
      break;
681
439k
    }
682
683
439k
  status = info->read_memory_func (memaddr, buffer, 2, info);
684
685
439k
  if (status)
686
125
    {
687
125
      info->memory_error_func (status, memaddr, info);
688
125
      return -1;
689
125
    }
690
691
439k
  insn = bfd_getl16 (buffer);
692
693
439k
  status2 = info->read_memory_func (memaddr+2, buffer, 2 , info);
694
695
439k
  if (!status2)
696
439k
    {
697
439k
      insn2 = bfd_getl16 (buffer);
698
      /* fprintf (stderr, "insn2 0x%08lx\n", insn2); */
699
439k
    }
700
701
  /* Special case.  */
702
439k
  if (length == 0
703
439k
      && ((target_processor & PROCESSOR_V850E2_UP) != 0))
704
424k
    {
705
424k
      if ((insn & 0xffff) == 0x02e0    /* jr 32bit */
706
424k
    && !status2 && (insn2 & 0x1) == 0)
707
12
  {
708
12
    length = 2;
709
12
    code_length = 6;
710
12
  }
711
424k
      else if ((insn & 0xffe0) == 0x02e0  /* jarl 32bit */
712
424k
         && !status2 && (insn2 & 0x1) == 0)
713
418
  {
714
418
    length = 2;
715
418
    code_length = 6;
716
418
  }
717
423k
      else if ((insn & 0xffe0) == 0x06e0  /* jmp 32bit */
718
423k
         && !status2 && (insn2 & 0x1) == 0)
719
340
  {
720
340
    length = 2;
721
340
    code_length = 6;
722
340
  }
723
424k
    }
724
725
439k
  if (length == 0
726
439k
      && ((target_processor & PROCESSOR_V850E3V5_UP) != 0))
727
308k
    {
728
308k
      if (   ((insn & 0xffe0) == 0x07a0    /* ld.dw 23bit (v850e3v5) */
729
308k
        && !status2 && (insn2 & 0x000f) == 0x0009)
730
308k
    || ((insn & 0xffe0) == 0x07a0    /* st.dw 23bit (v850e3v5) */
731
308k
        && !status2 && (insn2 & 0x000f) == 0x000f))
732
526
  {
733
526
    length = 4;
734
526
    code_length = 6;
735
526
  }
736
308k
    }
737
738
439k
  if (length == 0
739
439k
      && ((target_processor & PROCESSOR_V850E2V3_UP) != 0))
740
356k
    {
741
356k
      if (((insn & 0xffe0) == 0x0780    /* ld.b 23bit */
742
356k
     && !status2 && (insn2 & 0x000f) == 0x0005)
743
356k
    || ((insn & 0xffe0) == 0x07a0    /* ld.bu 23bit */
744
355k
        && !status2 && (insn2 & 0x000f) == 0x0005)
745
356k
    || ((insn & 0xffe0) == 0x0780    /* ld.h 23bit */
746
355k
        && !status2 && (insn2 & 0x000f) == 0x0007)
747
356k
    || ((insn & 0xffe0) == 0x07a0    /* ld.hu 23bit */
748
355k
        && !status2 && (insn2 & 0x000f) == 0x0007)
749
356k
    || ((insn & 0xffe0) == 0x0780    /* ld.w 23bit */
750
355k
        && !status2 && (insn2 & 0x000f) == 0x0009))
751
962
  {
752
962
    length = 4;
753
962
    code_length = 6;
754
962
  }
755
355k
      else if (((insn & 0xffe0) == 0x0780  /* st.b 23bit */
756
355k
         && !status2 && (insn2 & 0x000f) == 0x000d)
757
355k
        || ((insn & 0xffe0) == 0x07a0  /* st.h 23bit */
758
354k
      && !status2 && (insn2 & 0x000f) == 0x000d)
759
355k
        || ((insn & 0xffe0) == 0x0780  /* st.w 23bit */
760
354k
      && !status2 && (insn2 & 0x000f) == 0x000f))
761
1.10k
  {
762
1.10k
    length = 4;
763
1.10k
    code_length = 6;
764
1.10k
  }
765
356k
    }
766
767
439k
  if (length == 0
768
439k
      && target_processor != PROCESSOR_V850)
769
425k
    {
770
425k
      if ((insn & 0xffe0) == 0x0620)    /* 32 bit MOV */
771
138
  {
772
138
    length = 2;
773
138
    code_length = 6;
774
138
  }
775
425k
      else if ((insn & 0xffc0) == 0x0780  /* prepare {list}, imm5, imm16<<16 */
776
425k
         && !status2 && (insn2 & 0x001f) == 0x0013)
777
10
  {
778
10
    length = 4;
779
10
    code_length = 6;
780
10
  }
781
425k
      else if ((insn & 0xffc0) == 0x0780  /* prepare {list}, imm5, imm16 */
782
425k
         && !status2 && (insn2 & 0x001f) == 0x000b)
783
373
  {
784
373
    length = 4;
785
373
    code_length = 6;
786
373
  }
787
425k
      else if ((insn & 0xffc0) == 0x0780  /* prepare {list}, imm5, imm32 */
788
425k
         && !status2 && (insn2 & 0x001f) == 0x001b)
789
74
  {
790
74
    length = 4;
791
74
    code_length = 8;
792
74
  }
793
425k
    }
794
795
439k
  if (length == 4
796
439k
      || (length == 0
797
436k
    && (insn & 0x0600) == 0x0600))
798
106k
    {
799
      /* This is a 4 byte insn.  */
800
106k
      status = info->read_memory_func (memaddr, buffer, 4, info);
801
106k
      if (!status)
802
106k
  {
803
106k
    insn = bfd_getl32 (buffer);
804
805
106k
    if (!length)
806
103k
      length = code_length = 4;
807
106k
  }
808
106k
    }
809
810
439k
  if (code_length > length)
811
3.95k
    {
812
3.95k
      status = info->read_memory_func (memaddr + length, buffer, code_length - length, info);
813
3.95k
      if (status)
814
9
  length = 0;
815
3.95k
    }
816
817
439k
  if (length == 0 && !status)
818
332k
    length = code_length = 2;
819
820
439k
  if (length == 2)
821
333k
    insn &= 0xffff;
822
823
  /* when the last 2 bytes of section is 0xffff, length will be 0 and cause infinitive loop */
824
439k
  if (length == 0)
825
14
    return -1;
826
827
439k
  match = disassemble (memaddr, info, length, insn);
828
829
439k
  if (!match)
830
14.7k
    {
831
14.7k
      int l = 0;
832
833
14.7k
      status = info->read_memory_func (memaddr, buffer, code_length, info);
834
835
30.0k
      while (l < code_length)
836
15.2k
  {
837
15.2k
    if (code_length - l == 2)
838
8.72k
      {
839
8.72k
        insn = bfd_getl16 (buffer + l) & 0xffff;
840
8.72k
        info->fprintf_func (info->stream, ".short\t0x%04lx", insn);
841
8.72k
        l += 2;
842
8.72k
      }
843
6.56k
    else
844
6.56k
      {
845
6.56k
        insn = bfd_getl32 (buffer + l);
846
6.56k
        info->fprintf_func (info->stream, ".long\t0x%08lx", insn);
847
6.56k
        l += 4;
848
6.56k
      }
849
15.2k
  }
850
14.7k
    }
851
852
439k
  return code_length;
853
439k
}