From e2e82b115cc0eed19dd88f87970e6c0417141baa Mon Sep 17 00:00:00 2001 From: Cooper Qu Date: Mon, 31 Aug 2020 11:27:54 +0800 Subject: [PATCH] CSKY: Refine operand format error reporting. Rename SET_ERROR_NUMBER to SET_ERROR_STRING, and add SET_ERROR_INTEGER to report error message which pass an integer argument. gas/ * config/tc-csky.c (csky_error_state): New member 'arg_int'. (SET_ERROR_NUMBER): Rename to SET_ERROR_STRING. (SET_ERROR_INTEGER): New. (err_formats): Add error format for ERROR_FREG_OVER_RANGE and ERROR_VREG_OVER_RANGE. (csky_show_error): Pass an integer argument for some error numbers. (parse_exp): Call SET_ERROR_STRING instead of SET_ERROR_NUMBER. (parse_rt): Likewise. (parse_type_ctrlreg): Likewise. (csky_get_reg_val): Likewise. (is_reglist_legal): Likewise. (is_freglist_legal): Likewise. (is_reglist_dash_comma_legal): Likewise. (is_reg_lshift_illegal): Likewise. (is_psr_bit): Likewise. (parse_type_cpreg): Likewise. (parse_type_cpcreg): Likewise. (parse_type_areg): Likewise. (parse_type_freg): Likewise. (parse_ldst_imm): Likewise and call SET_ERROR_INTEGER. (get_operand_value): Likewise. (parse_operands_op): Likewise and call is_imm_within_range, is_imm_within_range_ext and is_oimm_within_range. (md_assemble): Likewise. (is_imm_within_range): New. (is_imm_within_range_ext): Rename from is_imm_over_range. (is_oimm_within_range): Rename from is_oimm_over_range. (v2_work_add_sub): Call SET_ERROR_INTEGER. (csky_rolc): call is_imm_within_range instead of is_imm_over_range. opcodes/ * csky-dis.c (csky_output_operand): Assign dis_info.value for OPRND_TYPE_VREG. --- gas/ChangeLog | 34 ++++++ gas/config/tc-csky.c | 283 ++++++++++++++++++++++++++----------------- opcodes/ChangeLog | 5 + opcodes/csky-dis.c | 1 + 4 files changed, 214 insertions(+), 109 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 1f30a6bc52..70e5889333 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,37 @@ +2020-08-31 Cooper Qu + + * config/tc-csky.c (csky_error_state): New member 'arg_int'. + (SET_ERROR_NUMBER): Rename to SET_ERROR_STRING. + (SET_ERROR_INTEGER): New. + (err_formats): Add error format for ERROR_FREG_OVER_RANGE and + ERROR_VREG_OVER_RANGE. + (csky_show_error): Pass an integer argument for some error + numbers. + (parse_exp): Call SET_ERROR_STRING instead of SET_ERROR_NUMBER. + (parse_rt): Likewise. + (parse_type_ctrlreg): Likewise. + (csky_get_reg_val): Likewise. + (is_reglist_legal): Likewise. + (is_freglist_legal): Likewise. + (is_reglist_dash_comma_legal): Likewise. + (is_reg_lshift_illegal): Likewise. + (is_psr_bit): Likewise. + (parse_type_cpreg): Likewise. + (parse_type_cpcreg): Likewise. + (parse_type_areg): Likewise. + (parse_type_freg): Likewise. + (parse_ldst_imm): Likewise and call SET_ERROR_INTEGER. + (get_operand_value): Likewise. + (parse_operands_op): Likewise and call is_imm_within_range, + is_imm_within_range_ext and is_oimm_within_range. + (md_assemble): Likewise. + (is_imm_within_range): New. + (is_imm_within_range_ext): Rename from is_imm_over_range. + (is_oimm_within_range): Rename from is_oimm_over_range. + (v2_work_add_sub): Call SET_ERROR_INTEGER. + (csky_rolc): call is_imm_within_range instead of + is_imm_over_range. + 2020-08-31 Cooper Qu * config/tc-csky.c (md_begin): Add warning when -mdsp and diff --git a/gas/config/tc-csky.c b/gas/config/tc-csky.c index 6fc24acde0..01f1d51660 100644 --- a/gas/config/tc-csky.c +++ b/gas/config/tc-csky.c @@ -327,6 +327,8 @@ enum error_number /* The following are errors. */ ERROR_CREG_ILLEGAL = 0, ERROR_REG_OVER_RANGE, + ERROR_FREG_OVER_RANGE, + ERROR_VREG_OVER_RANGE, ERROR_GREG_ILLEGAL, ERROR_802J_REG_OVER_RANGE, ERROR_REG_FORMAT, @@ -372,13 +374,14 @@ struct csky_error_state { enum error_number err_num; int opnum; + int arg_int; const void *arg1; const void *arg2; } error_state; /* This macro is used to set error number and arg1 in the global state. */ -#define SET_ERROR_NUMBER(err, msg) \ +#define SET_ERROR_STRING(err, msg) \ do { \ if (error_state.err_num > err) \ { \ @@ -387,6 +390,14 @@ struct csky_error_state } \ } while (0) +#define SET_ERROR_INTEGER(err, integer) \ + do { \ + if (error_state.err_num > err) \ + { \ + error_state.err_num = err; \ + error_state.arg_int = integer; \ + } \ + } while (0) /* Map error identifiers onto a format string, which will use arg1 and arg2 from the global error state. */ @@ -400,6 +411,8 @@ static const struct csky_error_format_map err_formats[] = { {ERROR_CREG_ILLEGAL, "Operand %d error: control register is illegal."}, {ERROR_REG_OVER_RANGE, "Operand %d error: r%d register is over range."}, + {ERROR_FREG_OVER_RANGE, "Operand %d error: vr%d register is over range."}, + {ERROR_VREG_OVER_RANGE, "Operand %d error: vr%d register is out of range."}, {ERROR_GREG_ILLEGAL, "Operand %d error: general register is illegal."}, {ERROR_802J_REG_OVER_RANGE, "Operand %d register %s out of range (802j only has registers:0-15,23,24,25,30)"}, {ERROR_REG_FORMAT, "Operand %d error: %s."}, @@ -857,11 +870,11 @@ csky_show_error (enum error_number err, int idx, void *arg1, void *arg2) break; case ERROR_OPERANDS_NUMBER: case ERROR_IMM_POWER: - as_bad (_(err_formats[err].fmt), (long)arg1); + as_bad (_(err_formats[err].fmt), error_state.arg_int); break; case ERROR_OFFSET_UNALIGNED: - as_bad (_(err_formats[err].fmt), idx, (long)arg1); + as_bad (_(err_formats[err].fmt), idx, error_state.arg_int); break; case ERROR_RELOC_ILLEGAL: case ERROR_BAD_END: @@ -869,7 +882,9 @@ csky_show_error (enum error_number err, int idx, void *arg1, void *arg2) as_bad (_(err_formats[err].fmt), (char *)arg1); break; case ERROR_REG_OVER_RANGE: - as_bad (_(err_formats[err].fmt), idx, (long) arg1); + case ERROR_FREG_OVER_RANGE: + case ERROR_VREG_OVER_RANGE: + as_bad (_(err_formats[err].fmt), idx, error_state.arg_int); break; case ERROR_802J_REG_OVER_RANGE: case ERROR_REG_FORMAT: @@ -1903,7 +1918,7 @@ parse_exp (char *s, expressionS *e) lex_got (&insn_reloc, NULL); if (e->X_op == O_absent) - SET_ERROR_NUMBER (ERROR_MISSING_OPERAND, NULL); + SET_ERROR_STRING (ERROR_MISSING_OPERAND, NULL); new = input_line_pointer; input_line_pointer = save; @@ -2022,7 +2037,7 @@ parse_rt (char *s, if (*s == ']') s++; else - SET_ERROR_NUMBER (ERROR_MISSING_RSQUARE_BRACKETS, NULL); + SET_ERROR_STRING (ERROR_MISSING_RSQUARE_BRACKETS, NULL); if (ep) *ep = e; @@ -2179,14 +2194,14 @@ parse_type_ctrlreg (char** oper) } else { - SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, "control"); + SET_ERROR_STRING (ERROR_REG_OVER_RANGE, "control"); return FALSE; } if (*s == ',') s++; else { - SET_ERROR_NUMBER (ERROR_CREG_ILLEGAL, NULL); + SET_ERROR_STRING (ERROR_CREG_ILLEGAL, NULL); return FALSE; } char *pS = s; @@ -2197,7 +2212,7 @@ parse_type_ctrlreg (char** oper) else { /* Error. Missing '>'. */ - SET_ERROR_NUMBER (ERROR_MISSING_RANGLE_BRACKETS, NULL); + SET_ERROR_STRING (ERROR_MISSING_RANGLE_BRACKETS, NULL); return FALSE; } expressionS e; @@ -2215,13 +2230,13 @@ parse_type_ctrlreg (char** oper) else { /* Error. Missing '<'. */ - SET_ERROR_NUMBER (ERROR_MISSING_LANGLE_BRACKETS, NULL); + SET_ERROR_STRING (ERROR_MISSING_LANGLE_BRACKETS, NULL); return FALSE; } } else { - SET_ERROR_NUMBER (ERROR_CREG_ILLEGAL, NULL); + SET_ERROR_STRING (ERROR_CREG_ILLEGAL, NULL); return FALSE; } } @@ -2444,7 +2459,7 @@ csky_get_reg_val (char *str, int *len) /* CK801 register range is r0-r8 & r13-r15. */ if ((reg > 8 && reg < 13) || reg > 15) { - SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg); + SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg); return -1; } } @@ -2453,13 +2468,13 @@ csky_get_reg_val (char *str, int *len) /* CK802 register range is r0-r15 & r23-r25 & r30. */ if ((reg > 15 && reg < 23) || (reg > 25 && reg != 30)) { - SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg); + SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg); return -1; } } else if (reg > 31 || reg < 0) { - SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg); + SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg); return -1; } @@ -2501,14 +2516,14 @@ is_reglist_legal (char **oper) if (reg1 == -1 || (IS_CSKY_V1 (mach_flag) && (reg1 == 0 || reg1 == 15))) { - SET_ERROR_NUMBER (ERROR_REG_FORMAT, + SET_ERROR_STRING (ERROR_REG_FORMAT, "The first reg must not be r0/r15"); return FALSE; } if (**oper != '-') { - SET_ERROR_NUMBER (ERROR_REG_FORMAT, + SET_ERROR_STRING (ERROR_REG_FORMAT, "The operand format must be rx-ry"); return FALSE; } @@ -2519,7 +2534,7 @@ is_reglist_legal (char **oper) if (reg2 == -1 || (IS_CSKY_V1 (mach_flag) && reg1 == 15)) { - SET_ERROR_NUMBER (ERROR_REG_FORMAT, + SET_ERROR_STRING (ERROR_REG_FORMAT, "The operand format must be r15 in C-SKY V1"); return FALSE; } @@ -2527,7 +2542,7 @@ is_reglist_legal (char **oper) { if (reg2 < reg1) { - SET_ERROR_NUMBER (ERROR_REG_FORMAT, + SET_ERROR_STRING (ERROR_REG_FORMAT, "The operand format must be rx-ry (rx < ry)"); return FALSE; } @@ -2550,14 +2565,14 @@ is_freglist_legal (char **oper) if (reg1 == -1) { - SET_ERROR_NUMBER (ERROR_REG_FORMAT, + SET_ERROR_STRING (ERROR_REG_FORMAT, "The fpu register format is not recognized."); return FALSE; } if (**oper != '-') { - SET_ERROR_NUMBER (ERROR_REG_FORMAT, + SET_ERROR_STRING (ERROR_REG_FORMAT, "The operand format must be vrx-vry/frx-fry."); return FALSE; } @@ -2568,17 +2583,23 @@ is_freglist_legal (char **oper) if (reg2 == -1) { - SET_ERROR_NUMBER (ERROR_REG_FORMAT, + SET_ERROR_STRING (ERROR_REG_FORMAT, "The fpu register format is not recognized."); return FALSE; } if (reg2 < reg1) { - SET_ERROR_NUMBER (ERROR_REG_FORMAT, + SET_ERROR_STRING (ERROR_REG_FORMAT, "The operand format must be rx-ry(rx < ry)"); return FALSE; } + reg2 = reg2 - reg1; + if (reg2 > (int)0x3) + { + SET_ERROR_STRING(ERROR_REG_FORMAT, (void *)"vry-vrx is over range"); + return FALSE; + } reg2 <<= 4; reg1 |= reg2; csky_insn.val[csky_insn.idx++] = reg1; @@ -2599,7 +2620,7 @@ is_reglist_dash_comma_legal (char **oper, struct operand *oprnd) reg1 = csky_get_reg_val (*oper, &len); if (reg1 == -1) { - SET_ERROR_NUMBER (ERROR_REG_LIST, NULL); + SET_ERROR_STRING (ERROR_REG_LIST, NULL); return FALSE; } flag |= (1 << reg1); @@ -2610,13 +2631,13 @@ is_reglist_dash_comma_legal (char **oper, struct operand *oprnd) reg2 = csky_get_reg_val (*oper, &len); if (reg2 == -1) { - SET_ERROR_NUMBER (ERROR_REG_LIST, NULL); + SET_ERROR_STRING (ERROR_REG_LIST, NULL); return FALSE; } *oper += len; if (reg1 > reg2) { - SET_ERROR_NUMBER (ERROR_REG_LIST, NULL); + SET_ERROR_STRING (ERROR_REG_LIST, NULL); return FALSE; } while (reg2 >= reg1) @@ -2632,7 +2653,7 @@ is_reglist_dash_comma_legal (char **oper, struct operand *oprnd) #define REGLIST_BITS 0x10038ff0 if (flag & ~(REGLIST_BITS)) { - SET_ERROR_NUMBER (ERROR_REG_LIST, NULL); + SET_ERROR_STRING (ERROR_REG_LIST, NULL); return FALSE; } /* Check r4-r11. */ @@ -2665,7 +2686,7 @@ is_reglist_dash_comma_legal (char **oper, struct operand *oprnd) list |= (1 << 8); if (oprnd->mask == OPRND_MASK_0_4 && (list & ~OPRND_MASK_0_4)) { - SET_ERROR_NUMBER (ERROR_REG_LIST, NULL); + SET_ERROR_STRING (ERROR_REG_LIST, NULL); return FALSE; } csky_insn.val[csky_insn.idx++] = list; @@ -2681,14 +2702,14 @@ is_reg_lshift_illegal (char **oper, int is_float) reg = csky_get_reg_val (*oper, &len); if (reg == -1) { - SET_ERROR_NUMBER (ERROR_REG_FORMAT, "The register must be r0-r31."); + SET_ERROR_STRING (ERROR_REG_FORMAT, "The register must be r0-r31."); return FALSE; } *oper += len; if ((*oper)[0] != '<' || (*oper)[1] != '<') { - SET_ERROR_NUMBER (ERROR_UNDEFINE, + SET_ERROR_STRING (ERROR_UNDEFINE, "Operand format error; should be (rx, ry << n)"); return FALSE; } @@ -2702,13 +2723,13 @@ is_reg_lshift_illegal (char **oper, int is_float) /* The immediate must be in [0, 3]. */ if (e.X_add_number < 0 || e.X_add_number > 3) { - SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL); + SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL); return FALSE; } } else { - SET_ERROR_NUMBER (ERROR_EXP_CONSTANT, NULL); + SET_ERROR_STRING (ERROR_EXP_CONSTANT, NULL); return FALSE; } if (is_float) @@ -2721,7 +2742,31 @@ is_reg_lshift_illegal (char **oper, int is_float) } static bfd_boolean -is_imm_over_range (char **oper, int min, int max, int ext) +is_imm_within_range (char **oper, int min, int max) +{ + expressionS e; + bfd_boolean ret = FALSE; + char *new_oper = parse_exp (*oper, &e); + if (e.X_op == O_constant) + { + ret = TRUE; + *oper = new_oper; + if (e.X_add_number < min || e.X_add_number > max) + { + ret = FALSE; + SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL); + } + csky_insn.val[csky_insn.idx++] = e.X_add_number; + } + + else + SET_ERROR_STRING(ERROR_IMM_ILLEGAL, NULL); + + return ret; +} + +static bfd_boolean +is_imm_within_range_ext (char **oper, int min, int max, int ext) { expressionS e; bfd_boolean ret = FALSE; @@ -2734,16 +2779,19 @@ is_imm_over_range (char **oper, int min, int max, int ext) && (e.X_add_number < min || e.X_add_number > max)) { ret = FALSE; - SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL); + SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL); } csky_insn.val[csky_insn.idx++] = e.X_add_number; } + else + SET_ERROR_STRING(ERROR_IMM_ILLEGAL, NULL); + return ret; } static bfd_boolean -is_oimm_over_range (char **oper, int min, int max) +is_oimm_within_range (char **oper, int min, int max) { expressionS e; bfd_boolean ret = FALSE; @@ -2755,7 +2803,7 @@ is_oimm_over_range (char **oper, int min, int max) if (e.X_add_number < min || e.X_add_number > max) { ret = FALSE; - SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL); + SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL); } csky_insn.val[csky_insn.idx++] = e.X_add_number - 1; } @@ -2789,7 +2837,7 @@ is_psr_bit (char **oper) } i++; } - SET_ERROR_NUMBER (ERROR_OPCODE_PSRBIT, NULL); + SET_ERROR_STRING (ERROR_OPCODE_PSRBIT, NULL); return FALSE; } @@ -2847,7 +2895,7 @@ parse_type_cpreg (char** oper) return TRUE; } } - SET_ERROR_NUMBER (ERROR_CPREG_ILLEGAL, *oper); + SET_ERROR_STRING (ERROR_CPREG_ILLEGAL, *oper); return FALSE; } @@ -2868,7 +2916,7 @@ parse_type_cpcreg (char** oper) return TRUE; } } - SET_ERROR_NUMBER (ERROR_CPREG_ILLEGAL, *oper); + SET_ERROR_STRING (ERROR_CPREG_ILLEGAL, *oper); return FALSE; } @@ -2880,7 +2928,7 @@ parse_type_areg (char** oper) i = csky_get_reg_val (*oper, &len); if (i == -1) { - SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL, NULL); + SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL); return FALSE; } *oper += len; @@ -2897,15 +2945,15 @@ parse_type_freg (char** oper, int even) reg = csky_get_freg_val (*oper, &len); if (reg == -1) { - SET_ERROR_NUMBER (ERROR_REG_FORMAT, - "The fpu register format is not recognized."); + SET_ERROR_STRING (ERROR_REG_FORMAT, + (void *)"The fpu register format is not recognized."); return FALSE; } *oper += len; csky_insn.opcode_end = *oper; if (even && reg & 0x1) { - SET_ERROR_NUMBER (ERROR_EXP_EVEN_FREG, NULL); + SET_ERROR_STRING (ERROR_EXP_EVEN_FREG, NULL); return FALSE; } csky_insn.val[csky_insn.idx++] = reg; @@ -2939,19 +2987,21 @@ parse_ldst_imm (char **oper, struct csky_opcode_info *op ATTRIBUTE_UNUSED, expressionS e; *oper = parse_exp (*oper, &e); if (e.X_op != O_constant) + { /* Not a constant. */ + SET_ERROR_STRING(ERROR_UNDEFINE, (void *)"Operand format is error. eg. \"ld rz, (rx, n)\""); return FALSE; + } else if (e.X_add_number < 0 || e.X_add_number >= max) { /* Out of range. */ - SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL); + SET_ERROR_STRING(ERROR_IMM_OVERFLOW, NULL); return FALSE; } if ((e.X_add_number % (1 << shift)) != 0) { /* Not aligned. */ - SET_ERROR_NUMBER (ERROR_OFFSET_UNALIGNED, - (void *)"Operand format is error. eg. \"ld rz, (rx, n)\""); + SET_ERROR_INTEGER (ERROR_OFFSET_UNALIGNED, ((unsigned long)1 << shift)); return FALSE; } @@ -3124,7 +3174,7 @@ get_operand_value (struct csky_opcode_info *op, } else { - SET_ERROR_NUMBER ((oprnd->type == OPRND_TYPE_BRACKET + SET_ERROR_STRING ((oprnd->type == OPRND_TYPE_BRACKET ? ERROR_MISSING_LBRACKET : ERROR_MISSING_LANGLE_BRACKETS), NULL); return FALSE; @@ -3145,7 +3195,7 @@ get_operand_value (struct csky_opcode_info *op, *s = '\0'; else { - SET_ERROR_NUMBER ((oprnd->type == OPRND_TYPE_BRACKET + SET_ERROR_STRING ((oprnd->type == OPRND_TYPE_BRACKET ? ERROR_MISSING_RBRACKET : ERROR_MISSING_RANGLE_BRACKETS), NULL); return FALSE; @@ -3158,6 +3208,12 @@ get_operand_value (struct csky_opcode_info *op, } if (**oper == ',') *oper += 1; + else if (**oper != '\0') + { + SET_ERROR_STRING (ERROR_MISSING_COMMA, NULL); + return FALSE; + } + if (get_operand_value (op, oper, &soprnd->subs[1]) == FALSE) { *s = rc; @@ -3200,13 +3256,13 @@ get_operand_value (struct csky_opcode_info *op, if (reg == -1) { - SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL, NULL); + SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL); return FALSE; } else if ((oprnd->type == OPRND_TYPE_GREG0_7 && reg > 7) || (oprnd->type == OPRND_TYPE_GREG0_15 && reg > 15)) { - SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg); + SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, reg); return FALSE; } *oper += len; @@ -3223,7 +3279,7 @@ get_operand_value (struct csky_opcode_info *op, || (IS_CSKY_V1 (mach_flag) && (reg == V1_REG_SP || reg == V1_REG_LR))) { - SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg); + SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg); return FALSE; } csky_insn.val[csky_insn.idx++] = reg; @@ -3254,22 +3310,22 @@ get_operand_value (struct csky_opcode_info *op, csky_insn.val[csky_insn.idx++] = 0; return TRUE; } - SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL, NULL); + SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL); return FALSE; case OPRND_TYPE_IMM_LDST: return parse_ldst_imm (oper, op, oprnd); case OPRND_TYPE_IMM_FLDST: return parse_ldst_imm (oper, op, oprnd); case OPRND_TYPE_IMM1b: - return is_imm_over_range (oper, 0, 1, -1); + return is_imm_within_range (oper, 0, 1); case OPRND_TYPE_IMM2b: - return is_imm_over_range (oper, 0, 3, -1); + return is_imm_within_range (oper, 0, 3); case OPRND_TYPE_IMM2b_JMPIX: /* ck802j support jmpix16, but not support jmpix32. */ if (IS_CSKY_ARCH_802 (mach_flag) && (op->opcode & 0xffff0000) != 0) { - SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL, NULL); + SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL); return FALSE; } *oper = parse_exp (*oper, &csky_insn.e1); @@ -3278,7 +3334,7 @@ get_operand_value (struct csky_opcode_info *op, csky_insn.opcode_end = *oper; if (csky_insn.e1.X_add_number & 0x7) { - SET_ERROR_NUMBER (ERROR_JMPIX_OVER_RANGE, NULL); + SET_ERROR_STRING (ERROR_JMPIX_OVER_RANGE, NULL); return FALSE; } csky_insn.val[csky_insn.idx++] @@ -3286,13 +3342,12 @@ get_operand_value (struct csky_opcode_info *op, } return TRUE; case OPRND_TYPE_IMM4b: - return is_imm_over_range (oper, 0, 15, -1); - break; + return is_imm_within_range (oper, 0, 15); case OPRND_TYPE_IMM5b: - return is_imm_over_range (oper, 0, 31, -1); + return is_imm_within_range (oper, 0, 31); /* This type for "bgeni" in csky v1 ISA. */ case OPRND_TYPE_IMM5b_7_31: - if (is_imm_over_range (oper, 0, 31, -1)) + if (is_imm_within_range (oper, 0, 31)) { int val = csky_insn.val[csky_insn.idx - 1]; /* immediate values of 0 -> 6 translate to movi. */ @@ -3309,9 +3364,9 @@ get_operand_value (struct csky_opcode_info *op, return FALSE; case OPRND_TYPE_IMM5b_1_31: - return is_imm_over_range (oper, 1, 31, -1); + return is_imm_within_range (oper, 1, 31); case OPRND_TYPE_IMM5b_POWER: - if (is_imm_over_range (oper, 1, (1u << 31) - 1, 1u << 31)) + if (is_imm_within_range_ext (oper, 1, (1u << 31) - 1, 1u << 31)) { int log; int val = csky_insn.val[csky_insn.idx - 1]; @@ -3324,7 +3379,7 @@ get_operand_value (struct csky_opcode_info *op, /* This type for "mgeni" in csky v1 ISA. */ case OPRND_TYPE_IMM5b_7_31_POWER: - if (is_imm_over_range (oper, 1, (1u << 31) - 1, 1u << 31)) + if (is_imm_within_range_ext (oper, 1, (1u << 31) - 1, 1u << 31)) { int log; int val = csky_insn.val[csky_insn.idx - 1]; @@ -3348,7 +3403,7 @@ get_operand_value (struct csky_opcode_info *op, { unsigned max_shift = IS_CSKY_V1 (mach_flag) ? 31 : 32; - if (is_imm_over_range (oper, 1, max_shift, -1)) + if (is_imm_within_range (oper, 1, max_shift)) { int i = csky_insn.idx - 1; csky_insn.val[i] = 32 - csky_insn.val[i]; @@ -3361,7 +3416,7 @@ get_operand_value (struct csky_opcode_info *op, case OPRND_TYPE_IMM5b_BMASKI: /* For csky v1 bmask inst. */ - if (!is_imm_over_range (oper, 8, 31, 0)) + if (!is_imm_within_range_ext (oper, 8, 31, 0)) { unsigned int mask_val = csky_insn.val[csky_insn.idx - 1]; if (mask_val > 0 && mask_val < 8) @@ -3379,7 +3434,7 @@ get_operand_value (struct csky_opcode_info *op, case OPRND_TYPE_IMM8b_BMASKI: /* For csky v2 bmask, which will transfer to 16bits movi. */ - if (is_imm_over_range (oper, 1, 8, -1)) + if (is_imm_within_range (oper, 1, 8)) { unsigned int mask_val = csky_insn.val[csky_insn.idx - 1]; csky_insn.val[csky_insn.idx - 1] = (1 << mask_val) - 1; @@ -3387,11 +3442,11 @@ get_operand_value (struct csky_opcode_info *op, } return FALSE; case OPRND_TYPE_OIMM4b: - return is_oimm_over_range (oper, 1, 16); + return is_oimm_within_range (oper, 1, 16); case OPRND_TYPE_OIMM5b: - return is_oimm_over_range (oper, 1, 32); + return is_oimm_within_range (oper, 1, 32); case OPRND_TYPE_OIMM5b_IDLY: - if (is_imm_over_range (oper, 0, 32, -1)) + if (is_imm_within_range (oper, 0, 32)) { /* imm5b for idly n: 0<=n<4, imm5b=3; 4<=n<=32, imm5b=n-1. */ unsigned long imm = csky_insn.val[csky_insn.idx - 1]; @@ -3409,7 +3464,7 @@ get_operand_value (struct csky_opcode_info *op, /* For csky v2 bmask inst. */ case OPRND_TYPE_OIMM5b_BMASKI: - if (!is_oimm_over_range (oper, 17, 32)) + if (!is_oimm_within_range (oper, 17, 32)) { int mask_val = csky_insn.val[csky_insn.idx - 1]; if (mask_val + 1 == 0) @@ -3427,17 +3482,17 @@ get_operand_value (struct csky_opcode_info *op, } return TRUE; case OPRND_TYPE_IMM7b: - return is_imm_over_range (oper, 0, 127, -1); + return is_imm_within_range (oper, 0, 127); case OPRND_TYPE_IMM8b: - return is_imm_over_range (oper, 0, 255, -1); + return is_imm_within_range (oper, 0, 255); case OPRND_TYPE_IMM12b: - return is_imm_over_range (oper, 0, 4095, -1); + return is_imm_within_range (oper, 0, 4095); case OPRND_TYPE_IMM15b: - return is_imm_over_range (oper, 0, 0xfffff, -1); + return is_imm_within_range (oper, 0, 0xfffff); case OPRND_TYPE_IMM16b: - return is_imm_over_range (oper, 0, 65535, -1); + return is_imm_within_range (oper, 0, 65535); case OPRND_TYPE_OIMM16b: - return is_oimm_over_range (oper, 1, 65536); + return is_oimm_within_range (oper, 1, 65536); case OPRND_TYPE_IMM32b: { expressionS e; @@ -3501,7 +3556,7 @@ get_operand_value (struct csky_opcode_info *op, ret = FALSE; } if (!ret) - SET_ERROR_NUMBER (ERROR_OPERANDS_ILLEGAL, csky_insn.opcode_end); + SET_ERROR_STRING (ERROR_OPERANDS_ILLEGAL, csky_insn.opcode_end); return ret; } case OPRND_TYPE_RM: @@ -3541,20 +3596,20 @@ get_operand_value (struct csky_opcode_info *op, int reg; if (**oper != '(') { - SET_ERROR_NUMBER (ERROR_MISSING_LBRACKET, NULL); + SET_ERROR_STRING (ERROR_MISSING_LBRACKET, NULL); return FALSE; } *oper += 1; reg = csky_get_reg_val (*oper, &len); if (reg == -1) { - SET_ERROR_NUMBER (ERROR_EXP_GREG, NULL); + SET_ERROR_STRING (ERROR_EXP_GREG, NULL); return FALSE; } *oper += len; if (**oper != ')') { - SET_ERROR_NUMBER (ERROR_MISSING_RBRACKET, NULL); + SET_ERROR_STRING (ERROR_MISSING_RBRACKET, NULL); return FALSE; } *oper += 1; @@ -3650,7 +3705,7 @@ get_operand_value (struct csky_opcode_info *op, reg = csky_get_reg_val (*oper, &len); if (reg == -1) { - SET_ERROR_NUMBER (ERROR_REG_FORMAT, + SET_ERROR_STRING (ERROR_REG_FORMAT, "The first operand must be register r1."); return FALSE; } @@ -3668,7 +3723,7 @@ get_operand_value (struct csky_opcode_info *op, reg = csky_get_reg_val (*oper, &len); if (reg == -1) { - SET_ERROR_NUMBER (ERROR_REG_FORMAT, + SET_ERROR_STRING (ERROR_REG_FORMAT, "The second operand must be register r1."); return FALSE; } @@ -3693,12 +3748,12 @@ get_operand_value (struct csky_opcode_info *op, reg = csky_get_reg_val (*oper, &len); if (reg == -1) { - SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL, NULL); + SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL); return FALSE; } if (reg != csky_insn.val[0]) { - SET_ERROR_NUMBER (ERROR_REG_FORMAT, + SET_ERROR_STRING (ERROR_REG_FORMAT, "The second register must be the same as the first."); return FALSE; } @@ -3716,7 +3771,7 @@ get_operand_value (struct csky_opcode_info *op, reg = csky_get_reg_val (*oper, &len); if (reg == -1) { - SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL, NULL); + SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL); return FALSE; } /* dummy reg's real type should be same with first operand. */ @@ -3772,16 +3827,16 @@ get_operand_value (struct csky_opcode_info *op, if (reg == -1) { if (max_reg == 31) - SET_ERROR_NUMBER (ERROR_REG_FORMAT, + SET_ERROR_STRING (ERROR_REG_FORMAT, "The register must be r0-r31"); else - SET_ERROR_NUMBER (ERROR_REG_FORMAT, + SET_ERROR_STRING (ERROR_REG_FORMAT, "The register must be r0-r15"); return FALSE; } if (reg > max_reg) { - SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg); + SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg); return FALSE; } reg |= reg << shift_num; @@ -3890,7 +3945,7 @@ get_operand_value (struct csky_opcode_info *op, *oper = new_oper; if (e.X_add_number > 31) { - SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL); + SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL); return FALSE; } csky_insn.val[csky_insn.idx++] = e.X_add_number; @@ -3898,7 +3953,7 @@ get_operand_value (struct csky_opcode_info *op, { if (csky_insn.val[csky_insn.idx - 1] > csky_insn.val[csky_insn.idx - 2]) { - SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL); + SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL); return FALSE; } csky_insn.val[csky_insn.idx - 2] -= e.X_add_number; @@ -3917,7 +3972,7 @@ get_operand_value (struct csky_opcode_info *op, if (**oper == '[') { (*oper)++; - if (is_imm_over_range (oper, 0, 0xf, -1)) + if (is_imm_within_range (oper, 0, 0xf)) { if (**oper == ']') { @@ -3928,11 +3983,11 @@ get_operand_value (struct csky_opcode_info *op, return TRUE; } else - SET_ERROR_NUMBER (ERROR_MISSING_RSQUARE_BRACKETS, NULL); + SET_ERROR_STRING (ERROR_MISSING_RSQUARE_BRACKETS, NULL); } } else - SET_ERROR_NUMBER (ERROR_MISSING_LSQUARE_BRACKETS, NULL); + SET_ERROR_STRING (ERROR_MISSING_LSQUARE_BRACKETS, NULL); } return FALSE; @@ -3963,7 +4018,7 @@ parse_operands_op (char *str, struct csky_opcode_info *op) || (op[i].operand_num == -1 && csky_insn.number != 0))) { /* The smaller err_num is more serious. */ - SET_ERROR_NUMBER (ERROR_OPERANDS_NUMBER, op[i].operand_num); + SET_ERROR_INTEGER (ERROR_OPERANDS_NUMBER, op[i].operand_num); flag_pass = FALSE; continue; } @@ -3985,14 +4040,14 @@ parse_operands_op (char *str, struct csky_opcode_info *op) oper++; else { - SET_ERROR_NUMBER (ERROR_MISSING_COMMA, NULL); + SET_ERROR_STRING (ERROR_MISSING_COMMA, NULL); flag_pass = FALSE; break; } } else if (!is_end_of_line[(unsigned char) *oper]) { - SET_ERROR_NUMBER (ERROR_BAD_END, NULL); + SET_ERROR_STRING (ERROR_BAD_END, NULL); flag_pass = FALSE; break; } @@ -4233,12 +4288,12 @@ md_assemble (char *str) return; } else if (error_state.err_num > ERROR_OPERANDS_NUMBER) - SET_ERROR_NUMBER (ERROR_OPERANDS_NUMBER, csky_insn.macro->oprnd_num); + SET_ERROR_STRING (ERROR_OPERANDS_NUMBER, csky_insn.macro->oprnd_num); } if (csky_insn.opcode == NULL) { - SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL, NULL); + SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL); csky_show_error (error_state.err_num, error_state.opnum, (void *)error_state.arg1, (void *)error_state.arg1); return; @@ -5551,7 +5606,7 @@ static void csky_idly (void) { char *s = csky_insn.opcode_end; - if (!is_imm_over_range (&s, 4, 4, -1)) + if (!is_imm_within_range (&s, 4, 4)) { as_bad (_("second operand must be 4")); return; @@ -5571,7 +5626,7 @@ csky_rolc (void) s += csky_get_macro_operand (s, reg, ','); ++s; - if (is_imm_over_range (&s, 1, 1, -1)) + if (is_imm_within_range (&s, 1, 1)) { csky_macro_md_assemble ("addc", reg, reg, NULL); return; @@ -6404,23 +6459,33 @@ v2_work_add_sub (void) if (csky_insn.number == 3) { if (csky_insn.val[0] > 7) - csky_show_error (ERROR_REG_OVER_RANGE, 1, - (void *)(long)csky_insn.val[0], NULL); + { + SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[0]); + csky_show_error (ERROR_REG_OVER_RANGE, 1, NULL, NULL); + } if (csky_insn.val[1] > 7) - csky_show_error (ERROR_REG_OVER_RANGE, 2, - (void *)(long)csky_insn.val[1], NULL); + { + SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[1]); + csky_show_error (ERROR_REG_OVER_RANGE, 2, NULL, NULL); + } if (csky_insn.val[2] > 7) - csky_show_error (ERROR_REG_OVER_RANGE, 3, - (void *)(long)csky_insn.val[2], NULL); + { + SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[2]); + csky_show_error (ERROR_REG_OVER_RANGE, 3, NULL, NULL); + } } else { if (csky_insn.val[0] > 15) - csky_show_error (ERROR_REG_OVER_RANGE, 1, - (void *)(long)csky_insn.val[0], NULL); + { + SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[0]); + csky_show_error (ERROR_REG_OVER_RANGE, 1, NULL, NULL); + } if (csky_insn.val[1] > 15) - csky_show_error (ERROR_REG_OVER_RANGE, 2, - (void *)(long)csky_insn.val[1], NULL); + { + SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[1]); + csky_show_error (ERROR_REG_OVER_RANGE, 2, NULL, NULL); + } } return FALSE; } diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index b6119c459b..20e7ec31a1 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,8 @@ +2020-08-31 Cooper Qu + + * csky-dis.c (csky_output_operand): Assign dis_info.value for + OPRND_TYPE_VREG. + 2020-08-30 Alan Modra * cr16-dis.c: Formatting. diff --git a/opcodes/csky-dis.c b/opcodes/csky-dis.c index 6becad0130..09eed4b825 100644 --- a/opcodes/csky-dis.c +++ b/opcodes/csky-dis.c @@ -342,6 +342,7 @@ csky_output_operand (char *str, struct operand const *oprnd, strcat (str, buf); break; case OPRND_TYPE_VREG: + dis_info.value = value; sprintf (buf, "vr%d", (int)value); strcat (str, buf); break; -- 2.34.1