Coverage Report

Created: 2026-09-14 08:07

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
887k
#define CSKY_INST_TYPE unsigned long
35
237M
#define HAS_SUB_OPERAND (unsigned int)0xffffffff
36
1.08k
#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
2.09M
#define INIT_MACH_FLAG  0xffffffff
67
2.66M
#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
1.27k
{
97
1.27k
  const char *name;
98
1.27k
  name = bfd_asymbol_name (info->symtab[n]);
99
1.27k
  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
1.27k
  return false;
106
1.27k
}
107
108
static int
109
csky_get_operand_mask (struct operand const *oprnd)
110
235M
{
111
235M
  int mask = 0;
112
235M
  if (oprnd->mask == HAS_SUB_OPERAND)
113
10.9M
    {
114
10.9M
      struct soperand *sop = (struct soperand *)oprnd;
115
10.9M
      mask |= csky_get_operand_mask (&sop->subs[0]);
116
10.9M
      mask |= csky_get_operand_mask (&sop->subs[1]);
117
10.9M
      return mask;
118
10.9M
    }
119
224M
  return oprnd->mask;
120
235M
}
121
122
static int
123
csky_get_mask (struct csky_opcode_info const *pinfo)
124
492M
{
125
492M
  int i = 0;
126
492M
  int mask = 0;
127
  /* List type.  */
128
492M
  if (pinfo->operand_num == -1)
129
1.52M
    mask |= csky_get_operand_mask (&pinfo->oprnd.oprnds[i]);
130
491M
  else
131
703M
    for (; i < pinfo->operand_num; i++)
132
212M
      mask |= csky_get_operand_mask (&pinfo->oprnd.oprnds[i]);
133
134
492M
  mask = ~mask;
135
492M
  return mask;
136
492M
}
137
138
static unsigned int
139
csky_chars_to_number (unsigned char * buf, int n)
140
89.7k
{
141
89.7k
  int i;
142
89.7k
  unsigned int val = 0;
143
144
89.7k
  if (dis_info.info->endian == BFD_ENDIAN_BIG)
145
318k
    for (i = 0; i < n; i++)
146
254k
      val = val << 8 | buf[i];
147
25.9k
  else
148
129k
    for (i = n - 1; i >= 0; i--)
149
103k
      val = val << 8 | buf[i];
150
89.7k
  return val;
151
89.7k
}
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
889k
{
159
889k
  int i;
160
889k
  unsigned int mask;
161
889k
  struct csky_opcode const *p;
162
163
889k
  p = g_opcodeP;
164
281M
  while (p->mnemonic)
165
281M
    {
166
281M
  if (!(p->isa_flag16 & dis_info.isa)
167
223M
        && !(p->isa_flag32 & dis_info.isa))
168
34.6M
  {
169
34.6M
    p++;
170
34.6M
    continue;
171
34.6M
  }
172
173
      /* Get the opcode mask.  */
174
738M
      for (i = 0; i < OP_TABLE_NUM; i++)
175
492M
  if (length == 2)
176
431M
    {
177
431M
      mask =  csky_get_mask (&p->op16[i]);
178
431M
      if (mask != 0 && (inst & mask) == p->op16[i].opcode)
179
760k
        {
180
760k
    *pinfo = &p->op16[i];
181
760k
    g_opcodeP = p;
182
760k
    return p;
183
760k
        }
184
431M
    }
185
61.4M
  else if (length == 4)
186
61.4M
    {
187
61.4M
      mask =  csky_get_mask (&p->op32[i]);
188
61.4M
      if (mask != 0
189
61.4M
    && ((unsigned long)(inst & mask)
190
61.4M
        == (unsigned long)p->op32[i].opcode))
191
28.4k
        {
192
28.4k
    *pinfo = &p->op32[i];
193
28.4k
    g_opcodeP = p;
194
28.4k
    return p;
195
28.4k
        }
196
61.4M
    }
197
245M
      p++;
198
245M
    }
199
200
99.6k
  return NULL;
201
889k
}
202
203
static bool
204
is_extern_symbol (struct disassemble_info *info, bfd_vma addr)
205
75.3k
{
206
75.3k
  if (info->section != NULL && info->section->relocation != NULL)
207
202
    {
208
202
      unsigned int rel_count = 0;
209
202
      struct reloc_cache_entry *pt = info->section->relocation;
210
10.6k
      for (; rel_count < info->section->reloc_count; rel_count++, pt++)
211
10.5k
  if (addr == pt->address)
212
88
    return true;
213
202
    }
214
75.2k
  return false;
215
75.3k
}
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
366
{
225
366
  const char *name;
226
227
366
  if (sym == NULL)
228
0
    return false;
229
366
  name = bfd_asymbol_name (sym);
230
366
  return name && *name != '$';
231
366
}
232
233
disassembler_ftype
234
csky_get_disassembler (bfd *abfd)
235
1.07k
{
236
1.07k
  obj_attribute *attr;
237
1.07k
  const char *sec_name = NULL;
238
1.07k
  if (!abfd || bfd_get_flavour (abfd) != bfd_target_elf_flavour)
239
866
    dis_info.isa = CSKY_DEFAULT_ISA;
240
210
  else
241
210
    {
242
210
      mach_flag = elf_elfheader (abfd)->e_flags;
243
244
210
      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
210
      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
210
      else
256
210
        dis_info.isa = CSKY_DEFAULT_ISA;
257
210
    }
258
259
1.07k
   return print_insn_csky;
260
1.07k
}
261
262
/* Parse a disassembler option.  */
263
static bool
264
parse_csky_option (const char *opt, void *data ATTRIBUTE_UNUSED)
265
2.39k
{
266
2.39k
  if (strcmp (opt, "abi-names") == 0)
267
90
    using_abi = 1;
268
2.30k
  else
269
2.30k
    fprintf (stderr, "unrecognized disassembler option: %s", opt);
270
2.39k
  return true;
271
2.39k
}
272
273
/* Get general register name.  */
274
static const char *
275
get_gr_name (int regno)
276
944k
{
277
944k
  return csky_get_general_reg_name (mach_flag, regno, using_abi);
278
944k
}
279
280
/* Get control register name.  */
281
static const char *
282
get_cr_name (unsigned int regno, int bank)
283
2.87k
{
284
2.87k
  return csky_get_control_reg_name (mach_flag, bank, regno, using_abi);
285
2.87k
}
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.49M
{
291
1.49M
  int ret = 0;;
292
1.49M
  int bit = 0;
293
1.49M
  int result = 0;
294
1.49M
  bfd_vma value;
295
1.49M
  int mask = oprnd->mask;
296
1.49M
  int max = 0;
297
1.49M
  char buf[128];
298
299
  /* Get operand value with mask.  */
300
1.49M
  value = inst & mask;
301
13.9M
  for (; mask; mask >>= 1, value >>=1)
302
12.4M
    if (mask & 0x1)
303
6.96M
      {
304
6.96M
  result |= ((value & 0x1) << bit);
305
6.96M
  max |= (1 << bit);
306
6.96M
  bit++;
307
6.96M
      }
308
1.49M
  value = result;
309
310
  /* Here is general instructions that have no reloc.  */
311
1.49M
  switch (oprnd->type)
312
1.49M
    {
313
2.98k
    case OPRND_TYPE_CTRLREG:
314
2.98k
  if (IS_CSKY_V1(mach_flag) && ((value & 0x1f) == 0x1f))
315
110
    return -1;
316
2.87k
  strcat (str, get_cr_name((value & 0x1f), (value >> 5)));
317
2.87k
  break;
318
29.5k
    case OPRND_TYPE_DUMMY_REG:
319
29.5k
      mask = dis_info.opinfo->oprnd.oprnds[0].mask;
320
29.5k
      value = inst & mask;
321
147k
      for (; mask; mask >>= 1, value >>=1)
322
118k
  if (mask & 0x1)
323
118k
    {
324
118k
      result |= ((value & 0x1) << bit);
325
118k
      bit++;
326
118k
    }
327
29.5k
      value = result;
328
29.5k
      strcat (str, get_gr_name (value));
329
29.5k
      break;
330
440k
    case OPRND_TYPE_GREG0_7:
331
791k
    case OPRND_TYPE_GREG0_15:
332
791k
    case OPRND_TYPE_GREG16_31:
333
806k
    case OPRND_TYPE_REGnsplr:
334
827k
    case OPRND_TYPE_AREG:
335
827k
      strcat (str, get_gr_name (value));
336
827k
      break;
337
4.71k
    case OPRND_TYPE_CPREG:
338
4.71k
      sprintf (buf, "cpr%d", (int)value);
339
4.71k
      strcat (str, buf);
340
4.71k
      break;
341
441
    case OPRND_TYPE_FREG:
342
441
      sprintf (buf, "fr%d", (int)value);
343
441
      strcat (str, buf);
344
441
      break;
345
1.36k
    case OPRND_TYPE_VREG:
346
1.36k
      dis_info.value = value;
347
1.36k
      sprintf (buf, "vr%d", (int)value);
348
1.36k
      strcat (str, buf);
349
1.36k
      break;
350
1.02k
    case OPRND_TYPE_CPCREG:
351
1.02k
      sprintf (buf, "cpcr%d", (int)value);
352
1.02k
      strcat (str, buf);
353
1.02k
      break;
354
2.35k
    case OPRND_TYPE_CPIDX:
355
2.35k
      sprintf (buf, "cp%d", (int)value);
356
2.35k
      strcat (str, buf);
357
2.35k
      break;
358
1.93k
    case OPRND_TYPE_IMM2b_JMPIX:
359
1.93k
      value = (value + 2) << 3;
360
1.93k
      sprintf (buf, "%d", (int)value);
361
1.93k
      strcat (str, buf);
362
1.93k
      break;
363
153k
    case OPRND_TYPE_IMM_LDST:
364
153k
    case OPRND_TYPE_IMM_FLDST:
365
153k
      value <<= oprnd->shift;
366
153k
      sprintf (buf, "0x%x", (unsigned int)value);
367
153k
      strcat (str, buf);
368
153k
      break;
369
10.0k
    case OPRND_TYPE_IMM7b_LS2:
370
22.9k
    case OPRND_TYPE_IMM8b_LS2:
371
22.9k
      sprintf (buf, "%d", (int)(value << 2));
372
22.9k
      strcat (str, buf);
373
22.9k
      ret = 0;
374
22.9k
      break;
375
1.35k
    case OPRND_TYPE_IMM5b_BMASKI:
376
1.35k
      if ((value != 0) && (value > 31 || value < 8))
377
509
  {
378
509
    ret = -1;
379
509
    break;
380
509
  }
381
849
      sprintf (buf, "%d", (int)value);
382
849
      strcat (str, buf);
383
849
      ret = 0;
384
849
      break;
385
5.14k
    case OPRND_TYPE_IMM5b_1_31:
386
5.14k
      if (value > 31 || value < 1)
387
129
  {
388
129
    ret = -1;
389
129
    break;
390
129
  }
391
5.01k
      sprintf (buf, "%d", (int)value);
392
5.01k
      strcat (str, buf);
393
5.01k
      ret = 0;
394
5.01k
      break;
395
1.70k
    case OPRND_TYPE_IMM5b_7_31:
396
1.70k
      if (value > 31 || value < 7)
397
489
  {
398
489
    ret = -1;
399
489
    break;
400
489
  }
401
1.21k
      sprintf (buf, "%d", (int)value);
402
1.21k
      strcat (str, buf);
403
1.21k
      ret = 0;
404
1.21k
      break;
405
32
    case OPRND_TYPE_IMM5b_VSH:
406
32
      {
407
32
  char num[128];
408
32
  value = ((value & 0x1) << 4) | (value >> 1);
409
32
  sprintf (num, "%d", (int)value);
410
32
  strcat (str, num);
411
32
  ret = 0;
412
32
  break;
413
1.70k
      }
414
15
    case OPRND_TYPE_MSB2SIZE:
415
30
    case OPRND_TYPE_LSB2SIZE:
416
30
      {
417
30
  static int size;
418
30
  if (oprnd->type == OPRND_TYPE_MSB2SIZE)
419
15
    size = value;
420
15
  else
421
15
    {
422
15
      str[strlen (str) - 2] = '\0';
423
15
      sprintf (buf, "%d, %d", (int)(size + value), (int)value);
424
15
      strcat (str, buf);
425
15
    }
426
30
  break;
427
15
      }
428
0
    case OPRND_TYPE_IMM1b:
429
780
    case OPRND_TYPE_IMM2b:
430
956
    case OPRND_TYPE_IMM4b:
431
62.1k
    case OPRND_TYPE_IMM5b:
432
62.2k
    case OPRND_TYPE_IMM5b_LS:
433
67.4k
    case OPRND_TYPE_IMM7b:
434
95.1k
    case OPRND_TYPE_IMM8b:
435
99.2k
    case OPRND_TYPE_IMM12b:
436
107k
    case OPRND_TYPE_IMM15b:
437
107k
    case OPRND_TYPE_IMM16b:
438
107k
    case OPRND_TYPE_IMM16b_MOVIH:
439
110k
    case OPRND_TYPE_IMM16b_ORI:
440
110k
      sprintf (buf, "%d", (int)value);
441
110k
      strcat (str, buf);
442
110k
      ret = 0;
443
110k
      break;
444
2.26k
    case OPRND_TYPE_OFF8b:
445
2.27k
    case OPRND_TYPE_OFF16b:
446
2.27k
      {
447
2.27k
  unsigned char ibytes[4];
448
2.27k
  int shift = oprnd->shift;
449
2.27k
  int status;
450
2.27k
  unsigned int mem_val;
451
452
2.27k
  dis_info.info->stop_vma = 0;
453
454
2.27k
  value = ((dis_info.mem + (value << shift)
455
2.27k
      + ((IS_CSKY_V1 (mach_flag)) ? 2 : 0))
456
2.27k
     & 0xfffffffc);
457
2.27k
  status = dis_info.info->read_memory_func (value, ibytes, 4,
458
2.27k
              dis_info.info);
459
2.27k
  if (status != 0)
460
301
    {
461
301
      dis_info.info->memory_error_func (status, dis_info.mem,
462
301
                dis_info.info);
463
301
      return -1;
464
301
    }
465
1.97k
  mem_val = csky_chars_to_number (ibytes, 4);
466
  /* Remove [] around literal value to match ABI syntax.  */
467
1.97k
  sprintf (buf, "0x%X", mem_val);
468
1.97k
  strcat (str, buf);
469
  /* For jmpi/jsri, we'll try to get a symbol for the target.  */
470
1.97k
  if (dis_info.info->print_address_func && mem_val != 0)
471
1.75k
    {
472
1.75k
      dis_info.value = mem_val;
473
1.75k
      dis_info.need_output_symbol = 1;
474
1.75k
    }
475
219
  else
476
219
    {
477
219
      sprintf (buf, "\t// from address pool at 0x%x",
478
219
         (unsigned int)value);
479
219
      strcat (str, buf);
480
219
    }
481
1.97k
  break;
482
2.27k
      }
483
91
    case OPRND_TYPE_BLOOP_OFF4b:
484
182
    case OPRND_TYPE_BLOOP_OFF12b:
485
30.1k
    case OPRND_TYPE_OFF11b:
486
30.8k
    case OPRND_TYPE_OFF16b_LSL1:
487
31.5k
    case OPRND_TYPE_IMM_OFF18b:
488
36.4k
    case OPRND_TYPE_OFF26b:
489
36.4k
      {
490
36.4k
  int shift = oprnd->shift;
491
36.4k
  if (value & ((max >> 1) + 1))
492
24.3k
    value |= ~max;
493
36.4k
  if (is_extern_symbol (dis_info.info, dis_info.mem))
494
0
    value = 0;
495
36.4k
  else if (IS_CSKY_V1 (mach_flag))
496
29.9k
    value = dis_info.mem + 2 + (value << shift);
497
6.49k
  else
498
6.49k
    value = dis_info.mem + (value << shift);
499
36.4k
  dis_info.need_output_symbol = 1;
500
36.4k
  dis_info.value= value;
501
36.4k
  sprintf (buf, "0x%x", (unsigned int)value);
502
36.4k
  strcat (str, buf);
503
36.4k
  break;
504
31.5k
      }
505
30.9k
    case OPRND_TYPE_CONSTANT:
506
30.9k
    case OPRND_TYPE_FCONSTANT:
507
30.9k
      {
508
30.9k
  int shift = oprnd->shift;
509
30.9k
  bfd_byte ibytes[8];
510
30.9k
  int status;
511
30.9k
  bfd_vma addr;
512
30.9k
  int nbytes;
513
514
30.9k
  dis_info.info->stop_vma = 0;
515
30.9k
  value <<= shift;
516
517
30.9k
  if (IS_CSKY_V1 (mach_flag))
518
14.3k
    addr = (dis_info.mem + 2 + value) & 0xfffffffc;
519
16.6k
  else
520
16.6k
    addr = (dis_info.mem + value) & 0xfffffffc;
521
522
30.9k
  if (oprnd->type == OPRND_TYPE_FCONSTANT
523
0
      && dis_info.opinfo->opcode != CSKYV2_INST_FLRW)
524
0
    nbytes = 8;
525
30.9k
  else
526
30.9k
    nbytes = 4;
527
528
30.9k
  status = dis_info.info->read_memory_func (addr, ibytes,
529
30.9k
              nbytes, dis_info.info);
530
30.9k
  if (status != 0)
531
    /* Address out of bounds.  -> lrw rx, [pc, 0ffset]. */
532
5.10k
    sprintf (buf, "[pc, %d]\t// from address pool at %x", (int)value,
533
5.10k
       (unsigned int)addr);
534
25.8k
  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
25.8k
  else
552
25.8k
    {
553
25.8k
      dis_info.value = addr;
554
25.8k
      dis_info.need_output_symbol = 1;
555
25.8k
      value = csky_chars_to_number (ibytes, 4);
556
25.8k
      sprintf (buf, "0x%x", (unsigned int) value);
557
25.8k
    }
558
559
30.9k
  strcat (str, buf);
560
30.9k
  break;
561
30.9k
      }
562
83.3k
    case OPRND_TYPE_ELRW_CONSTANT:
563
83.3k
      {
564
83.3k
  int shift = oprnd->shift;
565
83.3k
  char ibytes[4];
566
83.3k
  int status;
567
83.3k
  bfd_vma addr;
568
83.3k
  dis_info.info->stop_vma = 0;
569
570
83.3k
  value = 0x80 + ((~value) & 0x7f);
571
572
83.3k
  value = value << shift;
573
83.3k
  addr = (dis_info.mem + value) & 0xfffffffc;
574
575
83.3k
  status = dis_info.info->read_memory_func (addr, (bfd_byte *)ibytes,
576
83.3k
              4, dis_info.info);
577
83.3k
  if (status != 0)
578
    /* Address out of bounds.  -> lrw rx, [pc, 0ffset]. */
579
21.4k
    sprintf (buf, "[pc, %d]\t// from address pool at %x", (int) value,
580
21.4k
       (unsigned int)addr);
581
61.8k
  else
582
61.8k
    {
583
61.8k
      dis_info.value = addr;
584
61.8k
      value = csky_chars_to_number ((unsigned char *)ibytes, 4);
585
61.8k
      dis_info.need_output_symbol = 1;
586
61.8k
      sprintf (buf, "0x%x", (unsigned int)value);
587
61.8k
    }
588
589
83.3k
  strcat (str, buf);
590
83.3k
  break;
591
30.9k
      }
592
17
    case OPRND_TYPE_SFLOAT:
593
28
    case OPRND_TYPE_DFLOAT:
594
28
      {
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
28
  uint64_t imm4;
603
28
  uint64_t imm8;
604
28
  uint64_t dbnum;
605
28
  unsigned char valbytes[8];
606
28
  double fvalue;
607
608
28
  imm4 = ((inst >> 16) & 0xf);
609
28
  imm4 = (uint64_t)(1023 - (imm4 - 11)) << 52;
610
611
28
  imm8 = (uint64_t)((inst >> 4) & 0xf) << 44;
612
28
  imm8 |= (uint64_t)((inst >> 21) & 0xf) << 48;
613
614
28
  dbnum = (uint64_t)((inst >> 20) & 1) << 63;
615
28
  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
28
  valbytes[0] = dbnum & 0xff;
620
28
  valbytes[1] = (dbnum >> 8) & 0xff;
621
28
  valbytes[2] = (dbnum >> 16) & 0xff;
622
28
  valbytes[3] = (dbnum >> 24) & 0xff;
623
28
  valbytes[4] = (dbnum >> 32) & 0xff;
624
28
  valbytes[5] = (dbnum >> 40) & 0xff;
625
28
  valbytes[6] = (dbnum >> 48) & 0xff;
626
28
  valbytes[7] = (dbnum >> 56) & 0xff;
627
628
28
  floatformat_to_double (&floatformat_ieee_double_little, valbytes,
629
28
             &fvalue);
630
631
28
  sprintf (buf, "%.7g", fvalue);
632
28
  strcat (str, buf);
633
28
  break;
634
17
      }
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
1.22k
    case OPRND_TYPE_LABEL_WITH_BRACKET:
694
1.22k
      sprintf (buf, "[0x%x]", (unsigned int)value);
695
1.22k
      strcat (str, buf);
696
1.22k
      strcat (str, "\t// the offset is based on .data");
697
1.22k
      break;
698
5.58k
    case OPRND_TYPE_OIMM3b:
699
5.81k
    case OPRND_TYPE_OIMM4b:
700
22.4k
    case OPRND_TYPE_OIMM5b:
701
22.4k
    case OPRND_TYPE_OIMM5b_IDLY:
702
58.1k
    case OPRND_TYPE_OIMM8b:
703
58.8k
    case OPRND_TYPE_OIMM12b:
704
59.0k
    case OPRND_TYPE_OIMM16b:
705
59.1k
    case OPRND_TYPE_OIMM18b:
706
59.1k
      value += 1;
707
59.1k
      sprintf (buf, "%d", (int)value);
708
59.1k
      strcat (str, buf);
709
59.1k
      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
38
    case OPRND_TYPE_FREGLIST_DASH:
721
38
      if (IS_CSKY_V2 (mach_flag))
722
38
  {
723
38
    int vrx = 0;
724
38
    int vry = 0;
725
38
    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
38
    else
733
38
      {
734
38
        vrx = value & 0xf;
735
38
        vry = vrx + (value >> 4);
736
38
      }
737
38
    sprintf (buf, "fr%d-fr%d", vrx, vry);
738
38
    strcat (str, buf);
739
38
  }
740
38
      break;
741
1.47k
    case OPRND_TYPE_REGLIST_DASH:
742
1.47k
      if (IS_CSKY_V1 (mach_flag))
743
1.47k
  {
744
1.47k
    sprintf (buf, "%s-r15", get_gr_name (value));
745
1.47k
    strcat (str, buf);
746
1.47k
  }
747
6
      else
748
6
  {
749
6
    if ((value & 0x1f) + (value >> 5) > 31)
750
3
      {
751
3
        ret = -1;
752
3
        break;
753
3
      }
754
3
    strcat (str, get_gr_name ((value >> 5)));
755
3
    strcat (str, "-");
756
3
    strcat (str, get_gr_name ((value & 0x1f) + (value >> 5)));
757
3
  }
758
1.47k
      break;
759
1.47k
    case OPRND_TYPE_PSR_BITS_LIST:
760
150
      {
761
150
  struct psrbit const *bits;
762
150
  int first_oprnd = true;
763
150
  int i = 0;
764
150
  if (IS_CSKY_V1 (mach_flag))
765
108
    {
766
108
      if (value == 0)
767
14
        {
768
14
    strcat (str, "af");
769
14
    break;
770
14
        }
771
94
      bits = cskyv1_psr_bits;
772
94
    }
773
42
  else
774
42
    bits = cskyv2_psr_bits;
775
370
  while (value != 0 && bits[i].name != NULL)
776
234
      {
777
234
        if (value & bits[i].value)
778
204
    {
779
204
      if (!first_oprnd)
780
110
        strcat (str, ", ");
781
204
      strcat (str, bits[i].name);
782
204
      value &= ~bits[i].value;
783
204
      first_oprnd = false;
784
204
    }
785
234
        i++;
786
234
      }
787
136
  break;
788
150
      }
789
1.47k
    case OPRND_TYPE_REGbsp:
790
1.47k
      if (IS_CSKY_V1 (mach_flag))
791
1.47k
  sprintf(buf, "(%s)", get_gr_name (0));
792
0
      else
793
0
  sprintf(buf, "(%s)", get_gr_name (14));
794
1.47k
      strcat (str, buf);
795
1.47k
      break;
796
50.8k
    case OPRND_TYPE_REGsp:
797
50.8k
      if (IS_CSKY_V1 (mach_flag))
798
0
  strcat (str, get_gr_name (0));
799
50.8k
      else
800
50.8k
  strcat (str, get_gr_name (14));
801
50.8k
      break;
802
2.34k
    case OPRND_TYPE_REGnr4_r7:
803
2.39k
    case OPRND_TYPE_AREG_WITH_BRACKET:
804
2.39k
      strcat (str, "(");
805
2.39k
      strcat (str, get_gr_name (value));
806
2.39k
      strcat (str, ")");
807
2.39k
      break;
808
1.12k
    case OPRND_TYPE_AREG_WITH_LSHIFT:
809
1.12k
      strcat (str, get_gr_name (value >> 5));
810
1.12k
      strcat (str, " << ");
811
1.12k
      if ((value & 0x1f) == 0x1)
812
52
  strcat (str, "0");
813
1.07k
      else if ((value & 0x1f) == 0x2)
814
32
  strcat (str, "1");
815
1.03k
      else if ((value & 0x1f) == 0x4)
816
116
  strcat (str, "2");
817
922
      else if ((value & 0x1f) == 0x8)
818
35
  strcat (str, "3");
819
1.12k
      break;
820
171
    case OPRND_TYPE_AREG_WITH_LSHIFT_FPU:
821
171
      strcat (str, get_gr_name (value >> 2));
822
171
      strcat (str, " << ");
823
171
      if ((value & 0x3) == 0x0)
824
29
  strcat (str, "0");
825
142
      else if ((value & 0x3) == 0x1)
826
121
  strcat (str, "1");
827
21
      else if ((value & 0x3) == 0x2)
828
16
  strcat (str, "2");
829
5
      else if ((value & 0x3) == 0x3)
830
5
  strcat (str, "3");
831
171
      break;
832
10
    case OPRND_TYPE_VREG_WITH_INDEX:
833
10
      {
834
10
  unsigned freg_val = value & 0xf;
835
10
  unsigned index_val = (value >> 4) & 0xf;
836
10
  sprintf (buf, "vr%d[%d]", freg_val, index_val);
837
10
  strcat(str, buf);
838
10
  break;
839
2.34k
      }
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
2.34k
      }
848
2.34k
    case OPRND_TYPE_REGr4_r7:
849
2.34k
      if (IS_CSKY_V1 (mach_flag))
850
2.34k
  {
851
2.34k
    sprintf (buf, "%s-%s", get_gr_name (4), get_gr_name (7));
852
2.34k
    strcat (str, buf);
853
2.34k
  }
854
2.34k
      break;
855
1.66k
    case OPRND_TYPE_CONST1:
856
1.66k
      strcat (str, "1");
857
1.66k
      break;
858
3.16k
    case OPRND_TYPE_REG_r1a:
859
3.21k
    case OPRND_TYPE_REG_r1b:
860
3.21k
      strcat (str, get_gr_name (1));
861
3.21k
      break;
862
169
    case OPRND_TYPE_REG_r28:
863
169
      strcat (str, get_gr_name (28));
864
169
      break;
865
11.0k
    case OPRND_TYPE_REGLIST_DASH_COMMA:
866
      /* 16-bit reglist.  */
867
11.0k
      if (value & 0xf)
868
8.53k
  {
869
8.53k
    strcat (str, get_gr_name (4));
870
8.53k
    if ((value & 0xf) > 1)
871
5.83k
      {
872
5.83k
        strcat (str, "-");
873
5.83k
        strcat (str, get_gr_name ((value & 0xf) + 3));
874
5.83k
      }
875
8.53k
    if (value & ~0xf)
876
5.91k
      strcat (str, ", ");
877
8.53k
  }
878
11.0k
      if (value & 0x10)
879
7.51k
  {
880
    /* r15.  */
881
7.51k
    strcat (str, get_gr_name (15));
882
7.51k
    if (value & ~0x1f)
883
0
      strcat (str, ", ");
884
7.51k
  }
885
11.0k
      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.0k
      break;
905
14.5k
    case OPRND_TYPE_UNCOND10b:
906
14.9k
    case OPRND_TYPE_UNCOND16b:
907
38.8k
    case OPRND_TYPE_COND10b:
908
38.9k
    case OPRND_TYPE_COND16b:
909
38.9k
      {
910
38.9k
  int shift = oprnd->shift;
911
912
38.9k
  if (value & ((max >> 1) + 1))
913
15.5k
    value |= ~max;
914
38.9k
  if (is_extern_symbol (dis_info.info, dis_info.mem))
915
88
    value = 0;
916
38.8k
  else
917
38.8k
    value = dis_info.mem + (value << shift);
918
38.9k
  sprintf (buf, "0x%x", (unsigned int)value);
919
38.9k
  strcat (str, buf);
920
38.9k
  dis_info.need_output_symbol = 1;
921
38.9k
  dis_info.value = value;
922
38.9k
      }
923
38.9k
      break;
924
925
39
    default:
926
39
      ret = -1;
927
39
      break;
928
1.49M
    }
929
1.49M
  return ret;
930
1.49M
}
931
932
static int
933
csky_print_operand (char *str, struct operand const *oprnd,
934
        CSKY_INST_TYPE inst, int reloc)
935
1.66M
{
936
1.66M
  int ret = -1;
937
1.66M
  char *lc = "";
938
1.66M
  char *rc = "";
939
1.66M
  if (oprnd->mask == HAS_SUB_OPERAND)
940
166k
    {
941
166k
      struct soperand *sop = (struct soperand *)oprnd;
942
166k
      if (oprnd->type == OPRND_TYPE_BRACKET)
943
154k
  {
944
154k
    lc = "(";
945
154k
    rc = ")";
946
154k
  }
947
11.9k
      else if (oprnd->type == OPRND_TYPE_ABRACKET)
948
11.9k
  {
949
11.9k
    lc = "<";
950
11.9k
    rc = ">";
951
11.9k
  }
952
166k
      strcat (str, lc);
953
166k
      ret = csky_print_operand (str, &sop->subs[0], inst, reloc);
954
166k
      if (ret)
955
0
  return ret;
956
166k
      strcat (str, ", ");
957
166k
      ret = csky_print_operand (str, &sop->subs[1], inst, reloc);
958
166k
      strcat (str, rc);
959
166k
      return ret;
960
166k
    }
961
1.49M
  return csky_output_operand (str, oprnd, inst, reloc);
962
1.66M
}
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
789k
{
969
789k
  int i = 0;
970
789k
  int ret = 0;
971
789k
  if (pinfo->operand_num)
972
665k
    strcat (str, "      \t");
973
789k
  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
778k
  else
980
2.09M
    for (; i < pinfo->operand_num; i++)
981
1.31M
      {
982
1.31M
  if (i != 0)
983
663k
    strcat (str, ", ");
984
1.31M
  ret = csky_print_operand (str, &pinfo->oprnd.oprnds[i], inst, reloc);
985
1.31M
  if (ret)
986
1.58k
    return ret;
987
1.31M
      }
988
787k
  info->fprintf_func (info->stream, "%s", str);
989
787k
  if (dis_info.need_output_symbol)
990
164k
    {
991
164k
      info->fprintf_func (info->stream, "\t// ");
992
164k
      info->print_address_func (dis_info.value, dis_info.info);
993
164k
    }
994
787k
  return 0;
995
789k
}
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
940k
#define CSKY_READ_DATA()                                        \
1010
940k
{                                                               \
1011
940k
  status = info->read_memory_func (memaddr, buf, 2, info);      \
1012
940k
  if (status)                                                   \
1013
940k
    {                                                           \
1014
445
      info->memory_error_func (status, memaddr, info);          \
1015
445
      return -1;                                                \
1016
445
    }                                                           \
1017
940k
  if (info->endian == BFD_ENDIAN_BIG)                           \
1018
940k
    inst |= (buf[0] << 8) | buf[1];                             \
1019
940k
  else if (info->endian == BFD_ENDIAN_LITTLE)                   \
1020
306k
    inst |= (buf[1] << 8) | buf[0];                             \
1021
306k
  else                                                          \
1022
306k
    abort();                                                    \
1023
940k
  info->bytes_per_chunk += 2;                                   \
1024
940k
  memaddr += 2;                                                 \
1025
940k
}
1026
1027
int
1028
print_insn_csky (bfd_vma memaddr, struct disassemble_info *info)
1029
887k
{
1030
887k
  unsigned char buf[4];
1031
887k
  CSKY_INST_TYPE inst = 0;
1032
887k
  int status;
1033
887k
  char str[256];
1034
887k
  unsigned long given;
1035
887k
  int is_data = false;
1036
887k
  void (*printer) (bfd_vma, struct disassemble_info *, long);
1037
887k
  unsigned int  size = 4;
1038
1039
887k
  memset (str, 0, sizeof (str));
1040
887k
  info->bytes_per_chunk = 0;
1041
887k
  info->bytes_per_chunk = 0;
1042
887k
  dis_info.mem = memaddr;
1043
887k
  dis_info.info = info;
1044
887k
  dis_info.need_output_symbol = 0;
1045
1046
887k
  if (info->disassembler_options)
1047
628
    {
1048
628
      for_each_disassembler_option (info, parse_csky_option, NULL);
1049
628
      info->disassembler_options = NULL;
1050
628
    }
1051
1052
887k
  if (mach_flag != INIT_MACH_FLAG && mach_flag != BINARY_MACH_FLAG)
1053
573k
    info->mach = mach_flag;
1054
314k
  else if (mach_flag == INIT_MACH_FLAG)
1055
5
    {
1056
5
      mach_flag = info->mach;
1057
5
      dis_info.isa = CSKY_DEFAULT_ISA;
1058
5
    }
1059
1060
887k
  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
887k
  if (info->symtab_size != 0
1069
875
      && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
1070
875
    {
1071
875
      bfd_vma addr;
1072
875
      int n;
1073
875
      int last_sym = -1;
1074
875
      enum sym_type type = CUR_TEXT;
1075
1076
875
      if (memaddr <= last_map_addr)
1077
10
  last_map_sym = -1;
1078
      /* Start scanning at the start of the function, or wherever
1079
   we finished last time.  */
1080
875
      n = 0;
1081
875
      if (n < last_map_sym)
1082
1
  n = last_map_sym;
1083
1084
      /* Scan up to the location being disassembled.  */
1085
3.12k
      for (; n < info->symtab_size; n++)
1086
2.43k
  {
1087
2.43k
    addr = bfd_asymbol_value (info->symtab[n]);
1088
2.43k
    if (addr > memaddr)
1089
192
      break;
1090
2.24k
    if ((info->section == NULL
1091
2.24k
         || info->section == info->symtab[n]->section)
1092
1.27k
        && get_sym_code_type (info, n, &type))
1093
0
      last_sym = n;
1094
2.24k
  }
1095
875
      last_map_sym = last_sym;
1096
875
      last_type = type;
1097
875
      is_data = (last_type == CUR_DATA);
1098
875
      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
875
    }
1118
887k
  info->bytes_per_line = 4;
1119
1120
887k
  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.66M
  CSKY_READ_DATA();
1143
2.66M
  if ((inst & 0xc000) == 0xc000 && IS_CSKY_V2 (mach_flag))
1144
52.5k
    {
1145
      /* It's a 32-bit instruction.  */
1146
52.5k
      inst <<= 16;
1147
105k
      CSKY_READ_DATA();
1148
105k
      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
105k
    }
1157
1158
887k
  if (IS_CSKY_V1 (mach_flag))
1159
229k
    g_opcodeP = csky_v1_opcodes;
1160
657k
  else
1161
657k
    g_opcodeP = csky_v2_opcodes;
1162
1163
887k
  do
1164
889k
    {
1165
889k
      struct csky_opcode const *op;
1166
889k
      struct csky_opcode_info const *pinfo = NULL;
1167
889k
      int reloc;
1168
1169
889k
      memset (str, 0, sizeof (str));
1170
889k
      op = csky_find_inst_info (&pinfo, inst, info->bytes_per_chunk);
1171
889k
      if (!op)
1172
99.6k
  {
1173
99.6k
    if (IS_CSKY_V1 (mach_flag))
1174
295
      info->fprintf_func (info->stream, ".short: 0x%04x",
1175
295
        (unsigned short)inst);
1176
99.3k
    else
1177
99.3k
      info->fprintf_func (info->stream, ".long: 0x%08x",
1178
99.3k
        (unsigned int)inst);
1179
99.6k
    return info->bytes_per_chunk;
1180
99.6k
  }
1181
1182
789k
      if (info->bytes_per_chunk == 2)
1183
760k
  reloc = op->reloc16;
1184
28.4k
      else
1185
28.4k
  reloc = op->reloc32;
1186
789k
      dis_info.opinfo = pinfo;
1187
789k
      strcat (str, op->mnemonic);
1188
1189
789k
      if (csky_print_operands (str, pinfo, info, inst, reloc))
1190
1.58k
  g_opcodeP++;
1191
787k
      else
1192
787k
  break;
1193
789k
    } while (1);
1194
1195
787k
  return info->bytes_per_chunk;
1196
887k
}