Coverage Report

Created: 2026-07-25 10:20

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