From 503ba600259856b41a88b56922e094ea826df270 Mon Sep 17 00:00:00 2001 From: Sudakshina Das Date: Mon, 12 Nov 2018 13:19:12 +0000 Subject: [BINUTILS, AARCH64, 6/8] Add Tag getting instruction in Memory Tagging Extension This patch is part of the patch series to add support for ARMv8.5-A Memory Tagging Extensions which is an optional extension to ARMv8.5-A and is enabled using the +memtag command line option. This patch add support to the Bulk Allocation Tag instructions from MTE. These are the following instructions added in this patch: - LDGV , []! - STGV , []! This needed a new kind of operand for the new addressing []! since this has no offset and only takes a pre-indexed version. Hence AARCH64_OPND_ADDR_SIMPLE_2 and ldtdgv_indexed are introduced. (AARCH64_OPND_ADDR_SIMPLE fulfilled the no offset criteria but does not allow writeback). We also needed new encoding and decoding functions to be able to do the same. where : Is the 64-bit destination GPR. : Is the 64-bit first source GPR or Stack pointer. *** include/ChangeLog *** 2018-11-12 Sudakshina Das * opcode/aarch64.h (aarch64_opnd): Add AARCH64_OPND_ADDR_SIMPLE_2. (aarch64_insn_class): Add ldstgv_indexed. *** opcodes/ChangeLog *** 2018-11-12 Sudakshina Das * aarch64-asm.c (aarch64_ins_addr_simple_2): New. * aarch64-asm.h (ins_addr_simple_2): Declare the above. * aarch64-dis.c (aarch64_ext_addr_simple_2): New. * aarch64-dis.h (ext_addr_simple_2): Declare the above. * aarch64-opc.c (operand_general_constraint_met_p): Add case for AARCH64_OPND_ADDR_SIMPLE_2 and ldstgv_indexed. (aarch64_print_operand): Add case for AARCH64_OPND_ADDR_SIMPLE_2. * aarch64-tbl.h (aarch64_opcode_table): Add stgv and ldgv. (AARCH64_OPERANDS): Define ADDR_SIMPLE_2. * aarch64-asm-2.c: Regenerated. * aarch64-dis-2.c: Regenerated. * aarch64-opc-2.c: Regenerated. *** gas/ChangeLog *** 2018-11-12 Sudakshina Das * config/tc-aarch64.c (parse_operands): Add switch case for AARCH64_OPND_ADDR_SIMPLE_2 and allow [base]! for it. (warn_unpredictable_ldst): Exempt ldstgv_indexed for ldgv. * testsuite/gas/aarch64/armv8_5-a-memtag.s: Add tests for ldgv and stgv. * testsuite/gas/aarch64/armv8_5-a-memtag.d: Likewise. * testsuite/gas/aarch64/illegal-memtag.s: Likewise. * testsuite/gas/aarch64/illegal-memtag.l: Likewise. --- gas/ChangeLog | 10 ++++++++++ gas/config/tc-aarch64.c | 20 +++++++++++++++++--- gas/testsuite/gas/aarch64/armv8_5-a-memtag.d | 11 +++++++++++ gas/testsuite/gas/aarch64/armv8_5-a-memtag.s | 13 +++++++++++++ gas/testsuite/gas/aarch64/illegal-memtag.l | 7 +++++++ gas/testsuite/gas/aarch64/illegal-memtag.s | 12 ++++++++++++ 6 files changed, 70 insertions(+), 3 deletions(-) (limited to 'gas') diff --git a/gas/ChangeLog b/gas/ChangeLog index eead118..eea9a4e 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,15 @@ 2018-11-12 Sudakshina Das + * config/tc-aarch64.c (parse_operands): Add switch case for + AARCH64_OPND_ADDR_SIMPLE_2 and allow [base]! for it. + (warn_unpredictable_ldst): Exempt ldstgv_indexed for ldgv. + * testsuite/gas/aarch64/armv8_5-a-memtag.s: Add tests for ldgv and stgv. + * testsuite/gas/aarch64/armv8_5-a-memtag.d: Likewise. + * testsuite/gas/aarch64/illegal-memtag.s: Likewise. + * testsuite/gas/aarch64/illegal-memtag.l: Likewise. + +2018-11-12 Sudakshina Das + * testsuite/gas/aarch64/armv8_5-a-memtag.s: Add tests for ldg. * testsuite/gas/aarch64/armv8_5-a-memtag.d: Likewise. * testsuite/gas/aarch64/illegal-memtag.s: Likewise. diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index a5eee96..3fed11c 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -3372,6 +3372,7 @@ parse_shifter_operand_reloc (char **str, aarch64_opnd_info *operand, [base,Wm,(S|U)XTW {#imm}] Pre-indexed [base,#imm]! + [base]! // in ld/stgv Post-indexed [base],#imm [base],Xm // in SIMD ld/st structure @@ -3680,10 +3681,11 @@ 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]! but accept [Rn] as a shorthand for [Rn,#0]. */ + bare [Rn]{!}; reject [Rn]! except for ld/stgv but accept [Rn] + as a shorthand for [Rn,#0]. */ if (operand->addr.preind == 0 && operand->addr.postind == 0) { - if (operand->addr.writeback) + if (operand->type != AARCH64_OPND_ADDR_SIMPLE_2 && operand->addr.writeback) { /* Reject [Rn]! */ set_syntax_error (_("missing offset in the pre-indexed address")); @@ -6137,6 +6139,7 @@ parse_operands (char *str, const aarch64_opcode *opcode) break; case AARCH64_OPND_ADDR_SIMPLE: + case AARCH64_OPND_ADDR_SIMPLE_2: case AARCH64_OPND_SIMD_ADDR_SIMPLE: { /* [{, #}] */ @@ -6146,7 +6149,8 @@ parse_operands (char *str, const aarch64_opcode *opcode) po_misc_or_fail (parse_address (&str, info)); if (info->addr.pcrel || info->addr.offset.is_reg || !info->addr.preind || info->addr.postind - || info->addr.writeback) + || (info->addr.writeback + && operands[i] != AARCH64_OPND_ADDR_SIMPLE_2)) { set_syntax_error (_("invalid addressing mode")); goto failure; @@ -6169,6 +6173,8 @@ parse_operands (char *str, const aarch64_opcode *opcode) } } po_char_or_fail (']'); + if (operands[i] == AARCH64_OPND_ADDR_SIMPLE_2) + po_char_or_fail ('!'); break; } @@ -6766,6 +6772,14 @@ warn_unpredictable_ldst (aarch64_instruction *instr, char *str) && opnds[1].addr.writeback) as_warn (_("unpredictable transfer with writeback -- `%s'"), str); break; + + case ldstgv_indexed: + /* Load operations must load different registers. */ + if ((opcode->opcode & (1 << 22)) + && opnds[0].reg.regno == opnds[1].addr.base_regno) + as_warn (_("unpredictable load of register -- `%s'"), str); + break; + case ldstpair_off: case ldstnapair_offs: case ldstpair_indexed: diff --git a/gas/testsuite/gas/aarch64/armv8_5-a-memtag.d b/gas/testsuite/gas/aarch64/armv8_5-a-memtag.d index 363bbe2..fa56bfa 100644 --- a/gas/testsuite/gas/aarch64/armv8_5-a-memtag.d +++ b/gas/testsuite/gas/aarch64/armv8_5-a-memtag.d @@ -121,3 +121,14 @@ Disassembly of section \.text: .*: d960001f ldg xzr, \[x0\] .*: d96ff000 ldg x0, \[x0, #4080\] .*: d9700000 ldg x0, \[x0, #-4096\] +.*: d9e0001b ldgv x27, \[x0\]! +.*: d9e00360 ldgv x0, \[x27\]! +.*: d9e00379 ldgv x25, \[x27\]! +.*: d9e003e0 ldgv x0, \[sp\]! +.*: d9e0001f ldgv xzr, \[x0\]! +.*: d9a00000 stgv x0, \[x0\]! +.*: d9a0001b stgv x27, \[x0\]! +.*: d9a00360 stgv x0, \[x27\]! +.*: d9a00379 stgv x25, \[x27\]! +.*: d9a003e0 stgv x0, \[sp\]! +.*: d9a0001f stgv xzr, \[x0\]! diff --git a/gas/testsuite/gas/aarch64/armv8_5-a-memtag.s b/gas/testsuite/gas/aarch64/armv8_5-a-memtag.s index 62c9436..2c2ff8f 100644 --- a/gas/testsuite/gas/aarch64/armv8_5-a-memtag.s +++ b/gas/testsuite/gas/aarch64/armv8_5-a-memtag.s @@ -30,6 +30,14 @@ func: \op [sp], #-4096 .endm + .macro expand_ldg_bulk op + \op x27, [x0]! + \op x0, [x27]! + \op x25, [x27]! + \op x0, [sp]! + \op xzr, [x0]! + .endm + # IRG expand_3_reg irg irg sp, x0 @@ -98,3 +106,8 @@ func: ldg xzr, [x0, #0] ldg x0, [x0, #4080] ldg x0, [x0, #-4096] + + expand_ldg_bulk ldgv + + stgv x0, [x0]! + expand_ldg_bulk stgv diff --git a/gas/testsuite/gas/aarch64/illegal-memtag.l b/gas/testsuite/gas/aarch64/illegal-memtag.l index dfdf00a..0d499d9 100644 --- a/gas/testsuite/gas/aarch64/illegal-memtag.l +++ b/gas/testsuite/gas/aarch64/illegal-memtag.l @@ -12,6 +12,9 @@ [^:]*:[0-9]+: Error: immediate offset out of range -1024 to 1008 at operand 3 -- `stgp x1,x2,\[x3,#1009\]' [^:]*:[0-9]+: Error: immediate value must be a multiple of 16 at operand 3 -- `stgp x1,x2,\[x3,#33\]' [^:]*:[0-9]+: Error: immediate offset out of range -1024 to 1008 at operand 3 -- `stgp x1,x2,\[x3,#-1025\]' +[^:]*:[0-9]+: Warning: unpredictable load of register -- `ldgv x1,\[x1\]!' +[^:]*:[0-9]+: Error: operand 2 must be a writeback address with base register \(no offset\) -- `ldgv x1,\[x2\]' +[^:]*:[0-9]+: Error: operand 2 must be a writeback address with base register \(no offset\) -- `stgv x1,\[x2\]' [^:]*:[0-9]+: Error: operand 1 must be an integer or stack pointer register -- `irg xzr,x2,x3' [^:]*:[0-9]+: Error: operand 2 must be an integer or stack pointer register -- `irg x1,xzr,x3' [^:]*:[0-9]+: Error: operand 3 must be an integer register -- `irg x1,x2,sp' @@ -37,3 +40,7 @@ [^:]*:[0-9]+: Error: 64-bit integer or SP register expected at operand 3 -- `stgp x0,x0,\[xzr\]' [^:]*:[0-9]+: Error: operand 1 must be an integer register -- `ldg sp,\[x0,#16\]' [^:]*:[0-9]+: Error: 64-bit integer or SP register expected at operand 2 -- `ldg x0,\[xzr,#16\]' +[^:]*:[0-9]+: Error: operand 1 must be an integer register -- `ldgv sp,\[x1\]!' +[^:]*:[0-9]+: Error: 64-bit integer or SP register expected at operand 2 -- `ldgv x0,\[xzr\]!' +[^:]*:[0-9]+: Error: operand 1 must be an integer register -- `stgv sp,\[x1\]!' +[^:]*:[0-9]+: Error: 64-bit integer or SP register expected at operand 2 -- `stgv x0,\[xzr\]!' diff --git a/gas/testsuite/gas/aarch64/illegal-memtag.s b/gas/testsuite/gas/aarch64/illegal-memtag.s index 35d1b12..7b7dcd9 100644 --- a/gas/testsuite/gas/aarch64/illegal-memtag.s +++ b/gas/testsuite/gas/aarch64/illegal-memtag.s @@ -20,6 +20,14 @@ func: stgp x1, x2, [x3, #33] stgp x1, x2, [x3, #-1025] + # LDGV : Warn for Xt == Xn + # STGV : Sould not warn for above + ldgv x1, [x1]! + stgv x1, [x1]! + # Error for no writeback + ldgv x1, [x2] + stgv x1, [x2] + # Illegal SP/XZR registers irg xzr, x2, x3 irg x1, xzr, x3 @@ -46,3 +54,7 @@ func: stgp x0, x0, [xzr] ldg sp, [x0, #16] ldg x0, [xzr, #16] + ldgv sp, [x1]! + ldgv x0, [xzr]! + stgv sp, [x1]! + stgv x0, [xzr]! -- cgit v1.1