diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2016-09-21 16:57:22 +0100 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2016-09-21 16:57:22 +0100 |
commit | 165d4950855493dd904a7996e7fcf58880d54219 (patch) | |
tree | fc047fa205dfb573b6ef4a25aa088adad21d7e26 /gas | |
parent | e950b3453948830c5ce9c2f70d114d0b38a4b4ac (diff) | |
download | gdb-165d4950855493dd904a7996e7fcf58880d54219.zip gdb-165d4950855493dd904a7996e7fcf58880d54219.tar.gz gdb-165d4950855493dd904a7996e7fcf58880d54219.tar.bz2 |
[AArch64][SVE 28/32] Add SVE FP immediate operands
This patch adds support for the new SVE floating-point immediate
operands. One operand uses the same 8-bit encoding as base AArch64,
but in a different position. The others use a single bit to select
between two values.
One of the single-bit operands is a choice between 0 and 1, where 0
is not a valid 8-bit encoding. I think the cleanest way of handling
these single-bit immediates is therefore to use the IEEE float encoding
itself as the immediate value and select between the two possible values
when encoding and decoding.
As described in the covering note for the patch that added F_STRICT,
we get better error messages by accepting unsuffixed vector registers
and leaving the qualifier matching code to report an error. This means
that we carry on parsing the other operands, and so can try to parse FP
immediates for invalid instructions like:
fcpy z0, #2.5
In this case there is no suffix to tell us whether the immediate should
be treated as single or double precision. Again, we get better error
messages by picking one (arbitrary) immediate size and reporting an error
for the missing suffix later.
include/
* opcode/aarch64.h (AARCH64_OPND_SVE_FPIMM8): New aarch64_opnd.
(AARCH64_OPND_SVE_I1_HALF_ONE, AARCH64_OPND_SVE_I1_HALF_TWO)
(AARCH64_OPND_SVE_I1_ZERO_ONE): Likewise.
opcodes/
* aarch64-tbl.h (AARCH64_OPERANDS): Add entries for the new SVE FP
immediate operands.
* aarch64-opc.h (FLD_SVE_i1): New aarch64_field_kind.
* aarch64-opc.c (fields): Add corresponding entry.
(operand_general_constraint_met_p): Handle the new SVE FP immediate
operands.
(aarch64_print_operand): Likewise.
* aarch64-opc-2.c: Regenerate.
* aarch64-asm.h (ins_sve_float_half_one, ins_sve_float_half_two)
(ins_sve_float_zero_one): New inserters.
* aarch64-asm.c (aarch64_ins_sve_float_half_one): New function.
(aarch64_ins_sve_float_half_two): Likewise.
(aarch64_ins_sve_float_zero_one): Likewise.
* aarch64-asm-2.c: Regenerate.
* aarch64-dis.h (ext_sve_float_half_one, ext_sve_float_half_two)
(ext_sve_float_zero_one): New extractors.
* aarch64-dis.c (aarch64_ext_sve_float_half_one): New function.
(aarch64_ext_sve_float_half_two): Likewise.
(aarch64_ext_sve_float_zero_one): Likewise.
* aarch64-dis-2.c: Regenerate.
gas/
* config/tc-aarch64.c (double_precision_operand_p): New function.
(parse_operands): Use it to calculate the dp_p input to
parse_aarch64_imm_float. Handle the new SVE FP immediate operands.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 6 | ||||
-rw-r--r-- | gas/config/tc-aarch64.c | 41 |
2 files changed, 44 insertions, 3 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index a146799..53faa4e 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,11 @@ 2016-09-21 Richard Sandiford <richard.sandiford@arm.com> + * config/tc-aarch64.c (double_precision_operand_p): New function. + (parse_operands): Use it to calculate the dp_p input to + parse_aarch64_imm_float. Handle the new SVE FP immediate operands. + +2016-09-21 Richard Sandiford <richard.sandiford@arm.com> + * config/tc-aarch64.c (parse_operands): Handle the new SVE integer immediate operands. diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 6b9ae29..01c8000 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -2232,6 +2232,20 @@ can_convert_double_to_float (uint64_t imm, uint32_t *fpword) return TRUE; } +/* Return true if we should treat OPERAND as a double-precision + floating-point operand rather than a single-precision one. */ +static bfd_boolean +double_precision_operand_p (const aarch64_opnd_info *operand) +{ + /* Check for unsuffixed SVE registers, which are allowed + for LDR and STR but not in instructions that require an + immediate. We get better error messages if we arbitrarily + pick one size, parse the immediate normally, and then + report the match failure in the normal way. */ + return (operand->qualifier == AARCH64_OPND_QLF_NIL + || aarch64_get_qualifier_esize (operand->qualifier) == 8); +} + /* Parse a floating-point immediate. Return TRUE on success and return the value in *IMMED in the format of IEEE754 single-precision encoding. *CCP points to the start of the string; DP_P is TRUE when the immediate @@ -5655,11 +5669,12 @@ parse_operands (char *str, const aarch64_opcode *opcode) case AARCH64_OPND_FPIMM: case AARCH64_OPND_SIMD_FPIMM: + case AARCH64_OPND_SVE_FPIMM8: { int qfloat; - bfd_boolean dp_p - = (aarch64_get_qualifier_esize (inst.base.operands[0].qualifier) - == 8); + bfd_boolean dp_p; + + dp_p = double_precision_operand_p (&inst.base.operands[0]); if (!parse_aarch64_imm_float (&str, &qfloat, dp_p, imm_reg_type) || !aarch64_imm_float_p (qfloat)) { @@ -5673,6 +5688,26 @@ parse_operands (char *str, const aarch64_opcode *opcode) } break; + case AARCH64_OPND_SVE_I1_HALF_ONE: + case AARCH64_OPND_SVE_I1_HALF_TWO: + case AARCH64_OPND_SVE_I1_ZERO_ONE: + { + int qfloat; + bfd_boolean dp_p; + + dp_p = double_precision_operand_p (&inst.base.operands[0]); + if (!parse_aarch64_imm_float (&str, &qfloat, dp_p, imm_reg_type)) + { + if (!error_p ()) + set_fatal_syntax_error (_("invalid floating-point" + " constant")); + goto failure; + } + inst.base.operands[i].imm.value = qfloat; + inst.base.operands[i].imm.is_fp = 1; + } + break; + case AARCH64_OPND_LIMM: po_misc_or_fail (parse_shifter_operand (&str, info, SHIFTED_LOGIC_IMM)); |