From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp2200-217.mail.aliyun.com (smtp2200-217.mail.aliyun.com [121.197.200.217]) by sourceware.org (Postfix) with ESMTPS id C64C13950C21 for ; Wed, 23 Sep 2020 15:51:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org C64C13950C21 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=c-sky.com Authentication-Results: sourceware.org; spf=none smtp.mailfrom=lifang_xia@c-sky.com X-Alimail-AntiSpam: AC=CONTINUE; BC=0.07436282|-1; CH=green; DM=|CONTINUE|false|; DS=CONTINUE|ham_system_inform|0.0839205-0.000671005-0.915409; FP=0|0|0|0|0|-1|-1|-1; HT=e02c03302; MF=lifang_xia@c-sky.com; NM=1; PH=DS; RN=2; RT=2; SR=0; TI=SMTPD_---.IbGlbDe_1600876293; Received: from 30.15.205.149(mailfrom:lifang_xia@c-sky.com fp:SMTPD_---.IbGlbDe_1600876293) by smtp.aliyun-inc.com(10.147.40.7); Wed, 23 Sep 2020 23:51:34 +0800 Subject: Re: [PATCH] CSKY: Add objdump option -M abi-names. To: Cooper Qu , binutils@sourceware.org References: <20200917063028.74459-1-cooper.qu@linux.alibaba.com> From: Lifang Xia Message-ID: Date: Wed, 23 Sep 2020 23:50:35 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.12.0 MIME-Version: 1.0 In-Reply-To: <20200917063028.74459-1-cooper.qu@linux.alibaba.com> Content-Type: text/plain; charset=gbk; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-8.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KAM_STOCKTIP, NICE_REPLY_A, SPF_HELO_NONE, SPF_NONE, TXREP, UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Sep 2020 15:51:50 -0000 Hi Cooper, Merged. Best Regards Lifang Xia On 2020/9/17 14:30, Cooper Qu wrote: > 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 > > 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. > > --- > gas/config/tc-csky.c | 641 ++++++++++++---------------- > gas/testsuite/gas/csky/all.d | 2 +- > gas/testsuite/gas/csky/cskyv2_all.d | 36 +- > gas/testsuite/gas/csky/cskyv2_all.s | 24 +- > gas/testsuite/gas/csky/trust.d | 9 +- > gas/testsuite/gas/csky/trust.s | 1 - > opcodes/csky-dis.c | 148 ++++--- > opcodes/csky-opc.h | 529 ++++++++++++++++++----- > 8 files changed, 794 insertions(+), 596 deletions(-) > > diff --git a/gas/config/tc-csky.c b/gas/config/tc-csky.c > index 808dca1e52c..60d5aa1f53b 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 606bcc0d3c6..af9acb50da8 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 bb688ec97d4..bb104a7bc09 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 6e6902e077b..6db5b202bfb 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 1a87b4d472b..adaa21cd77c 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 781dc8cbb84..862fa5bc94a 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/csky-dis.c b/opcodes/csky-dis.c > index ba0f4605f54..169368ac4be 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 > @@ -260,6 +261,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) > @@ -287,30 +322,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; > @@ -321,21 +336,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); > @@ -347,10 +359,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; > @@ -417,6 +431,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: > @@ -732,14 +747,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: > @@ -774,33 +794,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"); > @@ -812,7 +824,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"); > @@ -833,27 +845,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, ", "); > @@ -861,7 +874,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, ", "); > } > @@ -871,18 +884,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: > @@ -1025,6 +1038,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 a1c67e971b8..8cd0d1e2a2d 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