Coverage Report

Created: 2026-10-02 09:53

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