aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCooper Qu <cooper.qu@linux.alibaba.com>2020-09-17 14:30:28 +0800
committerLifang Xia <xlf194833_xia@alibaba-inc.com>2020-09-23 23:55:36 +0800
commitafdcafe89118cee761f9bf67ea1b1efc29311300 (patch)
tree6bfaa44e694d29891509d89d7bdcb1601418c27f
parent20a5fcbd5b28cca88511ac5a9ad5e54251e8fa6d (diff)
downloadgdb-afdcafe89118cee761f9bf67ea1b1efc29311300.zip
gdb-afdcafe89118cee761f9bf67ea1b1efc29311300.tar.gz
gdb-afdcafe89118cee761f9bf67ea1b1efc29311300.tar.bz2
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.
-rw-r--r--gas/ChangeLog30
-rw-r--r--gas/config/tc-csky.c641
-rw-r--r--gas/testsuite/gas/csky/all.d2
-rw-r--r--gas/testsuite/gas/csky/cskyv2_all.d36
-rw-r--r--gas/testsuite/gas/csky/cskyv2_all.s24
-rw-r--r--gas/testsuite/gas/csky/trust.d9
-rw-r--r--gas/testsuite/gas/csky/trust.s1
-rw-r--r--opcodes/ChangeLog34
-rw-r--r--opcodes/csky-dis.c148
-rw-r--r--opcodes/csky-opc.h529
10 files changed, 858 insertions, 596 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index c04b90a..b713493 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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>
diff --git a/gas/config/tc-csky.c b/gas/config/tc-csky.c
index 808dca1..60d5aa1 100644
--- a/gas/config/tc-csky.c
+++ b/gas/config/tc-csky.c
@@ -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
+ else if (TOLOWER (*(*oper + 0)) == 'c'
+ && TOLOWER (*(*oper + 1)) == 'r')
{
- if (s[0] == 'c' && s[1] == 'r')
+ s += 2;
+ if (*s != '<')
{
- 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;
- }
+ SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
+ return FALSE;
}
- else
+ 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, NULL);
+ SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
+ return FALSE;
+ }
+ s++;
+ }
+ else
+ {
+ crx = csky_get_control_regno (mach_flag & CSKY_ARCH_MASK,
+ s, &s, &sel);
+ if (crx < 0)
+ {
+ 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,183 +2646,23 @@ 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 += len;
+ *oper += 2;
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)
+ len = sprintf (sp_name, "r%d", sp_idx);
+ if (memcmp (*oper, sp_name, len) == 0)
{
- SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg);
- return -1;
+ *oper += len;
+ csky_insn.val[csky_insn.idx++] = sp_idx;
+ return TRUE;
}
- return reg;
+ return FALSE;
}
static int
@@ -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
diff --git a/gas/testsuite/gas/csky/all.d b/gas/testsuite/gas/csky/all.d
index 606bcc0..af9acb5 100644
--- a/gas/testsuite/gas/csky/all.d
+++ b/gas/testsuite/gas/csky/all.d
@@ -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
diff --git a/gas/testsuite/gas/csky/cskyv2_all.d b/gas/testsuite/gas/csky/cskyv2_all.d
index bb688ec..bb104a7 100644
--- a/gas/testsuite/gas/csky/cskyv2_all.d
+++ b/gas/testsuite/gas/csky/cskyv2_all.d
@@ -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
diff --git a/gas/testsuite/gas/csky/cskyv2_all.s b/gas/testsuite/gas/csky/cskyv2_all.s
index 6e6902e..6db5b20 100644
--- a/gas/testsuite/gas/csky/cskyv2_all.s
+++ b/gas/testsuite/gas/csky/cskyv2_all.s
@@ -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
diff --git a/gas/testsuite/gas/csky/trust.d b/gas/testsuite/gas/csky/trust.d
index 1a87b4d..adaa21c 100644
--- a/gas/testsuite/gas/csky/trust.d
+++ b/gas/testsuite/gas/csky/trust.d
@@ -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
#...
diff --git a/gas/testsuite/gas/csky/trust.s b/gas/testsuite/gas/csky/trust.s
index 781dc8cb..862fa5b 100644
--- a/gas/testsuite/gas/csky/trust.s
+++ b/gas/testsuite/gas/csky/trust.s
@@ -1,7 +1,6 @@
TRUST:
wsc
mfcr r4, psr
- mfcr r4, rid
mtcr r4, gcr
mtcr r4, sedcr
mfcr r4, sepcr
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 0ec12f9..2dd9d35 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -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,
diff --git a/opcodes/csky-dis.c b/opcodes/csky-dis.c
index a28160b..67fb4ee 100644
--- a/opcodes/csky-dis.c
+++ b/opcodes/csky-dis.c
@@ -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)
diff --git a/opcodes/csky-opc.h b/opcodes/csky-opc.h
index a1c67e9..8cd0d1e 100644
--- a/opcodes/csky-opc.h
+++ b/opcodes/csky-opc.h
@@ -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,128 +627,421 @@ struct csky_opcode
#define V1_REG_SP 0
#define V1_REG_LR 15
-struct csky_reg
+struct psrbit
{
+ int value;
+ int isa;
const char *name;
- int index;
- int flag;
};
-const char *csky_general_reg[] =
+const struct psrbit cskyv1_psr_bits[] =
{
- "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,
+ {1, 0, "ie"},
+ {2, 0, "fe"},
+ {4, 0, "ee"},
+ {8, 0, "af"},
+ {0, 0, NULL},
};
-/* TODO: optimize. */
-const char *cskyv2_general_alias_reg[] =
+const struct psrbit cskyv2_psr_bits[] =
{
- "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,
+ {8, 0, "ee"},
+ {4, 0, "ie"},
+ {2, 0, "fe"},
+ {1, 0, "af"},
+ {0x10, CSKY_ISA_TRUST, "sie"},
+ {0, 0, NULL},
};
-/* TODO: optimize. */
-const char *cskyv1_general_alias_reg[] =
+#define GENARAL_REG_BANK 0x80000000
+#define REG_SUPPORT_ALL 0xffffffff
+
+/* CSKY register description. */
+struct csky_reg_def
{
- "sp", "r1", "a0", "a1", "a2", "a3", "a4", "a5",
- "fp", "l0", "l1", "l2", "l3", "l4", "gb", "lr",
- NULL,
+ /* 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;
};
-/* TODO: optimize. */
-const char *csky_fpu_reg[] =
+/* 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[] =
{
- "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,
+#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},
};
-/* Control Registers. */
-struct csky_reg csky_ctrl_regs[] =
+/* C-SKY V1 control registers table. */
+static struct csky_reg_def csky_abiv1_control_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}
+#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},
};
-const char *csky_cp_idx[] =
+/* C-SKY V2 general registers table. */
+static struct csky_reg_def csky_abiv2_general_regs[] =
{
- "cp0", "cp1", "cp2", "cp3", "cp4", "cp5", "cp6", "cp7",
- "cp8", "cp9", "cp10", "cp11", "cp12", "cp13", "cp14", "cp15",
- "cp16", "cp17", "cp18", "cp19", "cp20",
- NULL,
+#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},
};
-const char *csky_cp_reg[] =
+/* C-SKY V2 control registers table. */
+static struct csky_reg_def csky_abiv2_control_regs[] =
{
- "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,
+
+#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},
};
-const char *csky_cp_creg[] =
+/* 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)
{
- "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,
-};
+ 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++;
+ }
-struct psrbit
+ 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)
{
- int value;
- int isa;
- const char *name;
-};
-const struct psrbit cskyv1_psr_bits[] =
+ 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)
{
- {1, 0, "ie"},
- {2, 0, "fe"},
- {4, 0, "ee"},
- {8, 0, "af"},
- {0, 0, NULL},
-};
-const struct psrbit cskyv2_psr_bits[] =
+ 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)
{
- {8, 0, "ee"},
- {4, 0, "ie"},
- {2, 0, "fe"},
- {1, 0, "af"},
- {0x10, CSKY_ISA_TRUST, "sie"},
- {0, 0, NULL},
-};
+ 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,12 +3916,12 @@ const struct csky_opcode csky_v2_opcodes[] =
#undef _TRANSFER
#define _TRANSFER 0
DOP16_DOP32 ("bclri",
- OPCODE_INFO3 (0x3880,
+ OPCODE_INFO2 (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,
+ 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)),
CSKYV2_ISA_E1,
OPCODE_INFO3 (0xc4002820,
@@ -3637,12 +3933,12 @@ const struct csky_opcode csky_v2_opcodes[] =
(21_25, IMM5b, OPRND_SHIFT_0_BIT)),
CSKYV2_ISA_1E2),
DOP16_DOP32 ("bseti",
- OPCODE_INFO3 (0x38a0,
+ OPCODE_INFO2 (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,
+ 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)),
CSKYV2_ISA_E1,
OPCODE_INFO3 (0xc4002840,
@@ -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