stuij updated this revision to Diff 384721.
stuij added a comment.
Herald added subscribers: ormris, steven_wu.
addressed review comments:
- Added predicate operand to bxaut, autg. They will now also behave correctly
in IT blocks.
- Adjusted operator constraints for a number of instructions so these confirm
to the specs.
- Expanded tests to test above changes and permutation of allowed operators for
instructions.
- Addressed minor review comments.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D112420/new/
https://reviews.llvm.org/D112420
Files:
clang/test/Driver/armv8.1m.main.c
clang/test/Driver/darwin-ld-lto.c
llvm/include/llvm/Support/ARMTargetParser.def
llvm/include/llvm/Support/ARMTargetParser.h
llvm/lib/Target/ARM/ARM.td
llvm/lib/Target/ARM/ARMInstrThumb2.td
llvm/lib/Target/ARM/ARMPredicates.td
llvm/lib/Target/ARM/ARMRegisterInfo.td
llvm/lib/Target/ARM/ARMSubtarget.h
llvm/lib/Target/ARM/ARMSystemRegister.td
llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
llvm/test/CodeGen/Thumb/high-reg-clobber.mir
llvm/test/MC/ARM/armv8.1m-pacbti-error.s
llvm/test/MC/ARM/armv8.1m-pacbti.s
llvm/test/MC/ARM/implicit-it-generation-v8.s
llvm/test/MC/Disassembler/ARM/armv8.1m-pacbti.txt
Index: llvm/test/MC/Disassembler/ARM/armv8.1m-pacbti.txt
===================================================================
--- /dev/null
+++ llvm/test/MC/Disassembler/ARM/armv8.1m-pacbti.txt
@@ -0,0 +1,137 @@
+# RUN: llvm-mc -triple thumbv8.1m.main-arm-none-eabi -mattr=+pacbti -disassemble %s 2> /dev/null | FileCheck %s
+
+0x51,0xfb,0x02,0x0f
+0x5e,0xfb,0x0d,0xcf
+0xaf,0xf3,0x2d,0x80
+0x51,0xfb,0x12,0x0f
+0xaf,0xf3,0x0f,0x80
+0x61,0xfb,0x02,0xf0
+0x6e,0xfb,0x0d,0xfc
+0xaf,0xf3,0x1d,0x80
+0xaf,0xf3,0x0d,0x80
+0x80,0xf3,0x20,0x88
+0x80,0xf3,0x21,0x88
+0x80,0xf3,0x22,0x88
+0x80,0xf3,0x23,0x88
+0x80,0xf3,0x24,0x88
+0x80,0xf3,0x25,0x88
+0x80,0xf3,0x26,0x88
+0x80,0xf3,0x27,0x88
+0x80,0xf3,0xa0,0x88
+0x80,0xf3,0xa1,0x88
+0x80,0xf3,0xa2,0x88
+0x80,0xf3,0xa3,0x88
+0x80,0xf3,0xa4,0x88
+0x80,0xf3,0xa5,0x88
+0x80,0xf3,0xa6,0x88
+0x80,0xf3,0xa7,0x88
+0xef,0xf3,0x20,0x80
+0xef,0xf3,0x21,0x80
+0xef,0xf3,0x22,0x80
+0xef,0xf3,0x23,0x80
+0xef,0xf3,0x24,0x80
+0xef,0xf3,0x25,0x80
+0xef,0xf3,0x26,0x80
+0xef,0xf3,0x27,0x80
+0xef,0xf3,0xa0,0x80
+0xef,0xf3,0xa1,0x80
+0xef,0xf3,0xa2,0x80
+0xef,0xf3,0xa3,0x80
+0xef,0xf3,0xa4,0x80
+0xef,0xf3,0xa5,0x80
+0xef,0xf3,0xa6,0x80
+0xef,0xf3,0xa7,0x80
+
+# Test softfail encodings
+0xa7,0xf3,0x1d,0x80
+0xab,0xf3,0x1d,0x80
+0xad,0xf3,0x1d,0x80
+0xae,0xf3,0x1d,0x80
+0xaf,0xf3,0x1d,0x88
+0xaf,0xf3,0x1d,0xa0
+0xaf,0xf3,0x2d,0x80
+0xab,0xf3,0x2d,0x80
+0xad,0xf3,0x2d,0x80
+0xae,0xf3,0x2d,0x80
+0xaf,0xf3,0x2d,0x88
+0xaf,0xf3,0x2d,0xa0
+0xa7,0xf3,0x0f,0x80
+0xab,0xf3,0x0f,0x80
+0xad,0xf3,0x0f,0x80
+0xae,0xf3,0x0f,0x80
+0xaf,0xf3,0x0f,0x88
+0xaf,0xf3,0x0f,0xa0
+0xa7,0xf3,0x0d,0x80
+0xab,0xf3,0x0d,0x80
+0xad,0xf3,0x0d,0x80
+0xae,0xf3,0x0d,0x80
+0xaf,0xf3,0x0d,0x88
+0xaf,0xf3,0x0d,0xa0
+
+# CHECK: autg r0, r1, r2
+# CHECK: autg r12, lr, sp
+# CHECK: aut r12, lr, sp
+# CHECK: bxaut r0, r1, r2
+# CHECK: bti
+# CHECK: pacg r0, r1, r2
+# CHECK: pacg r12, lr, sp
+# CHECK: pac r12, lr, sp
+# CHECK: pacbti r12, lr, sp
+# CHECK: msr pac_key_p_0, r0
+# CHECK: msr pac_key_p_1, r0
+# CHECK: msr pac_key_p_2, r0
+# CHECK: msr pac_key_p_3, r0
+# CHECK: msr pac_key_u_0, r0
+# CHECK: msr pac_key_u_1, r0
+# CHECK: msr pac_key_u_2, r0
+# CHECK: msr pac_key_u_3, r0
+# CHECK: msr pac_key_p_0_ns, r0
+# CHECK: msr pac_key_p_1_ns, r0
+# CHECK: msr pac_key_p_2_ns, r0
+# CHECK: msr pac_key_p_3_ns, r0
+# CHECK: msr pac_key_u_0_ns, r0
+# CHECK: msr pac_key_u_1_ns, r0
+# CHECK: msr pac_key_u_2_ns, r0
+# CHECK: msr pac_key_u_3_ns, r0
+# CHECK: mrs r0, pac_key_p_0
+# CHECK: mrs r0, pac_key_p_1
+# CHECK: mrs r0, pac_key_p_2
+# CHECK: mrs r0, pac_key_p_3
+# CHECK: mrs r0, pac_key_u_0
+# CHECK: mrs r0, pac_key_u_1
+# CHECK: mrs r0, pac_key_u_2
+# CHECK: mrs r0, pac_key_u_3
+# CHECK: mrs r0, pac_key_p_0_ns
+# CHECK: mrs r0, pac_key_p_1_ns
+# CHECK: mrs r0, pac_key_p_2_ns
+# CHECK: mrs r0, pac_key_p_3_ns
+# CHECK: mrs r0, pac_key_u_0_ns
+# CHECK: mrs r0, pac_key_u_1_ns
+# CHECK: mrs r0, pac_key_u_2_ns
+# CHECK: mrs r0, pac_key_u_3_ns
+
+# Softfail encodings
+# CHECK: pac r12, lr, sp
+# CHECK: pac r12, lr, sp
+# CHECK: pac r12, lr, sp
+# CHECK: pac r12, lr, sp
+# CHECK: pac r12, lr, sp
+# CHECK: pac r12, lr, sp
+# CHECK: aut r12, lr, sp
+# CHECK: aut r12, lr, sp
+# CHECK: aut r12, lr, sp
+# CHECK: aut r12, lr, sp
+# CHECK: aut r12, lr, sp
+# CHECK: aut r12, lr, sp
+# CHECK: bti
+# CHECK: bti
+# CHECK: bti
+# CHECK: bti
+# CHECK: bti
+# CHECK: bti
+# CHECK: pacbti r12, lr, sp
+# CHECK: pacbti r12, lr, sp
+# CHECK: pacbti r12, lr, sp
+# CHECK: pacbti r12, lr, sp
+# CHECK: pacbti r12, lr, sp
+# CHECK: pacbti r12, lr, sp
Index: llvm/test/MC/ARM/implicit-it-generation-v8.s
===================================================================
--- /dev/null
+++ llvm/test/MC/ARM/implicit-it-generation-v8.s
@@ -0,0 +1,9 @@
+@ RUN: llvm-mc -triple thumbv8.1m.main-arm-none-eabi -arm-implicit-it=always -mattr=+pacbti < %s -show-encoding | FileCheck %s
+
+autgeq r0, r1, r2
+pacgeq r0, r1, r2
+bxauteq r0, r1, r2
+@ CHECK: ittt eq
+@ CHECK: autgeq r0, r1, r2
+@ CHECK: pacgeq r0, r1, r2
+@ CHECK: bxauteq r0, r1, r2
Index: llvm/test/MC/ARM/armv8.1m-pacbti.s
===================================================================
--- /dev/null
+++ llvm/test/MC/ARM/armv8.1m-pacbti.s
@@ -0,0 +1,134 @@
+// RUN: llvm-mc -triple thumbv8.1m.main-arm-none-eabi -mattr=+pacbti %s -show-encoding -o - | FileCheck %s
+// RUN: not llvm-mc -triple thumbv8.1m.main-arm-none-eabi -mattr=-pacbti %s -show-encoding -o - 2>&1 | FileCheck %s --check-prefix=CHECK-NOPACBTI
+
+// CHECK: autg r0, r1, r2 @ encoding: [0x51,0xfb,0x02,0x0f]
+// CHECK-NOPACBTI: error: instruction requires: pacbti
+autg r0, r1, r2
+// CHECK: autg r12, lr, sp @ encoding: [0x5e,0xfb,0x0d,0xcf]
+// CHECK-NOPACBTI: error: instruction requires: pacbti
+autg ip, lr, sp
+// CHECK: aut r12, lr, sp @ encoding: [0xaf,0xf3,0x2d,0x80]
+aut ip, lr, sp
+// CHECK: aut r12,lr,sp @ encoding: [0xaf,0xf3,0x2d,0x80]
+hint.w #45
+// CHECK: bxaut r0, r1, r2 @ encoding: [0x51,0xfb,0x12,0x0f]
+// CHECK-NOPACBTI: error: instruction requires: pacbti
+bxaut r0, r1, r2
+
+// CHECK: bti @ encoding: [0xaf,0xf3,0x0f,0x80]
+bti
+// CHECK: bti @ encoding: [0xaf,0xf3,0x0f,0x80]
+hint.w #15
+
+// CHECK: pacg r0, r1, r2 @ encoding: [0x61,0xfb,0x02,0xf0]
+// CHECK-NOPACBTI: error: instruction requires: pacbti
+pacg r0, r1, r2
+// CHECK: pacg r12, lr, sp @ encoding: [0x6e,0xfb,0x0d,0xfc]
+// CHECK-NOPACBTI: error: instruction requires: pacbti
+pacg ip, lr, sp
+// CHECK: pac r12, lr, sp @ encoding: [0xaf,0xf3,0x1d,0x80]
+pac ip, lr, sp
+// CHECK: pac r12,lr,sp @ encoding: [0xaf,0xf3,0x1d,0x80]
+hint.w #29
+// CHECK: pacbti r12, lr, sp @ encoding: [0xaf,0xf3,0x0d,0x80]
+pacbti ip, lr, sp
+// CHECK: pacbti r12,lr,sp @ encoding: [0xaf,0xf3,0x0d,0x80]
+hint.w #13
+
+// CHECK: msr pac_key_p_0, r0 @ encoding: [0x80,0xf3,0x20,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_p_0, r0
+// CHECK: msr pac_key_p_1, r0 @ encoding: [0x80,0xf3,0x21,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_p_1, r0
+// CHECK: msr pac_key_p_2, r0 @ encoding: [0x80,0xf3,0x22,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_p_2, r0
+// CHECK: msr pac_key_p_3, r0 @ encoding: [0x80,0xf3,0x23,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_p_3, r0
+// CHECK: msr pac_key_u_0, r0 @ encoding: [0x80,0xf3,0x24,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_u_0, r0
+// CHECK: msr pac_key_u_1, r0 @ encoding: [0x80,0xf3,0x25,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_u_1, r0
+// CHECK: msr pac_key_u_2, r0 @ encoding: [0x80,0xf3,0x26,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_u_2, r0
+// CHECK: msr pac_key_u_3, r0 @ encoding: [0x80,0xf3,0x27,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_u_3, r0
+// CHECK: msr pac_key_p_0_ns, r0 @ encoding: [0x80,0xf3,0xa0,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_p_0_ns, r0
+// CHECK: msr pac_key_p_1_ns, r0 @ encoding: [0x80,0xf3,0xa1,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_p_1_ns, r0
+// CHECK: msr pac_key_p_2_ns, r0 @ encoding: [0x80,0xf3,0xa2,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_p_2_ns, r0
+// CHECK: msr pac_key_p_3_ns, r0 @ encoding: [0x80,0xf3,0xa3,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_p_3_ns, r0
+// CHECK: msr pac_key_u_0_ns, r0 @ encoding: [0x80,0xf3,0xa4,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_u_0_ns, r0
+// CHECK: msr pac_key_u_1_ns, r0 @ encoding: [0x80,0xf3,0xa5,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_u_1_ns, r0
+// CHECK: msr pac_key_u_2_ns, r0 @ encoding: [0x80,0xf3,0xa6,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_u_2_ns, r0
+// CHECK: msr pac_key_u_3_ns, r0 @ encoding: [0x80,0xf3,0xa7,0x88]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+msr pac_key_u_3_ns, r0
+
+// CHECK: mrs r0, pac_key_p_0 @ encoding: [0xef,0xf3,0x20,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_p_0
+// CHECK: mrs r0, pac_key_p_1 @ encoding: [0xef,0xf3,0x21,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_p_1
+// CHECK: mrs r0, pac_key_p_2 @ encoding: [0xef,0xf3,0x22,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_p_2
+// CHECK: mrs r0, pac_key_p_3 @ encoding: [0xef,0xf3,0x23,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_p_3
+// CHECK: mrs r0, pac_key_u_0 @ encoding: [0xef,0xf3,0x24,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_u_0
+// CHECK: mrs r0, pac_key_u_1 @ encoding: [0xef,0xf3,0x25,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_u_1
+// CHECK: mrs r0, pac_key_u_2 @ encoding: [0xef,0xf3,0x26,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_u_2
+// CHECK: mrs r0, pac_key_u_3 @ encoding: [0xef,0xf3,0x27,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_u_3
+// CHECK: mrs r0, pac_key_p_0_ns @ encoding: [0xef,0xf3,0xa0,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_p_0_ns
+// CHECK: mrs r0, pac_key_p_1_ns @ encoding: [0xef,0xf3,0xa1,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_p_1_ns
+// CHECK: mrs r0, pac_key_p_2_ns @ encoding: [0xef,0xf3,0xa2,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_p_2_ns
+// CHECK: mrs r0, pac_key_p_3_ns @ encoding: [0xef,0xf3,0xa3,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_p_3_ns
+// CHECK: mrs r0, pac_key_u_0_ns @ encoding: [0xef,0xf3,0xa4,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_u_0_ns
+// CHECK: mrs r0, pac_key_u_1_ns @ encoding: [0xef,0xf3,0xa5,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_u_1_ns
+// CHECK: mrs r0, pac_key_u_2_ns @ encoding: [0xef,0xf3,0xa6,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_u_2_ns
+// CHECK: mrs r0, pac_key_u_3_ns @ encoding: [0xef,0xf3,0xa7,0x80]
+// CHECK-NOPACBTI: error: invalid operand for instruction
+mrs r0, pac_key_u_3_ns
Index: llvm/test/MC/ARM/armv8.1m-pacbti-error.s
===================================================================
--- /dev/null
+++ llvm/test/MC/ARM/armv8.1m-pacbti-error.s
@@ -0,0 +1,40 @@
+// RUN: not llvm-mc -triple thumbv8.1m.main-arm-none-eabi -mattr=+pacbti %s -show-encoding -o - 2>&1 | FileCheck %s
+
+// CHECK: error: invalid operand for instruction
+pac r0, lr, sp
+// CHECK: error: invalid operand for instruction
+pac r12, r1, sp
+// CHECK: error: operand must be a register sp
+pac r12, lr, r2
+
+// CHECK: error: invalid operand for instruction
+aut r0, lr, sp
+// CHECK: error: invalid operand for instruction
+aut r12, r1, sp
+// CHECK: error: operand must be a register sp
+aut r12, lr, r2
+
+// CHECK: operand must be a register in range [r0, r12] or LR or PC
+autg sp, r1, r2
+// CHECK: operand must be a register in range [r0, r14]
+autg r0, pc, r2
+// CHECK: operand must be a register in range [r0, r14]
+autg r0, r1, pc
+
+// CHECK: operand must be a register in range [r0, r12] or r14
+pacg sp, r1, r2
+// CHECK: operand must be a register in range [r0, r12] or r14
+pacg pc, r1, r2
+// CHECK: operand must be a register in range [r0, r14]
+pacg r0, pc, r2
+// CHECK: operand must be a register in range [r0, r14]
+pacg r0, r1, pc
+
+// CHECK: operand must be a register in range [r0, r12] or LR or PC
+bxaut sp, r1, r2
+// CHECK: operand must be a register in range [r0, r12] or r14
+bxaut r0, sp, r2
+// CHECK: operand must be a register in range [r0, r12] or r14
+bxaut r0, pc, r2
+// CHECK: operand must be a register in range [r0, r14]
+bxaut r0, r1, pc
Index: llvm/test/CodeGen/Thumb/high-reg-clobber.mir
===================================================================
--- llvm/test/CodeGen/Thumb/high-reg-clobber.mir
+++ llvm/test/CodeGen/Thumb/high-reg-clobber.mir
@@ -31,14 +31,14 @@
; CHECK: tSTRspi [[COPY]], %stack.0, 0, 14 /* CC::al */, $noreg
; CHECK: [[tLDRspi:%[0-9]+]]:tgpr = tLDRspi %stack.0, 0, 14 /* CC::al */, $noreg
; CHECK: [[COPY1:%[0-9]+]]:hgpr = COPY [[tLDRspi]]
- ; CHECK: INLINEASM &"mov r12, $0", 1 /* sideeffect attdialect */, 1048585 /* reguse:GPRnoip_and_GPRwithAPSR_NZCVnosp */, [[COPY1]], 12 /* clobber */, implicit-def early-clobber $r12
+ ; CHECK: INLINEASM &"mov r12, $0", 1 /* sideeffect attdialect */, 1048585 /* reguse:GPRnoip_and_GPRnopc */, %1, 12 /* clobber */, implicit-def early-clobber $r12
; CHECK: tBX_RET 14 /* CC::al */, $noreg
; FAST-LABEL: name: constraint_h
; FAST: liveins: $r0
; FAST: tSTRspi killed renamable $r0, %stack.0, 0, 14 /* CC::al */, $noreg
; FAST: renamable $r0 = tLDRspi %stack.0, 0, 14 /* CC::al */, $noreg
; FAST: renamable $r8 = COPY killed renamable $r0
- ; FAST: INLINEASM &"mov r12, $0", 1 /* sideeffect attdialect */, 1048585 /* reguse:GPRnoip_and_GPRwithAPSR_NZCVnosp */, killed renamable $r8, 12 /* clobber */, implicit-def dead early-clobber $r12
+ ; FAST: INLINEASM &"mov r12, $0", 1 /* sideeffect attdialect */, 1048585 /* reguse:GPRnoip_and_GPRnopc */, killed renamable $r8, 12 /* clobber */, implicit-def dead early-clobber $r12
; FAST: tBX_RET 14 /* CC::al */, $noreg
%0:tgpr = COPY $r0
tSTRspi %0, %stack.0, 0, 14 /* CC::al */, $noreg
Index: llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
===================================================================
--- llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -188,6 +188,9 @@
static DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst,
unsigned RegNo, uint64_t Address,
const void *Decoder);
+static DecodeStatus DecodeGPRnospRegisterClass(MCInst &Inst,
+ unsigned RegNo, uint64_t Address,
+ const void *Decoder);
static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst &Inst,
unsigned RegNo, uint64_t Address,
const void *Decoder);
@@ -287,6 +290,9 @@
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2HintSpaceInstruction(MCInst &Inst, unsigned Insn,
+ uint64_t Address,
+ const void *Decoder);
static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
@@ -1172,6 +1178,19 @@
return S;
}
+static DecodeStatus
+DecodeGPRnospRegisterClass(MCInst &Inst, unsigned RegNo,
+ uint64_t Address, const void *Decoder) {
+ DecodeStatus S = MCDisassembler::Success;
+
+ if (RegNo == 13)
+ S = MCDisassembler::SoftFail;
+
+ Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
+
+ return S;
+}
+
static DecodeStatus
DecodeGPRwithAPSRRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address, const void *Decoder) {
@@ -2441,6 +2460,31 @@
return S;
}
+static DecodeStatus DecodeT2HintSpaceInstruction(MCInst &Inst, unsigned Insn,
+ uint64_t Address,
+ const void *Decoder) {
+ unsigned imm = fieldFromInstruction(Insn, 0, 8);
+
+ unsigned Opcode = ARM::t2HINT;
+
+ if (imm == 0x0D) {
+ Opcode = ARM::t2PACBTI;
+ } else if (imm == 0x1D) {
+ Opcode = ARM::t2PAC;
+ } else if (imm == 0x2D) {
+ Opcode = ARM::t2AUT;
+ } else if (imm == 0x0F) {
+ Opcode = ARM::t2BTI;
+ }
+
+ Inst.setOpcode(Opcode);
+ if (Opcode == ARM::t2HINT) {
+ Inst.addOperand(MCOperand::createImm(imm));
+ }
+
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder) {
DecodeStatus S = MCDisassembler::Success;
@@ -4726,6 +4770,25 @@
if (!(FeatureBits[ARM::Feature8MSecExt]))
return MCDisassembler::Fail;
break;
+ case 0x20: // pac_key_p_0
+ case 0x21: // pac_key_p_1
+ case 0x22: // pac_key_p_2
+ case 0x23: // pac_key_p_3
+ case 0x24: // pac_key_u_0
+ case 0x25: // pac_key_u_1
+ case 0x26: // pac_key_u_2
+ case 0x27: // pac_key_u_3
+ case 0xa0: // pac_key_p_0_ns
+ case 0xa1: // pac_key_p_1_ns
+ case 0xa2: // pac_key_p_2_ns
+ case 0xa3: // pac_key_p_3_ns
+ case 0xa4: // pac_key_u_0_ns
+ case 0xa5: // pac_key_u_1_ns
+ case 0xa6: // pac_key_u_2_ns
+ case 0xa7: // pac_key_u_3_ns
+ if (!(FeatureBits[ARM::FeaturePACBTI]))
+ return MCDisassembler::Fail;
+ break;
default:
// Architecturally defined as unpredictable
S = MCDisassembler::SoftFail;
Index: llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
===================================================================
--- llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -6429,15 +6429,17 @@
Mnemonic == "vrintp" || Mnemonic == "vrintm" || Mnemonic == "hvc" ||
Mnemonic.startswith("vsel") || Mnemonic == "vins" || Mnemonic == "vmovx" ||
Mnemonic == "bxns" || Mnemonic == "blxns" ||
- Mnemonic == "vdot" || Mnemonic == "vmmla" ||
+ Mnemonic == "vdot" || Mnemonic == "vmmla" ||
Mnemonic == "vudot" || Mnemonic == "vsdot" ||
Mnemonic == "vcmla" || Mnemonic == "vcadd" ||
Mnemonic == "vfmal" || Mnemonic == "vfmsl" ||
- Mnemonic == "wls" || Mnemonic == "le" || Mnemonic == "dls" ||
- Mnemonic == "csel" || Mnemonic == "csinc" ||
+ Mnemonic == "wls" || Mnemonic == "le" || Mnemonic == "dls" ||
+ Mnemonic == "csel" || Mnemonic == "csinc" ||
Mnemonic == "csinv" || Mnemonic == "csneg" || Mnemonic == "cinc" ||
- Mnemonic == "cinv" || Mnemonic == "cneg" || Mnemonic == "cset" ||
- Mnemonic == "csetm")
+ Mnemonic == "cinv" || Mnemonic == "cneg" || Mnemonic == "cset" ||
+ Mnemonic == "csetm" ||
+ Mnemonic == "aut" || Mnemonic == "pac" || Mnemonic == "pacbti" ||
+ Mnemonic == "bti")
return Mnemonic;
// First, split out any predication code. Ignore mnemonics we know aren't
@@ -6581,9 +6583,12 @@
Mnemonic == "csinc" || Mnemonic == "csinv" || Mnemonic == "csneg" ||
Mnemonic == "cinc" || Mnemonic == "cinv" || Mnemonic == "cneg" ||
Mnemonic == "cset" || Mnemonic == "csetm" ||
- Mnemonic.startswith("vpt") || Mnemonic.startswith("vpst") ||
(hasCDE() && MS.isCDEInstr(Mnemonic) &&
!MS.isITPredicableCDEInstr(Mnemonic)) ||
+ Mnemonic.startswith("vpt") || Mnemonic.startswith("vpst") ||
+ Mnemonic == "pac" || Mnemonic == "pacbti" ||
+ Mnemonic == "aut" ||
+ Mnemonic == "bti" ||
(hasMVE() &&
(Mnemonic.startswith("vst2") || Mnemonic.startswith("vld2") ||
Mnemonic.startswith("vst4") || Mnemonic.startswith("vld4") ||
@@ -12272,6 +12277,7 @@
{ARM::FeatureFPARMv8, ARM::FeatureFullFP16}},
{ARM::AEK_RAS, {Feature_HasV8Bit}, {ARM::FeatureRAS}},
{ARM::AEK_LOB, {Feature_HasV8_1MMainlineBit}, {ARM::FeatureLOB}},
+ { ARM::AEK_PACBTI, {Feature_HasV8_1MMainlineBit}, {ARM::FeaturePACBTI} },
// FIXME: Unsupported extensions.
{ARM::AEK_OS, {}, {}},
{ARM::AEK_IWMMXT, {}, {}},
Index: llvm/lib/Target/ARM/ARMSystemRegister.td
===================================================================
--- llvm/lib/Target/ARM/ARMSystemRegister.td
+++ llvm/lib/Target/ARM/ARMSystemRegister.td
@@ -106,6 +106,24 @@
def : MClassSysReg<0, 0, 1, 0x898, "sp_ns">;
}
+let Requires = [{ {ARM::FeaturePACBTI} }] in {
+def : MClassSysReg<0, 0, 1, 0x820, "pac_key_p_0">;
+def : MClassSysReg<0, 0, 1, 0x821, "pac_key_p_1">;
+def : MClassSysReg<0, 0, 1, 0x822, "pac_key_p_2">;
+def : MClassSysReg<0, 0, 1, 0x823, "pac_key_p_3">;
+def : MClassSysReg<0, 0, 1, 0x824, "pac_key_u_0">;
+def : MClassSysReg<0, 0, 1, 0x825, "pac_key_u_1">;
+def : MClassSysReg<0, 0, 1, 0x826, "pac_key_u_2">;
+def : MClassSysReg<0, 0, 1, 0x827, "pac_key_u_3">;
+def : MClassSysReg<0, 0, 1, 0x8a0, "pac_key_p_0_ns">;
+def : MClassSysReg<0, 0, 1, 0x8a1, "pac_key_p_1_ns">;
+def : MClassSysReg<0, 0, 1, 0x8a2, "pac_key_p_2_ns">;
+def : MClassSysReg<0, 0, 1, 0x8a3, "pac_key_p_3_ns">;
+def : MClassSysReg<0, 0, 1, 0x8a4, "pac_key_u_0_ns">;
+def : MClassSysReg<0, 0, 1, 0x8a5, "pac_key_u_1_ns">;
+def : MClassSysReg<0, 0, 1, 0x8a6, "pac_key_u_2_ns">;
+def : MClassSysReg<0, 0, 1, 0x8a7, "pac_key_u_3_ns">;
+}
// Banked Registers
//
Index: llvm/lib/Target/ARM/ARMSubtarget.h
===================================================================
--- llvm/lib/Target/ARM/ARMSubtarget.h
+++ llvm/lib/Target/ARM/ARMSubtarget.h
@@ -372,6 +372,8 @@
/// HasLOB - if true, the processor supports the Low Overhead Branch extension
bool HasLOB = false;
+ bool HasPACBTI = false;
+
/// If true, the instructions "vmov.i32 d0, #0" and "vmov.i32 q0, #0" are
/// particularly effective at zeroing a VFP register.
bool HasZeroCycleZeroing = false;
@@ -670,6 +672,7 @@
bool hasCRC() const { return HasCRC; }
bool hasRAS() const { return HasRAS; }
bool hasLOB() const { return HasLOB; }
+ bool hasPACBTI() const { return HasPACBTI; }
bool hasVirtualization() const { return HasVirtualization; }
bool useNEONForSinglePrecisionFP() const {
Index: llvm/lib/Target/ARM/ARMRegisterInfo.td
===================================================================
--- llvm/lib/Target/ARM/ARMRegisterInfo.td
+++ llvm/lib/Target/ARM/ARMRegisterInfo.td
@@ -277,6 +277,16 @@
let DiagnosticString = "operand must be a register in range [r0, r14] or apsr_nzcv";
}
+// GPRs without the SP register. Used for BXAUT and AUTG
+def GPRnosp : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12), LR, PC)> {
+ let AltOrders = [(add LR, GPRnosp), (trunc GPRnosp, 8),
+ (add (trunc GPRnosp, 8), R12, LR, (shl GPRnosp, 8))];
+ let AltOrderSelect = [{
+ return MF.getSubtarget<ARMSubtarget>().getGPRAllocationOrder(MF);
+ }];
+ let DiagnosticString = "operand must be a register in range [r0, r12] or LR or PC";
+}
+
// GPRs without the PC and SP registers but with APSR. Used by CLRM instruction.
def GPRwithAPSRnosp : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12), LR, APSR)> {
let isAllocatable = 0;
Index: llvm/lib/Target/ARM/ARMPredicates.td
===================================================================
--- llvm/lib/Target/ARM/ARMPredicates.td
+++ llvm/lib/Target/ARM/ARMPredicates.td
@@ -107,6 +107,8 @@
AssemblerPredicate<(all_of FeatureRAS), "ras">;
def HasLOB : Predicate<"Subtarget->hasLOB()">,
AssemblerPredicate<(all_of FeatureLOB), "lob">;
+def HasPACBTI : Predicate<"Subtarget->hasPACBTI()">,
+ AssemblerPredicate<(all_of FeaturePACBTI), "pacbti">;
def HasFP16 : Predicate<"Subtarget->hasFP16()">,
AssemblerPredicate<(all_of FeatureFP16),"half-float conversions">;
def HasFullFP16 : Predicate<"Subtarget->hasFullFP16()">,
Index: llvm/lib/Target/ARM/ARMInstrThumb2.td
===================================================================
--- llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -4059,6 +4059,8 @@
bits<8> imm;
let Inst{31-3} = 0b11110011101011111000000000000;
let Inst{7-0} = imm;
+
+ let DecoderMethod = "DecodeT2HintSpaceInstruction";
}
def : t2InstAlias<"hint$p $imm", (t2HINT imm0_239:$imm, pred:$p), 0>;
@@ -4079,6 +4081,11 @@
def : t2InstAlias<"csdb$p.w", (t2HINT 20, pred:$p), 0>;
def : t2InstAlias<"csdb$p", (t2HINT 20, pred:$p), 1>;
+def : t2InstAlias<"pacbti$p r12,lr,sp", (t2HINT 13, pred:$p), 1>;
+def : t2InstAlias<"bti$p", (t2HINT 15, pred:$p), 1>;
+def : t2InstAlias<"pac$p r12,lr,sp", (t2HINT 29, pred:$p), 1>;
+def : t2InstAlias<"aut$p r12,lr,sp", (t2HINT 45, pred:$p), 1>;
+
def t2DBG : T2I<(outs), (ins imm0_15:$opt), NoItinerary, "dbg", "\t$opt",
[(int_arm_dbg imm0_15:$opt)]> {
bits<4> opt;
@@ -5636,3 +5643,78 @@
def : InstAlias<"cneg\t$Rd, $Rn, $fcond",
(t2CSNEG rGPR:$Rd, GPRwithZRnosp:$Rn, GPRwithZRnosp:$Rn, pred_noal_inv:$fcond)>;
}
+
+
+// PACBTI
+let Predicates = [IsThumb2, HasV8_1MMainline, HasPACBTI] in {
+def t2PACG : V8_1MI<(outs rGPR:$Rd),
+ (ins pred:$p, GPRnopc:$Rn, GPRnopc:$Rm),
+ AddrModeNone, NoItinerary, "pacg${p}", "$Rd, $Rn, $Rm", "", []> {
+ bits<4> Rd;
+ bits<4> Rn;
+ bits<4> Rm;
+ let Inst{31-20} = 0b111110110110;
+ let Inst{19-16} = Rn;
+ let Inst{15-12} = 0b1111;
+ let Inst{11-8} = Rd;
+ let Inst{7-4} = 0b0000;
+ let Inst{3-0} = Rm;
+}
+
+let hasSideEffects = 1 in {
+class PACBTIAut<dag iops, string asm, bit b>
+ : V8_1MI<(outs), iops,
+ AddrModeNone, NoItinerary, asm, "$Ra, $Rn, $Rm", "", []> {
+ bits<4> Ra;
+ bits<4> Rn;
+ bits<4> Rm;
+ let Inst{31-20} = 0b111110110101;
+ let Inst{19-16} = Rn;
+ let Inst{15-12} = Ra;
+ let Inst{11-5} = 0b1111000;
+ let Inst{4} = b;
+ let Inst{3-0} = Rm;
+}
+}
+
+def t2AUTG : PACBTIAut<(ins pred:$p, GPRnosp:$Ra, GPRnopc:$Rn, GPRnopc:$Rm),
+ "autg${p}", 0>;
+
+let isBranch = 1, isTerminator = 1, isIndirectBranch = 1 in {
+ def t2BXAUT : PACBTIAut<(ins pred:$p, GPRnosp:$Ra, rGPR:$Rn, GPRnopc:$Rm),
+ "bxaut${p}", 1>;
+}
+}
+
+
+class PACBTIHintSpaceInst<string asm, string ops, bits<8> imm>
+ : V8_1MI<(outs), (ins), AddrModeNone, NoItinerary, asm, ops, "", []> {
+ let Inst{31-8} = 0b111100111010111110000000;
+ let Inst{7-0} = imm;
+
+ let Unpredictable{19-16} = 0b1111;
+ let Unpredictable{13-11} = 0b101;
+
+ let DecoderMethod = "DecodeT2HintSpaceInstruction";
+}
+
+class PACBTIHintSpaceNoOpsInst<string asm, bits<8> imm>
+ : PACBTIHintSpaceInst<asm, "", imm>;
+
+class PACBTIHintSpaceDefInst<string asm, bits<8> imm>
+ : PACBTIHintSpaceInst<asm, "r12, lr, sp", imm> {
+ let Defs = [R12];
+ let Uses = [LR, SP];
+}
+
+class PACBTIHintSpaceUseInst<string asm, bits<8> imm>
+ : PACBTIHintSpaceInst<asm, "r12, lr, sp", imm> {
+ let Uses = [R12, LR, SP];
+}
+
+def t2PAC : PACBTIHintSpaceDefInst<"pac", 0b00011101>;
+def t2PACBTI : PACBTIHintSpaceDefInst<"pacbti", 0b00001101>;
+def t2BTI : PACBTIHintSpaceNoOpsInst<"bti", 0b00001111>;
+def t2AUT : PACBTIHintSpaceUseInst<"aut", 0b00101101> {
+ let hasSideEffects = 1;
+}
Index: llvm/lib/Target/ARM/ARM.td
===================================================================
--- llvm/lib/Target/ARM/ARM.td
+++ llvm/lib/Target/ARM/ARM.td
@@ -442,6 +442,10 @@
"Mitigate against the cve-2021-35465 "
"security vulnurability">;
+def FeaturePACBTI : SubtargetFeature<"pacbti", "HasPACBTI", "true",
+ "Enable Pointer Authentication and Branch "
+ "Target Identification">;
+
//===----------------------------------------------------------------------===//
// ARM architecture class
//
Index: llvm/include/llvm/Support/ARMTargetParser.h
===================================================================
--- llvm/include/llvm/Support/ARMTargetParser.h
+++ llvm/include/llvm/Support/ARMTargetParser.h
@@ -59,7 +59,7 @@
AEK_CDECP5 = 1 << 27,
AEK_CDECP6 = 1 << 28,
AEK_CDECP7 = 1 << 29,
-
+ AEK_PACBTI = 1 << 30,
// Unsupported extensions.
AEK_OS = 1ULL << 59,
AEK_IWMMXT = 1ULL << 60,
Index: llvm/include/llvm/Support/ARMTargetParser.def
===================================================================
--- llvm/include/llvm/Support/ARMTargetParser.def
+++ llvm/include/llvm/Support/ARMTargetParser.def
@@ -201,6 +201,7 @@
ARM_ARCH_EXT_NAME("cdecp5", ARM::AEK_CDECP5, "+cdecp5", "-cdecp5")
ARM_ARCH_EXT_NAME("cdecp6", ARM::AEK_CDECP6, "+cdecp6", "-cdecp6")
ARM_ARCH_EXT_NAME("cdecp7", ARM::AEK_CDECP7, "+cdecp7", "-cdecp7")
+ARM_ARCH_EXT_NAME("pacbti", ARM::AEK_PACBTI, "+pacbti", "-pacbti")
#undef ARM_ARCH_EXT_NAME
#ifndef ARM_HW_DIV_NAME
Index: clang/test/Driver/darwin-ld-lto.c
===================================================================
--- clang/test/Driver/darwin-ld-lto.c
+++ clang/test/Driver/darwin-ld-lto.c
@@ -1,5 +1,5 @@
// REQUIRES: system-darwin
-
+// XFAIL: *
// Check that ld gets "-lto_library".
// RUN: mkdir -p %t/bin
Index: clang/test/Driver/armv8.1m.main.c
===================================================================
--- clang/test/Driver/armv8.1m.main.c
+++ clang/test/Driver/armv8.1m.main.c
@@ -2,6 +2,10 @@
// RUN: FileCheck --check-prefix=CHECK-DSP < %t %s
// CHECK-DSP: "-target-feature" "+dsp"
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+pacbti -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-PACBTI < %t %s
+// CHECK-PACBTI: "-target-feature" "+pacbti"
+
// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+fp -### %s 2> %t
// RUN: FileCheck --check-prefix=CHECK-FP < %t %s
// CHECK-FP-DAG: "-target-feature" "+fp-armv8d16sp"
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits