diff options
author | Cooper Qu <cooper.qu@linux.alibaba.com> | 2020-09-17 14:30:28 +0800 |
---|---|---|
committer | Lifang Xia <xlf194833_xia@alibaba-inc.com> | 2020-09-23 23:55:36 +0800 |
commit | afdcafe89118cee761f9bf67ea1b1efc29311300 (patch) | |
tree | 6bfaa44e694d29891509d89d7bdcb1601418c27f /gas | |
parent | 20a5fcbd5b28cca88511ac5a9ad5e54251e8fa6d (diff) | |
download | gdb-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.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 30 | ||||
-rw-r--r-- | gas/config/tc-csky.c | 641 | ||||
-rw-r--r-- | gas/testsuite/gas/csky/all.d | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/csky/cskyv2_all.d | 36 | ||||
-rw-r--r-- | gas/testsuite/gas/csky/cskyv2_all.s | 24 | ||||
-rw-r--r-- | gas/testsuite/gas/csky/trust.d | 9 | ||||
-rw-r--r-- | gas/testsuite/gas/csky/trust.s | 1 |
7 files changed, 327 insertions, 416 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 (®1, ®2, ®3)) 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 (®1, ®2, ®3)) 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 (®1, ®2, ®3)) 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 (®1, ®2, ®3)) 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 |