Coverage Report

Created: 2026-07-12 09:22

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