From aeec16c7d1313f0ffac901fe41edf5fb0451ccac Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 21 Jun 2016 20:16:55 +0100 Subject: [AArch64][SVE 25/32] Add support for SVE addressing modes This patch adds most of the new SVE addressing modes and associated operands. A follow-on patch adds MUL VL, since handling it separately makes the changes easier to read. The patch also introduces a new "operand-dependent data" field to the operand flags, based closely on the existing one for opcode flags. For SVE this new field needs only 2 bits, but it could be widened in future if necessary. include/opcode/ * aarch64.h (AARCH64_OPND_SVE_ADDR_RI_U6): New aarch64_opnd. (AARCH64_OPND_SVE_ADDR_RI_U6x2, AARCH64_OPND_SVE_ADDR_RI_U6x4) (AARCH64_OPND_SVE_ADDR_RI_U6x8, AARCH64_OPND_SVE_ADDR_RR) (AARCH64_OPND_SVE_ADDR_RR_LSL1, AARCH64_OPND_SVE_ADDR_RR_LSL2) (AARCH64_OPND_SVE_ADDR_RR_LSL3, AARCH64_OPND_SVE_ADDR_RX) (AARCH64_OPND_SVE_ADDR_RX_LSL1, AARCH64_OPND_SVE_ADDR_RX_LSL2) (AARCH64_OPND_SVE_ADDR_RX_LSL3, AARCH64_OPND_SVE_ADDR_RZ) (AARCH64_OPND_SVE_ADDR_RZ_LSL1, AARCH64_OPND_SVE_ADDR_RZ_LSL2) (AARCH64_OPND_SVE_ADDR_RZ_LSL3, AARCH64_OPND_SVE_ADDR_RZ_XTW_14) (AARCH64_OPND_SVE_ADDR_RZ_XTW_22, AARCH64_OPND_SVE_ADDR_RZ_XTW1_14) (AARCH64_OPND_SVE_ADDR_RZ_XTW1_22, AARCH64_OPND_SVE_ADDR_RZ_XTW2_14) (AARCH64_OPND_SVE_ADDR_RZ_XTW2_22, AARCH64_OPND_SVE_ADDR_RZ_XTW3_14) (AARCH64_OPND_SVE_ADDR_RZ_XTW3_22, AARCH64_OPND_SVE_ADDR_ZI_U5) (AARCH64_OPND_SVE_ADDR_ZI_U5x2, AARCH64_OPND_SVE_ADDR_ZI_U5x4) (AARCH64_OPND_SVE_ADDR_ZI_U5x8, AARCH64_OPND_SVE_ADDR_ZZ_LSL) (AARCH64_OPND_SVE_ADDR_ZZ_SXTW, AARCH64_OPND_SVE_ADDR_ZZ_UXTW): Likewise. opcodes/ * aarch64-tbl.h (AARCH64_OPERANDS): Add entries for the new SVE address operands. * aarch64-opc.h (FLD_SVE_imm6, FLD_SVE_msz, FLD_SVE_xs_14) (FLD_SVE_xs_22): New aarch64_field_kinds. (OPD_F_OD_MASK, OPD_F_OD_LSB, OPD_F_NO_ZR): New flags. (get_operand_specific_data): New function. * aarch64-opc.c (fields): Add entries for FLD_SVE_imm6, FLD_SVE_msz, FLD_SVE_xs_14 and FLD_SVE_xs_22. (operand_general_constraint_met_p): Handle the new SVE address operands. (sve_reg): New array. (get_addr_sve_reg_name): New function. (aarch64_print_operand): Handle the new SVE address operands. * aarch64-opc-2.c: Regenerate. * aarch64-asm.h (ins_sve_addr_ri_u6, ins_sve_addr_rr_lsl) (ins_sve_addr_rz_xtw, ins_sve_addr_zi_u5, ins_sve_addr_zz_lsl) (ins_sve_addr_zz_sxtw, ins_sve_addr_zz_uxtw): New inserters. * aarch64-asm.c (aarch64_ins_sve_addr_ri_u6): New function. (aarch64_ins_sve_addr_rr_lsl): Likewise. (aarch64_ins_sve_addr_rz_xtw): Likewise. (aarch64_ins_sve_addr_zi_u5): Likewise. (aarch64_ins_sve_addr_zz): Likewise. (aarch64_ins_sve_addr_zz_lsl): Likewise. (aarch64_ins_sve_addr_zz_sxtw): Likewise. (aarch64_ins_sve_addr_zz_uxtw): Likewise. * aarch64-asm-2.c: Regenerate. * aarch64-dis.h (ext_sve_addr_ri_u6, ext_sve_addr_rr_lsl) (ext_sve_addr_rz_xtw, ext_sve_addr_zi_u5, ext_sve_addr_zz_lsl) (ext_sve_addr_zz_sxtw, ext_sve_addr_zz_uxtw): New extractors. * aarch64-dis.c (aarch64_ext_sve_add_reg_imm): New function. (aarch64_ext_sve_addr_ri_u6): Likewise. (aarch64_ext_sve_addr_rr_lsl): Likewise. (aarch64_ext_sve_addr_rz_xtw): Likewise. (aarch64_ext_sve_addr_zi_u5): Likewise. (aarch64_ext_sve_addr_zz): Likewise. (aarch64_ext_sve_addr_zz_lsl): Likewise. (aarch64_ext_sve_addr_zz_sxtw): Likewise. (aarch64_ext_sve_addr_zz_uxtw): Likewise. * aarch64-dis-2.c: Regenerate. gas/ * config/tc-aarch64.c (aarch64_addr_reg_parse): New function, split out from aarch64_reg_parse_32_64. Handle Z registers too. (aarch64_reg_parse_32_64): Call it. (parse_address_main): Add base_qualifier, offset_qualifier and accept_sve parameters. Handle SVE base and offset registers. (parse_address): Update call to parse_address_main. (parse_address_reloc): Likewise. (parse_sve_address): New function. (parse_operands): Parse the new SVE address operands. Change-Id: Ic68d4760e4f610e736aa3dc79d2eb7858b29db27 --- opcodes/aarch64-tbl.h | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) (limited to 'opcodes/aarch64-tbl.h') diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h index 491235f..ef32e19 100644 --- a/opcodes/aarch64-tbl.h +++ b/opcodes/aarch64-tbl.h @@ -2820,6 +2820,93 @@ struct aarch64_opcode aarch64_opcode_table[] = "a prefetch operation specifier") \ Y (SYSTEM, hint, "BARRIER_PSB", 0, F (), \ "the PSB option name CSYNC") \ + Y(ADDRESS, sve_addr_ri_u6, "SVE_ADDR_RI_U6", 0 << OPD_F_OD_LSB, \ + F(FLD_Rn), "an address with a 6-bit unsigned offset") \ + Y(ADDRESS, sve_addr_ri_u6, "SVE_ADDR_RI_U6x2", 1 << OPD_F_OD_LSB, \ + F(FLD_Rn), \ + "an address with a 6-bit unsigned offset, multiplied by 2") \ + Y(ADDRESS, sve_addr_ri_u6, "SVE_ADDR_RI_U6x4", 2 << OPD_F_OD_LSB, \ + F(FLD_Rn), \ + "an address with a 6-bit unsigned offset, multiplied by 4") \ + Y(ADDRESS, sve_addr_ri_u6, "SVE_ADDR_RI_U6x8", 3 << OPD_F_OD_LSB, \ + F(FLD_Rn), \ + "an address with a 6-bit unsigned offset, multiplied by 8") \ + Y(ADDRESS, sve_addr_rr_lsl, "SVE_ADDR_RR", 0 << OPD_F_OD_LSB, \ + F(FLD_Rn,FLD_Rm), "an address with a scalar register offset") \ + Y(ADDRESS, sve_addr_rr_lsl, "SVE_ADDR_RR_LSL1", 1 << OPD_F_OD_LSB, \ + F(FLD_Rn,FLD_Rm), "an address with a scalar register offset") \ + Y(ADDRESS, sve_addr_rr_lsl, "SVE_ADDR_RR_LSL2", 2 << OPD_F_OD_LSB, \ + F(FLD_Rn,FLD_Rm), "an address with a scalar register offset") \ + Y(ADDRESS, sve_addr_rr_lsl, "SVE_ADDR_RR_LSL3", 3 << OPD_F_OD_LSB, \ + F(FLD_Rn,FLD_Rm), "an address with a scalar register offset") \ + Y(ADDRESS, sve_addr_rr_lsl, "SVE_ADDR_RX", \ + (0 << OPD_F_OD_LSB) | OPD_F_NO_ZR, F(FLD_Rn,FLD_Rm), \ + "an address with a scalar register offset") \ + Y(ADDRESS, sve_addr_rr_lsl, "SVE_ADDR_RX_LSL1", \ + (1 << OPD_F_OD_LSB) | OPD_F_NO_ZR, F(FLD_Rn,FLD_Rm), \ + "an address with a scalar register offset") \ + Y(ADDRESS, sve_addr_rr_lsl, "SVE_ADDR_RX_LSL2", \ + (2 << OPD_F_OD_LSB) | OPD_F_NO_ZR, F(FLD_Rn,FLD_Rm), \ + "an address with a scalar register offset") \ + Y(ADDRESS, sve_addr_rr_lsl, "SVE_ADDR_RX_LSL3", \ + (3 << OPD_F_OD_LSB) | OPD_F_NO_ZR, F(FLD_Rn,FLD_Rm), \ + "an address with a scalar register offset") \ + Y(ADDRESS, sve_addr_rr_lsl, "SVE_ADDR_RZ", 0 << OPD_F_OD_LSB, \ + F(FLD_Rn,FLD_SVE_Zm_16), \ + "an address with a vector register offset") \ + Y(ADDRESS, sve_addr_rr_lsl, "SVE_ADDR_RZ_LSL1", 1 << OPD_F_OD_LSB, \ + F(FLD_Rn,FLD_SVE_Zm_16), \ + "an address with a vector register offset") \ + Y(ADDRESS, sve_addr_rr_lsl, "SVE_ADDR_RZ_LSL2", 2 << OPD_F_OD_LSB, \ + F(FLD_Rn,FLD_SVE_Zm_16), \ + "an address with a vector register offset") \ + Y(ADDRESS, sve_addr_rr_lsl, "SVE_ADDR_RZ_LSL3", 3 << OPD_F_OD_LSB, \ + F(FLD_Rn,FLD_SVE_Zm_16), \ + "an address with a vector register offset") \ + Y(ADDRESS, sve_addr_rz_xtw, "SVE_ADDR_RZ_XTW_14", \ + 0 << OPD_F_OD_LSB, F(FLD_Rn,FLD_SVE_Zm_16,FLD_SVE_xs_14), \ + "an address with a vector register offset") \ + Y(ADDRESS, sve_addr_rz_xtw, "SVE_ADDR_RZ_XTW_22", \ + 0 << OPD_F_OD_LSB, F(FLD_Rn,FLD_SVE_Zm_16,FLD_SVE_xs_22), \ + "an address with a vector register offset") \ + Y(ADDRESS, sve_addr_rz_xtw, "SVE_ADDR_RZ_XTW1_14", \ + 1 << OPD_F_OD_LSB, F(FLD_Rn,FLD_SVE_Zm_16,FLD_SVE_xs_14), \ + "an address with a vector register offset") \ + Y(ADDRESS, sve_addr_rz_xtw, "SVE_ADDR_RZ_XTW1_22", \ + 1 << OPD_F_OD_LSB, F(FLD_Rn,FLD_SVE_Zm_16,FLD_SVE_xs_22), \ + "an address with a vector register offset") \ + Y(ADDRESS, sve_addr_rz_xtw, "SVE_ADDR_RZ_XTW2_14", \ + 2 << OPD_F_OD_LSB, F(FLD_Rn,FLD_SVE_Zm_16,FLD_SVE_xs_14), \ + "an address with a vector register offset") \ + Y(ADDRESS, sve_addr_rz_xtw, "SVE_ADDR_RZ_XTW2_22", \ + 2 << OPD_F_OD_LSB, F(FLD_Rn,FLD_SVE_Zm_16,FLD_SVE_xs_22), \ + "an address with a vector register offset") \ + Y(ADDRESS, sve_addr_rz_xtw, "SVE_ADDR_RZ_XTW3_14", \ + 3 << OPD_F_OD_LSB, F(FLD_Rn,FLD_SVE_Zm_16,FLD_SVE_xs_14), \ + "an address with a vector register offset") \ + Y(ADDRESS, sve_addr_rz_xtw, "SVE_ADDR_RZ_XTW3_22", \ + 3 << OPD_F_OD_LSB, F(FLD_Rn,FLD_SVE_Zm_16,FLD_SVE_xs_22), \ + "an address with a vector register offset") \ + Y(ADDRESS, sve_addr_zi_u5, "SVE_ADDR_ZI_U5", 0 << OPD_F_OD_LSB, \ + F(FLD_SVE_Zn), "an address with a 5-bit unsigned offset") \ + Y(ADDRESS, sve_addr_zi_u5, "SVE_ADDR_ZI_U5x2", 1 << OPD_F_OD_LSB, \ + F(FLD_SVE_Zn), \ + "an address with a 5-bit unsigned offset, multiplied by 2") \ + Y(ADDRESS, sve_addr_zi_u5, "SVE_ADDR_ZI_U5x4", 2 << OPD_F_OD_LSB, \ + F(FLD_SVE_Zn), \ + "an address with a 5-bit unsigned offset, multiplied by 4") \ + Y(ADDRESS, sve_addr_zi_u5, "SVE_ADDR_ZI_U5x8", 3 << OPD_F_OD_LSB, \ + F(FLD_SVE_Zn), \ + "an address with a 5-bit unsigned offset, multiplied by 8") \ + Y(ADDRESS, sve_addr_zz_lsl, "SVE_ADDR_ZZ_LSL", 0, \ + F(FLD_SVE_Zn,FLD_SVE_Zm_16), \ + "an address with a vector register offset") \ + Y(ADDRESS, sve_addr_zz_sxtw, "SVE_ADDR_ZZ_SXTW", 0, \ + F(FLD_SVE_Zn,FLD_SVE_Zm_16), \ + "an address with a vector register offset") \ + Y(ADDRESS, sve_addr_zz_uxtw, "SVE_ADDR_ZZ_UXTW", 0, \ + F(FLD_SVE_Zn,FLD_SVE_Zm_16), \ + "an address with a vector register offset") \ Y(IMMEDIATE, imm, "SVE_PATTERN", 0, F(FLD_SVE_pattern), \ "an enumeration value such as POW2") \ Y(IMMEDIATE, sve_scale, "SVE_PATTERN_SCALED", 0, \ -- cgit v1.1