Coverage Report

Created: 2026-04-04 08:16

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