[AArch64] Add ARMv8.3 FCMLA and FCADD instructions

Add support for FCMLA and FCADD complex arithmetic SIMD instructions.
FCMLA has an indexed element variant where the index range has to be
treated specially because a complex number takes two elements and the
indexed vector size depends on the other operands.

These complex number SIMD instructions are part of ARMv8.3
https://community.arm.com/groups/processors/blog/2016/10/27/armv8-a-architecture-2016-additions

include/
2016-11-18  Szabolcs Nagy  <szabolcs.nagy@arm.com>

	* opcode/aarch64.h (enum aarch64_opnd): Add AARCH64_OPND_IMM_ROT1,
	AARCH64_OPND_IMM_ROT2, AARCH64_OPND_IMM_ROT3.
	(enum aarch64_op): Add OP_FCMLA_ELEM.

opcodes/
2016-11-18  Szabolcs Nagy  <szabolcs.nagy@arm.com>

	* aarch64-tbl.h (QL_V3SAMEHSD_ROT, QL_ELEMENT_ROT): Define.
	(aarch64_feature_simd_v8_3, SIMD_V8_3): Define.
	(aarch64_opcode_table): Add fcmla and fcadd.
	(AARCH64_OPERANDS): Add IMM_ROT{1,2,3}.
	* aarch64-asm.h (aarch64_ins_imm_rotate): Declare.
	* aarch64-asm.c (aarch64_ins_imm_rotate): Define.
	* aarch64-dis.h (aarch64_ext_imm_rotate): Declare.
	* aarch64-dis.c (aarch64_ext_imm_rotate): Define.
	* aarch64-opc.h (enum aarch64_field_kind): Add FLD_rotate{1,2,3}.
	* aarch64-opc.c (fields): Add FLD_rotate{1,2,3}.
	(operand_general_constraint_met_p): Rotate and index range check.
	(aarch64_print_operand): Handle rotate operand.
	* aarch64-asm-2.c: Regenerate.
	* aarch64-dis-2.c: Likewise.
	* aarch64-opc-2.c: Likewise.

gas/
2016-11-18  Szabolcs Nagy  <szabolcs.nagy@arm.com>

	* config/tc-aarch64.c (parse_operands): Handle AARCH64_OPND_IMM_ROT*.
	* testsuite/gas/aarch64/advsimd-armv8_3.d: New.
	* testsuite/gas/aarch64/advsimd-armv8_3.s: New.
	* testsuite/gas/aarch64/illegal-fcmla.s: New.
	* testsuite/gas/aarch64/illegal-fcmla.l: New.
	* testsuite/gas/aarch64/illegal-fcmla.d: New.
This commit is contained in:
Szabolcs Nagy 2016-11-18 10:02:16 +00:00
parent 28617675c2
commit c2c4ff8d52
20 changed files with 3056 additions and 2700 deletions

View File

@ -1,3 +1,12 @@
2016-11-18 Szabolcs Nagy <szabolcs.nagy@arm.com>
* config/tc-aarch64.c (parse_operands): Handle AARCH64_OPND_IMM_ROT*.
* testsuite/gas/aarch64/advsimd-armv8_3.d: New.
* testsuite/gas/aarch64/advsimd-armv8_3.s: New.
* testsuite/gas/aarch64/illegal-fcmla.s: New.
* testsuite/gas/aarch64/illegal-fcmla.l: New.
* testsuite/gas/aarch64/illegal-fcmla.d: New.
2016-11-18 Szabolcs Nagy <szabolcs.nagy@arm.com>
* testsuite/gas/aarch64/ldst-exclusive-armv8_3.s: Add ldaprb, ldaprh, ldapr tests.

View File

@ -5561,6 +5561,9 @@ parse_operands (char *str, const aarch64_opcode *opcode)
case AARCH64_OPND_SVE_UIMM7:
case AARCH64_OPND_SVE_UIMM8:
case AARCH64_OPND_SVE_UIMM8_53:
case AARCH64_OPND_IMM_ROT1:
case AARCH64_OPND_IMM_ROT2:
case AARCH64_OPND_IMM_ROT3:
po_imm_nc_or_fail ();
info->imm.value = val;
break;

View File

@ -0,0 +1,33 @@
#as: -march=armv8.3-a
#objdump: -dr
.*: file format .*
Disassembly of section \.text:
0000000000000000 <.*>:
[^:]+: 6ec3c441 fcmla v1.2d, v2.2d, v3.2d, #0
[^:]+: 6ec3cc41 fcmla v1.2d, v2.2d, v3.2d, #90
[^:]+: 6ec3d441 fcmla v1.2d, v2.2d, v3.2d, #180
[^:]+: 6ec3dc41 fcmla v1.2d, v2.2d, v3.2d, #270
[^:]+: 2e83cc41 fcmla v1.2s, v2.2s, v3.2s, #90
[^:]+: 6e83cc41 fcmla v1.4s, v2.4s, v3.4s, #90
[^:]+: 2e43cc41 fcmla v1.4h, v2.4h, v3.4h, #90
[^:]+: 6e43cc41 fcmla v1.8h, v2.8h, v3.8h, #90
[^:]+: 6f831041 fcmla v1.4s, v2.4s, v3.s\[0\], #0
[^:]+: 6f833041 fcmla v1.4s, v2.4s, v3.s\[0\], #90
[^:]+: 6f835041 fcmla v1.4s, v2.4s, v3.s\[0\], #180
[^:]+: 6f837041 fcmla v1.4s, v2.4s, v3.s\[0\], #270
[^:]+: 6f833841 fcmla v1.4s, v2.4s, v3.s\[1\], #90
[^:]+: 2f433041 fcmla v1.4h, v2.4h, v3.h\[0\], #90
[^:]+: 2f633041 fcmla v1.4h, v2.4h, v3.h\[1\], #90
[^:]+: 6f433041 fcmla v1.8h, v2.8h, v3.h\[0\], #90
[^:]+: 6f633041 fcmla v1.8h, v2.8h, v3.h\[1\], #90
[^:]+: 6f433841 fcmla v1.8h, v2.8h, v3.h\[2\], #90
[^:]+: 6f633841 fcmla v1.8h, v2.8h, v3.h\[3\], #90
[^:]+: 6ec3e441 fcadd v1.2d, v2.2d, v3.2d, #90
[^:]+: 6ec3f441 fcadd v1.2d, v2.2d, v3.2d, #270
[^:]+: 2e83e441 fcadd v1.2s, v2.2s, v3.2s, #90
[^:]+: 6e83e441 fcadd v1.4s, v2.4s, v3.4s, #90
[^:]+: 2e43e441 fcadd v1.4h, v2.4h, v3.4h, #90
[^:]+: 6e43e441 fcadd v1.8h, v2.8h, v3.8h, #90

View File

@ -0,0 +1,36 @@
/* Test file for ARMv8.3 complex arithmetics instructions. */
.text
/* Three-same operands FCMLA. */
fcmla v1.2d, v2.2d, v3.2d, #0
fcmla v1.2d, v2.2d, v3.2d, #90
fcmla v1.2d, v2.2d, v3.2d, #180
fcmla v1.2d, v2.2d, v3.2d, #270
fcmla v1.2s, v2.2s, v3.2s, #90
fcmla v1.4s, v2.4s, v3.4s, #90
fcmla v1.4h, v2.4h, v3.4h, #90
fcmla v1.8h, v2.8h, v3.8h, #90
/* Indexed element FCMLA. */
fcmla v1.4s, v2.4s, v3.s[0], #0
fcmla v1.4s, v2.4s, v3.s[0], #90
fcmla v1.4s, v2.4s, v3.s[0], #180
fcmla v1.4s, v2.4s, v3.s[0], #270
fcmla v1.4s, v2.4s, v3.s[1], #90
fcmla v1.4h, v2.4h, v3.h[0], #90
fcmla v1.4h, v2.4h, v3.h[1], #90
fcmla v1.8h, v2.8h, v3.h[0], #90
fcmla v1.8h, v2.8h, v3.h[1], #90
fcmla v1.8h, v2.8h, v3.h[2], #90
fcmla v1.8h, v2.8h, v3.h[3], #90
/* Three-same operands FADD. */
fcadd v1.2d, v2.2d, v3.2d, #90
fcadd v1.2d, v2.2d, v3.2d, #270
fcadd v1.2s, v2.2s, v3.2s, #90
fcadd v1.4s, v2.4s, v3.4s, #90
fcadd v1.4h, v2.4h, v3.4h, #90
fcadd v1.8h, v2.8h, v3.8h, #90

View File

@ -0,0 +1,2 @@
#as: -march=armv8.3-a -mno-verbose-error
#error-output: illegal-fcmla.l

View File

@ -0,0 +1,17 @@
[^:]*: Assembler messages:
[^:]+:10: Error: rotate expected to be 0, 90, 180 or 270 at operand 4 -- `fcmla v0\.4s,v1\.4s,v2\.s\[0\],#-90'
[^:]+:11: Error: rotate expected to be 0, 90, 180 or 270 at operand 4 -- `fcmla v0\.4s,v1\.4s,v2\.s\[0\],#30'
[^:]+:12: Error: rotate expected to be 0, 90, 180 or 270 at operand 4 -- `fcmla v0\.4s,v1\.4s,v2\.s\[0\],#360'
[^:]+:13: Error: register element index out of range 0 to 1 at operand 3 -- `fcmla v0\.4h,v1\.4h,v2\.h\[2\],#90'
[^:]+:14: Error: register element index out of range 0 to 3 at operand 3 -- `fcmla v0\.8h,v1\.8h,v2\.h\[4\],#90'
[^:]+:15: Error: register element index out of range 0 to 1 at operand 3 -- `fcmla v0\.4s,v1\.4s,v2\.s\[2\],#90'
[^:]+:16: Error: operand mismatch -- `fcmla v0\.2s,v1\.2s,v2\.s\[0\],#90'
[^:]+:17: Error: operand mismatch -- `fcmla v0\.4s,v1\.4s,v2\.d\[0\],#90'
[^:]+:18: Error: operand mismatch -- `fcmla v0\.2d,v1\.2d,v2\.d\[0\],#0'
[^:]+:19: Error: rotate expected to be 0, 90, 180 or 270 at operand 4 -- `fcmla v0\.4s,v1\.4s,v2\.4s,#-90'
[^:]+:20: Error: rotate expected to be 0, 90, 180 or 270 at operand 4 -- `fcmla v0\.4s,v1\.4s,v2\.4s,#30'
[^:]+:21: Error: rotate expected to be 0, 90, 180 or 270 at operand 4 -- `fcmla v0\.4s,v1\.4s,v2\.4s,#360'
[^:]+:22: Error: invalid element size 8 and vector size combination s at operand 1 -- `fcmla v0\.8s,v1\.8s,v2\.8s,#0'
[^:]+:23: Error: operand mismatch -- `fcmla v0\.1d,v1\.1d,v2\.1d,#0'
[^:]+:24: Error: rotate expected to be 90 or 270 at operand 4 -- `fcadd v0\.4h,v1\.4h,v2\.4h,#0'
[^:]+:25: Error: rotate expected to be 90 or 270 at operand 4 -- `fcadd v0\.4h,v1\.4h,v2\.4h,#180'

View File

@ -0,0 +1,25 @@
// Test illegal ARMv8.3 FCMLA and FCADD instructions with -march=armv8.3-a.
.text
// Good.
fcmla v0.4s, v1.4s, v2.s[0], #90
fcmla v0.4s, v1.4s, v2.4s, #90
fcadd v0.4h, v1.4h, v2.4h, #90
// Bad.
fcmla v0.4s, v1.4s, v2.s[0], #-90
fcmla v0.4s, v1.4s, v2.s[0], #30
fcmla v0.4s, v1.4s, v2.s[0], #360
fcmla v0.4h, v1.4h, v2.h[2], #90
fcmla v0.8h, v1.8h, v2.h[4], #90
fcmla v0.4s, v1.4s, v2.s[2], #90
fcmla v0.2s, v1.2s, v2.s[0], #90
fcmla v0.4s, v1.4s, v2.d[0], #90
fcmla v0.2d, v1.2d, v2.d[0], #0
fcmla v0.4s, v1.4s, v2.4s, #-90
fcmla v0.4s, v1.4s, v2.4s, #30
fcmla v0.4s, v1.4s, v2.4s, #360
fcmla v0.8s, v1.8s, v2.8s, #0
fcmla v0.1d, v1.1d, v2.1d, #0
fcadd v0.4h, v1.4h, v2.4h, #0
fcadd v0.4h, v1.4h, v2.4h, #180

View File

@ -1,3 +1,9 @@
2016-11-18 Szabolcs Nagy <szabolcs.nagy@arm.com>
* opcode/aarch64.h (enum aarch64_opnd): Add AARCH64_OPND_IMM_ROT1,
AARCH64_OPND_IMM_ROT2, AARCH64_OPND_IMM_ROT3.
(enum aarch64_op): Add OP_FCMLA_ELEM.
2016-11-18 Szabolcs Nagy <szabolcs.nagy@arm.com>
* opcode/aarch64.h (enum aarch64_opnd): Add AARCH64_OPND_ADDR_SIMM10.

View File

@ -204,6 +204,9 @@ enum aarch64_opnd
AARCH64_OPND_HALF, /* #<imm16>{, LSL #<shift>} operand in move wide. */
AARCH64_OPND_FBITS, /* FP #<fbits> operand in e.g. SCVTF */
AARCH64_OPND_IMM_MOV, /* Immediate operand for the MOV alias. */
AARCH64_OPND_IMM_ROT1, /* Immediate rotate operand for FCMLA. */
AARCH64_OPND_IMM_ROT2, /* Immediate rotate operand for indexed FCMLA. */
AARCH64_OPND_IMM_ROT3, /* Immediate rotate operand for FCADD. */
AARCH64_OPND_COND, /* Standard condition as the last operand. */
AARCH64_OPND_COND1, /* Same as the above, but excluding AL and NV. */
@ -596,6 +599,8 @@ enum aarch64_op
OP_NOTS_P_P_P_Z,
OP_NOT_P_P_P_Z,
OP_FCMLA_ELEM, /* ARMv8.3, indexed element version. */
OP_TOTAL_NUM, /* Pseudo. */
};

View File

@ -1,3 +1,21 @@
2016-11-18 Szabolcs Nagy <szabolcs.nagy@arm.com>
* aarch64-tbl.h (QL_V3SAMEHSD_ROT, QL_ELEMENT_ROT): Define.
(aarch64_feature_simd_v8_3, SIMD_V8_3): Define.
(aarch64_opcode_table): Add fcmla and fcadd.
(AARCH64_OPERANDS): Add IMM_ROT{1,2,3}.
* aarch64-asm.h (aarch64_ins_imm_rotate): Declare.
* aarch64-asm.c (aarch64_ins_imm_rotate): Define.
* aarch64-dis.h (aarch64_ext_imm_rotate): Declare.
* aarch64-dis.c (aarch64_ext_imm_rotate): Define.
* aarch64-opc.h (enum aarch64_field_kind): Add FLD_rotate{1,2,3}.
* aarch64-opc.c (fields): Add FLD_rotate{1,2,3}.
(operand_general_constraint_met_p): Rotate and index range check.
(aarch64_print_operand): Handle rotate operand.
* aarch64-asm-2.c: Regenerate.
* aarch64-dis-2.c: Likewise.
* aarch64-opc-2.c: Likewise.
2016-11-18 Szabolcs Nagy <szabolcs.nagy@arm.com>
* aarch64-tbl.h (arch64_opcode_table): Add ldaprb, ldaprh, ldapr.

File diff suppressed because it is too large Load Diff

View File

@ -125,19 +125,28 @@ aarch64_ins_reglane (const aarch64_operand *self, const aarch64_opnd_info *info,
{
/* index for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
or SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
unsigned index = info->reglane.index;
if (inst->opcode->op == OP_FCMLA_ELEM)
/* Complex operand takes two elements. */
index *= 2;
switch (info->qualifier)
{
case AARCH64_OPND_QLF_S_H:
/* H:L:M */
insert_fields (code, info->reglane.index, 0, 3, FLD_M, FLD_L, FLD_H);
assert (index < 8);
insert_fields (code, index, 0, 3, FLD_M, FLD_L, FLD_H);
break;
case AARCH64_OPND_QLF_S_S:
/* H:L */
insert_fields (code, info->reglane.index, 0, 2, FLD_L, FLD_H);
assert (index < 4);
insert_fields (code, index, 0, 2, FLD_L, FLD_H);
break;
case AARCH64_OPND_QLF_S_D:
/* H */
insert_field (FLD_H, code, info->reglane.index, 0);
assert (index < 2);
insert_field (FLD_H, code, index, 0);
break;
default:
assert (0);
@ -427,6 +436,41 @@ aarch64_ins_fpimm (const aarch64_operand *self, const aarch64_opnd_info *info,
return NULL;
}
/* Insert field rot for the rotate immediate in
FCMLA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>, #<rotate>. */
const char *
aarch64_ins_imm_rotate (const aarch64_operand *self,
const aarch64_opnd_info *info,
aarch64_insn *code, const aarch64_inst *inst)
{
uint64_t rot = info->imm.value / 90;
switch (info->type)
{
case AARCH64_OPND_IMM_ROT1:
case AARCH64_OPND_IMM_ROT2:
/* value rot
0 0
90 1
180 2
270 3 */
assert (rot < 4U);
break;
case AARCH64_OPND_IMM_ROT3:
/* value rot
90 0
270 1 */
rot = (rot - 1) / 2;
assert (rot < 2U);
break;
default:
assert (0);
}
insert_field (self->fields[0], code, rot, inst->opcode->mask);
return NULL;
}
/* Insert #<fbits> for the immediate operand in fp fix-point instructions,
e.g. SCVTF <Dd>, <Wn>, #<fbits>. */
const char *

View File

@ -92,6 +92,7 @@ AARCH64_DECL_OPD_INSERTER (ins_sve_reglist);
AARCH64_DECL_OPD_INSERTER (ins_sve_scale);
AARCH64_DECL_OPD_INSERTER (ins_sve_shlimm);
AARCH64_DECL_OPD_INSERTER (ins_sve_shrimm);
AARCH64_DECL_OPD_INSERTER (ins_imm_rotate);
#undef AARCH64_DECL_OPD_INSERTER

File diff suppressed because it is too large Load Diff

View File

@ -351,6 +351,14 @@ aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info,
default:
return 0;
}
if (inst->opcode->op == OP_FCMLA_ELEM)
{
/* Complex operand takes two elements. */
if (info->reglane.index & 1)
return 0;
info->reglane.index /= 2;
}
}
return 1;
@ -703,6 +711,40 @@ aarch64_ext_fpimm (const aarch64_operand *self, aarch64_opnd_info *info,
return 1;
}
/* Decode rotate immediate for FCMLA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>, #rotate. */
int
aarch64_ext_imm_rotate (const aarch64_operand *self, aarch64_opnd_info *info,
const aarch64_insn code,
const aarch64_inst *inst ATTRIBUTE_UNUSED)
{
uint64_t rot = extract_field (self->fields[0], code, 0);
switch (info->type)
{
case AARCH64_OPND_IMM_ROT1:
case AARCH64_OPND_IMM_ROT2:
/* rot value
0 0
1 90
2 180
3 270 */
assert (rot < 4U);
break;
case AARCH64_OPND_IMM_ROT3:
/* rot value
0 90
1 270 */
assert (rot < 2U);
rot = 2 * rot + 1;
break;
default:
assert (0);
return 0;
}
info->imm.value = rot * 90;
return 1;
}
/* Decode scale for e.g. SCVTF <Dd>, <Wn>, #<fbits>. */
int
aarch64_ext_fbits (const aarch64_operand *self ATTRIBUTE_UNUSED,

View File

@ -114,6 +114,7 @@ AARCH64_DECL_OPD_EXTRACTOR (ext_sve_reglist);
AARCH64_DECL_OPD_EXTRACTOR (ext_sve_scale);
AARCH64_DECL_OPD_EXTRACTOR (ext_sve_shlimm);
AARCH64_DECL_OPD_EXTRACTOR (ext_sve_shrimm);
AARCH64_DECL_OPD_EXTRACTOR (ext_imm_rotate);
#undef AARCH64_DECL_OPD_EXTRACTOR

View File

@ -90,6 +90,9 @@ const struct aarch64_operand aarch64_operands[] =
{AARCH64_OPND_CLASS_IMMEDIATE, "HALF", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_imm16}, "a 16-bit immediate with optional left shift"},
{AARCH64_OPND_CLASS_IMMEDIATE, "FBITS", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_scale}, "the number of bits after the binary point in the fixed-point value"},
{AARCH64_OPND_CLASS_IMMEDIATE, "IMM_MOV", 0, {}, "an immediate"},
{AARCH64_OPND_CLASS_IMMEDIATE, "IMM_ROT1", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_rotate1}, "a 2-bit rotation specifier for complex arithmetic operations"},
{AARCH64_OPND_CLASS_IMMEDIATE, "IMM_ROT2", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_rotate2}, "a 2-bit rotation specifier for complex arithmetic operations"},
{AARCH64_OPND_CLASS_IMMEDIATE, "IMM_ROT3", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_rotate3}, "a 1-bit rotation specifier for complex arithmetic operations"},
{AARCH64_OPND_CLASS_COND, "COND", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a condition"},
{AARCH64_OPND_CLASS_COND, "COND1", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "one of the standard conditions, excluding AL and NV."},
{AARCH64_OPND_CLASS_ADDRESS, "ADDR_ADRP", OPD_F_SEXT | OPD_F_HAS_EXTRACTOR, {FLD_immhi, FLD_immlo}, "21-bit PC-relative address of a 4KB page"},
@ -210,85 +213,86 @@ const struct aarch64_operand aarch64_operands[] =
static const unsigned op_enum_table [] =
{
0,
860,
861,
862,
865,
866,
867,
868,
869,
863,
864,
865,
868,
869,
870,
871,
893,
894,
895,
898,
899,
900,
901,
902,
872,
866,
867,
873,
874,
896,
897,
898,
901,
902,
903,
904,
952,
953,
954,
905,
899,
900,
906,
907,
955,
12,
627,
628,
1147,
1149,
1151,
959,
1150,
1148,
311,
615,
626,
625,
956,
957,
622,
619,
611,
610,
617,
958,
12,
630,
631,
1150,
1152,
1154,
962,
1153,
1151,
312,
618,
629,
628,
960,
625,
622,
614,
613,
620,
621,
623,
624,
967,
655,
626,
627,
970,
658,
661,
656,
664,
659,
804,
171,
662,
807,
172,
173,
174,
507,
744,
380,
382,
404,
406,
1212,
1217,
1210,
1209,
1213,
175,
510,
747,
383,
385,
407,
409,
1215,
1220,
1222,
1213,
1212,
1216,
1223,
1219,
1225,
1224,
1226,
1222,
1228,
1227,
129,
};
/* Given the opcode enumerator OP, return the pointer to the corresponding

View File

@ -309,7 +309,10 @@ const aarch64_field fields[] =
{ 8, 2 }, /* SVE_tszl_8: triangular size select low, bits [9,8]. */
{ 19, 2 }, /* SVE_tszl_19: triangular size select low, bits [20,19]. */
{ 14, 1 }, /* SVE_xs_14: UXTW/SXTW select (bit 14). */
{ 22, 1 } /* SVE_xs_22: UXTW/SXTW select (bit 22). */
{ 22, 1 }, /* SVE_xs_22: UXTW/SXTW select (bit 22). */
{ 11, 2 }, /* rotate1: FCMLA immediate rotate. */
{ 13, 2 }, /* rotate2: Indexed element FCMLA immediate rotate. */
{ 12, 1 }, /* rotate3: FCADD immediate rotate. */
};
enum aarch64_operand_class
@ -2097,6 +2100,28 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
}
break;
case AARCH64_OPND_IMM_ROT1:
case AARCH64_OPND_IMM_ROT2:
if (opnd->imm.value != 0
&& opnd->imm.value != 90
&& opnd->imm.value != 180
&& opnd->imm.value != 270)
{
set_other_error (mismatch_detail, idx,
_("rotate expected to be 0, 90, 180 or 270"));
return 0;
}
break;
case AARCH64_OPND_IMM_ROT3:
if (opnd->imm.value != 90 && opnd->imm.value != 270)
{
set_other_error (mismatch_detail, idx,
_("rotate expected to be 90 or 270"));
return 0;
}
break;
case AARCH64_OPND_SHLL_IMM:
assert (idx == 2);
size = 8 * aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
@ -2436,7 +2461,15 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
case AARCH64_OPND_CLASS_SIMD_ELEMENT:
/* Get the upper bound for the element index. */
num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
if (opcode->op == OP_FCMLA_ELEM)
/* FCMLA index range depends on the vector size of other operands
and is halfed because complex numbers take two elements. */
num = aarch64_get_qualifier_nelem (opnds[0].qualifier)
* aarch64_get_qualifier_esize (opnds[0].qualifier) / 2;
else
num = 16;
num = num / aarch64_get_qualifier_esize (qualifier) - 1;
/* Index out-of-range. */
if (!value_in_range_p (opnd->reglane.index, 0, num))
{
@ -3185,6 +3218,9 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
case AARCH64_OPND_SVE_UIMM7:
case AARCH64_OPND_SVE_UIMM8:
case AARCH64_OPND_SVE_UIMM8_53:
case AARCH64_OPND_IMM_ROT1:
case AARCH64_OPND_IMM_ROT2:
case AARCH64_OPND_IMM_ROT3:
snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
break;

View File

@ -137,6 +137,9 @@ enum aarch64_field_kind
FLD_SVE_tszl_19,
FLD_SVE_xs_14,
FLD_SVE_xs_22,
FLD_rotate1,
FLD_rotate2,
FLD_rotate3,
};
/* Field description. */

View File

@ -969,6 +969,16 @@
QLF3(V_2D , V_2D , V_2D ) \
}
/* e.g. FCMLA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>, #<rotate>. */
#define QL_V3SAMEHSD_ROT \
{ \
QLF4 (V_4H, V_4H, V_4H, NIL), \
QLF4 (V_8H, V_8H, V_8H, NIL), \
QLF4 (V_2S, V_2S, V_2S, NIL), \
QLF4 (V_4S, V_4S, V_4S, NIL), \
QLF4 (V_2D, V_2D, V_2D, NIL), \
}
/* e.g. FMAXNM <Vd>.<T>, <Vn>.<T>, <Vm>.<T>. */
#define QL_V3SAMEH \
{ \
@ -1308,6 +1318,14 @@
QLF3 (V_8H, V_8H, S_H), \
}
/* e.g. FCMLA <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>], #<rotate>. */
#define QL_ELEMENT_ROT \
{ \
QLF4 (V_4H, V_4H, S_H, NIL), \
QLF4 (V_8H, V_8H, S_H, NIL), \
QLF4 (V_4S, V_4S, S_S, NIL), \
}
/* e.g. MOVI <Vd>.4S, #<imm8> {, LSL #<amount>}. */
#define QL_SIMD_IMM_S0W \
{ \
@ -1920,6 +1938,8 @@ static const aarch64_feature_set aarch64_feature_v8_3 =
AARCH64_FEATURE (AARCH64_FEATURE_V8_3, 0);
static const aarch64_feature_set aarch64_feature_fp_v8_3 =
AARCH64_FEATURE (AARCH64_FEATURE_V8_3 | AARCH64_FEATURE_FP, 0);
static const aarch64_feature_set aarch64_feature_simd_v8_3 =
AARCH64_FEATURE (AARCH64_FEATURE_V8_3 | AARCH64_FEATURE_SIMD, 0);
#define CORE &aarch64_feature_v8
#define FP &aarch64_feature_fp
@ -1937,6 +1957,7 @@ static const aarch64_feature_set aarch64_feature_fp_v8_3 =
#define SVE &aarch64_feature_sve
#define ARMV8_3 &aarch64_feature_v8_3
#define FP_V8_3 &aarch64_feature_fp_v8_3
#define SIMD_V8_3 &aarch64_feature_simd_v8_3
#define CORE_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
{ NAME, OPCODE, MASK, CLASS, OP, CORE, OPS, QUALS, FLAGS, 0, NULL }
@ -2104,6 +2125,7 @@ struct aarch64_opcode aarch64_opcode_table[] =
SF16_INSN ("fmulx", 0x2f009000, 0xbfc0f400, asimdelem, OP3 (Vd, Vn, Em), QL_ELEMENT_FP_H, F_SIZEQ),
RDMA_INSN ("sqrdmlah",0x2f00d000, 0xbf00f400, asimdelem, OP3 (Vd, Vn, Em), QL_ELEMENT, F_SIZEQ),
RDMA_INSN ("sqrdmlsh",0x2f00f000, 0xbf00f400, asimdelem, OP3 (Vd, Vn, Em), QL_ELEMENT, F_SIZEQ),
{"fcmla", 0x2f001000, 0xbf009400, asimdelem, OP_FCMLA_ELEM, SIMD_V8_3, OP4 (Vd, Vn, Em, IMM_ROT2), QL_ELEMENT_ROT, F_SIZEQ, 0, NULL},
/* AdvSIMD EXT. */
SIMD_INSN ("ext", 0x2e000000, 0xbfe08400, asimdext, 0, OP4 (Vd, Vn, Vm, IDX), QL_VEXT, F_SIZEQ),
/* AdvSIMD modified immediate. */
@ -2347,6 +2369,8 @@ struct aarch64_opcode aarch64_opcode_table[] =
/* AdvSIMD three same extension. */
RDMA_INSN ("sqrdmlah",0x2e008400, 0xbf20fe00, asimdsame, OP3 (Vd, Vn, Vm), QL_V3SAMEHS, F_SIZEQ),
RDMA_INSN ("sqrdmlsh",0x2e008c00, 0xbf20fe00, asimdsame, OP3 (Vd, Vn, Vm), QL_V3SAMEHS, F_SIZEQ),
{"fcmla", 0x2e00c400, 0xbf20e400, asimdsame, 0, SIMD_V8_3, OP4 (Vd, Vn, Vm, IMM_ROT1), QL_V3SAMEHSD_ROT, F_SIZEQ, 0, NULL},
{"fcadd", 0x2e00e400, 0xbf20ec00, asimdsame, 0, SIMD_V8_3, OP4 (Vd, Vn, Vm, IMM_ROT3), QL_V3SAMEHSD_ROT, F_SIZEQ, 0, NULL},
/* AdvSIMD shift by immediate. */
SIMD_INSN ("sshr", 0xf000400, 0xbf80fc00, asimdshf, 0, OP3 (Vd, Vn, IMM_VLSR), QL_VSHIFT, 0),
SIMD_INSN ("ssra", 0xf001400, 0xbf80fc00, asimdshf, 0, OP3 (Vd, Vn, IMM_VLSR), QL_VSHIFT, 0),
@ -4116,6 +4140,12 @@ struct aarch64_opcode aarch64_opcode_table[] =
Y(IMMEDIATE, fbits, "FBITS", 0, F(FLD_scale), \
"the number of bits after the binary point in the fixed-point value")\
X(IMMEDIATE, 0, 0, "IMM_MOV", 0, F(), "an immediate") \
Y(IMMEDIATE, imm_rotate, "IMM_ROT1", 0, F(FLD_rotate1), \
"a 2-bit rotation specifier for complex arithmetic operations") \
Y(IMMEDIATE, imm_rotate, "IMM_ROT2", 0, F(FLD_rotate2), \
"a 2-bit rotation specifier for complex arithmetic operations") \
Y(IMMEDIATE, imm_rotate, "IMM_ROT3", 0, F(FLD_rotate3), \
"a 1-bit rotation specifier for complex arithmetic operations") \
Y(COND, cond, "COND", 0, F(), "a condition") \
Y(COND, cond, "COND1", 0, F(), \
"one of the standard conditions, excluding AL and NV.") \