[binutils][aarch64] New SVE_ADDR_ZX operand.

Add AARCH64_OPND_SVE_ADDR_ZX operand that allows a vector of addresses
in a Zn register, offset by an Xm register.
This is used with scatter/gather SVE2 instructions.

gas/ChangeLog:

2019-05-09  Matthew Malcomson  <matthew.malcomson@arm.com>

	* config/tc-aarch64.c (REG_ZR): Macro specifying zero register.
	(parse_address_main): Account for new addressing mode [Zn.S, Xm].
	(parse_operands): Handle new SVE_ADDR_ZX operand.

include/ChangeLog:

2019-05-09  Matthew Malcomson  <matthew.malcomson@arm.com>

	* opcode/aarch64.h (enum aarch64_opnd): New SVE_ADDR_ZX operand.

opcodes/ChangeLog:

2019-05-09  Matthew Malcomson  <matthew.malcomson@arm.com>

	* aarch64-asm-2.c: Regenerated.
	* aarch64-dis-2.c: Regenerated.
	* aarch64-opc-2.c: Regenerated.
	* aarch64-opc.c (operand_general_constraint_met_p): Constraint checking
	for SVE_ADDR_ZX.
	(aarch64_print_operand): Add printing for SVE_ADDR_ZX.
	* aarch64-tbl.h (AARCH64_OPERANDS): Use new SVE_ADDR_ZX operand.
This commit is contained in:
Matthew Malcomson 2019-05-09 10:29:18 +01:00
parent 116adc2747
commit c469c86473
10 changed files with 159 additions and 70 deletions

View File

@ -1,3 +1,9 @@
2019-05-09 Matthew Malcomson <matthew.malcomson@arm.com>
* config/tc-aarch64.c (REG_ZR): Macro specifying zero register.
(parse_address_main): Account for new addressing mode [Zn.S, Xm].
(parse_operands): Handle new SVE_ADDR_ZX operand.
2019-05-09 Matthew Malcomson <matthew.malcomson@arm.com>
* config/tc-aarch64.c (parse_operands): Handle new SVE_Zm3_11_INDEX

View File

@ -449,6 +449,7 @@ get_reg_expected_msg (aarch64_reg_type reg_type)
/* Some well known registers that we refer to directly elsewhere. */
#define REG_SP 31
#define REG_ZR 31
/* Instructions take 4 bytes in the object file. */
#define INSN_SIZE 4
@ -3393,6 +3394,7 @@ parse_shifter_operand_reloc (char **str, aarch64_opnd_info *operand,
[base,Zm.D,(S|U)XTW {#imm}] // ignores top 32 bits of Zm.D elements
[Zn.S,#imm]
[Zn.D,#imm]
[Zn.S{, Xm}]
[Zn.S,Zm.S{,LSL #imm}] // in ADR
[Zn.D,Zm.D{,LSL #imm}] // in ADR
[Zn.D,Zm.D,(S|U)XTW {#imm}] // in ADR
@ -3558,6 +3560,7 @@ parse_address_main (char **str, aarch64_opnd_info *operand,
return FALSE;
}
/* We only accept:
[base,Xm] # For vector plus scalar SVE2 indexing.
[base,Xm{,LSL #imm}]
[base,Xm,SXTX {#imm}]
[base,Wm,(S|U)XTW {#imm}] */
@ -3571,7 +3574,10 @@ parse_address_main (char **str, aarch64_opnd_info *operand,
return FALSE;
}
if (aarch64_get_qualifier_esize (*base_qualifier)
!= aarch64_get_qualifier_esize (*offset_qualifier))
!= aarch64_get_qualifier_esize (*offset_qualifier)
&& (operand->type != AARCH64_OPND_SVE_ADDR_ZX
|| *base_qualifier != AARCH64_OPND_QLF_S_S
|| *offset_qualifier != AARCH64_OPND_QLF_X))
{
set_syntax_error (_("offset has different size from base"));
return FALSE;
@ -3689,7 +3695,9 @@ parse_address_main (char **str, aarch64_opnd_info *operand,
}
/* If at this point neither .preind nor .postind is set, we have a
bare [Rn]{!}; reject [Rn]! accept [Rn] as a shorthand for [Rn,#0]. */
bare [Rn]{!}; reject [Rn]! accept [Rn] as a shorthand for [Rn,#0].
For SVE2 vector plus scalar offsets, allow [Zn.<T>] as shorthand for
[Zn.<T>, xzr]. */
if (operand->addr.preind == 0 && operand->addr.postind == 0)
{
if (operand->addr.writeback)
@ -3700,8 +3708,17 @@ parse_address_main (char **str, aarch64_opnd_info *operand,
}
operand->addr.preind = 1;
inst.reloc.exp.X_op = O_constant;
inst.reloc.exp.X_add_number = 0;
if (operand->type == AARCH64_OPND_SVE_ADDR_ZX)
{
operand->addr.offset.is_reg = 1;
operand->addr.offset.regno = REG_ZR;
*offset_qualifier = AARCH64_OPND_QLF_X;
}
else
{
inst.reloc.exp.X_op = O_constant;
inst.reloc.exp.X_add_number = 0;
}
}
*str = p;
@ -6419,6 +6436,33 @@ parse_operands (char *str, const aarch64_opcode *opcode)
info->qualifier = offset_qualifier;
goto regoff_addr;
case AARCH64_OPND_SVE_ADDR_ZX:
/* [Zn.<T>{, <Xm>}]. */
po_misc_or_fail (parse_sve_address (&str, info, &base_qualifier,
&offset_qualifier));
/* Things to check:
base_qualifier either S_S or S_D
offset_qualifier must be X
*/
if ((base_qualifier != AARCH64_OPND_QLF_S_S
&& base_qualifier != AARCH64_OPND_QLF_S_D)
|| offset_qualifier != AARCH64_OPND_QLF_X)
{
set_syntax_error (_("invalid addressing mode"));
goto failure;
}
info->qualifier = base_qualifier;
if (!info->addr.offset.is_reg || info->addr.pcrel
|| !info->addr.preind || info->addr.writeback
|| info->shifter.operator_present != 0)
{
set_syntax_error (_("invalid addressing mode"));
goto failure;
}
info->shifter.kind = AARCH64_MOD_LSL;
break;
case AARCH64_OPND_SVE_ADDR_ZI_U5:
case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
case AARCH64_OPND_SVE_ADDR_ZI_U5x4:

View File

@ -1,3 +1,7 @@
2019-05-09 Matthew Malcomson <matthew.malcomson@arm.com>
* opcode/aarch64.h (enum aarch64_opnd): New SVE_ADDR_ZX operand.
2019-05-09 Matthew Malcomson <matthew.malcomson@arm.com>
* opcode/aarch64.h (enum aarch64_opnd): New SVE_Zm3_11_INDEX operand.

View File

@ -337,6 +337,7 @@ enum aarch64_opnd
AARCH64_OPND_SVE_ADDR_RX_LSL1, /* SVE [<Xn|SP>, <Xm>, LSL #1]. */
AARCH64_OPND_SVE_ADDR_RX_LSL2, /* SVE [<Xn|SP>, <Xm>, LSL #2]. */
AARCH64_OPND_SVE_ADDR_RX_LSL3, /* SVE [<Xn|SP>, <Xm>, LSL #3]. */
AARCH64_OPND_SVE_ADDR_ZX, /* SVE [Zn.<T>{, <Xm>}]. */
AARCH64_OPND_SVE_ADDR_RZ, /* SVE [<Xn|SP>, Zm.D]. */
AARCH64_OPND_SVE_ADDR_RZ_LSL1, /* SVE [<Xn|SP>, Zm.D, LSL #1]. */
AARCH64_OPND_SVE_ADDR_RZ_LSL2, /* SVE [<Xn|SP>, Zm.D, LSL #2]. */

View File

@ -1,3 +1,13 @@
2019-05-09 Matthew Malcomson <matthew.malcomson@arm.com>
* aarch64-asm-2.c: Regenerated.
* aarch64-dis-2.c: Regenerated.
* aarch64-opc-2.c: Regenerated.
* aarch64-opc.c (operand_general_constraint_met_p): Constraint checking
for SVE_ADDR_ZX.
(aarch64_print_operand): Add printing for SVE_ADDR_ZX.
* aarch64-tbl.h (AARCH64_OPERANDS): Use new SVE_ADDR_ZX operand.
2019-05-09 Matthew Malcomson <matthew.malcomson@arm.com>
* aarch64-asm-2.c: Regenerated.

View File

@ -628,7 +628,6 @@ aarch64_insert_operand (const aarch64_operand *self,
case 28:
case 29:
case 30:
case 161:
case 162:
case 163:
case 164:
@ -638,7 +637,7 @@ aarch64_insert_operand (const aarch64_operand *self,
case 168:
case 169:
case 170:
case 183:
case 171:
case 184:
case 185:
case 186:
@ -647,8 +646,9 @@ aarch64_insert_operand (const aarch64_operand *self,
case 189:
case 190:
case 191:
case 196:
case 199:
case 192:
case 197:
case 200:
return aarch64_ins_regno (self, info, code, inst, errors);
case 14:
return aarch64_ins_reg_extended (self, info, code, inst, errors);
@ -660,7 +660,7 @@ aarch64_insert_operand (const aarch64_operand *self,
case 32:
case 33:
case 34:
case 202:
case 203:
return aarch64_ins_reglane (self, info, code, inst, errors);
case 35:
return aarch64_ins_reglist (self, info, code, inst, errors);
@ -694,9 +694,8 @@ aarch64_insert_operand (const aarch64_operand *self,
case 80:
case 81:
case 82:
case 158:
case 160:
case 175:
case 159:
case 161:
case 176:
case 177:
case 178:
@ -704,7 +703,8 @@ aarch64_insert_operand (const aarch64_operand *self,
case 180:
case 181:
case 182:
case 201:
case 183:
case 202:
return aarch64_ins_imm (self, info, code, inst, errors);
case 43:
case 44:
@ -714,10 +714,10 @@ aarch64_insert_operand (const aarch64_operand *self,
case 47:
return aarch64_ins_advsimd_imm_modified (self, info, code, inst, errors);
case 51:
case 148:
case 149:
return aarch64_ins_fpimm (self, info, code, inst, errors);
case 68:
case 156:
case 157:
return aarch64_ins_limm (self, info, code, inst, errors);
case 69:
return aarch64_ins_aimm (self, info, code, inst, errors);
@ -727,11 +727,11 @@ aarch64_insert_operand (const aarch64_operand *self,
return aarch64_ins_fbits (self, info, code, inst, errors);
case 73:
case 74:
case 153:
case 154:
return aarch64_ins_imm_rotate2 (self, info, code, inst, errors);
case 75:
case 152:
case 154:
case 153:
case 155:
return aarch64_ins_imm_rotate1 (self, info, code, inst, errors);
case 76:
case 77:
@ -802,8 +802,8 @@ aarch64_insert_operand (const aarch64_operand *self,
case 128:
case 129:
case 130:
return aarch64_ins_sve_addr_rr_lsl (self, info, code, inst, errors);
case 131:
return aarch64_ins_sve_addr_rr_lsl (self, info, code, inst, errors);
case 132:
case 133:
case 134:
@ -811,49 +811,50 @@ aarch64_insert_operand (const aarch64_operand *self,
case 136:
case 137:
case 138:
return aarch64_ins_sve_addr_rz_xtw (self, info, code, inst, errors);
case 139:
return aarch64_ins_sve_addr_rz_xtw (self, info, code, inst, errors);
case 140:
case 141:
case 142:
return aarch64_ins_sve_addr_zi_u5 (self, info, code, inst, errors);
case 143:
return aarch64_ins_sve_addr_zz_lsl (self, info, code, inst, errors);
return aarch64_ins_sve_addr_zi_u5 (self, info, code, inst, errors);
case 144:
return aarch64_ins_sve_addr_zz_sxtw (self, info, code, inst, errors);
return aarch64_ins_sve_addr_zz_lsl (self, info, code, inst, errors);
case 145:
return aarch64_ins_sve_addr_zz_uxtw (self, info, code, inst, errors);
return aarch64_ins_sve_addr_zz_sxtw (self, info, code, inst, errors);
case 146:
return aarch64_ins_sve_aimm (self, info, code, inst, errors);
return aarch64_ins_sve_addr_zz_uxtw (self, info, code, inst, errors);
case 147:
return aarch64_ins_sve_aimm (self, info, code, inst, errors);
case 148:
return aarch64_ins_sve_asimm (self, info, code, inst, errors);
case 149:
return aarch64_ins_sve_float_half_one (self, info, code, inst, errors);
case 150:
return aarch64_ins_sve_float_half_two (self, info, code, inst, errors);
return aarch64_ins_sve_float_half_one (self, info, code, inst, errors);
case 151:
return aarch64_ins_sve_float_half_two (self, info, code, inst, errors);
case 152:
return aarch64_ins_sve_float_zero_one (self, info, code, inst, errors);
case 155:
case 156:
return aarch64_ins_inv_limm (self, info, code, inst, errors);
case 157:
case 158:
return aarch64_ins_sve_limm_mov (self, info, code, inst, errors);
case 159:
case 160:
return aarch64_ins_sve_scale (self, info, code, inst, errors);
case 171:
case 172:
return aarch64_ins_sve_shlimm (self, info, code, inst, errors);
case 173:
return aarch64_ins_sve_shlimm (self, info, code, inst, errors);
case 174:
case 175:
return aarch64_ins_sve_shrimm (self, info, code, inst, errors);
case 192:
case 193:
case 194:
case 195:
case 196:
return aarch64_ins_sve_quad_index (self, info, code, inst, errors);
case 197:
return aarch64_ins_sve_index (self, info, code, inst, errors);
case 198:
case 200:
return aarch64_ins_sve_index (self, info, code, inst, errors);
case 199:
case 201:
return aarch64_ins_sve_reglist (self, info, code, inst, errors);
default: assert (0); abort ();
}

View File

@ -20059,7 +20059,6 @@ aarch64_extract_operand (const aarch64_operand *self,
case 28:
case 29:
case 30:
case 161:
case 162:
case 163:
case 164:
@ -20069,7 +20068,7 @@ aarch64_extract_operand (const aarch64_operand *self,
case 168:
case 169:
case 170:
case 183:
case 171:
case 184:
case 185:
case 186:
@ -20078,8 +20077,9 @@ aarch64_extract_operand (const aarch64_operand *self,
case 189:
case 190:
case 191:
case 196:
case 199:
case 192:
case 197:
case 200:
return aarch64_ext_regno (self, info, code, inst, errors);
case 9:
return aarch64_ext_regrt_sysins (self, info, code, inst, errors);
@ -20095,7 +20095,7 @@ aarch64_extract_operand (const aarch64_operand *self,
case 32:
case 33:
case 34:
case 202:
case 203:
return aarch64_ext_reglane (self, info, code, inst, errors);
case 35:
return aarch64_ext_reglist (self, info, code, inst, errors);
@ -20130,9 +20130,8 @@ aarch64_extract_operand (const aarch64_operand *self,
case 80:
case 81:
case 82:
case 158:
case 160:
case 175:
case 159:
case 161:
case 176:
case 177:
case 178:
@ -20140,7 +20139,8 @@ aarch64_extract_operand (const aarch64_operand *self,
case 180:
case 181:
case 182:
case 201:
case 183:
case 202:
return aarch64_ext_imm (self, info, code, inst, errors);
case 43:
case 44:
@ -20152,10 +20152,10 @@ aarch64_extract_operand (const aarch64_operand *self,
case 48:
return aarch64_ext_shll_imm (self, info, code, inst, errors);
case 51:
case 148:
case 149:
return aarch64_ext_fpimm (self, info, code, inst, errors);
case 68:
case 156:
case 157:
return aarch64_ext_limm (self, info, code, inst, errors);
case 69:
return aarch64_ext_aimm (self, info, code, inst, errors);
@ -20165,11 +20165,11 @@ aarch64_extract_operand (const aarch64_operand *self,
return aarch64_ext_fbits (self, info, code, inst, errors);
case 73:
case 74:
case 153:
case 154:
return aarch64_ext_imm_rotate2 (self, info, code, inst, errors);
case 75:
case 152:
case 154:
case 153:
case 155:
return aarch64_ext_imm_rotate1 (self, info, code, inst, errors);
case 76:
case 77:
@ -20240,8 +20240,8 @@ aarch64_extract_operand (const aarch64_operand *self,
case 128:
case 129:
case 130:
return aarch64_ext_sve_addr_rr_lsl (self, info, code, inst, errors);
case 131:
return aarch64_ext_sve_addr_rr_lsl (self, info, code, inst, errors);
case 132:
case 133:
case 134:
@ -20249,49 +20249,50 @@ aarch64_extract_operand (const aarch64_operand *self,
case 136:
case 137:
case 138:
return aarch64_ext_sve_addr_rz_xtw (self, info, code, inst, errors);
case 139:
return aarch64_ext_sve_addr_rz_xtw (self, info, code, inst, errors);
case 140:
case 141:
case 142:
return aarch64_ext_sve_addr_zi_u5 (self, info, code, inst, errors);
case 143:
return aarch64_ext_sve_addr_zz_lsl (self, info, code, inst, errors);
return aarch64_ext_sve_addr_zi_u5 (self, info, code, inst, errors);
case 144:
return aarch64_ext_sve_addr_zz_sxtw (self, info, code, inst, errors);
return aarch64_ext_sve_addr_zz_lsl (self, info, code, inst, errors);
case 145:
return aarch64_ext_sve_addr_zz_uxtw (self, info, code, inst, errors);
return aarch64_ext_sve_addr_zz_sxtw (self, info, code, inst, errors);
case 146:
return aarch64_ext_sve_aimm (self, info, code, inst, errors);
return aarch64_ext_sve_addr_zz_uxtw (self, info, code, inst, errors);
case 147:
return aarch64_ext_sve_aimm (self, info, code, inst, errors);
case 148:
return aarch64_ext_sve_asimm (self, info, code, inst, errors);
case 149:
return aarch64_ext_sve_float_half_one (self, info, code, inst, errors);
case 150:
return aarch64_ext_sve_float_half_two (self, info, code, inst, errors);
return aarch64_ext_sve_float_half_one (self, info, code, inst, errors);
case 151:
return aarch64_ext_sve_float_half_two (self, info, code, inst, errors);
case 152:
return aarch64_ext_sve_float_zero_one (self, info, code, inst, errors);
case 155:
case 156:
return aarch64_ext_inv_limm (self, info, code, inst, errors);
case 157:
case 158:
return aarch64_ext_sve_limm_mov (self, info, code, inst, errors);
case 159:
case 160:
return aarch64_ext_sve_scale (self, info, code, inst, errors);
case 171:
case 172:
return aarch64_ext_sve_shlimm (self, info, code, inst, errors);
case 173:
return aarch64_ext_sve_shlimm (self, info, code, inst, errors);
case 174:
case 175:
return aarch64_ext_sve_shrimm (self, info, code, inst, errors);
case 192:
case 193:
case 194:
case 195:
case 196:
return aarch64_ext_sve_quad_index (self, info, code, inst, errors);
case 197:
return aarch64_ext_sve_index (self, info, code, inst, errors);
case 198:
case 200:
return aarch64_ext_sve_index (self, info, code, inst, errors);
case 199:
case 201:
return aarch64_ext_sve_reglist (self, info, code, inst, errors);
default: assert (0); abort ();
}

View File

@ -151,6 +151,7 @@ const struct aarch64_operand aarch64_operands[] =
{AARCH64_OPND_CLASS_ADDRESS, "SVE_ADDR_RX_LSL1", (1 << OPD_F_OD_LSB) | OPD_F_NO_ZR | OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rn,FLD_Rm}, "an address with a scalar register offset"},
{AARCH64_OPND_CLASS_ADDRESS, "SVE_ADDR_RX_LSL2", (2 << OPD_F_OD_LSB) | OPD_F_NO_ZR | OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rn,FLD_Rm}, "an address with a scalar register offset"},
{AARCH64_OPND_CLASS_ADDRESS, "SVE_ADDR_RX_LSL3", (3 << OPD_F_OD_LSB) | OPD_F_NO_ZR | OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rn,FLD_Rm}, "an address with a scalar register offset"},
{AARCH64_OPND_CLASS_ADDRESS, "SVE_ADDR_ZX", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Zn,FLD_Rm}, "vector of address with a scalar register offset"},
{AARCH64_OPND_CLASS_ADDRESS, "SVE_ADDR_RZ", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rn,FLD_SVE_Zm_16}, "an address with a vector register offset"},
{AARCH64_OPND_CLASS_ADDRESS, "SVE_ADDR_RZ_LSL1", 1 << OPD_F_OD_LSB | OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rn,FLD_SVE_Zm_16}, "an address with a vector register offset"},
{AARCH64_OPND_CLASS_ADDRESS, "SVE_ADDR_RZ_LSL2", 2 << OPD_F_OD_LSB | OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rn,FLD_SVE_Zm_16}, "an address with a vector register offset"},

View File

@ -1899,6 +1899,17 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
max_value = 7;
goto sve_imm_offset;
case AARCH64_OPND_SVE_ADDR_ZX:
/* Everything is already ensured by parse_operands or
aarch64_ext_sve_addr_rr_lsl (because this is a very specific
argument type). */
assert (opnd->addr.offset.is_reg);
assert (opnd->addr.preind);
assert ((aarch64_operands[type].flags & OPD_F_NO_ZR) == 0);
assert (opnd->shifter.kind == AARCH64_MOD_LSL);
assert (opnd->shifter.operator_present == 0);
break;
case AARCH64_OPND_SVE_ADDR_R:
case AARCH64_OPND_SVE_ADDR_RR:
case AARCH64_OPND_SVE_ADDR_RR_LSL1:
@ -3583,6 +3594,13 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
get_offset_int_reg_name (opnd));
break;
case AARCH64_OPND_SVE_ADDR_ZX:
print_register_offset_address
(buf, size, opnd,
get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
get_64bit_int_reg_name (opnd->addr.offset.regno, 0));
break;
case AARCH64_OPND_SVE_ADDR_RZ:
case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
case AARCH64_OPND_SVE_ADDR_RZ_LSL2:

View File

@ -4807,6 +4807,9 @@ struct aarch64_opcode aarch64_opcode_table[] =
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_ZX", \
0 << OPD_F_OD_LSB , F(FLD_SVE_Zn,FLD_Rm), \
"vector of 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") \