From 19cf5bffa2cecfd18afc6f74305f72a216bf21ac Mon Sep 17 00:00:00 2001 From: Oliver Stannard Date: Tue, 6 Feb 2018 09:24:47 +0000 Subject: [PATCH] [ARM][AArch64] Add CSDB speculation barrier instruction This adds the CSDB instruction, which is a new barrier instruction described by the whitepaper at [1]. This is in encoding space which was previously executed as a NOP, so it is available for all targets that have the relevant NOP encoding space. This matches the binutils behaviour for these instructions [2][3]. [1] https://developer.arm.com/support/security-update [2] https://sourceware.org/ml/binutils/2018-01/msg00116.html [3] https://sourceware.org/ml/binutils/2018-01/msg00120.html git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@324324 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64InstrInfo.td | 1 + lib/Target/ARM/ARMInstrInfo.td | 1 + lib/Target/ARM/ARMInstrThumb2.td | 2 ++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 25 ++++++++++++++----------- test/MC/AArch64/csdb.s | 4 ++++ test/MC/ARM/csdb-errors.s | 6 ++++++ test/MC/ARM/csdb.s | 8 ++++++++ test/MC/Disassembler/AArch64/csdb.txt | 4 ++++ test/MC/Disassembler/ARM/csdb-arm.txt | 4 ++++ test/MC/Disassembler/ARM/csdb-thumb.txt | 4 ++++ 10 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 test/MC/AArch64/csdb.s create mode 100644 test/MC/ARM/csdb-errors.s create mode 100644 test/MC/ARM/csdb.s create mode 100644 test/MC/Disassembler/AArch64/csdb.txt create mode 100644 test/MC/Disassembler/ARM/csdb-arm.txt create mode 100644 test/MC/Disassembler/ARM/csdb-thumb.txt diff --git a/lib/Target/AArch64/AArch64InstrInfo.td b/lib/Target/AArch64/AArch64InstrInfo.td index c0975795604..1751b04800c 100644 --- a/lib/Target/AArch64/AArch64InstrInfo.td +++ b/lib/Target/AArch64/AArch64InstrInfo.td @@ -420,6 +420,7 @@ def : InstAlias<"wfi", (HINT 0b011)>; def : InstAlias<"sev", (HINT 0b100)>; def : InstAlias<"sevl", (HINT 0b101)>; def : InstAlias<"esb", (HINT 0b10000)>, Requires<[HasRAS]>; +def : InstAlias<"csdb", (HINT 20)>; // v8.2a Statistical Profiling extension def : InstAlias<"psb $op", (HINT psbhint_op:$op)>, Requires<[HasSPE]>; diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index e477d16923d..2269e81d713 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -2004,6 +2004,7 @@ def : InstAlias<"wfi$p", (HINT 3, pred:$p)>, Requires<[IsARM, HasV6K]>; def : InstAlias<"sev$p", (HINT 4, pred:$p)>, Requires<[IsARM, HasV6K]>; def : InstAlias<"sevl$p", (HINT 5, pred:$p)>, Requires<[IsARM, HasV8]>; def : InstAlias<"esb$p", (HINT 16, pred:$p)>, Requires<[IsARM, HasRAS]>; +def : InstAlias<"csdb$p", (HINT 20, pred:$p)>, Requires<[IsARM, HasV6K]>; def SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel", "\t$Rd, $Rn, $Rm", diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 8ca11d83dcf..249445cccce 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -3700,6 +3700,8 @@ def : t2InstAlias<"esb$p.w", (t2HINT 16, pred:$p), 1> { def : t2InstAlias<"esb$p", (t2HINT 16, pred:$p), 0> { let Predicates = [IsThumb2, HasRAS]; } +def : t2InstAlias<"csdb$p.w", (t2HINT 20, pred:$p), 0>; +def : t2InstAlias<"csdb$p", (t2HINT 20, pred:$p), 1>; def t2DBG : T2I<(outs), (ins imm0_15:$opt), NoItinerary, "dbg", "\t$opt", [(int_arm_dbg imm0_15:$opt)]> { diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 55a73ff537c..3d251887883 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -6616,19 +6616,22 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst, break; } case ARM::HINT: - case ARM::t2HINT: - if (hasRAS()) { - // ESB is not predicable (pred must be AL) - unsigned Imm8 = Inst.getOperand(0).getImm(); - unsigned Pred = Inst.getOperand(1).getImm(); - if (Imm8 == 0x10 && Pred != ARMCC::AL) - return Error(Operands[1]->getStartLoc(), "instruction 'esb' is not " - "predicable, but condition " - "code specified"); - } - // Without the RAS extension, this behaves as any other unallocated hint. + case ARM::t2HINT: { + unsigned Imm8 = Inst.getOperand(0).getImm(); + unsigned Pred = Inst.getOperand(1).getImm(); + // ESB is not predicable (pred must be AL). Without the RAS extension, this + // behaves as any other unallocated hint. + if (Imm8 == 0x10 && Pred != ARMCC::AL && hasRAS()) + return Error(Operands[1]->getStartLoc(), "instruction 'esb' is not " + "predicable, but condition " + "code specified"); + if (Imm8 == 0x14 && Pred != ARMCC::AL) + return Error(Operands[1]->getStartLoc(), "instruction 'csdb' is not " + "predicable, but condition " + "code specified"); break; } + } return false; } diff --git a/test/MC/AArch64/csdb.s b/test/MC/AArch64/csdb.s new file mode 100644 index 00000000000..bc52280ba85 --- /dev/null +++ b/test/MC/AArch64/csdb.s @@ -0,0 +1,4 @@ +// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding < %s | FileCheck %s + + csdb +// CHECK: csdb // encoding: [0x9f,0x22,0x03,0xd5] diff --git a/test/MC/ARM/csdb-errors.s b/test/MC/ARM/csdb-errors.s new file mode 100644 index 00000000000..af74a46b27c --- /dev/null +++ b/test/MC/ARM/csdb-errors.s @@ -0,0 +1,6 @@ +// RUN: not llvm-mc -triple armv8a-none-eabi %s 2>&1 | FileCheck %s +// RUN: not llvm-mc -triple thumbv8a-none-eabi %s 2>&1 | FileCheck %s + + it eq + csdbeq +// CHECK: error: instruction 'csdb' is not predicable, but condition code specified diff --git a/test/MC/ARM/csdb.s b/test/MC/ARM/csdb.s new file mode 100644 index 00000000000..4d78be40fa0 --- /dev/null +++ b/test/MC/ARM/csdb.s @@ -0,0 +1,8 @@ +@ RUN: llvm-mc -triple armv8a-none-eabi -show-encoding %s | FileCheck %s --check-prefix=ARM +@ RUN: llvm-mc -triple thumbv8a-none-eabi -show-encoding %s | FileCheck %s --check-prefix=THUMB +@ RUN: not llvm-mc -triple thumbv6m-none-eabi -show-encoding %s 2>&1 | FileCheck %s --check-prefix=ERROR + + csdb +@ ARM: csdb @ encoding: [0x14,0xf0,0x20,0xe3] +@ THUMB: csdb @ encoding: [0xaf,0xf3,0x14,0x80] +@ ERROR: error: instruction requires: thumb2 diff --git a/test/MC/Disassembler/AArch64/csdb.txt b/test/MC/Disassembler/AArch64/csdb.txt new file mode 100644 index 00000000000..ca78f765122 --- /dev/null +++ b/test/MC/Disassembler/AArch64/csdb.txt @@ -0,0 +1,4 @@ +# RUN: llvm-mc -triple aarch64-none-linux-gnu --disassemble < %s | FileCheck %s + +[0x9f,0x22,0x03,0xd5] +# CHECK: csdb diff --git a/test/MC/Disassembler/ARM/csdb-arm.txt b/test/MC/Disassembler/ARM/csdb-arm.txt new file mode 100644 index 00000000000..afea2a84fa6 --- /dev/null +++ b/test/MC/Disassembler/ARM/csdb-arm.txt @@ -0,0 +1,4 @@ +# RUN: llvm-mc < %s -triple armv8a-none-eabi -disassemble | FileCheck %s + +[0x14,0xf0,0x20,0xe3] +# CHECK: csdb diff --git a/test/MC/Disassembler/ARM/csdb-thumb.txt b/test/MC/Disassembler/ARM/csdb-thumb.txt new file mode 100644 index 00000000000..094c1d7ae22 --- /dev/null +++ b/test/MC/Disassembler/ARM/csdb-thumb.txt @@ -0,0 +1,4 @@ +# RUN: llvm-mc < %s -triple thumbv8a-none-eabi -disassemble | FileCheck %s + +[0xaf,0xf3,0x14,0x80] +# CHECK: csdb -- 2.11.0