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

View File

@@ -1,3 +1,33 @@
20200-09-17 Cooper Qu <cooper.qu@linux.alibaba.com>
* 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.
2020-09-23 Lili Cui <lili.cui@intel.com>

View File

@@ -174,6 +174,7 @@ bfd_boolean float_work_fmovi (void);
bfd_boolean dsp_work_bloop (void);
bfd_boolean float_work_fpuv3_fmovi (void);
bfd_boolean float_work_fpuv3_fstore (void);
bfd_boolean v2_work_addc (void);
/* csky-opc.h must be included after workers are declared. */
#include "opcodes/csky-opc.h"
@@ -2508,133 +2509,101 @@ static bfd_boolean
parse_type_ctrlreg (char** oper)
{
int i = -1;
int len = 0;
int group = 0;
int crx;
int sel;
char *s = *oper;
expressionS e;
if (TOLOWER (*(*oper + 0)) == 'c'
&& TOLOWER (*(*oper + 1)) == 'r'
&& ISDIGIT (*(*oper + 2)))
{
/* The control registers are named crxx. */
i = *(*oper + 2) - 0x30;
i = ISDIGIT (*(*oper + 3)) ? (*(*oper + 3) - 0x30) + 10 * i : i;
len = ISDIGIT (*(*oper + 3)) ? 4 : 3;
*oper += len;
}
else if (!(TOLOWER (*(*oper + 0)) == 'c'
&& TOLOWER (*(*oper + 1)) == 'r'))
{
/* The control registers are aliased. */
struct csky_reg *reg = &csky_ctrl_regs[0];
while (reg->name)
{
if (memcmp (*oper, reg->name, strlen (reg->name)) == 0
&& (!reg->flag || (isa_flag & reg->flag)))
{
i = reg->index;
len = strlen (reg->name);
*oper += len;
break;
}
reg++;
s = *oper+2;
s = parse_exp (s, &e);
if (e.X_op == O_constant)
{
i = e.X_add_number;
*oper = s;
}
}
if (IS_CSKY_V2 (mach_flag))
{
char *s = *oper;
int crx;
int sel;
s = *oper;
if (i != -1)
{
crx = i;
sel = 0;
sel = group;
}
else if (TOLOWER (*(*oper + 0)) == 'c'
&& TOLOWER (*(*oper + 1)) == 'r')
{
s += 2;
if (*s != '<')
{
SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
return FALSE;
}
s++;
crx = strtol(s, &s, 10);
if (crx < 0 || crx > 31 || *s != ',')
{
SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
return FALSE;
}
s++;
sel = strtol(s, &s, 10);
if (sel < 0 || sel > 31 || *s != '>')
{
SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
return FALSE;
}
s++;
}
else
{
if (s[0] == 'c' && s[1] == 'r')
crx = csky_get_control_regno (mach_flag & CSKY_ARCH_MASK,
s, &s, &sel);
if (crx < 0)
{
s += 2;
if (*s == '<')
{
s++;
if (s[0] == '3' && s[1] >= '0' && s[1] <= '1')
{
crx = 30 + s[1] - '0';
s += 2;
}
else if (s[0] == '2' && s[1] >= '0' && s[1] <= '9')
{
crx = 20 + s[1] - '0';
s += 2;
}
else if (s[0] == '1' && s[1] >= '0' && s[1] <= '9')
{
crx = 10 + s[1] - '0';
s += 2;
}
else if (s[0] >= '0' && s[0] <= '9')
{
crx = s[0] - '0';
s += 1;
}
else
{
SET_ERROR_STRING (ERROR_REG_OVER_RANGE, "control");
return FALSE;
}
if (*s == ',')
s++;
else
{
SET_ERROR_STRING (ERROR_CREG_ILLEGAL, NULL);
return FALSE;
}
char *pS = s;
while (*pS != '>' && !is_end_of_line[(unsigned char) *pS])
pS++;
if (*pS == '>')
*pS = '\0';
else
{
/* Error. Missing '>'. */
SET_ERROR_STRING (ERROR_MISSING_RANGLE_BRACKETS, NULL);
return FALSE;
}
expressionS e;
s = parse_exp (s, &e);
if (e.X_op == O_constant
&& e.X_add_number >= 0
&& e.X_add_number <= 31)
{
*oper = s;
sel = e.X_add_number;
}
else
return FALSE;
}
else
{
/* Error. Missing '<'. */
SET_ERROR_STRING (ERROR_MISSING_LANGLE_BRACKETS, NULL);
return FALSE;
}
}
else
{
SET_ERROR_STRING (ERROR_CREG_ILLEGAL, NULL);
SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
return FALSE;
}
}
i = (sel << 5) | crx;
}
else if (i == -1)
{
i = csky_get_control_regno (mach_flag & CSKY_ARCH_MASK,
s, &s, &sel);
if (i < 0)
{
SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
return FALSE;
}
}
*oper = s;
csky_insn.val[csky_insn.idx++] = i;
return TRUE;
}
static int
csky_get_reg_val (char *str, int *len)
{
int regno = 0;
char *s = str;
regno = csky_get_general_regno (mach_flag & CSKY_ARCH_MASK, str, &s);
*len = (s - str);
return regno;
}
static bfd_boolean
is_reg_sp_with_bracket (char **oper)
{
const char **regs;
int reg;
int sp_idx;
int len;
@@ -2646,40 +2615,30 @@ is_reg_sp_with_bracket (char **oper)
if (**oper != '(')
return FALSE;
*oper += 1;
regs = csky_general_reg;
len = strlen (regs[sp_idx]);
if (memcmp (*oper, regs[sp_idx], len) == 0)
reg = csky_get_reg_val (*oper, &len);
*oper += len;
if (reg == sp_idx)
{
*oper += len;
if (**oper != ')')
return FALSE;
{
SET_ERROR_STRING (ERROR_UNDEFINE,
"Operand format is error. '(sp)' expected");
return FALSE;
}
*oper += 1;
csky_insn.val[csky_insn.idx++] = sp_idx;
return TRUE;
}
else
{
if (IS_CSKY_V1 (mach_flag))
regs = cskyv1_general_alias_reg;
else
regs = cskyv2_general_alias_reg;
len = strlen (regs[sp_idx]);
if (memcmp (*oper, regs[sp_idx], len) == 0)
{
*oper += len;
if (**oper != ')')
return FALSE;
*oper += 1;
return TRUE;
}
}
SET_ERROR_STRING (ERROR_UNDEFINE,
"Operand format is error. '(sp)' expected");
return FALSE;
}
static bfd_boolean
is_reg_sp (char **oper)
{
const char **regs;
char sp_name[16];
int sp_idx;
int len;
if (IS_CSKY_V1 (mach_flag))
@@ -2687,185 +2646,25 @@ is_reg_sp (char **oper)
else
sp_idx = 14;
regs = csky_general_reg;
len = strlen (regs[sp_idx]);
if (memcmp (*oper, regs[sp_idx], len) == 0)
/* ABI names: "sp". */
if (memcmp (*oper, "sp", 2) == 0)
{
*oper += 2;
csky_insn.val[csky_insn.idx++] = sp_idx;
return TRUE;
}
len = sprintf (sp_name, "r%d", sp_idx);
if (memcmp (*oper, sp_name, len) == 0)
{
*oper += len;
csky_insn.val[csky_insn.idx++] = sp_idx;
return TRUE;
}
else
{
if (IS_CSKY_V1 (mach_flag))
regs = cskyv1_general_alias_reg;
else
regs = cskyv2_general_alias_reg;
len = strlen (regs[sp_idx]);
if (memcmp (*oper, regs[sp_idx], len) == 0)
{
*oper += len;
csky_insn.val[csky_insn.idx++] = sp_idx;
return TRUE;
}
}
return FALSE;
}
static int
csky_get_reg_val (char *str, int *len)
{
long reg = 0;
if (TOLOWER (str[0]) == 'r' && ISDIGIT (str[1]))
{
if (ISDIGIT (str[1]) && ISDIGIT (str[2]))
{
reg = (str[1] - '0') * 10 + str[2] - '0';
*len = 3;
}
else if (ISDIGIT (str[1]))
{
reg = str[1] - '0';
*len = 2;
}
else
return -1;
}
else if (TOLOWER (str[0]) == 's' && TOLOWER (str[1]) == 'p'
&& !ISDIGIT (str[2]))
{
/* sp. */
if (IS_CSKY_V1 (mach_flag))
reg = 0;
else
reg = 14;
*len = 2;
}
else if (TOLOWER (str[0]) == 'g' && TOLOWER (str[1]) == 'b'
&& !ISDIGIT (str[2]))
{
/* gb. */
if (IS_CSKY_V1 (mach_flag))
reg = 14;
else
reg = 28;
*len = 2;
}
else if (TOLOWER (str[0]) == 'l' && TOLOWER (str[1]) == 'r'
&& !ISDIGIT (str[2]))
{
/* lr. */
reg = 15;
*len = 2;
}
else if (TOLOWER (str[0]) == 't' && TOLOWER (str[1]) == 'l'
&& TOLOWER (str[2]) == 's' && !ISDIGIT (str[3]))
{
/* tls. */
if (IS_CSKY_V2 (mach_flag))
reg = 31;
else
return -1;
*len = 3;
}
else if (TOLOWER (str[0]) == 's' && TOLOWER (str[1]) == 'v'
&& TOLOWER (str[2]) == 'b' && TOLOWER (str[3]) == 'r')
{
if (IS_CSKY_V2 (mach_flag))
reg = 30;
else
return -1;
*len = 4;
}
else if (TOLOWER (str[0]) == 'a')
{
if (ISDIGIT (str[1]) && !ISDIGIT (str[2]))
{
if (IS_CSKY_V1 (mach_flag) && (str[1] - '0') <= 5)
/* a0 - a5. */
reg = 2 + str[1] - '0';
else if (IS_CSKY_V2 (mach_flag) && (str[1] - '0') <= 3)
/* a0 - a3. */
reg = str[1] - '0';
else
return -1;
*len = 2;
}
}
else if (TOLOWER (str[0]) == 't')
{
if (IS_CSKY_V2 (mach_flag))
{
reg = atoi (str + 1);
if (reg > 9)
return -1;
if (reg > 1)
/* t2 - t9. */
reg = reg + 16;
else
/* t0 - t1. */
reg = reg + 12;
*len = 2;
}
}
else if (TOLOWER (str[0]) == 'l')
{
if (str[1] < '0' || str[1] > '9')
return -1;
if (IS_CSKY_V2 (mach_flag))
{
reg = atoi (str + 1);
if (reg > 9)
return -1;
if (reg > 7)
/* l8 - l9. */
reg = reg + 8;
else
/* l0 - l7. */
reg = reg + 4;
}
else
{
reg = atoi (str + 1);
if (reg > 5)
return -1;
/* l0 - l6 -> r8 - r13. */
reg = reg + 8;
}
*len = 2;
}
else
return -1;
/* Is register available? */
if (IS_CSKY_ARCH_801 (mach_flag))
{
/* CK801 register range is r0-r8 & r13-r15. */
if ((reg > 8 && reg < 13) || reg > 15)
{
SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg);
return -1;
}
}
else if (IS_CSKY_ARCH_802 (mach_flag))
{
/* CK802 register range is r0-r15 & r23-r25 & r30. */
if ((reg > 15 && reg < 23) || (reg > 25 && reg != 30))
{
SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg);
return -1;
}
}
else if (reg > 31 || reg < 0)
{
SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg);
return -1;
}
return reg;
}
static int
csky_get_freg_val (char *str, int *len)
{
@@ -3168,7 +2967,6 @@ is_imm_within_range (char **oper, int min, int max)
e.X_add_number |= 0x80000000;
csky_insn.val[csky_insn.idx++] = e.X_add_number;
}
else
SET_ERROR_STRING(ERROR_IMM_ILLEGAL, NULL);
@@ -3217,6 +3015,8 @@ is_oimm_within_range (char **oper, int min, int max)
}
csky_insn.val[csky_insn.idx++] = e.X_add_number - 1;
}
else
SET_ERROR_STRING (ERROR_IMM_ILLEGAL, NULL);
return ret;
}
@@ -3291,43 +3091,51 @@ parse_type_cpidx (char** oper)
static bfd_boolean
parse_type_cpreg (char** oper)
{
const char **regs = csky_cp_reg;
int i;
int len;
expressionS e;
for (i = 0; i < (int)(sizeof (csky_cp_reg) / sizeof (char *)); i++)
if (strncasecmp (*oper, "cpr", 3) != 0)
{
len = strlen (regs[i]);
if (memcmp (*oper, regs[i], len) == 0 && !ISDIGIT (*(*oper + len)))
{
*oper += len;
csky_insn.val[csky_insn.idx++] = i;
return TRUE;
}
SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
return FALSE;
}
SET_ERROR_STRING (ERROR_CPREG_ILLEGAL, *oper);
return FALSE;
*oper += 3;
*oper = parse_exp (*oper, &e);
if (e.X_op != O_constant)
{
SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
return FALSE;
}
csky_insn.val[csky_insn.idx++] = e.X_add_number;
return TRUE;
}
static bfd_boolean
parse_type_cpcreg (char** oper)
{
const char **regs;
int i;
int len;
regs = csky_cp_creg;
for (i = 0; i < (int)(sizeof (csky_cp_creg) / sizeof (char *)); i++)
expressionS e;
if (strncasecmp (*oper, "cpcr", 4) != 0)
{
len = strlen (regs[i]);
if (memcmp (*oper, regs[i], len) == 0 && !ISDIGIT (*(*oper + len)))
{
*oper += len;
csky_insn.val[csky_insn.idx++] = i;
return TRUE;
}
SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
return FALSE;
}
SET_ERROR_STRING (ERROR_CPREG_ILLEGAL, *oper);
return FALSE;
*oper += 4;
*oper = parse_exp (*oper, &e);
if (e.X_op != O_constant)
{
SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
return FALSE;
}
csky_insn.val[csky_insn.idx++] = e.X_add_number;
return TRUE;
}
static bfd_boolean
@@ -3830,6 +3638,10 @@ get_operand_value (struct csky_opcode_info *op,
else
return FALSE;
case OPRND_TYPE_IMM5b_LS:
return is_imm_within_range (oper,
0,
csky_insn.val[csky_insn.idx - 1]);
case OPRND_TYPE_IMM5b_RORI:
{
unsigned max_shift = IS_CSKY_V1 (mach_flag) ? 31 : 32;
@@ -4769,6 +4581,7 @@ md_assemble (char *str)
(void *)error_state.arg1, (void *)error_state.arg1);
return;
}
error_state.err_num = ERROR_NONE;
/* if this insn has work in opcode table, then do it. */
if (csky_insn.opcode->work != NULL)
@@ -6195,21 +6008,26 @@ csky_addc64 (void)
int reg1;
int reg2;
int reg3;
char reg1_name[16] = {0};
char reg3_name[16] = {0};
if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
return;
csky_macro_md_assemble ("cmplt",
csky_general_reg[reg1],
csky_general_reg[reg1],
NULL);
csky_macro_md_assemble ("addc",
csky_general_reg[reg1 + (target_big_endian ? 1 : 0)],
csky_general_reg[reg3 + (target_big_endian ? 1 : 0)],
NULL);
csky_macro_md_assemble ("addc",
csky_general_reg[reg1 + (target_big_endian ? 0 : 1)],
csky_general_reg[reg3 + (target_big_endian ? 0 : 1)],
NULL);
sprintf (reg1_name, "r%d", reg1);
csky_macro_md_assemble ("cmplt", reg1_name, reg1_name, NULL);
if (error_state.err_num != ERROR_NONE)
return;
sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
csky_macro_md_assemble ("addc", reg1_name, reg3_name, NULL);
if (error_state.err_num != ERROR_NONE)
return;
sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
csky_macro_md_assemble ("addc", reg1_name, reg3_name, NULL);
return;
}
@@ -6221,21 +6039,26 @@ csky_subc64 (void)
int reg1;
int reg2;
int reg3;
char reg1_name[16] = {0};
char reg3_name[16] = {0};
if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
return;
csky_macro_md_assemble ("cmphs",
csky_general_reg[reg1],
csky_general_reg[reg1],
NULL);
csky_macro_md_assemble ("subc",
csky_general_reg[reg1 + (target_big_endian ? 1 : 0)],
csky_general_reg[reg3 + (target_big_endian ? 1 : 0)],
NULL);
csky_macro_md_assemble ("subc",
csky_general_reg[reg1 + (target_big_endian ? 0 : 1)],
csky_general_reg[reg3 + (target_big_endian ? 0 : 1)],
NULL);
sprintf (reg1_name, "r%d", reg1);
csky_macro_md_assemble ("cmphs", reg1_name, reg1_name, NULL);
if (error_state.err_num != ERROR_NONE)
return;
sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
csky_macro_md_assemble ("subc", reg1_name, reg3_name, NULL);
if (error_state.err_num != ERROR_NONE)
return;
sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
csky_macro_md_assemble ("subc", reg1_name, reg3_name, NULL);
return;
}
@@ -6247,17 +6070,20 @@ csky_or64 (void)
int reg1;
int reg2;
int reg3;
char reg1_name[16] = {0};
char reg3_name[16] = {0};
if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
return;
csky_macro_md_assemble ("or",
csky_general_reg[reg1 + (target_big_endian ? 1 : 0)],
csky_general_reg[reg3 + (target_big_endian ? 1 : 0)],
NULL);
csky_macro_md_assemble ("or",
csky_general_reg[reg1 + (target_big_endian ? 0 : 1)],
csky_general_reg[reg3 + (target_big_endian ? 0 : 1)],
NULL);
sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
csky_macro_md_assemble ("or", reg1_name, reg3_name, NULL);
if (error_state.err_num != ERROR_NONE)
return;
sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
csky_macro_md_assemble ("or", reg1_name, reg3_name, NULL);
return;
}
@@ -6269,17 +6095,21 @@ csky_xor64 (void)
int reg1;
int reg2;
int reg3;
char reg1_name[16] = {0};
char reg3_name[16] = {0};
if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
return;
csky_macro_md_assemble ("xor",
csky_general_reg[reg1 + (target_big_endian ? 1 : 0)],
csky_general_reg[reg3 + (target_big_endian ? 1 : 0)],
NULL);
csky_macro_md_assemble ("xor",
csky_general_reg[reg1 + (target_big_endian ? 0 : 1)],
csky_general_reg[reg3 + (target_big_endian ? 0 : 1)],
NULL);
sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
csky_macro_md_assemble ("xor", reg1_name, reg3_name, NULL);
if (error_state.err_num != ERROR_NONE)
return;
sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
csky_macro_md_assemble ("xor", reg1_name, reg3_name, NULL);
return;
}
@@ -6463,11 +6293,10 @@ v1_work_fpu_fo (void)
inst = csky_insn.inst;
/* Now get greg and inst, we can write instruction to floating unit. */
sprintf (buff, "lrw %s,0x%x", csky_general_reg[greg], inst);
sprintf (buff, "lrw r%d,0x%x", greg, inst);
md_assemble (buff);
sprintf (buff, "cpwir %s", csky_general_reg[greg]);
sprintf (buff, "cpwir r%d", greg);
md_assemble (buff);
return FALSE;
}
@@ -6496,9 +6325,9 @@ v1_work_fpu_fo_fc (void)
inst = csky_insn.inst;
/* Now get greg and inst, we can write instruction to floating unit. */
sprintf (buff, "lrw %s,0x%x", csky_general_reg[greg], inst);
sprintf (buff, "lrw r%d,0x%x", greg, inst);
md_assemble (buff);
sprintf (buff, "cpwir %s", csky_general_reg[greg]);
sprintf (buff, "cpwir r%d", greg);
md_assemble (buff);
sprintf (buff, "cprc");
md_assemble (buff);
@@ -6517,7 +6346,7 @@ v1_work_fpu_write (void)
freg = csky_insn.val[1];
/* Now get greg and freg, we can write instruction to floating unit. */
sprintf (buff, "cpwgr %s,%s", csky_general_reg[greg], csky_cp_reg[freg]);
sprintf (buff, "cpwgr r%d,cpr%d", greg, freg);
md_assemble (buff);
return FALSE;
@@ -6533,7 +6362,7 @@ v1_work_fpu_read (void)
greg = csky_insn.val[0];
freg = csky_insn.val[1];
/* Now get greg and freg, we can write instruction to floating unit. */
sprintf (buff, "cprgr %s,%s", csky_general_reg[greg], csky_cp_reg[freg]);
sprintf (buff, "cprgr r%d,cpr%d", greg, freg);
md_assemble (buff);
return FALSE;
@@ -6556,20 +6385,15 @@ v1_work_fpu_writed (void)
}
/* Now get greg and freg, we can write instruction to floating unit. */
if (target_big_endian)
sprintf (buff, "cpwgr %s,%s",
csky_general_reg[greg + 1], csky_cp_reg[freg]);
sprintf (buff, "cpwgr r%d,cpr%d", greg + 1, freg);
else
sprintf (buff, "cpwgr %s,%s",
csky_general_reg[greg], csky_cp_reg[freg]);
sprintf (buff, "cpwgr r%d,cpr%d", greg, freg);
md_assemble (buff);
if (target_big_endian)
sprintf (buff, "cpwgr %s,%s",
csky_general_reg[greg], csky_cp_reg[freg + 1]);
sprintf (buff, "cpwgr r%d,cpr%d", greg, freg + 1);
else
sprintf (buff, "cpwgr %s,%s",
csky_general_reg[greg + 1], csky_cp_reg[freg + 1]);
sprintf (buff, "cpwgr r%d,cpr%d", greg+1, freg + 1);
md_assemble (buff);
return FALSE;
}
@@ -6590,18 +6414,14 @@ v1_work_fpu_readd (void)
}
/* Now get greg and freg, we can write instruction to floating unit. */
if (target_big_endian)
sprintf (buff, "cprgr %s,%s",
csky_general_reg[greg + 1], csky_cp_reg[freg]);
sprintf (buff, "cprgr r%d,cpr%d", greg+1, freg);
else
sprintf (buff, "cprgr %s,%s",
csky_general_reg[greg], csky_cp_reg[freg]);
sprintf (buff, "cprgr r%d,cpr%d", greg, freg);
md_assemble (buff);
if (target_big_endian)
sprintf (buff, "cprgr %s,%s",
csky_general_reg[greg], csky_cp_reg[freg + 1]);
sprintf (buff, "cprgr r%d,cpr%d", greg, freg + 1);
else
sprintf (buff, "cprgr %s,%s",
csky_general_reg[greg + 1], csky_cp_reg[freg + 1]);
sprintf (buff, "cprgr r%d,cpr%d", greg+1, freg + 1);
md_assemble (buff);
return FALSE;
@@ -7677,6 +7497,69 @@ float_work_fpuv3_fstore(void)
return TRUE;
}
bfd_boolean
v2_work_addc (void)
{
int reg1;
int reg2;
int reg3 = 0;
int is_16_bit = 0;
reg1 = csky_insn.val[0];
reg2 = csky_insn.val[1];
if (csky_insn.number == 2)
{
if (reg1 > 15 || reg2 > 15)
{
is_16_bit = 0;
reg3 = reg1;
}
else
is_16_bit = 1;
}
else
{
reg3 = csky_insn.val[2];
if (reg1 > 15 || reg2 > 15 || reg3 > 15)
is_16_bit = 0;
else if (reg1 == reg2 || reg1 == reg3)
{
is_16_bit = 1;
reg2 = (reg1 == reg2) ? reg3 : reg2;
}
else
is_16_bit = 0;
}
if (is_16_bit
&& csky_insn.flag_force != INSN_OPCODE32F)
{
csky_insn.isize = 2;
csky_insn.inst = csky_insn.opcode->op16[0].opcode
| (reg1 << 6) | (reg2 << 2);
}
else if (csky_insn.flag_force != INSN_OPCODE16F)
{
csky_insn.isize = 4;
csky_insn.inst = csky_insn.opcode->op32[0].opcode
| (reg1 << 0) | (reg2 << 16) | (reg3 << 21);
}
else
{
SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, reg1 > 15 ? reg1 : reg2);
csky_show_error (ERROR_REG_OVER_RANGE, 0, 0, NULL);
}
/* Generate relax or reloc if necessary. */
csky_generate_frags ();
/* Write inst to frag. */
csky_write_insn (csky_insn.output,
csky_insn.inst,
csky_insn.isize);
return TRUE;
}
/* The following are for assembler directive handling. */
/* Helper function to adjust constant pool counts when we emit a

View File

@@ -20,7 +20,7 @@ Disassembly of section \.text:
\s*[0-9a-f]*:\s*0032\s*mvcv\s*r2
\s*[0-9a-f]*:\s*0042\s*ldq\s*r4-r7, \(r2\)
\s*[0-9a-f]*:\s*0052\s*stq\s*r4-r7, \(r2\)
\s*[0-9a-f]*:\s*0061\s*ldm\s*r1-r15, \(sp\)
\s*[0-9a-f]*:\s*0061\s*ldm\s*r1-r15, \(r0\)
\s*[0-9a-f]*:\s*0082\s*dect\s*r2, r2, 1
\s*[0-9a-f]*:\s*0092\s*decf\s*r2, r2, 1
\s*[0-9a-f]*:\s*00a2\s*inct\s*r2, r2, 1

View File

@@ -14,10 +14,10 @@ Disassembly of section \.text:
\s*[0-9a-f]*:\s*c6824848\s*lsri\s*r8,\s*r2,\s*20
\s*[0-9a-f]*:\s*5227\s*asri\s*r1,\s*r2,\s*7
\s*[0-9a-f]*:\s*6049\s*addc\s*r1,\s*r2
\s*[0-9a-f]*:\s*c4310051\s*addc\s*r17,\s*r17,\s*r1
\s*[0-9a-f]*:\s*c6210051\s*addc\s*r17,\s*r1,\s*r17
\s*[0-9a-f]*:\s*c4620041\s*addc\s*r1,\s*r2,\s*r3
\s*[0-9a-f]*:\s*6049\s*addc\s*r1,\s*r2
\s*[0-9a-f]*:\s*c6210041\s*addc\s*r1,\s*r1,\s*r17
\s*[0-9a-f]*:\s*c4310041\s*addc\s*r1,\s*r17,\s*r1
\s*[0-9a-f]*:\s*c7d20052\s*addc\s*r18,\s*r18,\s*r30
\s*[0-9a-f]*:\s*604b\s*subc\s*r1,\s*r2
\s*[0-9a-f]*:\s*c4310111\s*subc\s*r17,\s*r17,\s*r1
@@ -67,23 +67,23 @@ Disassembly of section \.text:
\s*[0-9a-f]*:\s*c4419421\s*mulsw\s*r1,\s*r1,\s*r2
\s*[0-9a-f]*:\s*8344\s*ld.b\s*r2,\s*\(r3,\s*0x4\)
\s*[0-9a-f]*:\s*8b42\s*ld.h\s*r2,\s*\(r3,\s*0x4\)
\s*[0-9a-f]*:\s*9841\s*ld.w\s*r2,\s*\(sp,\s*0x4\)
\s*[0-9a-f]*:\s*9841\s*ld.w\s*r2,\s*\(r14,\s*0x4\)
\s*[0-9a-f]*:\s*a344\s*st.b\s*r2,\s*\(r3,\s*0x4\)
\s*[0-9a-f]*:\s*ab42\s*st.h\s*r2,\s*\(r3,\s*0x4\)
\s*[0-9a-f]*:\s*b841\s*st.w\s*r2,\s*\(sp,\s*0x4\)
\s*[0-9a-f]*:\s*b841\s*st.w\s*r2,\s*\(r14,\s*0x4\)
\s*[0-9a-f]*:\s*d9030004\s*ld.b\s*r8,\s*\(r3,\s*0x4\)
\s*[0-9a-f]*:\s*d8481002\s*ld.h\s*r2,\s*\(r8,\s*0x4\)
\s*[0-9a-f]*:\s*9841\s*ld.w\s*r2,\s*\(sp,\s*0x4\)
\s*[0-9a-f]*:\s*9841\s*ld.w\s*r2,\s*\(r14,\s*0x4\)
\s*[0-9a-f]*:\s*dc480004\s*st.b\s*r2,\s*\(r8,\s*0x4\)
\s*[0-9a-f]*:\s*dc481002\s*st.h\s*r2,\s*\(r8,\s*0x4\)
\s*[0-9a-f]*:\s*dd0e2001\s*st.w\s*r8,\s*\(sp,\s*0x4\)
\s*[0-9a-f]*:\s*dd0e2001\s*st.w\s*r8,\s*\(r14,\s*0x4\)
\s*[0-9a-f]*:\s*d8434003\s*ld.bs\s*r2,\s*\(r3,\s*0x3\)
\s*[0-9a-f]*:\s*d8433001\s*ld.d\s*r2,\s*\(r3,\s*0x4\)
\s*[0-9a-f]*:\s*dc433001\s*st.d\s*r2,\s*\(r3,\s*0x4\)
\s*[0-9a-f]*:\s*dc437001\s*stex.w\s*r2,\s*\(r3,\s*0x4\)
\s*[0-9a-f]*:\s*d8437001\s*ldex.w\s*r2,\s*\(r3,\s*0x4\)
\s*[0-9a-f]*:\s*140c\s*addi\s*sp,\s*sp,\s*48
\s*[0-9a-f]*:\s*1b01\s*addi\s*r3,\s*sp,\s*4
\s*[0-9a-f]*:\s*140c\s*addi\s*r14,\s*r14,\s*48
\s*[0-9a-f]*:\s*1b01\s*addi\s*r3,\s*r14,\s*4
\s*[0-9a-f]*:\s*2113\s*addi\s*r1,\s*20
\s*[0-9a-f]*:\s*2113\s*addi\s*r1,\s*20
\s*[0-9a-f]*:\s*e6b50013\s*addi\s*r21,\s*r21,\s*20
@@ -92,16 +92,16 @@ Disassembly of section \.text:
\s*[0-9a-f]*:\s*e5040000\s*addi\s*r8,\s*r4,\s*1
\s*[0-9a-f]*:\s*e4240008\s*addi\s*r1,\s*r4,\s*9
\s*[0-9a-f]*:\s*cc3c0008\s*addi\s*r1,\s*r28,\s*9
\s*[0-9a-f]*:\s*e46e0000\s*addi\s*r3,\s*sp,\s*1
\s*[0-9a-f]*:\s*e46e03ff\s*addi\s*r3,\s*sp,\s*1024
\s*[0-9a-f]*:\s*e5ce0032\s*addi\s*sp,\s*sp,\s*51
\s*[0-9a-f]*:\s*e5ce01ff\s*addi\s*sp,\s*sp,\s*512
\s*[0-9a-f]*:\s*e46e0000\s*addi\s*r3,\s*r14,\s*1
\s*[0-9a-f]*:\s*e46e03ff\s*addi\s*r3,\s*r14,\s*1024
\s*[0-9a-f]*:\s*e5ce0032\s*addi\s*r14,\s*r14,\s*51
\s*[0-9a-f]*:\s*e5ce01ff\s*addi\s*r14,\s*r14,\s*512
\s*[0-9a-f]*:\s*2113\s*addi\s*r1,\s*20
\s*[0-9a-f]*:\s*5c42\s*addi\s*r2,\s*r4,\s*1
\s*[0-9a-f]*:\s*e4440000\s*addi\s*r2,\s*r4,\s*1
\s*[0-9a-f]*:\s*e46e03ff\s*addi\s*r3,\s*sp,\s*1024
\s*[0-9a-f]*:\s*e5ce0032\s*addi\s*sp,\s*sp,\s*51
\s*[0-9a-f]*:\s*142c\s*subi\s*sp,\s*sp,\s*48
\s*[0-9a-f]*:\s*e46e03ff\s*addi\s*r3,\s*r14,\s*1024
\s*[0-9a-f]*:\s*e5ce0032\s*addi\s*r14,\s*r14,\s*51
\s*[0-9a-f]*:\s*142c\s*subi\s*r14,\s*r14,\s*48
\s*[0-9a-f]*:\s*2913\s*subi\s*r1,\s*20
\s*[0-9a-f]*:\s*2913\s*subi\s*r1,\s*20
\s*[0-9a-f]*:\s*e6b51013\s*subi\s*r21,\s*r21,\s*20
@@ -110,12 +110,12 @@ Disassembly of section \.text:
\s*[0-9a-f]*:\s*e5041000\s*subi\s*r8,\s*r4,\s*1
\s*[0-9a-f]*:\s*e4241008\s*subi\s*r1,\s*r4,\s*9
\s*[0-9a-f]*:\s*e43c1008\s*subi\s*r1,\s*r28,\s*9
\s*[0-9a-f]*:\s*e5ce1032\s*subi\s*sp,\s*sp,\s*51
\s*[0-9a-f]*:\s*e5ce11ff\s*subi\s*sp,\s*sp,\s*512
\s*[0-9a-f]*:\s*e5ce1032\s*subi\s*r14,\s*r14,\s*51
\s*[0-9a-f]*:\s*e5ce11ff\s*subi\s*r14,\s*r14,\s*512
\s*[0-9a-f]*:\s*2913\s*subi\s*r1,\s*20
\s*[0-9a-f]*:\s*5c43\s*subi\s*r2,\s*r4,\s*1
\s*[0-9a-f]*:\s*e4441000\s*subi\s*r2,\s*r4,\s*1
\s*[0-9a-f]*:\s*e5ce1032\s*subi\s*sp,\s*sp,\s*51
\s*[0-9a-f]*:\s*e5ce1032\s*subi\s*r14,\s*r14,\s*51
\s*[0-9a-f]*:\s*60c2\s*subu\s*r3,\s*r0
\s*[0-9a-f]*:\s*6202\s*subu\s*r8,\s*r0
\s*[0-9a-f]*:\s*c4030089\s*subu\s*r9,\s*r3,\s*r0

View File

@@ -76,8 +76,8 @@ all:
st.d r2, (r3, 4)
stex.w r2, (r3, 4)
ldex.w r2, (r3, 4)
addi sp, sp, 0x30
addi r3, sp, 0x4
addi r14, r14, 0x30
addi r3, r14, 0x4
addi r1, 20
addi r1, r1, 20
addi r21, 20
@@ -86,16 +86,16 @@ all:
addi r8, r4, 1
addi r1, r4, 9
addi r1, r28, 9
addi r3, sp, 0x1
addi r3, sp, 0x400
addi sp, sp, 0x33
addi sp, sp, 0x200
addi r3, r14, 0x1
addi r3, r14, 0x400
addi r14, r14, 0x33
addi r14, r14, 0x200
addi16 r1, 20
addi16 r2, r4, 1
addi32 r2, r4, 1
addi32 r3, sp, 0x400
addi32 sp, sp, 0x33
subi sp, sp, 0x30
addi32 r3, r14, 0x400
addi32 r14, r14, 0x33
subi r14, r14, 0x30
subi r1, 20
subi r1, r1, 20
subi r21, 20
@@ -104,12 +104,12 @@ all:
subi r8, r4, 1
subi r1, r4, 9
subi r1, r28, 9
subi sp, sp, 0x33
subi sp, sp, 0x200
subi r14, r14, 0x33
subi r14, r14, 0x200
subi16 r1, 20
subi16 r2, r4, 1
subi32 r2, r4, 1
subi32 sp, sp, 0x33
subi32 r14, r14, 0x33
sub r3, r0
sub r8, r0
sub r9, r3, r0

View File

@@ -7,11 +7,10 @@
Disassembly of section \.text:
#...
\s*[0-9a-f]*:\s*c0003c20\s*wsc
\s*[0-9a-f]*:\s*c0006024\s*mfcr\s*r4,\s*cr<0,\s*0>
\s*[0-9a-f]*:\s*c0156024\s*mfcr\s*r4,\s*cr<21,\s*0>
\s*[0-9a-f]*:\s*c004642b\s*mtcr\s*r4,\s*cr<11,\s*0>
\s*[0-9a-f]*:\s*c0046428\s*mtcr\s*r4,\s*cr<8,\s*0>
\s*[0-9a-f]*:\s*c0096024\s*mfcr\s*r4,\s*cr<9,\s*0>
\s*[0-9a-f]*:\s*c0006024\s*mfcr\s*r4,\s*cr<0,\s+0>
\s*[0-9a-f]*:\s*c004642b\s*mtcr\s*r4,\s*cr<11,\s+0>
\s*[0-9a-f]*:\s*c0646428\s*mtcr\s*r4,\s*cr<8,\s+3>
\s*[0-9a-f]*:\s*c0696024\s*mfcr\s*r4,\s*cr<9,\s+3>
\s*[0-9a-f]*:\s*c2007420\s*psrset\s*sie
\s*[0-9a-f]*:\s*c2007020\s*psrclr\s*sie
#...

View File

@@ -1,7 +1,6 @@
TRUST:
wsc
mfcr r4, psr
mfcr r4, rid
mtcr r4, gcr
mtcr r4, sedcr
mfcr r4, sepcr

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,

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)

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