From 6456d318aaa7ea35511dad1f2facf0fb984972e5 Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Thu, 7 Feb 2019 16:55:23 +0000 Subject: AArch64: Add verifier for By elem Single and Double sized instructions. The AArch64 instruction set has cut-outs inside instructions encodings for when a given encoding that would normally fall within the encoding space of an instruction is instead undefined. This updates the first few instructions FMLA, FMLA, FMUL and FMULX in the case where sz:L == 11. gas/ChangeLog: PR binutils/23212 * testsuite/gas/aarch64/undefined_by_elem_sz_l.s: New test. * testsuite/gas/aarch64/undefined_by_elem_sz_l.d: New test. opcodes/ChangeLog: PR binutils/23212 * aarch64-opc.h (enum aarch64_field_kind): Add FLD_sz. * aarch64-opc.c (verify_elem_sd): New. (fields): Add FLD_sz entr. * aarch64-tbl.h (_SIMD_INSN): New. (aarch64_opcode_table): Add elem_sd verifier to fmla, fmls, fmul and fmulx scalar and vector by element isns. --- opcodes/ChangeLog | 10 ++++++++++ opcodes/aarch64-opc.c | 24 ++++++++++++++++++++++++ opcodes/aarch64-opc.h | 3 ++- opcodes/aarch64-tbl.h | 18 ++++++++++-------- 4 files changed, 46 insertions(+), 9 deletions(-) (limited to 'opcodes') diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 99118e4..2523b31 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,13 @@ +2019-02-07 Tamar Christina + + PR binutils/23212 + * aarch64-opc.h (enum aarch64_field_kind): Add FLD_sz. + * aarch64-opc.c (verify_elem_sd): New. + (fields): Add FLD_sz entr. + * aarch64-tbl.h (_SIMD_INSN): New. + (aarch64_opcode_table): Add elem_sd verifier to fmla, fmls, fmul and + fmulx scalar and vector by element isns. + 2019-02-07 Nick Clifton * po/sv.po: Updated Swedish translation. diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c index 22839ca..a174116 100644 --- a/opcodes/aarch64-opc.c +++ b/opcodes/aarch64-opc.c @@ -320,6 +320,7 @@ const aarch64_field fields[] = { 13, 2 }, /* rotate2: Indexed element FCMLA immediate rotate. */ { 12, 1 }, /* rotate3: FCADD immediate rotate. */ { 12, 2 }, /* SM3: Indexed element SM3 2 bits index immediate. */ + { 22, 1 }, /* sz: 1-bit element size select. */ }; enum aarch64_operand_class @@ -4728,6 +4729,29 @@ verify_ldpsw (const struct aarch64_inst *inst ATTRIBUTE_UNUSED, return ERR_OK; } +/* Verifier for vector by element 3 operands functions where the + conditions `if sz:L == 11 then UNDEFINED` holds. */ + +static enum err_type +verify_elem_sd (const struct aarch64_inst *inst, const aarch64_insn insn, + bfd_vma pc ATTRIBUTE_UNUSED, bfd_boolean encoding, + aarch64_operand_error *mismatch_detail ATTRIBUTE_UNUSED, + aarch64_instr_sequence *insn_sequence ATTRIBUTE_UNUSED) +{ + const aarch64_insn undef_pattern = 0x3; + aarch64_insn value; + + assert (inst->opcode); + assert (inst->opcode->operands[2] == AARCH64_OPND_Em); + value = encoding ? inst->value : insn; + assert (value); + + if (undef_pattern == extract_fields (value, 0, 2, FLD_sz, FLD_L)) + return ERR_UND; + + return ERR_OK; +} + /* Initialize an instruction sequence insn_sequence with the instruction INST. If INST is NULL the given insn_sequence is cleared and the sequence is left uninitialized. */ diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h index ffb3b83..f6c506d 100644 --- a/opcodes/aarch64-opc.h +++ b/opcodes/aarch64-opc.h @@ -146,7 +146,8 @@ enum aarch64_field_kind FLD_rotate1, FLD_rotate2, FLD_rotate3, - FLD_SM3_imm2 + FLD_SM3_imm2, + FLD_sz }; /* Field description. */ diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h index ac05aae..e0c3903 100644 --- a/opcodes/aarch64-tbl.h +++ b/opcodes/aarch64-tbl.h @@ -2239,6 +2239,8 @@ static const aarch64_feature_set aarch64_feature_memtag = { NAME, OPCODE, MASK, CLASS, OP, FP, OPS, QUALS, FLAGS, 0, 0, NULL } #define SIMD_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \ { NAME, OPCODE, MASK, CLASS, OP, SIMD, OPS, QUALS, FLAGS, 0, 0, NULL } +#define _SIMD_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS,VERIFIER) \ + { NAME, OPCODE, MASK, CLASS, OP, SIMD, OPS, QUALS, FLAGS, 0, 0, VERIFIER } #define CRYP_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \ { NAME, OPCODE, MASK, CLASS, 0, CRYPTO, OPS, QUALS, FLAGS, 0, 0, NULL } #define _CRC_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \ @@ -2420,11 +2422,11 @@ struct aarch64_opcode aarch64_opcode_table[] = SIMD_INSN ("sqdmull2",0x4f00b000, 0xff00f400, asimdelem, 0, OP3 (Vd, Vn, Em16), QL_ELEMENT_L2, F_SIZEQ), SIMD_INSN ("sqdmulh", 0x0f00c000, 0xbf00f400, asimdelem, 0, OP3 (Vd, Vn, Em16), QL_ELEMENT, F_SIZEQ), SIMD_INSN ("sqrdmulh",0x0f00d000, 0xbf00f400, asimdelem, 0, OP3 (Vd, Vn, Em16), QL_ELEMENT, F_SIZEQ), - SIMD_INSN ("fmla", 0x0f801000, 0xbf80f400, asimdelem, 0, OP3 (Vd, Vn, Em), QL_ELEMENT_FP, F_SIZEQ), + _SIMD_INSN ("fmla", 0x0f801000, 0xbf80f400, asimdelem, 0, OP3 (Vd, Vn, Em), QL_ELEMENT_FP, F_SIZEQ, VERIFIER (elem_sd)), SF16_INSN ("fmla", 0x0f001000, 0xbfc0f400, asimdelem, OP3 (Vd, Vn, Em16), QL_ELEMENT_FP_H, F_SIZEQ), - SIMD_INSN ("fmls", 0x0f805000, 0xbf80f400, asimdelem, 0, OP3 (Vd, Vn, Em), QL_ELEMENT_FP, F_SIZEQ), + _SIMD_INSN ("fmls", 0x0f805000, 0xbf80f400, asimdelem, 0, OP3 (Vd, Vn, Em), QL_ELEMENT_FP, F_SIZEQ, VERIFIER (elem_sd)), SF16_INSN ("fmls", 0x0f005000, 0xbfc0f400, asimdelem, OP3 (Vd, Vn, Em16), QL_ELEMENT_FP_H, F_SIZEQ), - SIMD_INSN ("fmul", 0x0f809000, 0xbf80f400, asimdelem, 0, OP3 (Vd, Vn, Em), QL_ELEMENT_FP, F_SIZEQ), + _SIMD_INSN ("fmul", 0x0f809000, 0xbf80f400, asimdelem, 0, OP3 (Vd, Vn, Em), QL_ELEMENT_FP, F_SIZEQ, VERIFIER (elem_sd)), SF16_INSN ("fmul", 0x0f009000, 0xbfc0f400, asimdelem, OP3 (Vd, Vn, Em16), QL_ELEMENT_FP_H, F_SIZEQ), SIMD_INSN ("mla", 0x2f000000, 0xbf00f400, asimdelem, 0, OP3 (Vd, Vn, Em16), QL_ELEMENT, F_SIZEQ), SIMD_INSN ("umlal", 0x2f002000, 0xff00f400, asimdelem, 0, OP3 (Vd, Vn, Em16), QL_ELEMENT_L, F_SIZEQ), @@ -2434,7 +2436,7 @@ struct aarch64_opcode aarch64_opcode_table[] = SIMD_INSN ("umlsl2", 0x6f006000, 0xff00f400, asimdelem, 0, OP3 (Vd, Vn, Em16), QL_ELEMENT_L2, F_SIZEQ), SIMD_INSN ("umull", 0x2f00a000, 0xff00f400, asimdelem, 0, OP3 (Vd, Vn, Em16), QL_ELEMENT_L, F_SIZEQ), SIMD_INSN ("umull2", 0x6f00a000, 0xff00f400, asimdelem, 0, OP3 (Vd, Vn, Em16), QL_ELEMENT_L2, F_SIZEQ), - SIMD_INSN ("fmulx", 0x2f809000, 0xbf80f400, asimdelem, 0, OP3 (Vd, Vn, Em), QL_ELEMENT_FP, F_SIZEQ), + _SIMD_INSN ("fmulx", 0x2f809000, 0xbf80f400, asimdelem, 0, OP3 (Vd, Vn, Em), QL_ELEMENT_FP, F_SIZEQ, VERIFIER (elem_sd)), SF16_INSN ("fmulx", 0x2f009000, 0xbfc0f400, asimdelem, OP3 (Vd, Vn, Em16), QL_ELEMENT_FP_H, F_SIZEQ), RDMA_INSN ("sqrdmlah",0x2f00d000, 0xbf00f400, asimdelem, OP3 (Vd, Vn, Em16), QL_ELEMENT, F_SIZEQ), RDMA_INSN ("sqrdmlsh",0x2f00f000, 0xbf00f400, asimdelem, OP3 (Vd, Vn, Em16), QL_ELEMENT, F_SIZEQ), @@ -2748,13 +2750,13 @@ struct aarch64_opcode aarch64_opcode_table[] = SIMD_INSN ("sqdmull", 0x5f00b000, 0xff00f400, asisdelem, 0, OP3 (Sd, Sn, Em16), QL_SISDL_HS, F_SSIZE), SIMD_INSN ("sqdmulh", 0x5f00c000, 0xff00f400, asisdelem, 0, OP3 (Sd, Sn, Em16), QL_SISD_HS, F_SSIZE), SIMD_INSN ("sqrdmulh", 0x5f00d000, 0xff00f400, asisdelem, 0, OP3 (Sd, Sn, Em16), QL_SISD_HS, F_SSIZE), - SIMD_INSN ("fmla", 0x5f801000, 0xff80f400, asisdelem, 0, OP3 (Sd, Sn, Em), QL_FP3, F_SSIZE), + _SIMD_INSN ("fmla", 0x5f801000, 0xff80f400, asisdelem, 0, OP3 (Sd, Sn, Em), QL_FP3, F_SSIZE, VERIFIER (elem_sd)), SF16_INSN ("fmla", 0x5f001000, 0xffc0f400, asisdelem, OP3 (Sd, Sn, Em16), QL_FP3_H, F_SSIZE), - SIMD_INSN ("fmls", 0x5f805000, 0xff80f400, asisdelem, 0, OP3 (Sd, Sn, Em), QL_FP3, F_SSIZE), + _SIMD_INSN ("fmls", 0x5f805000, 0xff80f400, asisdelem, 0, OP3 (Sd, Sn, Em), QL_FP3, F_SSIZE, VERIFIER (elem_sd)), SF16_INSN ("fmls", 0x5f005000, 0xffc0f400, asisdelem, OP3 (Sd, Sn, Em16), QL_FP3_H, F_SSIZE), - SIMD_INSN ("fmul", 0x5f809000, 0xff80f400, asisdelem, 0, OP3 (Sd, Sn, Em), QL_FP3, F_SSIZE), + _SIMD_INSN ("fmul", 0x5f809000, 0xff80f400, asisdelem, 0, OP3 (Sd, Sn, Em), QL_FP3, F_SSIZE, VERIFIER (elem_sd)), SF16_INSN ("fmul", 0x5f009000, 0xffc0f400, asisdelem, OP3 (Sd, Sn, Em16), QL_FP3_H, F_SSIZE), - SIMD_INSN ("fmulx", 0x7f809000, 0xff80f400, asisdelem, 0, OP3 (Sd, Sn, Em), QL_FP3, F_SSIZE), + _SIMD_INSN ("fmulx", 0x7f809000, 0xff80f400, asisdelem, 0, OP3 (Sd, Sn, Em), QL_FP3, F_SSIZE, VERIFIER (elem_sd)), SF16_INSN ("fmulx", 0x7f009000, 0xffc0f400, asisdelem, OP3 (Sd, Sn, Em16), QL_FP3_H, F_SSIZE), RDMA_INSN ("sqrdmlah", 0x7f00d000, 0xff00f400, asisdelem, OP3 (Sd, Sn, Em16), QL_SISD_HS, F_SSIZE), RDMA_INSN ("sqrdmlsh", 0x7f00f000, 0xff00f400, asisdelem, OP3 (Sd, Sn, Em16), QL_SISD_HS, F_SSIZE), -- cgit v1.1