aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2016-06-15 15:50:51 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2016-08-23 09:41:02 +0100
commit389db08a9b3c75250be8579515699d744489a9eb (patch)
treefb8e8f93141d7ff96e8f5eafdc49478bdefed8ad
parent10b362d05ee1849915dd33534eae201697bce957 (diff)
downloadgdb-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.c87
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: