diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2016-06-15 15:50:51 +0100 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2016-08-23 09:41:02 +0100 |
commit | 389db08a9b3c75250be8579515699d744489a9eb (patch) | |
tree | fb8e8f93141d7ff96e8f5eafdc49478bdefed8ad | |
parent | 10b362d05ee1849915dd33534eae201697bce957 (diff) | |
download | gdb-389db08a9b3c75250be8579515699d744489a9eb.zip gdb-389db08a9b3c75250be8579515699d744489a9eb.tar.gz gdb-389db08a9b3c75250be8579515699d744489a9eb.tar.bz2 |
[AArch64][SVE 11/32] Tweak aarch64_reg_parse_32_64 interface
aarch64_reg_parse_32_64 is currently used to parse address registers,
among other things. It returns two bits of information about the
register: whether it's W rather than X, and whether it's a zero register.
SVE adds addressing modes in which the base or offset can be a vector
register instead of a scalar, so a choice between W and X is no longer
enough. It's more convenient to pass the type of register around as
a qualifier instead.
As it happens, two callers of aarch64_reg_parse_32_64 already wanted
the information in the form of a qualifier, so the change feels pretty
natural even without SVE.
Also, the function took two parameters to control whether {W}SP
and (W|X)ZR should be accepted. These parameters were negative
"reject" parameters, but the closely-related parse_address_main
had a positive "accept" parameter (for post-indexed addressing).
One of the SVE patches adds a parameter to parse_address_main
that needs to be passed down alongside the aarch64_reg_parse_32_64
parameters, which as things stood led to an awkward mix of positive
and negative bools. The patch therefore changes the
aarch64_reg_parse_32_64 parameters to "accept_sp" and "accept_rz"
instead.
Finally, the two input parameters and isregzero return value were
all ints but logically bools. The patch changes the types to
bfd_boolean.
gas/
* config/tc-aarch64.c (aarch64_reg_parse_32_64): Return the register
type as a qualifier rather than an "isreg32" boolean. Turn the
SP/ZR control parameters from negative "reject" to positive
"accept". Make them and *ISREGZERO bfd_booleans rather than ints.
(parse_shifter_operand): Update accordingly.
(parse_address_main): Likewise.
(po_int_reg_or_fail): Likewise. Make the same reject->accept
change to the macro parameters.
(parse_operands): Update after the above changes, replacing
the "isreg32" local variable with one called "qualifier".
Change-Id: Ifa366ca8105100004ca86a04fa28457c85810d84
-rw-r--r-- | gas/config/tc-aarch64.c | 87 |
1 files changed, 51 insertions, 36 deletions
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 2489d5b..2e0e4f8 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -690,15 +690,21 @@ aarch64_check_reg_type (const reg_entry *reg, aarch64_reg_type type) } } -/* Parse a register and return PARSE_FAIL if the register is not of type R_Z_SP. - Return the register number otherwise. *ISREG32 is set to one if the - register is 32-bit wide; *ISREGZERO is set to one if the register is - of type Z_32 or Z_64. +/* Try to parse a base or offset register. ACCEPT_SP says whether {W}SP + should be considered valid and ACCEPT_RZ says whether zero registers + should be considered valid. + + Return the register number on success, setting *QUALIFIER to the + register qualifier and *ISREGZERO to whether the register is a zero + register. Return PARSE_FAIL otherwise. + Note that this function does not issue any diagnostics. */ static int -aarch64_reg_parse_32_64 (char **ccp, int reject_sp, int reject_rz, - int *isreg32, int *isregzero) +aarch64_reg_parse_32_64 (char **ccp, bfd_boolean accept_sp, + bfd_boolean accept_rz, + aarch64_opnd_qualifier_t *qualifier, + bfd_boolean *isregzero) { char *str = *ccp; const reg_entry *reg = parse_reg (&str); @@ -713,22 +719,28 @@ aarch64_reg_parse_32_64 (char **ccp, int reject_sp, int reject_rz, { case REG_TYPE_SP_32: case REG_TYPE_SP_64: - if (reject_sp) + if (!accept_sp) return PARSE_FAIL; - *isreg32 = reg->type == REG_TYPE_SP_32; - *isregzero = 0; + *qualifier = (reg->type == REG_TYPE_SP_32 + ? AARCH64_OPND_QLF_W + : AARCH64_OPND_QLF_X); + *isregzero = FALSE; break; case REG_TYPE_R_32: case REG_TYPE_R_64: - *isreg32 = reg->type == REG_TYPE_R_32; - *isregzero = 0; + *qualifier = (reg->type == REG_TYPE_R_32 + ? AARCH64_OPND_QLF_W + : AARCH64_OPND_QLF_X); + *isregzero = FALSE; break; case REG_TYPE_Z_32: case REG_TYPE_Z_64: - if (reject_rz) + if (!accept_rz) return PARSE_FAIL; - *isreg32 = reg->type == REG_TYPE_Z_32; - *isregzero = 1; + *qualifier = (reg->type == REG_TYPE_Z_32 + ? AARCH64_OPND_QLF_W + : AARCH64_OPND_QLF_X); + *isregzero = TRUE; break; default: return PARSE_FAIL; @@ -3033,12 +3045,13 @@ parse_shifter_operand (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode) { int reg; - int isreg32, isregzero; + aarch64_opnd_qualifier_t qualifier; + bfd_boolean isregzero; enum aarch64_operand_class opd_class = aarch64_get_operand_class (operand->type); - if ((reg = - aarch64_reg_parse_32_64 (str, 0, 0, &isreg32, &isregzero)) != PARSE_FAIL) + if ((reg = aarch64_reg_parse_32_64 (str, TRUE, TRUE, &qualifier, + &isregzero)) != PARSE_FAIL) { if (opd_class == AARCH64_OPND_CLASS_IMMEDIATE) { @@ -3053,7 +3066,7 @@ parse_shifter_operand (char **str, aarch64_opnd_info *operand, } operand->reg.regno = reg; - operand->qualifier = isreg32 ? AARCH64_OPND_QLF_W : AARCH64_OPND_QLF_X; + operand->qualifier = qualifier; /* Accept optional shift operation on register. */ if (! skip_past_comma (str)) @@ -3193,7 +3206,9 @@ parse_address_main (char **str, aarch64_opnd_info *operand, int reloc, { char *p = *str; int reg; - int isreg32, isregzero; + aarch64_opnd_qualifier_t base_qualifier; + aarch64_opnd_qualifier_t offset_qualifier; + bfd_boolean isregzero; expressionS *exp = &inst.reloc.exp; if (! skip_past_char (&p, '[')) @@ -3271,8 +3286,8 @@ parse_address_main (char **str, aarch64_opnd_info *operand, int reloc, /* [ */ /* Accept SP and reject ZR */ - reg = aarch64_reg_parse_32_64 (&p, 0, 1, &isreg32, &isregzero); - if (reg == PARSE_FAIL || isreg32) + reg = aarch64_reg_parse_32_64 (&p, TRUE, FALSE, &base_qualifier, &isregzero); + if (reg == PARSE_FAIL || base_qualifier == AARCH64_OPND_QLF_W) { set_syntax_error (_(get_reg_expected_msg (REG_TYPE_R_64))); return FALSE; @@ -3286,7 +3301,8 @@ parse_address_main (char **str, aarch64_opnd_info *operand, int reloc, operand->addr.preind = 1; /* Reject SP and accept ZR */ - reg = aarch64_reg_parse_32_64 (&p, 1, 0, &isreg32, &isregzero); + reg = aarch64_reg_parse_32_64 (&p, FALSE, TRUE, &offset_qualifier, + &isregzero); if (reg != PARSE_FAIL) { /* [Xn,Rm */ @@ -3309,13 +3325,13 @@ parse_address_main (char **str, aarch64_opnd_info *operand, int reloc, || operand->shifter.kind == AARCH64_MOD_LSL || operand->shifter.kind == AARCH64_MOD_SXTX) { - if (isreg32) + if (offset_qualifier == AARCH64_OPND_QLF_W) { set_syntax_error (_("invalid use of 32-bit register offset")); return FALSE; } } - else if (!isreg32) + else if (offset_qualifier == AARCH64_OPND_QLF_X) { set_syntax_error (_("invalid use of 64-bit register offset")); return FALSE; @@ -3399,11 +3415,12 @@ parse_address_main (char **str, aarch64_opnd_info *operand, int reloc, } if (accept_reg_post_index - && (reg = aarch64_reg_parse_32_64 (&p, 1, 1, &isreg32, + && (reg = aarch64_reg_parse_32_64 (&p, FALSE, FALSE, + &offset_qualifier, &isregzero)) != PARSE_FAIL) { /* [Xn],Xm */ - if (isreg32) + if (offset_qualifier == AARCH64_OPND_QLF_W) { set_syntax_error (_("invalid 32-bit register offset")); return FALSE; @@ -3723,19 +3740,16 @@ parse_sys_ins_reg (char **str, struct hash_control *sys_ins_regs) } \ } while (0) -#define po_int_reg_or_fail(reject_sp, reject_rz) do { \ - val = aarch64_reg_parse_32_64 (&str, reject_sp, reject_rz, \ - &isreg32, &isregzero); \ +#define po_int_reg_or_fail(accept_sp, accept_rz) do { \ + val = aarch64_reg_parse_32_64 (&str, accept_sp, accept_rz, \ + &qualifier, &isregzero); \ if (val == PARSE_FAIL) \ { \ set_default_error (); \ goto failure; \ } \ info->reg.regno = val; \ - if (isreg32) \ - info->qualifier = AARCH64_OPND_QLF_W; \ - else \ - info->qualifier = AARCH64_OPND_QLF_X; \ + info->qualifier = qualifier; \ } while (0) #define po_imm_nc_or_fail() do { \ @@ -4993,10 +5007,11 @@ parse_operands (char *str, const aarch64_opcode *opcode) for (i = 0; operands[i] != AARCH64_OPND_NIL; i++) { int64_t val; - int isreg32, isregzero; + bfd_boolean isregzero; int comma_skipped_p = 0; aarch64_reg_type rtype; struct vector_type_el vectype; + aarch64_opnd_qualifier_t qualifier; aarch64_opnd_info *info = &inst.base.operands[i]; DEBUG_TRACE ("parse operand %d", i); @@ -5032,12 +5047,12 @@ parse_operands (char *str, const aarch64_opcode *opcode) case AARCH64_OPND_Ra: case AARCH64_OPND_Rt_SYS: case AARCH64_OPND_PAIRREG: - po_int_reg_or_fail (1, 0); + po_int_reg_or_fail (FALSE, TRUE); break; case AARCH64_OPND_Rd_SP: case AARCH64_OPND_Rn_SP: - po_int_reg_or_fail (0, 1); + po_int_reg_or_fail (TRUE, FALSE); break; case AARCH64_OPND_Rm_EXT: |