Coverage Report

Created: 2026-09-14 08:07

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