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
+30
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>
+265 -382
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
+1 -1
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
+18 -18
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
+12 -12
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
+4 -5
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
#...
-1
View File
@@ -1,7 +1,6 @@
TRUST:
wsc
mfcr r4, psr
mfcr r4, rid
mtcr r4, gcr
mtcr r4, sedcr
mfcr r4, sepcr