Coverage Report

Created: 2026-07-25 10:20

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