Coverage Report

Created: 2025-06-24 06:45

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