Coverage Report

Created: 2026-03-10 08:46

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