Coverage Report

Created: 2026-04-04 08:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/opcodes/csky-dis.c
Line
Count
Source
1
/* C-SKY disassembler.
2
   Copyright (C) 1988-2026 Free Software Foundation, Inc.
3
   Contributed by C-SKY Microsystems and Mentor Graphics.
4
5
   This file is part of the GNU opcodes library.
6
7
   This library is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
12
   It is distributed in the hope that it will be useful, but WITHOUT
13
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15
   License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
22
#include "sysdep.h"
23
#include "config.h"
24
#include <stdio.h>
25
#include <stdint.h>
26
#include <elf/csky.h>
27
#include "disassemble.h"
28
#include "elf-bfd.h"
29
#include "opcode/csky.h"
30
#include "libiberty.h"
31
#include "csky-opc.h"
32
#include "floatformat.h"
33
34
652k
#define CSKY_INST_TYPE unsigned long
35
166M
#define HAS_SUB_OPERAND (unsigned int)0xffffffff
36
932
#define CSKY_DEFAULT_ISA 0xffffffff
37
38
enum sym_type
39
{
40
  CUR_TEXT,
41
  CUR_DATA
42
};
43
44
struct csky_dis_info
45
{
46
  /* Mem to disassemble.  */
47
  bfd_vma mem;
48
  /* Disassemble info.  */
49
  disassemble_info *info;
50
  /* Opcode information.  */
51
  struct csky_opcode_info const *opinfo;
52
  uint64_t isa;
53
  /* The value of operand to show.  */
54
  int value;
55
  /* Whether to look up/print a symbol name.  */
56
  int need_output_symbol;
57
} dis_info;
58
59
60
enum sym_type last_type;
61
int last_map_sym = 1;
62
bfd_vma last_map_addr = 0;
63
int using_abi = 0;
64
65
/* Only for objdump tool.  */
66
1.54M
#define INIT_MACH_FLAG  0xffffffff
67
1.95M
#define BINARY_MACH_FLAG 0x0
68
69
static unsigned int mach_flag = INIT_MACH_FLAG;
70
71
static void
72
print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
73
     struct disassemble_info *info,
74
     long given)
75
0
{
76
0
  switch (info->bytes_per_chunk)
77
0
    {
78
0
    case 1:
79
0
      info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
80
0
      break;
81
0
    case 2:
82
0
      info->fprintf_func (info->stream, ".short\t0x%04lx", given);
83
0
      break;
84
0
    case 4:
85
0
      info->fprintf_func (info->stream, ".long\t0x%08lx", given);
86
0
      break;
87
0
    default:
88
0
      abort ();
89
0
    }
90
0
}
91
92
static int
93
get_sym_code_type (struct disassemble_info *info,
94
       int n,
95
       enum sym_type *sym_type)
96
0
{
97
0
  const char *name;
98
0
  name = bfd_asymbol_name (info->symtab[n]);
99
0
  if (name[0] == '$' && (name[1] == 't' || name[1] == 'd')
100
0
      && (name[2] == 0 || name[2] == '.'))
101
0
    {
102
0
      *sym_type = ((name[1] == 't') ? CUR_TEXT : CUR_DATA);
103
0
      return true;
104
0
    }
105
0
  return false;
106
0
}
107
108
static int
109
csky_get_operand_mask (struct operand const *oprnd)
110
165M
{
111
165M
  int mask = 0;
112
165M
  if (oprnd->mask == HAS_SUB_OPERAND)
113
7.78M
    {
114
7.78M
      struct soperand *sop = (struct soperand *)oprnd;
115
7.78M
      mask |= csky_get_operand_mask (&sop->subs[0]);
116
7.78M
      mask |= csky_get_operand_mask (&sop->subs[1]);
117
7.78M
      return mask;
118
7.78M
    }
119
157M
  return oprnd->mask;
120
165M
}
121
122
static int
123
csky_get_mask (struct csky_opcode_info const *pinfo)
124
372M
{
125
372M
  int i = 0;
126
372M
  int mask = 0;
127
  /* List type.  */
128
372M
  if (pinfo->operand_num == -1)
129
1.10M
    mask |= csky_get_operand_mask (&pinfo->oprnd.oprnds[i]);
130
371M
  else
131
520M
    for (; i < pinfo->operand_num; i++)
132
148M
      mask |= csky_get_operand_mask (&pinfo->oprnd.oprnds[i]);
133
134
372M
  mask = ~mask;
135
372M
  return mask;
136
372M
}
137
138
static unsigned int
139
csky_chars_to_number (unsigned char * buf, int n)
140
59.4k
{
141
59.4k
  int i;
142
59.4k
  unsigned int val = 0;
143
144
59.4k
  if (dis_info.info->endian == BFD_ENDIAN_BIG)
145
173k
    for (i = 0; i < n; i++)
146
139k
      val = val << 8 | buf[i];
147
24.6k
  else
148
123k
    for (i = n - 1; i >= 0; i--)
149
98.7k
      val = val << 8 | buf[i];
150
59.4k
  return val;
151
59.4k
}
152
153
static struct csky_opcode const *g_opcodeP;
154
155
static struct csky_opcode const *
156
csky_find_inst_info (struct csky_opcode_info const **pinfo,
157
         CSKY_INST_TYPE inst, int length)
158
652k
{
159
652k
  int i;
160
652k
  unsigned int mask;
161
652k
  struct csky_opcode const *p;
162
163
652k
  p = g_opcodeP;
164
215M
  while (p->mnemonic)
165
215M
    {
166
215M
  if (!(p->isa_flag16 & dis_info.isa)
167
172M
        && !(p->isa_flag32 & dis_info.isa))
168
28.4M
  {
169
28.4M
    p++;
170
28.4M
    continue;
171
28.4M
  }
172
173
      /* Get the opcode mask.  */
174
559M
      for (i = 0; i < OP_TABLE_NUM; i++)
175
372M
  if (length == 2)
176
335M
    {
177
335M
      mask =  csky_get_mask (&p->op16[i]);
178
335M
      if (mask != 0 && (inst & mask) == p->op16[i].opcode)
179
555k
        {
180
555k
    *pinfo = &p->op16[i];
181
555k
    g_opcodeP = p;
182
555k
    return p;
183
555k
        }
184
335M
    }
185
37.5M
  else if (length == 4)
186
37.5M
    {
187
37.5M
      mask =  csky_get_mask (&p->op32[i]);
188
37.5M
      if (mask != 0
189
37.5M
    && ((unsigned long)(inst & mask)
190
37.5M
        == (unsigned long)p->op32[i].opcode))
191
16.0k
        {
192
16.0k
    *pinfo = &p->op32[i];
193
16.0k
    g_opcodeP = p;
194
16.0k
    return p;
195
16.0k
        }
196
37.5M
    }
197
186M
      p++;
198
186M
    }
199
200
81.8k
  return NULL;
201
652k
}
202
203
static bool
204
is_extern_symbol (struct disassemble_info *info, bfd_vma addr)
205
52.5k
{
206
52.5k
  if (info->section != NULL && info->section->relocation != NULL)
207
0
    {
208
0
      unsigned int rel_count = 0;
209
0
      struct reloc_cache_entry *pt = info->section->relocation;
210
0
      for (; rel_count < info->section->reloc_count; rel_count++, pt++)
211
0
  if (addr == pt->address)
212
0
    return true;
213
0
    }
214
52.5k
  return false;
215
52.5k
}
216
217
218
/* Suppress printing of mapping symbols emitted by the assembler to mark
219
   the beginning of code and data sequences.  */
220
221
bool
222
csky_symbol_is_valid (asymbol *sym,
223
          struct disassemble_info *info ATTRIBUTE_UNUSED)
224
0
{
225
0
  const char *name;
226
227
0
  if (sym == NULL)
228
0
    return false;
229
0
  name = bfd_asymbol_name (sym);
230
0
  return name && *name != '$';
231
0
}
232
233
disassembler_ftype
234
csky_get_disassembler (bfd *abfd)
235
930
{
236
930
  obj_attribute *attr;
237
930
  const char *sec_name = NULL;
238
930
  if (!abfd || bfd_get_flavour (abfd) != bfd_target_elf_flavour)
239
832
    dis_info.isa = CSKY_DEFAULT_ISA;
240
98
  else
241
98
    {
242
98
      mach_flag = elf_elfheader (abfd)->e_flags;
243
244
98
      sec_name = get_elf_backend_data (abfd)->obj_attrs_section;
245
      /* Skip any input that hasn't attribute section.
246
         This enables to link object files without attribute section with
247
         any others.  */
248
98
      if (bfd_get_section_by_name (abfd, sec_name) != NULL)
249
0
        {
250
0
          attr = elf_known_obj_attributes_proc (abfd);
251
0
          dis_info.isa = attr[Tag_CSKY_ISA_EXT_FLAGS].i;
252
0
          dis_info.isa <<= 32;
253
0
          dis_info.isa |= attr[Tag_CSKY_ISA_FLAGS].i;
254
0
        }
255
98
      else
256
98
        dis_info.isa = CSKY_DEFAULT_ISA;
257
98
    }
258
259
930
   return print_insn_csky;
260
930
}
261
262
/* Parse a disassembler option.  */
263
static bool
264
parse_csky_option (const char *opt, void *data ATTRIBUTE_UNUSED)
265
2.72k
{
266
2.72k
  if (strcmp (opt, "abi-names") == 0)
267
140
    using_abi = 1;
268
2.58k
  else
269
2.58k
    fprintf (stderr, "unrecognized disassembler option: %s", opt);
270
2.72k
  return true;
271
2.72k
}
272
273
/* Get general register name.  */
274
static const char *
275
get_gr_name (int regno)
276
698k
{
277
698k
  return csky_get_general_reg_name (mach_flag, regno, using_abi);
278
698k
}
279
280
/* Get control register name.  */
281
static const char *
282
get_cr_name (unsigned int regno, int bank)
283
3.00k
{
284
3.00k
  return csky_get_control_reg_name (mach_flag, bank, regno, using_abi);
285
3.00k
}
286
287
static int
288
csky_output_operand (char *str, struct operand const *oprnd,
289
         CSKY_INST_TYPE inst, int reloc ATTRIBUTE_UNUSED)
290
1.08M
{
291
1.08M
  int ret = 0;;
292
1.08M
  int bit = 0;
293
1.08M
  int result = 0;
294
1.08M
  bfd_vma value;
295
1.08M
  int mask = oprnd->mask;
296
1.08M
  int max = 0;
297
1.08M
  char buf[128];
298
299
  /* Get operand value with mask.  */
300
1.08M
  value = inst & mask;
301
9.98M
  for (; mask; mask >>= 1, value >>=1)
302
8.89M
    if (mask & 0x1)
303
4.97M
      {
304
4.97M
  result |= ((value & 0x1) << bit);
305
4.97M
  max |= (1 << bit);
306
4.97M
  bit++;
307
4.97M
      }
308
1.08M
  value = result;
309
310
  /* Here is general instructions that have no reloc.  */
311
1.08M
  switch (oprnd->type)
312
1.08M
    {
313
3.03k
    case OPRND_TYPE_CTRLREG:
314
3.03k
  if (IS_CSKY_V1(mach_flag) && ((value & 0x1f) == 0x1f))
315
30
    return -1;
316
3.00k
  strcat (str, get_cr_name((value & 0x1f), (value >> 5)));
317
3.00k
  break;
318
22.9k
    case OPRND_TYPE_DUMMY_REG:
319
22.9k
      mask = dis_info.opinfo->oprnd.oprnds[0].mask;
320
22.9k
      value = inst & mask;
321
114k
      for (; mask; mask >>= 1, value >>=1)
322
91.6k
  if (mask & 0x1)
323
91.6k
    {
324
91.6k
      result |= ((value & 0x1) << bit);
325
91.6k
      bit++;
326
91.6k
    }
327
22.9k
      value = result;
328
22.9k
      strcat (str, get_gr_name (value));
329
22.9k
      break;
330
313k
    case OPRND_TYPE_GREG0_7:
331
600k
    case OPRND_TYPE_GREG0_15:
332
600k
    case OPRND_TYPE_GREG16_31:
333
606k
    case OPRND_TYPE_REGnsplr:
334
618k
    case OPRND_TYPE_AREG:
335
618k
      strcat (str, get_gr_name (value));
336
618k
      break;
337
2.00k
    case OPRND_TYPE_CPREG:
338
2.00k
      sprintf (buf, "cpr%d", (int)value);
339
2.00k
      strcat (str, buf);
340
2.00k
      break;
341
237
    case OPRND_TYPE_FREG:
342
237
      sprintf (buf, "fr%d", (int)value);
343
237
      strcat (str, buf);
344
237
      break;
345
664
    case OPRND_TYPE_VREG:
346
664
      dis_info.value = value;
347
664
      sprintf (buf, "vr%d", (int)value);
348
664
      strcat (str, buf);
349
664
      break;
350
904
    case OPRND_TYPE_CPCREG:
351
904
      sprintf (buf, "cpcr%d", (int)value);
352
904
      strcat (str, buf);
353
904
      break;
354
1.38k
    case OPRND_TYPE_CPIDX:
355
1.38k
      sprintf (buf, "cp%d", (int)value);
356
1.38k
      strcat (str, buf);
357
1.38k
      break;
358
2.21k
    case OPRND_TYPE_IMM2b_JMPIX:
359
2.21k
      value = (value + 2) << 3;
360
2.21k
      sprintf (buf, "%d", (int)value);
361
2.21k
      strcat (str, buf);
362
2.21k
      break;
363
113k
    case OPRND_TYPE_IMM_LDST:
364
113k
    case OPRND_TYPE_IMM_FLDST:
365
113k
      value <<= oprnd->shift;
366
113k
      sprintf (buf, "0x%x", (unsigned int)value);
367
113k
      strcat (str, buf);
368
113k
      break;
369
5.94k
    case OPRND_TYPE_IMM7b_LS2:
370
14.4k
    case OPRND_TYPE_IMM8b_LS2:
371
14.4k
      sprintf (buf, "%d", (int)(value << 2));
372
14.4k
      strcat (str, buf);
373
14.4k
      ret = 0;
374
14.4k
      break;
375
792
    case OPRND_TYPE_IMM5b_BMASKI:
376
792
      if ((value != 0) && (value > 31 || value < 8))
377
143
  {
378
143
    ret = -1;
379
143
    break;
380
143
  }
381
649
      sprintf (buf, "%d", (int)value);
382
649
      strcat (str, buf);
383
649
      ret = 0;
384
649
      break;
385
2.86k
    case OPRND_TYPE_IMM5b_1_31:
386
2.86k
      if (value > 31 || value < 1)
387
87
  {
388
87
    ret = -1;
389
87
    break;
390
87
  }
391
2.77k
      sprintf (buf, "%d", (int)value);
392
2.77k
      strcat (str, buf);
393
2.77k
      ret = 0;
394
2.77k
      break;
395
1.31k
    case OPRND_TYPE_IMM5b_7_31:
396
1.31k
      if (value > 31 || value < 7)
397
360
  {
398
360
    ret = -1;
399
360
    break;
400
360
  }
401
954
      sprintf (buf, "%d", (int)value);
402
954
      strcat (str, buf);
403
954
      ret = 0;
404
954
      break;
405
7
    case OPRND_TYPE_IMM5b_VSH:
406
7
      {
407
7
  char num[128];
408
7
  value = ((value & 0x1) << 4) | (value >> 1);
409
7
  sprintf (num, "%d", (int)value);
410
7
  strcat (str, num);
411
7
  ret = 0;
412
7
  break;
413
1.31k
      }
414
7
    case OPRND_TYPE_MSB2SIZE:
415
14
    case OPRND_TYPE_LSB2SIZE:
416
14
      {
417
14
  static int size;
418
14
  if (oprnd->type == OPRND_TYPE_MSB2SIZE)
419
7
    size = value;
420
7
  else
421
7
    {
422
7
      str[strlen (str) - 2] = '\0';
423
7
      sprintf (buf, "%d, %d", (int)(size + value), (int)value);
424
7
      strcat (str, buf);
425
7
    }
426
14
  break;
427
7
      }
428
0
    case OPRND_TYPE_IMM1b:
429
601
    case OPRND_TYPE_IMM2b:
430
657
    case OPRND_TYPE_IMM4b:
431
40.6k
    case OPRND_TYPE_IMM5b:
432
40.6k
    case OPRND_TYPE_IMM5b_LS:
433
44.2k
    case OPRND_TYPE_IMM7b:
434
66.0k
    case OPRND_TYPE_IMM8b:
435
68.4k
    case OPRND_TYPE_IMM12b:
436
72.5k
    case OPRND_TYPE_IMM15b:
437
72.6k
    case OPRND_TYPE_IMM16b:
438
72.6k
    case OPRND_TYPE_IMM16b_MOVIH:
439
74.2k
    case OPRND_TYPE_IMM16b_ORI:
440
74.2k
      sprintf (buf, "%d", (int)value);
441
74.2k
      strcat (str, buf);
442
74.2k
      ret = 0;
443
74.2k
      break;
444
1.47k
    case OPRND_TYPE_OFF8b:
445
1.48k
    case OPRND_TYPE_OFF16b:
446
1.48k
      {
447
1.48k
  unsigned char ibytes[4];
448
1.48k
  int shift = oprnd->shift;
449
1.48k
  int status;
450
1.48k
  unsigned int mem_val;
451
452
1.48k
  dis_info.info->stop_vma = 0;
453
454
1.48k
  value = ((dis_info.mem + (value << shift)
455
1.48k
      + ((IS_CSKY_V1 (mach_flag)) ? 2 : 0))
456
1.48k
     & 0xfffffffc);
457
1.48k
  status = dis_info.info->read_memory_func (value, ibytes, 4,
458
1.48k
              dis_info.info);
459
1.48k
  if (status != 0)
460
170
    {
461
170
      dis_info.info->memory_error_func (status, dis_info.mem,
462
170
                dis_info.info);
463
170
      return -1;
464
170
    }
465
1.31k
  mem_val = csky_chars_to_number (ibytes, 4);
466
  /* Remove [] around literal value to match ABI syntax.  */
467
1.31k
  sprintf (buf, "0x%X", mem_val);
468
1.31k
  strcat (str, buf);
469
  /* For jmpi/jsri, we'll try to get a symbol for the target.  */
470
1.31k
  if (dis_info.info->print_address_func && mem_val != 0)
471
1.23k
    {
472
1.23k
      dis_info.value = mem_val;
473
1.23k
      dis_info.need_output_symbol = 1;
474
1.23k
    }
475
80
  else
476
80
    {
477
80
      sprintf (buf, "\t// from address pool at 0x%x",
478
80
         (unsigned int)value);
479
80
      strcat (str, buf);
480
80
    }
481
1.31k
  break;
482
1.48k
      }
483
32
    case OPRND_TYPE_BLOOP_OFF4b:
484
64
    case OPRND_TYPE_BLOOP_OFF12b:
485
24.1k
    case OPRND_TYPE_OFF11b:
486
24.6k
    case OPRND_TYPE_OFF16b_LSL1:
487
25.1k
    case OPRND_TYPE_IMM_OFF18b:
488
28.4k
    case OPRND_TYPE_OFF26b:
489
28.4k
      {
490
28.4k
  int shift = oprnd->shift;
491
28.4k
  if (value & ((max >> 1) + 1))
492
18.1k
    value |= ~max;
493
28.4k
  if (is_extern_symbol (dis_info.info, dis_info.mem))
494
0
    value = 0;
495
28.4k
  else if (IS_CSKY_V1 (mach_flag))
496
24.0k
    value = dis_info.mem + 2 + (value << shift);
497
4.32k
  else
498
4.32k
    value = dis_info.mem + (value << shift);
499
28.4k
  dis_info.need_output_symbol = 1;
500
28.4k
  dis_info.value= value;
501
28.4k
  sprintf (buf, "0x%x", (unsigned int)value);
502
28.4k
  strcat (str, buf);
503
28.4k
  break;
504
25.1k
      }
505
19.8k
    case OPRND_TYPE_CONSTANT:
506
19.8k
    case OPRND_TYPE_FCONSTANT:
507
19.8k
      {
508
19.8k
  int shift = oprnd->shift;
509
19.8k
  bfd_byte ibytes[8];
510
19.8k
  int status;
511
19.8k
  bfd_vma addr;
512
19.8k
  int nbytes;
513
514
19.8k
  dis_info.info->stop_vma = 0;
515
19.8k
  value <<= shift;
516
517
19.8k
  if (IS_CSKY_V1 (mach_flag))
518
6.04k
    addr = (dis_info.mem + 2 + value) & 0xfffffffc;
519
13.8k
  else
520
13.8k
    addr = (dis_info.mem + value) & 0xfffffffc;
521
522
19.8k
  if (oprnd->type == OPRND_TYPE_FCONSTANT
523
0
      && dis_info.opinfo->opcode != CSKYV2_INST_FLRW)
524
0
    nbytes = 8;
525
19.8k
  else
526
19.8k
    nbytes = 4;
527
528
19.8k
  status = dis_info.info->read_memory_func (addr, ibytes,
529
19.8k
              nbytes, dis_info.info);
530
19.8k
  if (status != 0)
531
    /* Address out of bounds.  -> lrw rx, [pc, 0ffset]. */
532
2.78k
    sprintf (buf, "[pc, %d]\t// from address pool at %x", (int)value,
533
2.78k
       (unsigned int)addr);
534
17.0k
  else if (oprnd->type == OPRND_TYPE_FCONSTANT)
535
0
    {
536
0
      double f;
537
538
0
      if (dis_info.opinfo->opcode == CSKYV2_INST_FLRW)
539
        /* flrws.  */
540
0
        floatformat_to_double ((dis_info.info->endian == BFD_ENDIAN_BIG
541
0
              ? &floatformat_ieee_single_big
542
0
              : &floatformat_ieee_single_little),
543
0
             ibytes, &f);
544
0
      else
545
0
        floatformat_to_double ((dis_info.info->endian == BFD_ENDIAN_BIG
546
0
              ? &floatformat_ieee_double_big
547
0
              : &floatformat_ieee_double_little),
548
0
             ibytes, &f);
549
0
      sprintf (buf, "%.7g", f);
550
0
    }
551
17.0k
  else
552
17.0k
    {
553
17.0k
      dis_info.value = addr;
554
17.0k
      dis_info.need_output_symbol = 1;
555
17.0k
      value = csky_chars_to_number (ibytes, 4);
556
17.0k
      sprintf (buf, "0x%x", (unsigned int) value);
557
17.0k
    }
558
559
19.8k
  strcat (str, buf);
560
19.8k
  break;
561
19.8k
      }
562
55.2k
    case OPRND_TYPE_ELRW_CONSTANT:
563
55.2k
      {
564
55.2k
  int shift = oprnd->shift;
565
55.2k
  char ibytes[4];
566
55.2k
  int status;
567
55.2k
  bfd_vma addr;
568
55.2k
  dis_info.info->stop_vma = 0;
569
570
55.2k
  value = 0x80 + ((~value) & 0x7f);
571
572
55.2k
  value = value << shift;
573
55.2k
  addr = (dis_info.mem + value) & 0xfffffffc;
574
575
55.2k
  status = dis_info.info->read_memory_func (addr, (bfd_byte *)ibytes,
576
55.2k
              4, dis_info.info);
577
55.2k
  if (status != 0)
578
    /* Address out of bounds.  -> lrw rx, [pc, 0ffset]. */
579
14.2k
    sprintf (buf, "[pc, %d]\t// from address pool at %x", (int) value,
580
14.2k
       (unsigned int)addr);
581
41.0k
  else
582
41.0k
    {
583
41.0k
      dis_info.value = addr;
584
41.0k
      value = csky_chars_to_number ((unsigned char *)ibytes, 4);
585
41.0k
      dis_info.need_output_symbol = 1;
586
41.0k
      sprintf (buf, "0x%x", (unsigned int)value);
587
41.0k
    }
588
589
55.2k
  strcat (str, buf);
590
55.2k
  break;
591
19.8k
      }
592
0
    case OPRND_TYPE_SFLOAT:
593
1
    case OPRND_TYPE_DFLOAT:
594
1
      {
595
  /* This is for fmovis/fmovid, which have an internal 13-bit
596
     encoding that they convert to single/double precision
597
     (respectively).  We'll convert the 13-bit encoding to an IEEE
598
     double and then to host double format to print it.
599
     Sign bit: bit 20.
600
     4-bit exponent: bits 19:16, biased by 11.
601
     8-bit mantissa: split between 24:21 and 7:4.  */
602
1
  uint64_t imm4;
603
1
  uint64_t imm8;
604
1
  uint64_t dbnum;
605
1
  unsigned char valbytes[8];
606
1
  double fvalue;
607
608
1
  imm4 = ((inst >> 16) & 0xf);
609
1
  imm4 = (uint64_t)(1023 - (imm4 - 11)) << 52;
610
611
1
  imm8 = (uint64_t)((inst >> 4) & 0xf) << 44;
612
1
  imm8 |= (uint64_t)((inst >> 21) & 0xf) << 48;
613
614
1
  dbnum = (uint64_t)((inst >> 20) & 1) << 63;
615
1
  dbnum |= imm4 | imm8;
616
617
  /* Do this a byte at a time so we don't have to
618
     worry about the host's endianness.  */
619
1
  valbytes[0] = dbnum & 0xff;
620
1
  valbytes[1] = (dbnum >> 8) & 0xff;
621
1
  valbytes[2] = (dbnum >> 16) & 0xff;
622
1
  valbytes[3] = (dbnum >> 24) & 0xff;
623
1
  valbytes[4] = (dbnum >> 32) & 0xff;
624
1
  valbytes[5] = (dbnum >> 40) & 0xff;
625
1
  valbytes[6] = (dbnum >> 48) & 0xff;
626
1
  valbytes[7] = (dbnum >> 56) & 0xff;
627
628
1
  floatformat_to_double (&floatformat_ieee_double_little, valbytes,
629
1
             &fvalue);
630
631
1
  sprintf (buf, "%.7g", fvalue);
632
1
  strcat (str, buf);
633
1
  break;
634
0
      }
635
0
    case OPRND_TYPE_HFLOAT_FMOVI:
636
0
    case OPRND_TYPE_SFLOAT_FMOVI:
637
0
      {
638
0
  int imm4;
639
0
  int imm8;
640
0
  imm4 = ((inst >> 16) & 0xf);
641
0
  imm4 = (138 - imm4) << 23;
642
643
0
  imm8 = ((inst >> 8) & 0x3);
644
0
  imm8 |= (((inst >> 20) & 0x3f) << 2);
645
0
  imm8 <<= 15;
646
647
0
  value = ((inst >> 5) & 1) << 31;
648
0
  value |= imm4 | imm8;
649
650
0
  imm4 = 138 - (imm4 >> 23);
651
0
  imm8 >>= 15;
652
0
  if ((inst >> 5) & 1)
653
0
    {
654
0
      imm8 = 0 - imm8;
655
0
    }
656
657
0
  float f = 0;
658
0
  memcpy (&f, &value, sizeof (float));
659
0
  sprintf (buf, "%.7g\t// imm9:%4d, imm4:%2d", f, imm8, imm4);
660
0
  strcat (str, buf);
661
662
0
  break;
663
0
      }
664
665
0
    case OPRND_TYPE_DFLOAT_FMOVI:
666
0
      {
667
0
  uint64_t imm4;
668
0
  uint64_t imm8;
669
0
  uint64_t dvalue;
670
0
  imm4 = ((inst >> 16) & 0xf);
671
0
  imm4 = (1034 - imm4) << 52;
672
673
0
  imm8 = ((inst >> 8) & 0x3);
674
0
  imm8 |= (((inst >> 20) & 0x3f) << 2);
675
0
  imm8 <<= 44;
676
677
0
  dvalue = (((uint64_t)inst >> 5) & 1) << 63;
678
0
  dvalue |= imm4 | imm8;
679
680
0
  imm4 = 1034 - (imm4 >> 52);
681
0
  imm8 >>= 44;
682
0
  if (inst >> 5)
683
0
    {
684
0
      imm8 = 0 - imm8;
685
0
    }
686
0
  double d = 0;
687
0
  memcpy (&d, &dvalue, sizeof (double));
688
0
  sprintf (buf, "%.7g\t// imm9:%4ld, imm4:%2ld", d, (long) imm8, (long) imm4);
689
0
  strcat (str, buf);
690
691
0
  break;
692
0
      }
693
675
    case OPRND_TYPE_LABEL_WITH_BRACKET:
694
675
      sprintf (buf, "[0x%x]", (unsigned int)value);
695
675
      strcat (str, buf);
696
675
      strcat (str, "\t// the offset is based on .data");
697
675
      break;
698
3.82k
    case OPRND_TYPE_OIMM3b:
699
3.92k
    case OPRND_TYPE_OIMM4b:
700
18.8k
    case OPRND_TYPE_OIMM5b:
701
18.8k
    case OPRND_TYPE_OIMM5b_IDLY:
702
46.3k
    case OPRND_TYPE_OIMM8b:
703
46.7k
    case OPRND_TYPE_OIMM12b:
704
46.8k
    case OPRND_TYPE_OIMM16b:
705
46.9k
    case OPRND_TYPE_OIMM18b:
706
46.9k
      value += 1;
707
46.9k
      sprintf (buf, "%d", (int)value);
708
46.9k
      strcat (str, buf);
709
46.9k
      break;
710
0
    case OPRND_TYPE_OIMM5b_BMASKI:
711
0
      if (value > 32 || value < 16)
712
0
  {
713
0
    ret = -1;
714
0
    break;
715
0
  }
716
0
      sprintf (buf, "%d", (int)(value + 1));
717
0
      strcat (str, buf);
718
0
      ret = 0;
719
0
      break;
720
25
    case OPRND_TYPE_FREGLIST_DASH:
721
25
      if (IS_CSKY_V2 (mach_flag))
722
25
  {
723
25
    int vrx = 0;
724
25
    int vry = 0;
725
25
    if (dis_info.isa & CSKY_ISA_FLOAT_7E60
726
0
        && (strstr (str, "fstm") != NULL
727
0
      || strstr (str, "fldm") != NULL))
728
0
      {
729
0
        vrx = value & 0x1f;
730
0
        vry = vrx + (value >> 5);
731
0
      }
732
25
    else
733
25
      {
734
25
        vrx = value & 0xf;
735
25
        vry = vrx + (value >> 4);
736
25
      }
737
25
    sprintf (buf, "fr%d-fr%d", vrx, vry);
738
25
    strcat (str, buf);
739
25
  }
740
25
      break;
741
651
    case OPRND_TYPE_REGLIST_DASH:
742
651
      if (IS_CSKY_V1 (mach_flag))
743
651
  {
744
651
    sprintf (buf, "%s-r15", get_gr_name (value));
745
651
    strcat (str, buf);
746
651
  }
747
0
      else
748
0
  {
749
0
    if ((value & 0x1f) + (value >> 5) > 31)
750
0
      {
751
0
        ret = -1;
752
0
        break;
753
0
      }
754
0
    strcat (str, get_gr_name ((value >> 5)));
755
0
    strcat (str, "-");
756
0
    strcat (str, get_gr_name ((value & 0x1f) + (value >> 5)));
757
0
  }
758
651
      break;
759
651
    case OPRND_TYPE_PSR_BITS_LIST:
760
26
      {
761
26
  struct psrbit const *bits;
762
26
  int first_oprnd = true;
763
26
  int i = 0;
764
26
  if (IS_CSKY_V1 (mach_flag))
765
24
    {
766
24
      if (value == 0)
767
8
        {
768
8
    strcat (str, "af");
769
8
    break;
770
8
        }
771
16
      bits = cskyv1_psr_bits;
772
16
    }
773
2
  else
774
2
    bits = cskyv2_psr_bits;
775
66
  while (value != 0 && bits[i].name != NULL)
776
48
      {
777
48
        if (value & bits[i].value)
778
44
    {
779
44
      if (!first_oprnd)
780
28
        strcat (str, ", ");
781
44
      strcat (str, bits[i].name);
782
44
      value &= ~bits[i].value;
783
44
      first_oprnd = false;
784
44
    }
785
48
        i++;
786
48
      }
787
18
  break;
788
26
      }
789
651
    case OPRND_TYPE_REGbsp:
790
651
      if (IS_CSKY_V1 (mach_flag))
791
651
  sprintf(buf, "(%s)", get_gr_name (0));
792
0
      else
793
0
  sprintf(buf, "(%s)", get_gr_name (14));
794
651
      strcat (str, buf);
795
651
      break;
796
33.0k
    case OPRND_TYPE_REGsp:
797
33.0k
      if (IS_CSKY_V1 (mach_flag))
798
0
  strcat (str, get_gr_name (0));
799
33.0k
      else
800
33.0k
  strcat (str, get_gr_name (14));
801
33.0k
      break;
802
825
    case OPRND_TYPE_REGnr4_r7:
803
853
    case OPRND_TYPE_AREG_WITH_BRACKET:
804
853
      strcat (str, "(");
805
853
      strcat (str, get_gr_name (value));
806
853
      strcat (str, ")");
807
853
      break;
808
417
    case OPRND_TYPE_AREG_WITH_LSHIFT:
809
417
      strcat (str, get_gr_name (value >> 5));
810
417
      strcat (str, " << ");
811
417
      if ((value & 0x1f) == 0x1)
812
9
  strcat (str, "0");
813
408
      else if ((value & 0x1f) == 0x2)
814
3
  strcat (str, "1");
815
405
      else if ((value & 0x1f) == 0x4)
816
36
  strcat (str, "2");
817
369
      else if ((value & 0x1f) == 0x8)
818
21
  strcat (str, "3");
819
417
      break;
820
83
    case OPRND_TYPE_AREG_WITH_LSHIFT_FPU:
821
83
      strcat (str, get_gr_name (value >> 2));
822
83
      strcat (str, " << ");
823
83
      if ((value & 0x3) == 0x0)
824
10
  strcat (str, "0");
825
73
      else if ((value & 0x3) == 0x1)
826
72
  strcat (str, "1");
827
1
      else if ((value & 0x3) == 0x2)
828
0
  strcat (str, "2");
829
1
      else if ((value & 0x3) == 0x3)
830
1
  strcat (str, "3");
831
83
      break;
832
4
    case OPRND_TYPE_VREG_WITH_INDEX:
833
4
      {
834
4
  unsigned freg_val = value & 0xf;
835
4
  unsigned index_val = (value >> 4) & 0xf;
836
4
  sprintf (buf, "vr%d[%d]", freg_val, index_val);
837
4
  strcat(str, buf);
838
4
  break;
839
825
      }
840
0
    case OPRND_TYPE_FREG_WITH_INDEX:
841
0
      {
842
0
  unsigned freg_val = value & 0xf;
843
0
  unsigned index_val = (value >> 4) & 0xf;
844
0
  sprintf (buf, "fr%d[%d]", freg_val, index_val);
845
0
  strcat(str, buf);
846
0
  break;
847
825
      }
848
825
    case OPRND_TYPE_REGr4_r7:
849
825
      if (IS_CSKY_V1 (mach_flag))
850
825
  {
851
825
    sprintf (buf, "%s-%s", get_gr_name (4), get_gr_name (7));
852
825
    strcat (str, buf);
853
825
  }
854
825
      break;
855
1.74k
    case OPRND_TYPE_CONST1:
856
1.74k
      strcat (str, "1");
857
1.74k
      break;
858
2.03k
    case OPRND_TYPE_REG_r1a:
859
2.08k
    case OPRND_TYPE_REG_r1b:
860
2.08k
      strcat (str, get_gr_name (1));
861
2.08k
      break;
862
100
    case OPRND_TYPE_REG_r28:
863
100
      strcat (str, get_gr_name (28));
864
100
      break;
865
7.90k
    case OPRND_TYPE_REGLIST_DASH_COMMA:
866
      /* 16-bit reglist.  */
867
7.90k
      if (value & 0xf)
868
6.14k
  {
869
6.14k
    strcat (str, get_gr_name (4));
870
6.14k
    if ((value & 0xf) > 1)
871
5.06k
      {
872
5.06k
        strcat (str, "-");
873
5.06k
        strcat (str, get_gr_name ((value & 0xf) + 3));
874
5.06k
      }
875
6.14k
    if (value & ~0xf)
876
5.02k
      strcat (str, ", ");
877
6.14k
  }
878
7.90k
      if (value & 0x10)
879
6.31k
  {
880
    /* r15.  */
881
6.31k
    strcat (str, get_gr_name (15));
882
6.31k
    if (value & ~0x1f)
883
0
      strcat (str, ", ");
884
6.31k
  }
885
7.90k
      if (dis_info.opinfo->oprnd.oprnds[0].mask != OPRND_MASK_0_4)
886
0
  {
887
    /* 32bits reglist.  */
888
0
    value >>= 5;
889
0
    if (value & 0x3)
890
0
      {
891
0
        strcat (str, get_gr_name (16));
892
0
        if ((value & 0x7) > 1)
893
0
    {
894
0
      strcat (str, "-");
895
0
      strcat (str, get_gr_name ((value & 0x7) + 15));
896
0
    }
897
0
        if (value & ~0x7)
898
0
    strcat (str, ", ");
899
0
        }
900
0
    if (value & 0x8)
901
      /* r15.  */
902
0
      strcat (str, get_gr_name (28));
903
0
  }
904
7.90k
      break;
905
9.61k
    case OPRND_TYPE_UNCOND10b:
906
9.93k
    case OPRND_TYPE_UNCOND16b:
907
24.0k
    case OPRND_TYPE_COND10b:
908
24.1k
    case OPRND_TYPE_COND16b:
909
24.1k
      {
910
24.1k
  int shift = oprnd->shift;
911
912
24.1k
  if (value & ((max >> 1) + 1))
913
9.65k
    value |= ~max;
914
24.1k
  if (is_extern_symbol (dis_info.info, dis_info.mem))
915
0
    value = 0;
916
24.1k
  else
917
24.1k
    value = dis_info.mem + (value << shift);
918
24.1k
  sprintf (buf, "0x%x", (unsigned int)value);
919
24.1k
  strcat (str, buf);
920
24.1k
  dis_info.need_output_symbol = 1;
921
24.1k
  dis_info.value = value;
922
24.1k
      }
923
24.1k
      break;
924
925
28
    default:
926
28
      ret = -1;
927
28
      break;
928
1.08M
    }
929
1.08M
  return ret;
930
1.08M
}
931
932
static int
933
csky_print_operand (char *str, struct operand const *oprnd,
934
        CSKY_INST_TYPE inst, int reloc)
935
1.20M
{
936
1.20M
  int ret = -1;
937
1.20M
  char *lc = "";
938
1.20M
  char *rc = "";
939
1.20M
  if (oprnd->mask == HAS_SUB_OPERAND)
940
120k
    {
941
120k
      struct soperand *sop = (struct soperand *)oprnd;
942
120k
      if (oprnd->type == OPRND_TYPE_BRACKET)
943
113k
  {
944
113k
    lc = "(";
945
113k
    rc = ")";
946
113k
  }
947
6.39k
      else if (oprnd->type == OPRND_TYPE_ABRACKET)
948
6.39k
  {
949
6.39k
    lc = "<";
950
6.39k
    rc = ">";
951
6.39k
  }
952
120k
      strcat (str, lc);
953
120k
      ret = csky_print_operand (str, &sop->subs[0], inst, reloc);
954
120k
      if (ret)
955
0
  return ret;
956
120k
      strcat (str, ", ");
957
120k
      ret = csky_print_operand (str, &sop->subs[1], inst, reloc);
958
120k
      strcat (str, rc);
959
120k
      return ret;
960
120k
    }
961
1.08M
  return csky_output_operand (str, oprnd, inst, reloc);
962
1.20M
}
963
964
static int
965
csky_print_operands (char *str, struct csky_opcode_info const *pinfo,
966
         struct disassemble_info *info, CSKY_INST_TYPE inst,
967
         int reloc)
968
571k
{
969
571k
  int i = 0;
970
571k
  int ret = 0;
971
571k
  if (pinfo->operand_num)
972
482k
    strcat (str, "      \t");
973
571k
  if (pinfo->operand_num == -1)
974
7.93k
    {
975
7.93k
      ret = csky_print_operand (str, &pinfo->oprnd.oprnds[i], inst, reloc);
976
7.93k
      if (ret)
977
0
  return ret;
978
7.93k
    }
979
563k
  else
980
1.51M
    for (; i < pinfo->operand_num; i++)
981
956k
      {
982
956k
  if (i != 0)
983
482k
    strcat (str, ", ");
984
956k
  ret = csky_print_operand (str, &pinfo->oprnd.oprnds[i], inst, reloc);
985
956k
  if (ret)
986
818
    return ret;
987
956k
      }
988
570k
  info->fprintf_func (info->stream, "%s", str);
989
570k
  if (dis_info.need_output_symbol)
990
111k
    {
991
111k
      info->fprintf_func (info->stream, "\t// ");
992
111k
      info->print_address_func (dis_info.value, dis_info.info);
993
111k
    }
994
570k
  return 0;
995
571k
}
996
997
static void
998
number_to_chars_littleendian (char *buf, CSKY_INST_TYPE val, int n)
999
0
{
1000
0
  if (n <= 0)
1001
0
    abort ();
1002
0
  while (n--)
1003
0
    {
1004
0
      *buf++ = val & 0xff;
1005
0
      val >>= 8;
1006
0
    }
1007
0
}
1008
1009
683k
#define CSKY_READ_DATA()                                        \
1010
683k
{                                                               \
1011
683k
  status = info->read_memory_func (memaddr, buf, 2, info);      \
1012
683k
  if (status)                                                   \
1013
683k
    {                                                           \
1014
371
      info->memory_error_func (status, memaddr, info);          \
1015
371
      return -1;                                                \
1016
371
    }                                                           \
1017
683k
  if (info->endian == BFD_ENDIAN_BIG)                           \
1018
683k
    inst |= (buf[0] << 8) | buf[1];                             \
1019
683k
  else if (info->endian == BFD_ENDIAN_LITTLE)                   \
1020
280k
    inst |= (buf[1] << 8) | buf[0];                             \
1021
280k
  else                                                          \
1022
280k
    abort();                                                    \
1023
683k
  info->bytes_per_chunk += 2;                                   \
1024
683k
  memaddr += 2;                                                 \
1025
683k
}
1026
1027
int
1028
print_insn_csky (bfd_vma memaddr, struct disassemble_info *info)
1029
652k
{
1030
652k
  unsigned char buf[4];
1031
652k
  CSKY_INST_TYPE inst = 0;
1032
652k
  int status;
1033
652k
  char str[256];
1034
652k
  unsigned long given;
1035
652k
  int is_data = false;
1036
652k
  void (*printer) (bfd_vma, struct disassemble_info *, long);
1037
652k
  unsigned int  size = 4;
1038
1039
652k
  memset (str, 0, sizeof (str));
1040
652k
  info->bytes_per_chunk = 0;
1041
652k
  info->bytes_per_chunk = 0;
1042
652k
  dis_info.mem = memaddr;
1043
652k
  dis_info.info = info;
1044
652k
  dis_info.need_output_symbol = 0;
1045
1046
652k
  if (info->disassembler_options)
1047
676
    {
1048
676
      for_each_disassembler_option (info, parse_csky_option, NULL);
1049
676
      info->disassembler_options = NULL;
1050
676
    }
1051
1052
652k
  if (mach_flag != INIT_MACH_FLAG && mach_flag != BINARY_MACH_FLAG)
1053
414k
    info->mach = mach_flag;
1054
237k
  else if (mach_flag == INIT_MACH_FLAG)
1055
2
    {
1056
2
      mach_flag = info->mach;
1057
2
      dis_info.isa = CSKY_DEFAULT_ISA;
1058
2
    }
1059
1060
652k
  if (mach_flag == BINARY_MACH_FLAG && info->endian == BFD_ENDIAN_UNKNOWN)
1061
0
    {
1062
0
      info->endian = BFD_ENDIAN_LITTLE;
1063
0
      dis_info.isa = CSKY_DEFAULT_ISA;
1064
0
    }
1065
1066
  /* First check the full symtab for a mapping symbol, even if there
1067
     are no usable non-mapping symbols for this address.  */
1068
652k
  if (info->symtab_size != 0
1069
0
      && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
1070
0
    {
1071
0
      bfd_vma addr;
1072
0
      int n;
1073
0
      int last_sym = -1;
1074
0
      enum sym_type type = CUR_TEXT;
1075
1076
0
      if (memaddr <= last_map_addr)
1077
0
  last_map_sym = -1;
1078
      /* Start scanning at the start of the function, or wherever
1079
   we finished last time.  */
1080
0
      n = 0;
1081
0
      if (n < last_map_sym)
1082
0
  n = last_map_sym;
1083
1084
      /* Scan up to the location being disassembled.  */
1085
0
      for (; n < info->symtab_size; n++)
1086
0
  {
1087
0
    addr = bfd_asymbol_value (info->symtab[n]);
1088
0
    if (addr > memaddr)
1089
0
      break;
1090
0
    if ((info->section == NULL
1091
0
         || info->section == info->symtab[n]->section)
1092
0
        && get_sym_code_type (info, n, &type))
1093
0
      last_sym = n;
1094
0
  }
1095
0
      last_map_sym = last_sym;
1096
0
      last_type = type;
1097
0
      is_data = (last_type == CUR_DATA);
1098
0
      if (is_data)
1099
0
  {
1100
0
    size = 4 - ( memaddr & 3);
1101
0
    for (n = last_sym + 1; n < info->symtab_size; n++)
1102
0
      {
1103
0
        addr = bfd_asymbol_value (info->symtab[n]);
1104
0
        if (addr > memaddr)
1105
0
    {
1106
0
      if (addr - memaddr < size)
1107
0
        size = addr - memaddr;
1108
0
      break;
1109
0
    }
1110
0
      }
1111
    /* If the next symbol is after three bytes, we need to
1112
       print only part of the data, so that we can use either
1113
       .byte or .short.  */
1114
0
    if (size == 3)
1115
0
      size = (memaddr & 1) ? 1 : 2;
1116
0
  }
1117
0
    }
1118
652k
  info->bytes_per_line = 4;
1119
1120
652k
  if (is_data)
1121
0
    {
1122
0
      int i;
1123
1124
      /* Size was already set above.  */
1125
0
      info->bytes_per_chunk = size;
1126
0
      printer = print_insn_data;
1127
1128
0
      status = info->read_memory_func (memaddr, (bfd_byte *) buf, size, info);
1129
0
      given = 0;
1130
0
      if (info->endian == BFD_ENDIAN_LITTLE)
1131
0
  for (i = size - 1; i >= 0; i--)
1132
0
    given = buf[i] | (given << 8);
1133
0
      else
1134
0
  for (i = 0; i < (int) size; i++)
1135
0
    given = buf[i] | (given << 8);
1136
1137
0
      printer (memaddr, info, given);
1138
0
      return info->bytes_per_chunk;
1139
0
    }
1140
1141
  /* Handle instructions.  */
1142
1.95M
  CSKY_READ_DATA();
1143
1.95M
  if ((inst & 0xc000) == 0xc000 && IS_CSKY_V2 (mach_flag))
1144
31.0k
    {
1145
      /* It's a 32-bit instruction.  */
1146
31.0k
      inst <<= 16;
1147
62.0k
      CSKY_READ_DATA();
1148
62.0k
      if (info->buffer && (info->endian == BFD_ENDIAN_LITTLE))
1149
0
  {
1150
0
    char* src = (char *)(info->buffer
1151
0
             + ((memaddr - 4 - info->buffer_vma)
1152
0
          * info->octets_per_byte));
1153
0
    if (info->endian == BFD_ENDIAN_LITTLE)
1154
0
      number_to_chars_littleendian (src, inst, 4);
1155
0
  }
1156
62.0k
    }
1157
1158
652k
  if (IS_CSKY_V1 (mach_flag))
1159
171k
    g_opcodeP = csky_v1_opcodes;
1160
480k
  else
1161
480k
    g_opcodeP = csky_v2_opcodes;
1162
1163
652k
  do
1164
652k
    {
1165
652k
      struct csky_opcode const *op;
1166
652k
      struct csky_opcode_info const *pinfo = NULL;
1167
652k
      int reloc;
1168
1169
652k
      memset (str, 0, sizeof (str));
1170
652k
      op = csky_find_inst_info (&pinfo, inst, info->bytes_per_chunk);
1171
652k
      if (!op)
1172
81.8k
  {
1173
81.8k
    if (IS_CSKY_V1 (mach_flag))
1174
201
      info->fprintf_func (info->stream, ".short: 0x%04x",
1175
201
        (unsigned short)inst);
1176
81.6k
    else
1177
81.6k
      info->fprintf_func (info->stream, ".long: 0x%08x",
1178
81.6k
        (unsigned int)inst);
1179
81.8k
    return info->bytes_per_chunk;
1180
81.8k
  }
1181
1182
571k
      if (info->bytes_per_chunk == 2)
1183
555k
  reloc = op->reloc16;
1184
16.0k
      else
1185
16.0k
  reloc = op->reloc32;
1186
571k
      dis_info.opinfo = pinfo;
1187
571k
      strcat (str, op->mnemonic);
1188
1189
571k
      if (csky_print_operands (str, pinfo, info, inst, reloc))
1190
818
  g_opcodeP++;
1191
570k
      else
1192
570k
  break;
1193
571k
    } while (1);
1194
1195
570k
  return info->bytes_per_chunk;
1196
652k
}