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:
Cooper Qu
2020-09-17 14:30:28 +08:00
committed by Lifang Xia
parent 20a5fcbd5b
commit afdcafe891
10 changed files with 868 additions and 606 deletions
+34
View File
@@ -1,3 +1,37 @@
2020-09-17 Cooper Qu <<cooper.qu@linux.alibaba.com>>
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.
2020-09-23 Lili Cui <lili.cui@intel.com>
* i386-dis.c (enum): Add REG_0F38D8_PREFIX_1,
+84 -64
View File
@@ -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)
+420 -123
View File
@@ -20,6 +20,7 @@
02110-1301, USA. */
#include "opcode/csky.h"
#include "safe-ctype.h"
#define OP_TABLE_NUM 2
#define MAX_OPRND_NUM 5
@@ -128,6 +129,8 @@ enum operand_type
/* OPRND_TYPE_IMM5b_a_b means: Immediate in (a, b). */
OPRND_TYPE_IMM5b_1_31,
OPRND_TYPE_IMM5b_7_31,
/* OPRND_TYPE_IMM5b_LS means: Imm <= prev Imm. */
OPRND_TYPE_IMM5b_LS,
/* Operand type for rori and rotri. */
OPRND_TYPE_IMM5b_RORI,
OPRND_TYPE_IMM5b_POWER,
@@ -624,110 +627,13 @@ struct csky_opcode
#define V1_REG_SP 0
#define V1_REG_LR 15
struct csky_reg
{
const char *name;
int index;
int flag;
};
const char *csky_general_reg[] =
{
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
NULL,
};
/* TODO: optimize. */
const char *cskyv2_general_alias_reg[] =
{
"a0", "a1", "a2", "a3", "l0", "l1", "l2", "l3",
"l4", "l5", "l6", "l7", "t0", "t1", "sp", "lr",
"l8", "l9", "t2", "t3", "t4", "t5", "t6", "t7",
"t8", "t9", "r26", "r27", "rdb", "gb", "r30", "r31",
NULL,
};
/* TODO: optimize. */
const char *cskyv1_general_alias_reg[] =
{
"sp", "r1", "a0", "a1", "a2", "a3", "a4", "a5",
"fp", "l0", "l1", "l2", "l3", "l4", "gb", "lr",
NULL,
};
/* TODO: optimize. */
const char *csky_fpu_reg[] =
{
"fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
"fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
"fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
"fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31",
NULL,
};
/* Control Registers. */
struct csky_reg csky_ctrl_regs[] =
{
{"psr", 0, 0}, {"vbr", 1, 0}, {"epsr", 2, 0}, {"fpsr", 3, 0},
{"epc", 4, 0}, {"fpc", 5, 0}, {"ss0", 6, 0}, {"ss1", 7, 0},
{"ss2", 8, 0}, {"ss3", 9, 0}, {"ss4", 10, 0}, {"gcr", 11, 0},
{"gsr", 12, 0}, {"cpuidr", 13, 0}, {"dcsr", 14, 0}, {"cwr", 15, 0},
{"cfr", 16, 0}, {"ccr", 17, 0}, {"capr", 19, 0}, {"pacr", 20, 0},
{"rid", 21, 0}, {"sedcr", 8, CSKY_ISA_TRUST}, {"sepcr", 9, CSKY_ISA_TRUST},
{NULL, 0, 0}
};
const char *csky_cp_idx[] =
{
"cp0", "cp1", "cp2", "cp3", "cp4", "cp5", "cp6", "cp7",
"cp8", "cp9", "cp10", "cp11", "cp12", "cp13", "cp14", "cp15",
"cp16", "cp17", "cp18", "cp19", "cp20",
NULL,
};
const char *csky_cp_reg[] =
{
"cpr0", "cpr1", "cpr2", "cpr3", "cpr4", "cpr5", "cpr6", "cpr7",
"cpr8", "cpr9", "cpr10", "cpr11", "cpr12", "cpr13", "cpr14", "cpr15",
"cpr16", "cpr17", "cpr18", "cpr19", "cpr20", "cpr21", "cpr22", "cpr23",
"cpr24", "cpr25", "cpr26", "cpr27", "cpr28", "cpr29", "cpr30", "cpr31",
"cpr32", "cpr33", "cpr34", "cpr35", "cpr36", "cpr37", "cpr38", "cpr39",
"cpr40", "cpr41", "cpr42", "cpr43", "cpr44", "cpr45", "cpr46", "cpr47",
"cpr48", "cpr49", "cpr50", "cpr51", "cpr52", "cpr53", "cpr54", "cpr55",
"cpr56", "cpr57", "cpr58", "cpr59", "cpr60", "cpr61", "cpr62", "cpr63",
NULL,
};
const char *csky_cp_creg[] =
{
"cpcr0", "cpcr1", "cpcr2", "cpcr3",
"cpcr4", "cpcr5", "cpcr6", "cpcr7",
"cpcr8", "cpcr9", "cpcr10", "cpcr11",
"cpcr12", "cpcr13", "cpcr14", "cpcr15",
"cpcr16", "cpcr17", "cpcr18", "cpcr19",
"cpcr20", "cpcr21", "cpcr22", "cpcr23",
"cpcr24", "cpcr25", "cpcr26", "cpcr27",
"cpcr28", "cpcr29", "cpcr30", "cpcr31",
"cpcr32", "cpcr33", "cpcr34", "cpcr35",
"cpcr36", "cpcr37", "cpcr38", "cpcr39",
"cpcr40", "cpcr41", "cpcr42", "cpcr43",
"cpcr44", "cpcr45", "cpcr46", "cpcr47",
"cpcr48", "cpcr49", "cpcr50", "cpcr51",
"cpcr52", "cpcr53", "cpcr54", "cpcr55",
"cpcr56", "cpcr57", "cpcr58", "cpcr59",
"cpcr60", "cpcr61", "cpcr62", "cpcr63",
NULL,
};
struct psrbit
{
int value;
int isa;
const char *name;
};
const struct psrbit cskyv1_psr_bits[] =
{
{1, 0, "ie"},
@@ -736,6 +642,7 @@ const struct psrbit cskyv1_psr_bits[] =
{8, 0, "af"},
{0, 0, NULL},
};
const struct psrbit cskyv2_psr_bits[] =
{
{8, 0, "ee"},
@@ -746,6 +653,395 @@ const struct psrbit cskyv2_psr_bits[] =
{0, 0, NULL},
};
#define GENARAL_REG_BANK 0x80000000
#define REG_SUPPORT_ALL 0xffffffff
/* CSKY register description. */
struct csky_reg_def
{
/* The group number for control registers,
and set the bank of genaral registers to a special number. */
int bank;
int regno;
/* The name displayed by serial number. */
const char *name;
/* The name displayed by ABI infomation,
used when objdump add option -Mabi-names. */
const char *abi_name;
/* The flags indicate which arches support the register. */
int arch_flag;
/* Some registers depend on special features. */
char *features;
};
/* Arch flag. */
#define ASH(a) (1 << CSKY_ARCH_##a)
/* All arches exclued 801. */
#define REG_SUPPORT_A (REG_SUPPORT_ALL & ~ASH(801))
/* All arches exclued 801 and 802. */
#define REG_SUPPORT_B (REG_SUPPORT_ALL & ~(ASH(801) | ASH(802)))
/* All arches exclued 801, 802, 803, 805.*/
#define REG_SUPPORT_C (REG_SUPPORT_ALL & ~(ASH(801) \
| ASH(802) | ASH(803) | ASH(805)))
/* All arches exclued 801, 802, 803, 805, 807, 810. */
#define REG_SUPPORT_D (REG_SUPPORT_C & ~(ASH(807) | ASH(810)))
/* All arches exclued 807, 810, 860. */
#define REG_SUPPORT_E (REG_SUPPORT_ALL & ~(ASH(807) | ASH(810) | \
ASH(860)))
/* C-SKY V1 general registers table. */
static struct csky_reg_def csky_abiv1_general_regs[] =
{
#define DECLARE_REG(regno, abi_name, support) \
{GENARAL_REG_BANK, regno, "r"#regno, abi_name, support, NULL}
DECLARE_REG (0, "sp", REG_SUPPORT_ALL),
DECLARE_REG (1, NULL, REG_SUPPORT_ALL),
DECLARE_REG (2, "a0", REG_SUPPORT_ALL),
DECLARE_REG (3, "a1", REG_SUPPORT_ALL),
DECLARE_REG (4, "a2", REG_SUPPORT_ALL),
DECLARE_REG (5, "a3", REG_SUPPORT_ALL),
DECLARE_REG (6, "a4", REG_SUPPORT_ALL),
DECLARE_REG (7, "a5", REG_SUPPORT_ALL),
DECLARE_REG (8, "fp", REG_SUPPORT_ALL),
DECLARE_REG (8, "l0", REG_SUPPORT_ALL),
DECLARE_REG (9, "l1", REG_SUPPORT_ALL),
DECLARE_REG (10, "l2", REG_SUPPORT_ALL),
DECLARE_REG (11, "l3", REG_SUPPORT_ALL),
DECLARE_REG (12, "l4", REG_SUPPORT_ALL),
DECLARE_REG (13, "l5", REG_SUPPORT_ALL),
DECLARE_REG (14, "gb", REG_SUPPORT_ALL),
DECLARE_REG (15, "lr", REG_SUPPORT_ALL),
#undef DECLARE_REG
{-1, -1, NULL, NULL, 0, NULL},
};
/* C-SKY V1 control registers table. */
static struct csky_reg_def csky_abiv1_control_regs[] =
{
#define DECLARE_REG(regno, abi_name, support) \
{0, regno, "cr"#regno, abi_name, support, NULL}
DECLARE_REG (0, "psr", REG_SUPPORT_ALL),
DECLARE_REG (1, "vbr", REG_SUPPORT_ALL),
DECLARE_REG (2, "epsr", REG_SUPPORT_ALL),
DECLARE_REG (3, "fpsr", REG_SUPPORT_ALL),
DECLARE_REG (4, "epc", REG_SUPPORT_ALL),
DECLARE_REG (5, "fpc", REG_SUPPORT_ALL),
DECLARE_REG (6, "ss0", REG_SUPPORT_ALL),
DECLARE_REG (7, "ss1", REG_SUPPORT_ALL),
DECLARE_REG (8, "ss2", REG_SUPPORT_ALL),
DECLARE_REG (9, "ss3", REG_SUPPORT_ALL),
DECLARE_REG (10, "ss4", REG_SUPPORT_ALL),
DECLARE_REG (11, "gcr", REG_SUPPORT_ALL),
DECLARE_REG (12, "gsr", REG_SUPPORT_ALL),
DECLARE_REG (13, "cpid", REG_SUPPORT_ALL),
DECLARE_REG (14, "dcsr", REG_SUPPORT_ALL),
DECLARE_REG (15, "cwr", REG_SUPPORT_ALL),
DECLARE_REG (16, NULL, REG_SUPPORT_ALL),
DECLARE_REG (17, "cfr", REG_SUPPORT_ALL),
DECLARE_REG (18, "ccr", REG_SUPPORT_ALL),
DECLARE_REG (19, "capr", REG_SUPPORT_ALL),
DECLARE_REG (20, "pacr", REG_SUPPORT_ALL),
DECLARE_REG (21, "prsr", REG_SUPPORT_ALL),
DECLARE_REG (22, "mir", REG_SUPPORT_ALL),
DECLARE_REG (23, "mrr", REG_SUPPORT_ALL),
DECLARE_REG (24, "mel0", REG_SUPPORT_ALL),
DECLARE_REG (25, "mel1", REG_SUPPORT_ALL),
DECLARE_REG (26, "meh", REG_SUPPORT_ALL),
DECLARE_REG (27, "mcr", REG_SUPPORT_ALL),
DECLARE_REG (28, "mpr", REG_SUPPORT_ALL),
DECLARE_REG (29, "mwr", REG_SUPPORT_ALL),
DECLARE_REG (30, "mcir", REG_SUPPORT_ALL),
#undef DECLARE_REG
{-1, -1, NULL, NULL, 0, NULL},
};
/* C-SKY V2 general registers table. */
static struct csky_reg_def csky_abiv2_general_regs[] =
{
#ifdef DECLARE_REG
#undef DECLARE_REG
#endif
#define DECLARE_REG(regno, abi_name, support) \
{GENARAL_REG_BANK, regno, "r"#regno, abi_name, support, NULL}
DECLARE_REG (0, "a0", REG_SUPPORT_ALL),
DECLARE_REG (1, "a1", REG_SUPPORT_ALL),
DECLARE_REG (2, "a2", REG_SUPPORT_ALL),
DECLARE_REG (3, "a3", REG_SUPPORT_ALL),
DECLARE_REG (4, "l0", REG_SUPPORT_ALL),
DECLARE_REG (5, "l1", REG_SUPPORT_ALL),
DECLARE_REG (6, "l2", REG_SUPPORT_ALL),
DECLARE_REG (7, "l3", REG_SUPPORT_ALL),
DECLARE_REG (8, "l4", REG_SUPPORT_ALL),
DECLARE_REG (9, "l5", REG_SUPPORT_A),
DECLARE_REG (10, "l6", REG_SUPPORT_A),
DECLARE_REG (11, "l7", REG_SUPPORT_A),
DECLARE_REG (12, "t0", REG_SUPPORT_A),
DECLARE_REG (13, "t1", REG_SUPPORT_ALL),
DECLARE_REG (14, "sp", REG_SUPPORT_ALL),
DECLARE_REG (15, "lr", REG_SUPPORT_ALL),
DECLARE_REG (16, "l8", REG_SUPPORT_B),
DECLARE_REG (17, "l9", REG_SUPPORT_B),
DECLARE_REG (18, "t2", REG_SUPPORT_B),
DECLARE_REG (19, "t3", REG_SUPPORT_B),
DECLARE_REG (20, "t4", REG_SUPPORT_B),
DECLARE_REG (21, "t5", REG_SUPPORT_B),
DECLARE_REG (22, "t6", REG_SUPPORT_B),
DECLARE_REG (23, "t7", REG_SUPPORT_B),
DECLARE_REG (24, "t8", REG_SUPPORT_B),
DECLARE_REG (25, "t9", REG_SUPPORT_B),
DECLARE_REG (26, NULL, REG_SUPPORT_B),
DECLARE_REG (27, NULL, REG_SUPPORT_B),
DECLARE_REG (28, "gb", REG_SUPPORT_B),
DECLARE_REG (28, "rgb", REG_SUPPORT_B),
DECLARE_REG (28, "rdb", REG_SUPPORT_B),
DECLARE_REG (29, "tb", REG_SUPPORT_B),
DECLARE_REG (29, "rtb", REG_SUPPORT_B),
DECLARE_REG (30, "svbr", REG_SUPPORT_A),
DECLARE_REG (31, "tls", REG_SUPPORT_B),
/* The followings JAVA/BCTM's features. */
DECLARE_REG (23, "fp", REG_SUPPORT_ALL),
DECLARE_REG (24, "top", REG_SUPPORT_ALL),
DECLARE_REG (25, "bsp", REG_SUPPORT_ALL),
{-1, -1, NULL, NULL, 0, NULL},
};
/* C-SKY V2 control registers table. */
static struct csky_reg_def csky_abiv2_control_regs[] =
{
#ifdef DECLARE_REG
#undef DECLARE_REG
#endif
/* Bank0. */
#define DECLARE_REG(regno, abi_name) \
{0, regno, "cr<"#regno", 0>", abi_name, REG_SUPPORT_ALL, NULL}
DECLARE_REG (0, "psr"),
DECLARE_REG (1, "vbr"),
DECLARE_REG (2, "epsr"),
DECLARE_REG (3, "fpsr"),
DECLARE_REG (4, "epc"),
DECLARE_REG (5, "fpc"),
DECLARE_REG (6, "ss0"),
DECLARE_REG (7, "ss1"),
DECLARE_REG (8, "ss2"),
DECLARE_REG (9, "ss3"),
DECLARE_REG (10, "ss4"),
DECLARE_REG (11, "gcr"),
DECLARE_REG (12, "gsr"),
DECLARE_REG (13, "cpid"),
DECLARE_REG (14, "dcsr"),
DECLARE_REG (15, NULL),
DECLARE_REG (16, NULL),
DECLARE_REG (17, "cfr"),
DECLARE_REG (18, "ccr"),
DECLARE_REG (19, "capr"),
DECLARE_REG (20, "pacr"),
DECLARE_REG (21, "prsr"),
DECLARE_REG (22, "cir"),
DECLARE_REG (23, "ccr2"),
DECLARE_REG (24, NULL),
DECLARE_REG (25, "cer2"),
DECLARE_REG (26, NULL),
DECLARE_REG (27, NULL),
DECLARE_REG (28, "rvbr"),
DECLARE_REG (29, "rmr"),
DECLARE_REG (30, "mpid"),
#undef DECLARE_REG
#define DECLARE_REG(regno, abi_name, support) \
{0, regno, "cr<"#regno", 0>", abi_name, support, NULL}
DECLARE_REG (31, "chr", REG_SUPPORT_E),
DECLARE_REG (31, "hint", REG_SUPPORT_C),
/* Bank1. */
#undef DECLARE_REG
#define DECLARE_REG(regno, abi_name) \
{1, regno, "cr<"#regno", 1>", abi_name, REG_SUPPORT_ALL, NULL}
DECLARE_REG (14, "usp"),
DECLARE_REG (26, "cindex"),
DECLARE_REG (27, "cdata0"),
DECLARE_REG (28, "cdata1"),
DECLARE_REG (29, "cdata2"),
DECLARE_REG (30, "cdata3"),
DECLARE_REG (31, "cins"),
/* Bank2. */
#undef DECLARE_REG
#define DECLARE_REG(regno, abi_name) \
{2, regno, "cr<"#regno", 2>", abi_name, REG_SUPPORT_ALL, NULL}
DECLARE_REG (0, "fid"),
DECLARE_REG (1, "fcr"),
DECLARE_REG (2, "fesr"),
/* Bank3. */
#undef DECLARE_REG
#define DECLARE_REG(regno, abi_name) \
{3, regno, "cr<"#regno", 3>", abi_name, REG_SUPPORT_ALL, NULL}
DECLARE_REG (8, "dcr"),
DECLARE_REG (8, "sedcr"),
DECLARE_REG (9, "pcr"),
DECLARE_REG (9, "sepcr"),
/* Bank15. */
#undef DECLARE_REG
#define DECLARE_REG(regno, abi_name) \
{15, regno, "cr<"#regno", 15>", abi_name, REG_SUPPORT_ALL, NULL}
DECLARE_REG (0, "mir"),
DECLARE_REG (2, "mel0"),
DECLARE_REG (3, "mel1"),
DECLARE_REG (4, "meh"),
DECLARE_REG (6, "mpr"),
DECLARE_REG (8, "mcir"),
DECLARE_REG (28, "mpgd0"),
DECLARE_REG (29, "mpgd"),
DECLARE_REG (29, "mpgd1"),
DECLARE_REG (30, "msa0"),
DECLARE_REG (31, "msa1"),
#undef DECLARE_REG
{-1, -1, NULL, NULL, 0, NULL},
};
/* Get register name according to giving parameters,
IS_ABI controls whether is ABI name or not. */
static inline const char *
get_register_name (struct csky_reg_def *reg_table,
int arch, int bank, int regno, int is_abi)
{
static char regname[64] = {0};
unsigned int i = 0;
while (reg_table[i].name != NULL)
{
if (reg_table[i].bank == bank
&& reg_table[i].regno == regno
&& (reg_table[i].arch_flag & (1 << arch)))
{
if (is_abi && reg_table[i].abi_name)
return reg_table[i].abi_name;
else
return reg_table[i].name;
}
i++;
}
if (bank & 0x80000000)
return "unkown register";
sprintf (regname, "cr<%d, %d>", regno, bank);
return regname;
}
/* Get register number according to giving parameters.
If not found, return -1. */
static inline int
get_register_number (struct csky_reg_def *reg_table,
int arch, char *s, char **end, int *bank)
{
unsigned int i = 0;
int len = 0;
while (reg_table[i].name != NULL)
{
len = strlen (reg_table[i].name);
if ((strncasecmp (reg_table[i].name, s, len) == 0)
&& !(ISDIGIT (s[len]))
&& (reg_table[i].arch_flag & (1 << arch)))
{
*end = s + len;
*bank = reg_table[i].bank;
return reg_table[i].regno;
}
if (reg_table[i].abi_name == NULL)
{
i++;
continue;
}
len = strlen (reg_table[i].abi_name);
if ((strncasecmp (reg_table[i].abi_name, s, len) == 0)
&& !(ISALNUM (s[len]))
&& (reg_table[i].arch_flag & (1 << arch)))
{
*end = s + len;
*bank = reg_table[i].bank;
return reg_table[i].regno;
}
i++;
}
return -1;
}
/* Return general register's name. */
static inline const char *
csky_get_general_reg_name (int arch, int regno, int is_abi)
{
struct csky_reg_def *reg_table;
if (IS_CSKY_ARCH_V1(arch))
reg_table = csky_abiv1_general_regs;
else
reg_table = csky_abiv2_general_regs;
return get_register_name (reg_table, arch,
GENARAL_REG_BANK, regno, is_abi);
}
/* Return general register's number. */
static inline int
csky_get_general_regno(int arch, char *s, char **end)
{
struct csky_reg_def *reg_table;
int bank = 0;
if (IS_CSKY_ARCH_V1(arch))
reg_table = csky_abiv1_general_regs;
else
reg_table = csky_abiv2_general_regs;
return get_register_number (reg_table, arch, s, end, &bank);
}
/* Return control register's name. */
static inline const char *
csky_get_control_reg_name (int arch, int bank, int regno, int is_abi)
{
struct csky_reg_def *reg_table;
if (IS_CSKY_ARCH_V1(arch))
reg_table = csky_abiv1_control_regs;
else
reg_table = csky_abiv2_control_regs;
return get_register_name (reg_table, arch, bank,
regno, is_abi);
}
/* Return control register's number. */
static inline int
csky_get_control_regno(int arch, char *s, char **end, int *bank)
{
struct csky_reg_def *reg_table;
if (IS_CSKY_ARCH_V1(arch))
reg_table = csky_abiv1_control_regs;
else
reg_table = csky_abiv2_control_regs;
return get_register_number (reg_table, arch, s, end, bank);
}
/* C-SKY V1 opcodes. */
const struct csky_opcode csky_v1_opcodes[] =
@@ -3620,13 +3916,13 @@ const struct csky_opcode csky_v2_opcodes[] =
#undef _TRANSFER
#define _TRANSFER 0
DOP16_DOP32 ("bclri",
OPCODE_INFO2 (0x3880,
(8_10, GREG0_7, OPRND_SHIFT_0_BIT),
(0_4, IMM5b, OPRND_SHIFT_0_BIT)),
OPCODE_INFO3 (0x3880,
(8_10, GREG0_7, OPRND_SHIFT_0_BIT),
(NONE, DUMMY_REG, OPRND_SHIFT_0_BIT),
(0_4, IMM5b, OPRND_SHIFT_0_BIT)),
OPCODE_INFO2 (0x3880,
(8_10, GREG0_7, OPRND_SHIFT_0_BIT),
(0_4, IMM5b, OPRND_SHIFT_0_BIT)),
CSKYV2_ISA_E1,
OPCODE_INFO3 (0xc4002820,
(0_4, AREG, OPRND_SHIFT_0_BIT),
@@ -3637,13 +3933,13 @@ const struct csky_opcode csky_v2_opcodes[] =
(21_25, IMM5b, OPRND_SHIFT_0_BIT)),
CSKYV2_ISA_1E2),
DOP16_DOP32 ("bseti",
OPCODE_INFO2 (0x38a0,
(8_10, GREG0_7, OPRND_SHIFT_0_BIT),
(0_4, IMM5b, OPRND_SHIFT_0_BIT)),
OPCODE_INFO3 (0x38a0,
(8_10, GREG0_7, OPRND_SHIFT_0_BIT),
(NONE, DUMMY_REG, OPRND_SHIFT_0_BIT),
(0_4, IMM5b, OPRND_SHIFT_0_BIT)),
OPCODE_INFO2 (0x38a0,
(8_10, GREG0_7, OPRND_SHIFT_0_BIT),
(0_4, IMM5b, OPRND_SHIFT_0_BIT)),
CSKYV2_ISA_E1,
OPCODE_INFO3 (0xc4002840,
(0_4, AREG, OPRND_SHIFT_0_BIT),
@@ -3707,23 +4003,24 @@ const struct csky_opcode csky_v2_opcodes[] =
(16_20, AREG, OPRND_SHIFT_0_BIT),
(21_25, IMM5b, OPRND_SHIFT_0_BIT)),
CSKYV2_ISA_1E2),
DOP16_DOP32 ("addc",
OPCODE_INFO2 (0x6001,
(6_9, GREG0_15, OPRND_SHIFT_0_BIT),
(2_5, GREG0_15, OPRND_SHIFT_0_BIT)),
OPCODE_INFO3 (0x6001,
(6_9, GREG0_15, OPRND_SHIFT_0_BIT),
(2_5, 2IN1_DUMMY, OPRND_SHIFT_0_BIT),
(2_5, 2IN1_DUMMY, OPRND_SHIFT_0_BIT)),
CSKYV2_ISA_E1,
OPCODE_INFO3 (0xc4000040,
(0_4, AREG, OPRND_SHIFT_0_BIT),
(16_20, AREG, OPRND_SHIFT_0_BIT),
(21_25, AREG, OPRND_SHIFT_0_BIT)),
OPCODE_INFO2 (0xc4000040,
(0_4or16_20, DUP_AREG, OPRND_SHIFT_0_BIT),
(21_25, AREG, OPRND_SHIFT_0_BIT)),
CSKYV2_ISA_1E2),
DOP16_DOP32_WITH_WORK ("addc",
OPCODE_INFO2 (0x6001,
(6_9, GREG0_15, OPRND_SHIFT_0_BIT),
(2_5, GREG0_15, OPRND_SHIFT_0_BIT)),
OPCODE_INFO3 (0x6001,
(6_9, GREG0_15, OPRND_SHIFT_0_BIT),
(2_5, GREG0_15, OPRND_SHIFT_0_BIT),
(2_5, GREG0_15, OPRND_SHIFT_0_BIT)),
CSKYV2_ISA_E1,
OPCODE_INFO3 (0xc4000040,
(0_4, AREG, OPRND_SHIFT_0_BIT),
(16_20, AREG, OPRND_SHIFT_0_BIT),
(21_25, AREG, OPRND_SHIFT_0_BIT)),
OPCODE_INFO2 (0xc4000040,
(0_4or16_20, AREG, OPRND_SHIFT_0_BIT),
(21_25, AREG, OPRND_SHIFT_0_BIT)),
CSKYV2_ISA_1E2,
v2_work_addc),
DOP16_DOP32 ("subc",
OPCODE_INFO2 (0x6003,
(6_9, GREG0_15, OPRND_SHIFT_0_BIT),
@@ -4015,14 +4312,14 @@ const struct csky_opcode csky_v2_opcodes[] =
(0_4, AREG, OPRND_SHIFT_0_BIT),
(16_20, AREG, OPRND_SHIFT_0_BIT),
(5_9, IMM5b, OPRND_SHIFT_0_BIT),
(21_25, IMM5b, OPRND_SHIFT_0_BIT)),
(21_25, IMM5b_LS, OPRND_SHIFT_0_BIT)),
CSKYV2_ISA_2E3),
OP32 ("sext",
OPCODE_INFO4 (0xc4005800,
(0_4, AREG, OPRND_SHIFT_0_BIT),
(16_20, AREG, OPRND_SHIFT_0_BIT),
(5_9, IMM5b, OPRND_SHIFT_0_BIT),
(21_25, IMM5b, OPRND_SHIFT_0_BIT)),
(21_25, IMM5b_LS, OPRND_SHIFT_0_BIT)),
CSKYV2_ISA_2E3),
#undef _TRANSFER
#define _TRANSFER 2