From c3a871f55831884f9f731a1fbda7f6d5601dec9f Mon Sep 17 00:00:00 2001 From: Nelson Chu Date: Wed, 22 Aug 2018 11:13:23 +0800 Subject: [PATCH 04/13] NDS32: Add reduced-register checking for the specific instructions. Some instructions, like lmw/smw(pop25/push25) and audio extension instructions, can not use r11-r14,r16-r27(r14) in the reduced register configuration. opcodes/ * nds32-asm.c (parse_aext_reg): Add new parameter. (parse_re, parse_re2, parse_aext_reg): Only reduced registers are allowed to use. All callers changed. --- opcodes/ChangeLog | 7 +++ opcodes/nds32-asm.c | 102 ++++++++++++++++++++++++++++++-------------- 2 files changed, 78 insertions(+), 31 deletions(-) diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 70bad4b79d..de15200170 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,10 @@ +2018-09-17 Nelson Chu + + * nds32-asm.c (parse_aext_reg): Add new parameter. + (parse_re, parse_re2, parse_aext_reg): Only reduced registers + are allowed to use. + All callers changed. + 2018-09-17 Nelson Chu * disassemble.c (disassemble_init_for_target): diff --git a/opcodes/nds32-asm.c b/opcodes/nds32-asm.c index e15e308307..eca0e87fed 100644 --- a/opcodes/nds32-asm.c +++ b/opcodes/nds32-asm.c @@ -63,7 +63,8 @@ static int parse_fe5 (struct nds32_asm_desc *, struct nds32_asm_insn *, char **, int64_t *); static int parse_pi5 (struct nds32_asm_desc *, struct nds32_asm_insn *, char **, int64_t *); -static int parse_aext_reg (char **, int *, int); +static int parse_aext_reg (struct nds32_asm_desc *, char **, + int *, int); static int parse_a30b20 (struct nds32_asm_desc *, struct nds32_asm_insn *, char **, int64_t *); static int parse_rt21 (struct nds32_asm_desc *, struct nds32_asm_insn *, @@ -1699,6 +1700,11 @@ parse_re (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, if (__GF (pinsn->insn, 20, 5) > (unsigned int) k->value) return NASM_ERR_OPERAND; + /* Register not allowed in reduced register. */ + if ((pdesc->flags & NASM_OPEN_REDUCED_REG) + && (k->attr & ATTR (RDREG)) == 0) + return NASM_ERR_REG_REDUCED; + *value = k->value; *pstr = end; return NASM_R_CONST; @@ -1726,6 +1732,11 @@ parse_re2 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, if (k == NULL) return NASM_ERR_OPERAND; + /* Register not allowed in reduced register. */ + if ((pdesc->flags & NASM_OPEN_REDUCED_REG) + && (k->attr & ATTR (RDREG)) == 0) + return NASM_ERR_REG_REDUCED; + if (k->value == 6) *value = 0; else if (k->value == 8) @@ -1781,7 +1792,8 @@ static int aext_im5_ip = 0; static int aext_im6_ip = 0; /* Parse the operand of audio ext. */ static int -parse_aext_reg (char **pstr, int *value, int hw_res) +parse_aext_reg (struct nds32_asm_desc *pdesc, char **pstr, + int *value, int hw_res) { char *end = *pstr; char odstr[MAX_KEYWORD_LEN]; @@ -1798,20 +1810,26 @@ parse_aext_reg (char **pstr, int *value, int hw_res) if (k == NULL) return NASM_ERR_OPERAND; + if (hw_res == HW_GPR + && (pdesc->flags & NASM_OPEN_REDUCED_REG) + && (k->attr & ATTR (RDREG)) == 0) + return NASM_ERR_REG_REDUCED; + *value = k->value; *pstr = end; return NASM_R_CONST; } static int -parse_a30b20 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, +parse_a30b20 (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, char **pstr, int64_t *value) { int rt_value, ret; - ret = parse_aext_reg (pstr, &rt_value, HW_GPR); - + ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR); + if (ret == NASM_ERR_REG_REDUCED) + return NASM_ERR_REG_REDUCED; if ((ret == NASM_ERR_OPERAND) || (rt_value > 15)) return NASM_ERR_OPERAND; @@ -1821,16 +1839,18 @@ parse_a30b20 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, } static int -parse_rt21 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, +parse_rt21 (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, char **pstr, int64_t *value) { int rt_value, ret, tmp_value, tmp1, tmp2; - ret = parse_aext_reg (pstr, &rt_value, HW_GPR); - + ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR); + if (ret == NASM_ERR_REG_REDUCED) + return NASM_ERR_REG_REDUCED; if ((ret == NASM_ERR_OPERAND) || (rt_value > 15)) return NASM_ERR_OPERAND; + tmp1 = (aext_a30b20 & 0x08); tmp2 = (rt_value & 0x08); if (tmp1 != tmp2) @@ -1844,17 +1864,19 @@ parse_rt21 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, } static int -parse_rte_start (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, +parse_rte_start (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, char **pstr, int64_t *value) { int rt_value, ret, tmp1, tmp2; - ret = parse_aext_reg (pstr, &rt_value, HW_GPR); - + ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR); + if (ret == NASM_ERR_REG_REDUCED) + return NASM_ERR_REG_REDUCED; if ((ret == NASM_ERR_OPERAND) || (rt_value > 15) || (rt_value & 0x01)) return NASM_ERR_OPERAND; + tmp1 = (aext_a30b20 & 0x08); tmp2 = (rt_value & 0x08); if (tmp1 != tmp2) @@ -1868,21 +1890,25 @@ parse_rte_start (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, } static int -parse_rte_end (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, +parse_rte_end (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, char **pstr, int64_t *value) { int rt_value, ret, tmp1, tmp2; - ret = parse_aext_reg (pstr, &rt_value, HW_GPR); + ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR); + if (ret == NASM_ERR_REG_REDUCED) + return NASM_ERR_REG_REDUCED; if ((ret == NASM_ERR_OPERAND) || (rt_value > 15) || ((rt_value & 0x01) == 0) || (rt_value != (aext_rte + 1))) return NASM_ERR_OPERAND; + tmp1 = (aext_a30b20 & 0x08); tmp2 = (rt_value & 0x08); if (tmp1 != tmp2) return NASM_ERR_OPERAND; + /* Rt=CONCAT(c, t21, 0), t21:bit11-10. */ rt_value = (rt_value & 0x06) << 4; *value = rt_value; @@ -1890,16 +1916,19 @@ parse_rte_end (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, } static int -parse_rte69_start (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, +parse_rte69_start (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, char **pstr, int64_t *value) { int rt_value, ret; - ret = parse_aext_reg (pstr, &rt_value, HW_GPR); + ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR); + if (ret == NASM_ERR_REG_REDUCED) + return NASM_ERR_REG_REDUCED; if ((ret == NASM_ERR_OPERAND) || (rt_value & 0x01)) return NASM_ERR_OPERAND; + aext_rte = rt_value; rt_value = (rt_value >> 1); *value = rt_value; @@ -1907,17 +1936,20 @@ parse_rte69_start (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, } static int -parse_rte69_end (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, +parse_rte69_end (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, char **pstr, int64_t *value) { int rt_value, ret; - ret = parse_aext_reg (pstr, &rt_value, HW_GPR); + ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR); + if (ret == NASM_ERR_REG_REDUCED) + return NASM_ERR_REG_REDUCED; if ((ret == NASM_ERR_OPERAND) || ((rt_value & 0x01) == 0) || (rt_value != (aext_rte + 1))) return NASM_ERR_OPERAND; + aext_rte = rt_value; rt_value = (rt_value >> 1); *value = rt_value; @@ -1925,15 +1957,16 @@ parse_rte69_end (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, } static int -parse_im5_ip (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, +parse_im5_ip (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, char **pstr, int64_t *value) { int rt_value, ret, new_value; - ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_I); + ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_I); if (ret == NASM_ERR_OPERAND) return NASM_ERR_OPERAND; + /* p = bit[4].bit[1:0], r = bit[4].bit[3:2]. */ new_value = (rt_value & 0x04) << 2; new_value |= (rt_value & 0x03); @@ -1943,35 +1976,38 @@ parse_im5_ip (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, } static int -parse_im5_mr (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, +parse_im5_mr (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, char **pstr, int64_t *value) { int rt_value, ret, new_value, tmp1, tmp2; - ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_M); + ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_M); if (ret == NASM_ERR_OPERAND) return NASM_ERR_OPERAND; + /* p = bit[4].bit[1:0], r = bit[4].bit[3:2]. */ new_value = (rt_value & 0x07) << 2; tmp1 = (aext_im5_ip & 0x10); tmp2 = (new_value & 0x10); if (tmp1 != tmp2) return NASM_ERR_OPERAND; + *value = new_value; return NASM_R_CONST; } static int -parse_im6_ip (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, +parse_im6_ip (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, char **pstr, int64_t *value) { int rt_value, ret; - ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_I); + ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_I); if ((ret == NASM_ERR_OPERAND) || (rt_value > 3)) return NASM_ERR_OPERAND; + /* p = 0.bit[1:0]. */ aext_im6_ip = rt_value; *value = aext_im6_ip; @@ -1979,47 +2015,51 @@ parse_im6_ip (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, } static int -parse_im6_iq (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, +parse_im6_iq (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, char **pstr, int64_t *value) { int rt_value, ret; - ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_I); + ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_I); if ((ret == NASM_ERR_OPERAND) || (rt_value < 4)) return NASM_ERR_OPERAND; + /* q = 1.bit[1:0]. */ if ((rt_value & 0x03) != aext_im6_ip) return NASM_ERR_OPERAND; + *value = aext_im6_ip; return NASM_R_CONST; } static int -parse_im6_mr (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, +parse_im6_mr (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, char **pstr, int64_t *value) { int rt_value, ret; - ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_M); + ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_M); if ((ret == NASM_ERR_OPERAND) || (rt_value > 3)) return NASM_ERR_OPERAND; + /* r = 0.bit[3:2]. */ *value = (rt_value & 0x03); return NASM_R_CONST; } static int -parse_im6_ms (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, +parse_im6_ms (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, char **pstr, int64_t *value) { int rt_value, ret; - ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_M); + ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_M); if ((ret == NASM_ERR_OPERAND) || (rt_value < 4)) return NASM_ERR_OPERAND; + /* s = 1.bit[5:4]. */ *value = (rt_value & 0x03); return NASM_R_CONST; @@ -2045,9 +2085,9 @@ parse_operand (nds32_asm_desc_t *pdesc, nds32_asm_insn_t *pinsn, if (fld->parse) { r = fld->parse (pdesc, pinsn, &end, &value); - if (r == NASM_ERR_OPERAND) + if (r == NASM_ERR_OPERAND || r == NASM_ERR_REG_REDUCED) { - pdesc->result = NASM_ERR_OPERAND; + pdesc->result = r; return 0; } goto done; -- 2.17.0