Coverage Report

Created: 2026-05-11 07:54

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
691k
#define CSKY_INST_TYPE unsigned long
35
173M
#define HAS_SUB_OPERAND (unsigned int)0xffffffff
36
939
#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.66M
#define INIT_MACH_FLAG  0xffffffff
67
2.07M
#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
171M
{
111
171M
  int mask = 0;
112
171M
  if (oprnd->mask == HAS_SUB_OPERAND)
113
8.33M
    {
114
8.33M
      struct soperand *sop = (struct soperand *)oprnd;
115
8.33M
      mask |= csky_get_operand_mask (&sop->subs[0]);
116
8.33M
      mask |= csky_get_operand_mask (&sop->subs[1]);
117
8.33M
      return mask;
118
8.33M
    }
119
163M
  return oprnd->mask;
120
171M
}
121
122
static int
123
csky_get_mask (struct csky_opcode_info const *pinfo)
124
421M
{
125
421M
  int i = 0;
126
421M
  int mask = 0;
127
  /* List type.  */
128
421M
  if (pinfo->operand_num == -1)
129
1.19M
    mask |= csky_get_operand_mask (&pinfo->oprnd.oprnds[i]);
130
420M
  else
131
574M
    for (; i < pinfo->operand_num; i++)
132
154M
      mask |= csky_get_operand_mask (&pinfo->oprnd.oprnds[i]);
133
134
421M
  mask = ~mask;
135
421M
  return mask;
136
421M
}
137
138
static unsigned int
139
csky_chars_to_number (unsigned char * buf, int n)
140
60.8k
{
141
60.8k
  int i;
142
60.8k
  unsigned int val = 0;
143
144
60.8k
  if (dis_info.info->endian == BFD_ENDIAN_BIG)
145
158k
    for (i = 0; i < n; i++)
146
127k
      val = val << 8 | buf[i];
147
29.1k
  else
148
145k
    for (i = n - 1; i >= 0; i--)
149
116k
      val = val << 8 | buf[i];
150
60.8k
  return val;
151
60.8k
}
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
692k
{
159
692k
  int i;
160
692k
  unsigned int mask;
161
692k
  struct csky_opcode const *p;
162
163
692k
  p = g_opcodeP;
164
245M
  while (p->mnemonic)
165
245M
    {
166
245M
  if (!(p->isa_flag16 & dis_info.isa)
167
200M
        && !(p->isa_flag32 & dis_info.isa))
168
34.4M
  {
169
34.4M
    p++;
170
34.4M
    continue;
171
34.4M
  }
172
173
      /* Get the opcode mask.  */
174
632M
      for (i = 0; i < OP_TABLE_NUM; i++)
175
421M
  if (length == 2)
176
385M
    {
177
385M
      mask =  csky_get_mask (&p->op16[i]);
178
385M
      if (mask != 0 && (inst & mask) == p->op16[i].opcode)
179
578k
        {
180
578k
    *pinfo = &p->op16[i];
181
578k
    g_opcodeP = p;
182
578k
    return p;
183
578k
        }
184
385M
    }
185
36.1M
  else if (length == 4)
186
36.1M
    {
187
36.1M
      mask =  csky_get_mask (&p->op32[i]);
188
36.1M
      if (mask != 0
189
36.1M
    && ((unsigned long)(inst & mask)
190
36.1M
        == (unsigned long)p->op32[i].opcode))
191
15.3k
        {
192
15.3k
    *pinfo = &p->op32[i];
193
15.3k
    g_opcodeP = p;
194
15.3k
    return p;
195
15.3k
        }
196
36.1M
    }
197
210M
      p++;
198
210M
    }
199
200
98.9k
  return NULL;
201
692k
}
202
203
static bool
204
is_extern_symbol (struct disassemble_info *info, bfd_vma addr)
205
58.8k
{
206
58.8k
  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
58.8k
  return false;
215
58.8k
}
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
937
{
236
937
  obj_attribute *attr;
237
937
  const char *sec_name = NULL;
238
937
  if (!abfd || bfd_get_flavour (abfd) != bfd_target_elf_flavour)
239
856
    dis_info.isa = CSKY_DEFAULT_ISA;
240
81
  else
241
81
    {
242
81
      mach_flag = elf_elfheader (abfd)->e_flags;
243
244
81
      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
81
      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
81
      else
256
81
        dis_info.isa = CSKY_DEFAULT_ISA;
257
81
    }
258
259
937
   return print_insn_csky;
260
937
}
261
262
/* Parse a disassembler option.  */
263
static bool
264
parse_csky_option (const char *opt, void *data ATTRIBUTE_UNUSED)
265
2.87k
{
266
2.87k
  if (strcmp (opt, "abi-names") == 0)
267
68
    using_abi = 1;
268
2.80k
  else
269
2.80k
    fprintf (stderr, "unrecognized disassembler option: %s", opt);
270
2.87k
  return true;
271
2.87k
}
272
273
/* Get general register name.  */
274
static const char *
275
get_gr_name (int regno)
276
725k
{
277
725k
  return csky_get_general_reg_name (mach_flag, regno, using_abi);
278
725k
}
279
280
/* Get control register name.  */
281
static const char *
282
get_cr_name (unsigned int regno, int bank)
283
2.56k
{
284
2.56k
  return csky_get_control_reg_name (mach_flag, bank, regno, using_abi);
285
2.56k
}
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.13M
{
291
1.13M
  int ret = 0;;
292
1.13M
  int bit = 0;
293
1.13M
  int result = 0;
294
1.13M
  bfd_vma value;
295
1.13M
  int mask = oprnd->mask;
296
1.13M
  int max = 0;
297
1.13M
  char buf[128];
298
299
  /* Get operand value with mask.  */
300
1.13M
  value = inst & mask;
301
10.4M
  for (; mask; mask >>= 1, value >>=1)
302
9.27M
    if (mask & 0x1)
303
5.20M
      {
304
5.20M
  result |= ((value & 0x1) << bit);
305
5.20M
  max |= (1 << bit);
306
5.20M
  bit++;
307
5.20M
      }
308
1.13M
  value = result;
309
310
  /* Here is general instructions that have no reloc.  */
311
1.13M
  switch (oprnd->type)
312
1.13M
    {
313
2.59k
    case OPRND_TYPE_CTRLREG:
314
2.59k
  if (IS_CSKY_V1(mach_flag) && ((value & 0x1f) == 0x1f))
315
30
    return -1;
316
2.56k
  strcat (str, get_cr_name((value & 0x1f), (value >> 5)));
317
2.56k
  break;
318
22.1k
    case OPRND_TYPE_DUMMY_REG:
319
22.1k
      mask = dis_info.opinfo->oprnd.oprnds[0].mask;
320
22.1k
      value = inst & mask;
321
110k
      for (; mask; mask >>= 1, value >>=1)
322
88.4k
  if (mask & 0x1)
323
88.4k
    {
324
88.4k
      result |= ((value & 0x1) << bit);
325
88.4k
      bit++;
326
88.4k
    }
327
22.1k
      value = result;
328
22.1k
      strcat (str, get_gr_name (value));
329
22.1k
      break;
330
333k
    case OPRND_TYPE_GREG0_7:
331
619k
    case OPRND_TYPE_GREG0_15:
332
619k
    case OPRND_TYPE_GREG16_31:
333
625k
    case OPRND_TYPE_REGnsplr:
334
636k
    case OPRND_TYPE_AREG:
335
636k
      strcat (str, get_gr_name (value));
336
636k
      break;
337
1.89k
    case OPRND_TYPE_CPREG:
338
1.89k
      sprintf (buf, "cpr%d", (int)value);
339
1.89k
      strcat (str, buf);
340
1.89k
      break;
341
249
    case OPRND_TYPE_FREG:
342
249
      sprintf (buf, "fr%d", (int)value);
343
249
      strcat (str, buf);
344
249
      break;
345
685
    case OPRND_TYPE_VREG:
346
685
      dis_info.value = value;
347
685
      sprintf (buf, "vr%d", (int)value);
348
685
      strcat (str, buf);
349
685
      break;
350
895
    case OPRND_TYPE_CPCREG:
351
895
      sprintf (buf, "cpcr%d", (int)value);
352
895
      strcat (str, buf);
353
895
      break;
354
1.49k
    case OPRND_TYPE_CPIDX:
355
1.49k
      sprintf (buf, "cp%d", (int)value);
356
1.49k
      strcat (str, buf);
357
1.49k
      break;
358
3.04k
    case OPRND_TYPE_IMM2b_JMPIX:
359
3.04k
      value = (value + 2) << 3;
360
3.04k
      sprintf (buf, "%d", (int)value);
361
3.04k
      strcat (str, buf);
362
3.04k
      break;
363
113k
    case OPRND_TYPE_IMM_LDST:
364
114k
    case OPRND_TYPE_IMM_FLDST:
365
114k
      value <<= oprnd->shift;
366
114k
      sprintf (buf, "0x%x", (unsigned int)value);
367
114k
      strcat (str, buf);
368
114k
      break;
369
7.24k
    case OPRND_TYPE_IMM7b_LS2:
370
16.4k
    case OPRND_TYPE_IMM8b_LS2:
371
16.4k
      sprintf (buf, "%d", (int)(value << 2));
372
16.4k
      strcat (str, buf);
373
16.4k
      ret = 0;
374
16.4k
      break;
375
661
    case OPRND_TYPE_IMM5b_BMASKI:
376
661
      if ((value != 0) && (value > 31 || value < 8))
377
146
  {
378
146
    ret = -1;
379
146
    break;
380
146
  }
381
515
      sprintf (buf, "%d", (int)value);
382
515
      strcat (str, buf);
383
515
      ret = 0;
384
515
      break;
385
3.15k
    case OPRND_TYPE_IMM5b_1_31:
386
3.15k
      if (value > 31 || value < 1)
387
95
  {
388
95
    ret = -1;
389
95
    break;
390
95
  }
391
3.06k
      sprintf (buf, "%d", (int)value);
392
3.06k
      strcat (str, buf);
393
3.06k
      ret = 0;
394
3.06k
      break;
395
1.47k
    case OPRND_TYPE_IMM5b_7_31:
396
1.47k
      if (value > 31 || value < 7)
397
388
  {
398
388
    ret = -1;
399
388
    break;
400
388
  }
401
1.08k
      sprintf (buf, "%d", (int)value);
402
1.08k
      strcat (str, buf);
403
1.08k
      ret = 0;
404
1.08k
      break;
405
1
    case OPRND_TYPE_IMM5b_VSH:
406
1
      {
407
1
  char num[128];
408
1
  value = ((value & 0x1) << 4) | (value >> 1);
409
1
  sprintf (num, "%d", (int)value);
410
1
  strcat (str, num);
411
1
  ret = 0;
412
1
  break;
413
1.47k
      }
414
5
    case OPRND_TYPE_MSB2SIZE:
415
10
    case OPRND_TYPE_LSB2SIZE:
416
10
      {
417
10
  static int size;
418
10
  if (oprnd->type == OPRND_TYPE_MSB2SIZE)
419
5
    size = value;
420
5
  else
421
5
    {
422
5
      str[strlen (str) - 2] = '\0';
423
5
      sprintf (buf, "%d, %d", (int)(size + value), (int)value);
424
5
      strcat (str, buf);
425
5
    }
426
10
  break;
427
5
      }
428
0
    case OPRND_TYPE_IMM1b:
429
564
    case OPRND_TYPE_IMM2b:
430
614
    case OPRND_TYPE_IMM4b:
431
41.6k
    case OPRND_TYPE_IMM5b:
432
41.6k
    case OPRND_TYPE_IMM5b_LS:
433
45.3k
    case OPRND_TYPE_IMM7b:
434
72.1k
    case OPRND_TYPE_IMM8b:
435
74.3k
    case OPRND_TYPE_IMM12b:
436
78.1k
    case OPRND_TYPE_IMM15b:
437
78.2k
    case OPRND_TYPE_IMM16b:
438
78.2k
    case OPRND_TYPE_IMM16b_MOVIH:
439
79.7k
    case OPRND_TYPE_IMM16b_ORI:
440
79.7k
      sprintf (buf, "%d", (int)value);
441
79.7k
      strcat (str, buf);
442
79.7k
      ret = 0;
443
79.7k
      break;
444
1.28k
    case OPRND_TYPE_OFF8b:
445
1.28k
    case OPRND_TYPE_OFF16b:
446
1.28k
      {
447
1.28k
  unsigned char ibytes[4];
448
1.28k
  int shift = oprnd->shift;
449
1.28k
  int status;
450
1.28k
  unsigned int mem_val;
451
452
1.28k
  dis_info.info->stop_vma = 0;
453
454
1.28k
  value = ((dis_info.mem + (value << shift)
455
1.28k
      + ((IS_CSKY_V1 (mach_flag)) ? 2 : 0))
456
1.28k
     & 0xfffffffc);
457
1.28k
  status = dis_info.info->read_memory_func (value, ibytes, 4,
458
1.28k
              dis_info.info);
459
1.28k
  if (status != 0)
460
155
    {
461
155
      dis_info.info->memory_error_func (status, dis_info.mem,
462
155
                dis_info.info);
463
155
      return -1;
464
155
    }
465
1.13k
  mem_val = csky_chars_to_number (ibytes, 4);
466
  /* Remove [] around literal value to match ABI syntax.  */
467
1.13k
  sprintf (buf, "0x%X", mem_val);
468
1.13k
  strcat (str, buf);
469
  /* For jmpi/jsri, we'll try to get a symbol for the target.  */
470
1.13k
  if (dis_info.info->print_address_func && mem_val != 0)
471
1.06k
    {
472
1.06k
      dis_info.value = mem_val;
473
1.06k
      dis_info.need_output_symbol = 1;
474
1.06k
    }
475
66
  else
476
66
    {
477
66
      sprintf (buf, "\t// from address pool at 0x%x",
478
66
         (unsigned int)value);
479
66
      strcat (str, buf);
480
66
    }
481
1.13k
  break;
482
1.28k
      }
483
39
    case OPRND_TYPE_BLOOP_OFF4b:
484
78
    case OPRND_TYPE_BLOOP_OFF12b:
485
23.8k
    case OPRND_TYPE_OFF11b:
486
24.3k
    case OPRND_TYPE_OFF16b_LSL1:
487
24.8k
    case OPRND_TYPE_IMM_OFF18b:
488
27.9k
    case OPRND_TYPE_OFF26b:
489
27.9k
      {
490
27.9k
  int shift = oprnd->shift;
491
27.9k
  if (value & ((max >> 1) + 1))
492
17.9k
    value |= ~max;
493
27.9k
  if (is_extern_symbol (dis_info.info, dis_info.mem))
494
0
    value = 0;
495
27.9k
  else if (IS_CSKY_V1 (mach_flag))
496
23.8k
    value = dis_info.mem + 2 + (value << shift);
497
4.16k
  else
498
4.16k
    value = dis_info.mem + (value << shift);
499
27.9k
  dis_info.need_output_symbol = 1;
500
27.9k
  dis_info.value= value;
501
27.9k
  sprintf (buf, "0x%x", (unsigned int)value);
502
27.9k
  strcat (str, buf);
503
27.9k
  break;
504
24.8k
      }
505
20.3k
    case OPRND_TYPE_CONSTANT:
506
20.3k
    case OPRND_TYPE_FCONSTANT:
507
20.3k
      {
508
20.3k
  int shift = oprnd->shift;
509
20.3k
  bfd_byte ibytes[8];
510
20.3k
  int status;
511
20.3k
  bfd_vma addr;
512
20.3k
  int nbytes;
513
514
20.3k
  dis_info.info->stop_vma = 0;
515
20.3k
  value <<= shift;
516
517
20.3k
  if (IS_CSKY_V1 (mach_flag))
518
5.73k
    addr = (dis_info.mem + 2 + value) & 0xfffffffc;
519
14.6k
  else
520
14.6k
    addr = (dis_info.mem + value) & 0xfffffffc;
521
522
20.3k
  if (oprnd->type == OPRND_TYPE_FCONSTANT
523
0
      && dis_info.opinfo->opcode != CSKYV2_INST_FLRW)
524
0
    nbytes = 8;
525
20.3k
  else
526
20.3k
    nbytes = 4;
527
528
20.3k
  status = dis_info.info->read_memory_func (addr, ibytes,
529
20.3k
              nbytes, dis_info.info);
530
20.3k
  if (status != 0)
531
    /* Address out of bounds.  -> lrw rx, [pc, 0ffset]. */
532
3.05k
    sprintf (buf, "[pc, %d]\t// from address pool at %x", (int)value,
533
3.05k
       (unsigned int)addr);
534
17.3k
  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.3k
  else
552
17.3k
    {
553
17.3k
      dis_info.value = addr;
554
17.3k
      dis_info.need_output_symbol = 1;
555
17.3k
      value = csky_chars_to_number (ibytes, 4);
556
17.3k
      sprintf (buf, "0x%x", (unsigned int) value);
557
17.3k
    }
558
559
20.3k
  strcat (str, buf);
560
20.3k
  break;
561
20.3k
      }
562
56.3k
    case OPRND_TYPE_ELRW_CONSTANT:
563
56.3k
      {
564
56.3k
  int shift = oprnd->shift;
565
56.3k
  char ibytes[4];
566
56.3k
  int status;
567
56.3k
  bfd_vma addr;
568
56.3k
  dis_info.info->stop_vma = 0;
569
570
56.3k
  value = 0x80 + ((~value) & 0x7f);
571
572
56.3k
  value = value << shift;
573
56.3k
  addr = (dis_info.mem + value) & 0xfffffffc;
574
575
56.3k
  status = dis_info.info->read_memory_func (addr, (bfd_byte *)ibytes,
576
56.3k
              4, dis_info.info);
577
56.3k
  if (status != 0)
578
    /* Address out of bounds.  -> lrw rx, [pc, 0ffset]. */
579
13.9k
    sprintf (buf, "[pc, %d]\t// from address pool at %x", (int) value,
580
13.9k
       (unsigned int)addr);
581
42.4k
  else
582
42.4k
    {
583
42.4k
      dis_info.value = addr;
584
42.4k
      value = csky_chars_to_number ((unsigned char *)ibytes, 4);
585
42.4k
      dis_info.need_output_symbol = 1;
586
42.4k
      sprintf (buf, "0x%x", (unsigned int)value);
587
42.4k
    }
588
589
56.3k
  strcat (str, buf);
590
56.3k
  break;
591
20.3k
      }
592
0
    case OPRND_TYPE_SFLOAT:
593
2
    case OPRND_TYPE_DFLOAT:
594
2
      {
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
2
  uint64_t imm4;
603
2
  uint64_t imm8;
604
2
  uint64_t dbnum;
605
2
  unsigned char valbytes[8];
606
2
  double fvalue;
607
608
2
  imm4 = ((inst >> 16) & 0xf);
609
2
  imm4 = (uint64_t)(1023 - (imm4 - 11)) << 52;
610
611
2
  imm8 = (uint64_t)((inst >> 4) & 0xf) << 44;
612
2
  imm8 |= (uint64_t)((inst >> 21) & 0xf) << 48;
613
614
2
  dbnum = (uint64_t)((inst >> 20) & 1) << 63;
615
2
  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
2
  valbytes[0] = dbnum & 0xff;
620
2
  valbytes[1] = (dbnum >> 8) & 0xff;
621
2
  valbytes[2] = (dbnum >> 16) & 0xff;
622
2
  valbytes[3] = (dbnum >> 24) & 0xff;
623
2
  valbytes[4] = (dbnum >> 32) & 0xff;
624
2
  valbytes[5] = (dbnum >> 40) & 0xff;
625
2
  valbytes[6] = (dbnum >> 48) & 0xff;
626
2
  valbytes[7] = (dbnum >> 56) & 0xff;
627
628
2
  floatformat_to_double (&floatformat_ieee_double_little, valbytes,
629
2
             &fvalue);
630
631
2
  sprintf (buf, "%.7g", fvalue);
632
2
  strcat (str, buf);
633
2
  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
709
    case OPRND_TYPE_LABEL_WITH_BRACKET:
694
709
      sprintf (buf, "[0x%x]", (unsigned int)value);
695
709
      strcat (str, buf);
696
709
      strcat (str, "\t// the offset is based on .data");
697
709
      break;
698
4.08k
    case OPRND_TYPE_OIMM3b:
699
4.16k
    case OPRND_TYPE_OIMM4b:
700
21.8k
    case OPRND_TYPE_OIMM5b:
701
21.8k
    case OPRND_TYPE_OIMM5b_IDLY:
702
52.2k
    case OPRND_TYPE_OIMM8b:
703
52.6k
    case OPRND_TYPE_OIMM12b:
704
52.7k
    case OPRND_TYPE_OIMM16b:
705
52.8k
    case OPRND_TYPE_OIMM18b:
706
52.8k
      value += 1;
707
52.8k
      sprintf (buf, "%d", (int)value);
708
52.8k
      strcat (str, buf);
709
52.8k
      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
645
    case OPRND_TYPE_REGLIST_DASH:
742
645
      if (IS_CSKY_V1 (mach_flag))
743
644
  {
744
644
    sprintf (buf, "%s-r15", get_gr_name (value));
745
644
    strcat (str, buf);
746
644
  }
747
1
      else
748
1
  {
749
1
    if ((value & 0x1f) + (value >> 5) > 31)
750
0
      {
751
0
        ret = -1;
752
0
        break;
753
0
      }
754
1
    strcat (str, get_gr_name ((value >> 5)));
755
1
    strcat (str, "-");
756
1
    strcat (str, get_gr_name ((value & 0x1f) + (value >> 5)));
757
1
  }
758
645
      break;
759
645
    case OPRND_TYPE_PSR_BITS_LIST:
760
30
      {
761
30
  struct psrbit const *bits;
762
30
  int first_oprnd = true;
763
30
  int i = 0;
764
30
  if (IS_CSKY_V1 (mach_flag))
765
26
    {
766
26
      if (value == 0)
767
4
        {
768
4
    strcat (str, "af");
769
4
    break;
770
4
        }
771
22
      bits = cskyv1_psr_bits;
772
22
    }
773
4
  else
774
4
    bits = cskyv2_psr_bits;
775
92
  while (value != 0 && bits[i].name != NULL)
776
66
      {
777
66
        if (value & bits[i].value)
778
66
    {
779
66
      if (!first_oprnd)
780
44
        strcat (str, ", ");
781
66
      strcat (str, bits[i].name);
782
66
      value &= ~bits[i].value;
783
66
      first_oprnd = false;
784
66
    }
785
66
        i++;
786
66
      }
787
26
  break;
788
30
      }
789
644
    case OPRND_TYPE_REGbsp:
790
644
      if (IS_CSKY_V1 (mach_flag))
791
644
  sprintf(buf, "(%s)", get_gr_name (0));
792
0
      else
793
0
  sprintf(buf, "(%s)", get_gr_name (14));
794
644
      strcat (str, buf);
795
644
      break;
796
36.7k
    case OPRND_TYPE_REGsp:
797
36.7k
      if (IS_CSKY_V1 (mach_flag))
798
0
  strcat (str, get_gr_name (0));
799
36.7k
      else
800
36.7k
  strcat (str, get_gr_name (14));
801
36.7k
      break;
802
753
    case OPRND_TYPE_REGnr4_r7:
803
782
    case OPRND_TYPE_AREG_WITH_BRACKET:
804
782
      strcat (str, "(");
805
782
      strcat (str, get_gr_name (value));
806
782
      strcat (str, ")");
807
782
      break;
808
526
    case OPRND_TYPE_AREG_WITH_LSHIFT:
809
526
      strcat (str, get_gr_name (value >> 5));
810
526
      strcat (str, " << ");
811
526
      if ((value & 0x1f) == 0x1)
812
30
  strcat (str, "0");
813
496
      else if ((value & 0x1f) == 0x2)
814
13
  strcat (str, "1");
815
483
      else if ((value & 0x1f) == 0x4)
816
42
  strcat (str, "2");
817
441
      else if ((value & 0x1f) == 0x8)
818
26
  strcat (str, "3");
819
526
      break;
820
94
    case OPRND_TYPE_AREG_WITH_LSHIFT_FPU:
821
94
      strcat (str, get_gr_name (value >> 2));
822
94
      strcat (str, " << ");
823
94
      if ((value & 0x3) == 0x0)
824
5
  strcat (str, "0");
825
89
      else if ((value & 0x3) == 0x1)
826
88
  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
94
      break;
832
3
    case OPRND_TYPE_VREG_WITH_INDEX:
833
3
      {
834
3
  unsigned freg_val = value & 0xf;
835
3
  unsigned index_val = (value >> 4) & 0xf;
836
3
  sprintf (buf, "vr%d[%d]", freg_val, index_val);
837
3
  strcat(str, buf);
838
3
  break;
839
753
      }
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
753
      }
848
753
    case OPRND_TYPE_REGr4_r7:
849
753
      if (IS_CSKY_V1 (mach_flag))
850
753
  {
851
753
    sprintf (buf, "%s-%s", get_gr_name (4), get_gr_name (7));
852
753
    strcat (str, buf);
853
753
  }
854
753
      break;
855
1.32k
    case OPRND_TYPE_CONST1:
856
1.32k
      strcat (str, "1");
857
1.32k
      break;
858
1.96k
    case OPRND_TYPE_REG_r1a:
859
2.01k
    case OPRND_TYPE_REG_r1b:
860
2.01k
      strcat (str, get_gr_name (1));
861
2.01k
      break;
862
104
    case OPRND_TYPE_REG_r28:
863
104
      strcat (str, get_gr_name (28));
864
104
      break;
865
11.1k
    case OPRND_TYPE_REGLIST_DASH_COMMA:
866
      /* 16-bit reglist.  */
867
11.1k
      if (value & 0xf)
868
8.44k
  {
869
8.44k
    strcat (str, get_gr_name (4));
870
8.44k
    if ((value & 0xf) > 1)
871
6.59k
      {
872
6.59k
        strcat (str, "-");
873
6.59k
        strcat (str, get_gr_name ((value & 0xf) + 3));
874
6.59k
      }
875
8.44k
    if (value & ~0xf)
876
6.54k
      strcat (str, ", ");
877
8.44k
  }
878
11.1k
      if (value & 0x10)
879
8.41k
  {
880
    /* r15.  */
881
8.41k
    strcat (str, get_gr_name (15));
882
8.41k
    if (value & ~0x1f)
883
0
      strcat (str, ", ");
884
8.41k
  }
885
11.1k
      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
11.1k
      break;
905
10.0k
    case OPRND_TYPE_UNCOND10b:
906
10.3k
    case OPRND_TYPE_UNCOND16b:
907
30.8k
    case OPRND_TYPE_COND10b:
908
30.8k
    case OPRND_TYPE_COND16b:
909
30.8k
      {
910
30.8k
  int shift = oprnd->shift;
911
912
30.8k
  if (value & ((max >> 1) + 1))
913
10.5k
    value |= ~max;
914
30.8k
  if (is_extern_symbol (dis_info.info, dis_info.mem))
915
0
    value = 0;
916
30.8k
  else
917
30.8k
    value = dis_info.mem + (value << shift);
918
30.8k
  sprintf (buf, "0x%x", (unsigned int)value);
919
30.8k
  strcat (str, buf);
920
30.8k
  dis_info.need_output_symbol = 1;
921
30.8k
  dis_info.value = value;
922
30.8k
      }
923
30.8k
      break;
924
925
28
    default:
926
28
      ret = -1;
927
28
      break;
928
1.13M
    }
929
1.13M
  return ret;
930
1.13M
}
931
932
static int
933
csky_print_operand (char *str, struct operand const *oprnd,
934
        CSKY_INST_TYPE inst, int reloc)
935
1.25M
{
936
1.25M
  int ret = -1;
937
1.25M
  char *lc = "";
938
1.25M
  char *rc = "";
939
1.25M
  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
114k
  {
944
114k
    lc = "(";
945
114k
    rc = ")";
946
114k
  }
947
5.86k
      else if (oprnd->type == OPRND_TYPE_ABRACKET)
948
5.86k
  {
949
5.86k
    lc = "<";
950
5.86k
    rc = ">";
951
5.86k
  }
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.13M
  return csky_output_operand (str, oprnd, inst, reloc);
962
1.25M
}
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
593k
{
969
593k
  int i = 0;
970
593k
  int ret = 0;
971
593k
  if (pinfo->operand_num)
972
508k
    strcat (str, "      \t");
973
593k
  if (pinfo->operand_num == -1)
974
11.2k
    {
975
11.2k
      ret = csky_print_operand (str, &pinfo->oprnd.oprnds[i], inst, reloc);
976
11.2k
      if (ret)
977
0
  return ret;
978
11.2k
    }
979
582k
  else
980
1.58M
    for (; i < pinfo->operand_num; i++)
981
998k
      {
982
998k
  if (i != 0)
983
501k
    strcat (str, ", ");
984
998k
  ret = csky_print_operand (str, &pinfo->oprnd.oprnds[i], inst, reloc);
985
998k
  if (ret)
986
842
    return ret;
987
998k
      }
988
592k
  info->fprintf_func (info->stream, "%s", str);
989
592k
  if (dis_info.need_output_symbol)
990
119k
    {
991
119k
      info->fprintf_func (info->stream, "\t// ");
992
119k
      info->print_address_func (dis_info.value, dis_info.info);
993
119k
    }
994
592k
  return 0;
995
593k
}
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
721k
#define CSKY_READ_DATA()                                        \
1010
721k
{                                                               \
1011
721k
  status = info->read_memory_func (memaddr, buf, 2, info);      \
1012
721k
  if (status)                                                   \
1013
721k
    {                                                           \
1014
369
      info->memory_error_func (status, memaddr, info);          \
1015
369
      return -1;                                                \
1016
369
    }                                                           \
1017
721k
  if (info->endian == BFD_ENDIAN_BIG)                           \
1018
721k
    inst |= (buf[0] << 8) | buf[1];                             \
1019
721k
  else if (info->endian == BFD_ENDIAN_LITTLE)                   \
1020
341k
    inst |= (buf[1] << 8) | buf[0];                             \
1021
341k
  else                                                          \
1022
341k
    abort();                                                    \
1023
721k
  info->bytes_per_chunk += 2;                                   \
1024
721k
  memaddr += 2;                                                 \
1025
721k
}
1026
1027
int
1028
print_insn_csky (bfd_vma memaddr, struct disassemble_info *info)
1029
691k
{
1030
691k
  unsigned char buf[4];
1031
691k
  CSKY_INST_TYPE inst = 0;
1032
691k
  int status;
1033
691k
  char str[256];
1034
691k
  unsigned long given;
1035
691k
  int is_data = false;
1036
691k
  void (*printer) (bfd_vma, struct disassemble_info *, long);
1037
691k
  unsigned int  size = 4;
1038
1039
691k
  memset (str, 0, sizeof (str));
1040
691k
  info->bytes_per_chunk = 0;
1041
691k
  info->bytes_per_chunk = 0;
1042
691k
  dis_info.mem = memaddr;
1043
691k
  dis_info.info = info;
1044
691k
  dis_info.need_output_symbol = 0;
1045
1046
691k
  if (info->disassembler_options)
1047
688
    {
1048
688
      for_each_disassembler_option (info, parse_csky_option, NULL);
1049
688
      info->disassembler_options = NULL;
1050
688
    }
1051
1052
691k
  if (mach_flag != INIT_MACH_FLAG && mach_flag != BINARY_MACH_FLAG)
1053
408k
    info->mach = mach_flag;
1054
283k
  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
691k
  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
691k
  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
691k
  info->bytes_per_line = 4;
1119
1120
691k
  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
2.07M
  CSKY_READ_DATA();
1143
2.07M
  if ((inst & 0xc000) == 0xc000 && IS_CSKY_V2 (mach_flag))
1144
29.8k
    {
1145
      /* It's a 32-bit instruction.  */
1146
29.8k
      inst <<= 16;
1147
59.6k
      CSKY_READ_DATA();
1148
59.6k
      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
59.6k
    }
1157
1158
691k
  if (IS_CSKY_V1 (mach_flag))
1159
166k
    g_opcodeP = csky_v1_opcodes;
1160
525k
  else
1161
525k
    g_opcodeP = csky_v2_opcodes;
1162
1163
691k
  do
1164
692k
    {
1165
692k
      struct csky_opcode const *op;
1166
692k
      struct csky_opcode_info const *pinfo = NULL;
1167
692k
      int reloc;
1168
1169
692k
      memset (str, 0, sizeof (str));
1170
692k
      op = csky_find_inst_info (&pinfo, inst, info->bytes_per_chunk);
1171
692k
      if (!op)
1172
98.9k
  {
1173
98.9k
    if (IS_CSKY_V1 (mach_flag))
1174
208
      info->fprintf_func (info->stream, ".short: 0x%04x",
1175
208
        (unsigned short)inst);
1176
98.7k
    else
1177
98.7k
      info->fprintf_func (info->stream, ".long: 0x%08x",
1178
98.7k
        (unsigned int)inst);
1179
98.9k
    return info->bytes_per_chunk;
1180
98.9k
  }
1181
1182
593k
      if (info->bytes_per_chunk == 2)
1183
578k
  reloc = op->reloc16;
1184
15.3k
      else
1185
15.3k
  reloc = op->reloc32;
1186
593k
      dis_info.opinfo = pinfo;
1187
593k
      strcat (str, op->mnemonic);
1188
1189
593k
      if (csky_print_operands (str, pinfo, info, inst, reloc))
1190
842
  g_opcodeP++;
1191
592k
      else
1192
592k
  break;
1193
593k
    } while (1);
1194
1195
592k
  return info->bytes_per_chunk;
1196
691k
}