From 54a28c4ce5b18cccee584d7a5e26df750edfafe1 Mon Sep 17 00:00:00 2001 From: Jiong Wang Date: Wed, 19 Nov 2014 09:35:23 +0000 Subject: [AArch64] Warn on load pair to same register 2014-11-19 Ryan Mansfield * config/tc-aarch64.c (md_assemble): Call warn_unpredictable_ldst. (warn_unpredictable_ldst): New. 2014-11-19 Ryan Mansfield * gas/aarch64/diagnostic.s: Add new warnings test patterns. * gas/aarch64/diagnostic.l: Update expected diagnostic output. --- gas/ChangeLog | 5 +++++ gas/config/tc-aarch64.c | 36 ++++++++++++++++++++++++++++++++++ gas/testsuite/ChangeLog | 5 +++++ gas/testsuite/gas/aarch64/diagnostic.l | 9 +++++++++ gas/testsuite/gas/aarch64/diagnostic.s | 13 ++++++++++++ 5 files changed, 68 insertions(+) (limited to 'gas') diff --git a/gas/ChangeLog b/gas/ChangeLog index 943c239..8341ee4 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2014-11-19 Ryan Mansfield + + * config/tc-aarch64.c (md_assemble): Call warn_unpredictable_ldst. + (warn_unpredictable_ldst): New. + 2014-11-18 Igor Zamyatin * config/tc-i386-intel.c (i386_operator): Remove last argument diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 8cecfd0..41378f5 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -5490,6 +5490,40 @@ programmer_friendly_fixup (aarch64_instruction *instr) return TRUE; } +/* Check for loads and stores that will cause unpredictable behavior */ + +static void +warn_unpredictable_ldst (aarch64_instruction *instr, char *str) +{ + aarch64_inst *base = &instr->base; + const aarch64_opcode *opcode = base->opcode; + const aarch64_opnd_info *opnds = base->operands; + switch (opcode->iclass) + { + case ldst_pos: + case ldst_imm9: + case ldst_unscaled: + case ldst_unpriv: + if (opnds[0].reg.regno == opnds[1].reg.regno + && opnds[1].addr.writeback) + as_warn (_("unpredictable register after writeback -- `%s'"), str); + break; + case ldstpair_off: + case ldstnapair_offs: + case ldstpair_indexed: + if ((opnds[0].reg.regno == opnds[2].reg.regno + || opnds[1].reg.regno == opnds[2].reg.regno) + && opnds[2].addr.writeback) + as_warn (_("unpredictable register after writeback -- `%s'"), str); + if ((opcode->opcode & (1 << 22)) + && opnds[0].reg.regno == opnds[1].reg.regno) + as_warn (_("unpredictable load of register pair -- `%s'"), str); + break; + default: + break; + } +} + /* A wrapper function to interface with libopcodes on encoding and record the error message if there is any. @@ -5622,6 +5656,8 @@ md_assemble (char *str) return; } + warn_unpredictable_ldst (&inst, str); + if (inst.reloc.type == BFD_RELOC_UNUSED || !inst.reloc.need_libopcodes_p) output_inst (NULL); diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 40989b3..51119a2 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-11-19 Ryan Mansfield + + * gas/aarch64/diagnostic.s: Add new warnings test patterns. + * gas/aarch64/diagnostic.l: Update expected diagnostic output. + 2014-11-18 Igor Zamyatin * gas/i386/x86-64-mpx-branch-1.d: Don't use *_BND relocations. diff --git a/gas/testsuite/gas/aarch64/diagnostic.l b/gas/testsuite/gas/aarch64/diagnostic.l index 322e3c0..d5fdba8 100644 --- a/gas/testsuite/gas/aarch64/diagnostic.l +++ b/gas/testsuite/gas/aarch64/diagnostic.l @@ -105,3 +105,12 @@ [^:]*:109: Error: operand 5 should be an integer register -- `sys #0,c0,c0,#0,kk' [^:]*:110: Error: unexpected comma before the omitted optional operand at operand 5 -- `sys #0,c0,c0,#0,' [^:]*:112: Error: selected processor does not support `casp w0,w1,w2,w3,\[x4\]' +[^:]*:115: Warning: unpredictable load of register pair -- `ldp x0,x0,\[sp\]' +[^:]*:116: Warning: unpredictable load of register pair -- `ldp d0,d0,\[sp\]' +[^:]*:117: Warning: unpredictable load of register pair -- `ldp x0,x0,\[sp\],#16' +[^:]*:118: Warning: unpredictable load of register pair -- `ldnp x0,x0,\[sp\]' +[^:]*:121: Warning: unpredictable register after writeback -- `ldr x0,\[x0,#8\]!' +[^:]*:122: Warning: unpredictable register after writeback -- `str x0,\[x0,#8\]!' +[^:]*:123: Warning: unpredictable register after writeback -- `str x1,\[x1\],#8' +[^:]*:124: Warning: unpredictable register after writeback -- `stp x0,x1,\[x0,#16\]!' +[^:]*:125: Warning: unpredictable register after writeback -- `ldp x0,x1,\[x1\],#16' diff --git a/gas/testsuite/gas/aarch64/diagnostic.s b/gas/testsuite/gas/aarch64/diagnostic.s index b82ac8b..88001da 100644 --- a/gas/testsuite/gas/aarch64/diagnostic.s +++ b/gas/testsuite/gas/aarch64/diagnostic.s @@ -110,3 +110,16 @@ sys #0, c0, c0, #0, casp w0,w1,w2,w3,[x4] + + # test warning of unpredictable load pairs + ldp x0, x0, [sp] + ldp d0, d0, [sp] + ldp x0, x0, [sp], #16 + ldnp x0, x0, [sp] + + # test warning of unpredictable writeback + ldr x0, [x0, #8]! + str x0, [x0, #8]! + str x1, [x1], #8 + stp x0, x1, [x0, #16]! + ldp x0, x1, [x1], #16 -- cgit v1.1