mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-06 14:49:38 +08:00
CSKY: Add objdump option -M abi-names.
Add option parser for disassembler, and refine the codes of parse register operand and disassemble register operand. While strengthen the operands legality check of some instructions. Co-Authored-By: Lifang Xia <lifang_xia@c-sky.com> gas/ * config/tc-csky.c (parse_type_ctrlreg): Use function csky_get_control_regno to operand. (csky_get_reg_val): Likewise. (is_reg_sp_with_bracket): Use function csky_get_reg_val to parse operand. (is_reg_sp): Refine. (is_oimm_within_range): Fix, report error when operand is not constant. (parse_type_cpreg): Refine. (parse_type_cpcreg): Refine. (get_operand_value): Add handle of OPRND_TYPE_IMM5b_LS. (md_assemble): Fix no error reporting somtimes when operands number are not fit. (csky_addc64): Refine. (csky_subc64): Refine. (csky_or64): Refine. (v1_work_fpu_fo): Refine. (v1_work_fpu_read): Refine. (v1_work_fpu_writed): Refine. (v1_work_fpu_readd): Refine. (v2_work_addc): New function, strengthen the operands legality check of addc. * gas/testsuite/gas/csky/all.d : Use register number format when disassemble register name by default. * gas/testsuite/gas/csky/cskyv2_all.d : Likewise. * gas/testsuite/gas/csky/trust.d: Likewise. * gas/testsuite/gas/csky/cskyv2_ck860.d : Fix. * gas/testsuite/gas/csky/trust.s : Fix. opcodes/ * csky-dis.c (using_abi): New. (parse_csky_dis_options): New function. (get_gr_name): New function. (get_cr_name): New function. (csky_output_operand): Use get_gr_name and get_cr_name to disassemble and add handle of OPRND_TYPE_IMM5b_LS. (print_insn_csky): Parse disassembler options. * opcodes/csky-opc.h (OPRND_TYPE_IMM5b_LS): New enum. (GENARAL_REG_BANK): Define. (REG_SUPPORT_ALL): Define. (REG_SUPPORT_ALL): New. (ASH): Define. (REG_SUPPORT_A): Define. (REG_SUPPORT_B): Define. (REG_SUPPORT_C): Define. (REG_SUPPORT_D): Define. (REG_SUPPORT_E): Define. (csky_abiv1_general_regs): New. (csky_abiv1_control_regs): New. (csky_abiv2_general_regs): New. (csky_abiv2_control_regs): New. (get_register_name): New function. (get_register_number): New function. (csky_get_general_reg_name): New function. (csky_get_general_regno): New function. (csky_get_control_reg_name): New function. (csky_get_control_regno): New function. (csky_v2_opcodes): Prefer two oprerans format for bclri and bseti, strengthen the operands legality check of addc, zext and sext.
This commit is contained in:
@ -60,6 +60,7 @@ struct csky_dis_info
|
||||
enum sym_type last_type;
|
||||
int last_map_sym = 1;
|
||||
bfd_vma last_map_addr = 0;
|
||||
int using_abi = 0;
|
||||
|
||||
/* Only for objdump tool. */
|
||||
#define INIT_MACH_FLAG 0xffffffff
|
||||
@ -262,6 +263,40 @@ csky_get_disassembler (bfd *abfd)
|
||||
return print_insn_csky;
|
||||
}
|
||||
|
||||
/* Parse the string of disassembler options. */
|
||||
static void
|
||||
parse_csky_dis_options (const char *opts_in)
|
||||
{
|
||||
char *opts = xstrdup (opts_in);
|
||||
char *opt = opts;
|
||||
char *opt_end = opts;
|
||||
|
||||
for (; opt_end != NULL; opt = opt_end + 1)
|
||||
{
|
||||
if ((opt_end = strchr (opt, ',')) != NULL)
|
||||
*opt_end = 0;
|
||||
if (strcmp (opt, "abi-names") == 0)
|
||||
using_abi = 1;
|
||||
else
|
||||
fprintf (stderr,
|
||||
"unrecognized disassembler option: %s", opt);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get general register name. */
|
||||
static const char *
|
||||
get_gr_name (int regno)
|
||||
{
|
||||
return csky_get_general_reg_name (mach_flag & CSKY_ABI_MASK, regno, using_abi);
|
||||
}
|
||||
|
||||
/* Get control register name. */
|
||||
static const char *
|
||||
get_cr_name (unsigned int regno, int bank)
|
||||
{
|
||||
return csky_get_control_reg_name (mach_flag & CSKY_ABI_MASK, bank, regno, using_abi);
|
||||
}
|
||||
|
||||
static int
|
||||
csky_output_operand (char *str, struct operand const *oprnd,
|
||||
CSKY_INST_TYPE inst, int reloc ATTRIBUTE_UNUSED)
|
||||
@ -289,30 +324,10 @@ csky_output_operand (char *str, struct operand const *oprnd,
|
||||
switch (oprnd->type)
|
||||
{
|
||||
case OPRND_TYPE_CTRLREG:
|
||||
if (IS_CSKY_V1 (mach_flag))
|
||||
{
|
||||
/* In V1 only cr0-cr12 have alias names. */
|
||||
if (value <= 12)
|
||||
strcat (str, csky_ctrl_regs[value].name);
|
||||
/* Others using crn(n > 12). */
|
||||
else if (value <= 30)
|
||||
{
|
||||
sprintf (buf, "cr%d", (int)value);
|
||||
strcat (str, buf);
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int sel;
|
||||
int crx;
|
||||
sel = value >> 5;
|
||||
crx = value & 0x1f;
|
||||
sprintf (buf, "cr<%d, %d>", crx, sel);
|
||||
strcat (str, buf);
|
||||
}
|
||||
break;
|
||||
if (IS_CSKY_V1(mach_flag) && ((value & 0x1f) == 0x1f))
|
||||
return -1;
|
||||
strcat (str, get_cr_name((value & 0x1f), (value >> 5)));
|
||||
break;
|
||||
case OPRND_TYPE_DUMMY_REG:
|
||||
mask = dis_info.opinfo->oprnd.oprnds[0].mask;
|
||||
value = inst & mask;
|
||||
@ -323,21 +338,18 @@ csky_output_operand (char *str, struct operand const *oprnd,
|
||||
bit++;
|
||||
}
|
||||
value = result;
|
||||
strcat (str, csky_general_reg[value]);
|
||||
strcat (str, get_gr_name (value));
|
||||
break;
|
||||
case OPRND_TYPE_GREG0_7:
|
||||
case OPRND_TYPE_GREG0_15:
|
||||
case OPRND_TYPE_GREG16_31:
|
||||
case OPRND_TYPE_REGnsplr:
|
||||
case OPRND_TYPE_AREG:
|
||||
if (IS_CSKY_V2 (mach_flag) && value == 14)
|
||||
strcat (str, "sp");
|
||||
else
|
||||
strcat (str, csky_general_reg[value]);
|
||||
dis_info.value = value;
|
||||
strcat (str, get_gr_name (value));
|
||||
break;
|
||||
case OPRND_TYPE_CPREG:
|
||||
strcat (str, csky_cp_reg[value]);
|
||||
sprintf (buf, "cpr%d", (int)value);
|
||||
strcat (str, buf);
|
||||
break;
|
||||
case OPRND_TYPE_FREG:
|
||||
sprintf (buf, "fr%d", (int)value);
|
||||
@ -349,10 +361,12 @@ csky_output_operand (char *str, struct operand const *oprnd,
|
||||
strcat (str, buf);
|
||||
break;
|
||||
case OPRND_TYPE_CPCREG:
|
||||
strcat (str, csky_cp_creg[value]);
|
||||
sprintf (buf, "cpcr%d", (int)value);
|
||||
strcat (str, buf);
|
||||
break;
|
||||
case OPRND_TYPE_CPIDX:
|
||||
strcat (str, csky_cp_idx[value]);
|
||||
sprintf (buf, "cp%d", (int)value);
|
||||
strcat (str, buf);
|
||||
break;
|
||||
case OPRND_TYPE_IMM2b_JMPIX:
|
||||
value = (value + 2) << 3;
|
||||
@ -419,6 +433,7 @@ csky_output_operand (char *str, struct operand const *oprnd,
|
||||
case OPRND_TYPE_IMM2b:
|
||||
case OPRND_TYPE_IMM4b:
|
||||
case OPRND_TYPE_IMM5b:
|
||||
case OPRND_TYPE_IMM5b_LS:
|
||||
case OPRND_TYPE_IMM7b:
|
||||
case OPRND_TYPE_IMM8b:
|
||||
case OPRND_TYPE_IMM12b:
|
||||
@ -734,14 +749,19 @@ csky_output_operand (char *str, struct operand const *oprnd,
|
||||
case OPRND_TYPE_REGLIST_DASH:
|
||||
if (IS_CSKY_V1 (mach_flag))
|
||||
{
|
||||
strcat (str, csky_general_reg[value]);
|
||||
strcat (str, "-r15");
|
||||
sprintf (buf, "%s-r15", get_gr_name (value));
|
||||
strcat (str, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat (str, csky_general_reg[value >> 5]);
|
||||
if ((value & 0x1f) + (value >> 5) > 31)
|
||||
{
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
strcat (str, get_gr_name ((value >> 5)));
|
||||
strcat (str, "-");
|
||||
strcat (str, csky_general_reg[(value & 0x1f) + (value >> 5)]);
|
||||
strcat (str, get_gr_name ((value & 0x1f) + (value >> 5)));
|
||||
}
|
||||
break;
|
||||
case OPRND_TYPE_PSR_BITS_LIST:
|
||||
@ -776,33 +796,25 @@ csky_output_operand (char *str, struct operand const *oprnd,
|
||||
}
|
||||
case OPRND_TYPE_REGbsp:
|
||||
if (IS_CSKY_V1 (mach_flag))
|
||||
strcat (str, "(sp)");
|
||||
sprintf(buf, "(%s)", get_gr_name (0));
|
||||
else
|
||||
strcat (str, "(sp)");
|
||||
sprintf(buf, "(%s)", get_gr_name (14));
|
||||
strcat (str, buf);
|
||||
break;
|
||||
case OPRND_TYPE_REGsp:
|
||||
if (IS_CSKY_V1 (mach_flag))
|
||||
strcat (str, "sp");
|
||||
strcat (str, get_gr_name (0));
|
||||
else
|
||||
strcat (str, "sp");
|
||||
strcat (str, get_gr_name (14));
|
||||
break;
|
||||
case OPRND_TYPE_REGnr4_r7:
|
||||
case OPRND_TYPE_AREG_WITH_BRACKET:
|
||||
if (IS_CSKY_V1 (mach_flag) && (value < 4 || value > 7))
|
||||
{
|
||||
strcat (str, "(");
|
||||
strcat (str, csky_general_reg[value]);
|
||||
strcat (str, ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat (str, "(");
|
||||
strcat (str, csky_general_reg[value]);
|
||||
strcat (str, ")");
|
||||
}
|
||||
strcat (str, "(");
|
||||
strcat (str, get_gr_name (value));
|
||||
strcat (str, ")");
|
||||
break;
|
||||
case OPRND_TYPE_AREG_WITH_LSHIFT:
|
||||
strcat (str, csky_general_reg[value >> 5]);
|
||||
strcat (str, get_gr_name (value >> 5));
|
||||
strcat (str, " << ");
|
||||
if ((value & 0x1f) == 0x1)
|
||||
strcat (str, "0");
|
||||
@ -814,7 +826,7 @@ csky_output_operand (char *str, struct operand const *oprnd,
|
||||
strcat (str, "3");
|
||||
break;
|
||||
case OPRND_TYPE_AREG_WITH_LSHIFT_FPU:
|
||||
strcat (str, csky_general_reg[value >> 2]);
|
||||
strcat (str, get_gr_name (value >> 2));
|
||||
strcat (str, " << ");
|
||||
if ((value & 0x3) == 0x0)
|
||||
strcat (str, "0");
|
||||
@ -835,27 +847,28 @@ csky_output_operand (char *str, struct operand const *oprnd,
|
||||
}
|
||||
case OPRND_TYPE_REGr4_r7:
|
||||
if (IS_CSKY_V1 (mach_flag))
|
||||
strcat (str, "r4-r7");
|
||||
sprintf (buf, "%s-%s", get_gr_name (4), get_gr_name (7));
|
||||
strcat (str, buf);
|
||||
break;
|
||||
case OPRND_TYPE_CONST1:
|
||||
strcat (str, "1");
|
||||
break;
|
||||
case OPRND_TYPE_REG_r1a:
|
||||
case OPRND_TYPE_REG_r1b:
|
||||
strcat (str, "r1");
|
||||
strcat (str, get_gr_name (1));
|
||||
break;
|
||||
case OPRND_TYPE_REG_r28:
|
||||
strcat (str, "r28");
|
||||
strcat (str, get_gr_name (28));
|
||||
break;
|
||||
case OPRND_TYPE_REGLIST_DASH_COMMA:
|
||||
/* 16-bit reglist. */
|
||||
if (value & 0xf)
|
||||
{
|
||||
strcat (str, "r4");
|
||||
strcat (str, get_gr_name (4));
|
||||
if ((value & 0xf) > 1)
|
||||
{
|
||||
strcat (str, "-");
|
||||
strcat (str, csky_general_reg[(value & 0xf) + 3]);
|
||||
strcat (str, get_gr_name ((value & 0xf) + 3));
|
||||
}
|
||||
if (value & ~0xf)
|
||||
strcat (str, ", ");
|
||||
@ -863,7 +876,7 @@ csky_output_operand (char *str, struct operand const *oprnd,
|
||||
if (value & 0x10)
|
||||
{
|
||||
/* r15. */
|
||||
strcat (str, "r15");
|
||||
strcat (str, get_gr_name (15));
|
||||
if (value & ~0x1f)
|
||||
strcat (str, ", ");
|
||||
}
|
||||
@ -873,18 +886,18 @@ csky_output_operand (char *str, struct operand const *oprnd,
|
||||
value >>= 5;
|
||||
if (value & 0x3)
|
||||
{
|
||||
strcat (str, "r16");
|
||||
strcat (str, get_gr_name (16));
|
||||
if ((value & 0x7) > 1)
|
||||
{
|
||||
strcat (str, "-");
|
||||
strcat (str, csky_general_reg[(value & 0xf) + 15]);
|
||||
strcat (str, get_gr_name ((value & 0x7) + 15));
|
||||
}
|
||||
if (value & ~0x7)
|
||||
strcat (str, ", ");
|
||||
}
|
||||
if (value & 0x8)
|
||||
/* r15. */
|
||||
strcat (str, "r28");
|
||||
strcat (str, get_gr_name (28));
|
||||
}
|
||||
break;
|
||||
case OPRND_TYPE_UNCOND10b:
|
||||
@ -1027,6 +1040,13 @@ print_insn_csky (bfd_vma memaddr, struct disassemble_info *info)
|
||||
dis_info.mem = memaddr;
|
||||
dis_info.info = info;
|
||||
dis_info.need_output_symbol = 0;
|
||||
|
||||
if (info->disassembler_options)
|
||||
{
|
||||
parse_csky_dis_options (info->disassembler_options);
|
||||
info->disassembler_options = NULL;
|
||||
}
|
||||
|
||||
if (mach_flag != INIT_MACH_FLAG && mach_flag != BINARY_MACH_FLAG)
|
||||
info->mach = mach_flag;
|
||||
else if (mach_flag == INIT_MACH_FLAG)
|
||||
|
Reference in New Issue
Block a user