Index: include/llvm/IR/IntrinsicsAArch64.td =================================================================== --- include/llvm/IR/IntrinsicsAArch64.td +++ include/llvm/IR/IntrinsicsAArch64.td @@ -33,6 +33,11 @@ LLVMMatchType<0>], [IntrNoMem]>; //===----------------------------------------------------------------------===// +// HINT + +def int_aarch64_hint : Intrinsic<[], [llvm_i32_ty]>; + +//===----------------------------------------------------------------------===// // RBIT def int_aarch64_rbit : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], Index: lib/Target/AArch64/AArch64InstrFormats.td =================================================================== --- lib/Target/AArch64/AArch64InstrFormats.td +++ lib/Target/AArch64/AArch64InstrFormats.td @@ -764,15 +764,17 @@ // Base encoding for system instruction operands. let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in -class BaseSystemI - : I { +class BaseSystemI pattern = []> + : I { let Inst{31-22} = 0b1101010100; let Inst{21} = L; } // System instructions which do not have an Rt register. -class SimpleSystemI - : BaseSystemI { +class SimpleSystemI pattern = []> + : BaseSystemI { let Inst{4-0} = 0b11111; } @@ -785,13 +787,17 @@ } // Hint instructions that take both a CRm and a 3-bit immediate. -class HintI - : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#" $imm", "">, - Sched<[WriteHint]> { - bits <7> imm; - let Inst{20-12} = 0b000110010; - let Inst{11-5} = imm; -} +// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot +// model patterns with sufficiently fine granularity +let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in + class HintI + : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#" $imm", "", + [(int_aarch64_hint imm0_127:$imm)]>, + Sched<[WriteHint]> { + bits <7> imm; + let Inst{20-12} = 0b000110010; + let Inst{11-5} = imm; + } // System instructions taking a single literal operand which encodes into // CRm. op2 differentiates the opcodes. Index: test/CodeGen/AArch64/hints.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/hints.ll @@ -0,0 +1,67 @@ +; RUN: llc -mtriple aarch64-eabi -o - %s | FileCheck %s + +declare void @llvm.aarch64.hint(i32) nounwind + +define void @hint_nop() { +entry: + tail call void @llvm.aarch64.hint(i32 0) nounwind + ret void +} + +; CHECK-LABEL: hint_nop +; CHECK: nop + +define void @hint_yield() { +entry: + tail call void @llvm.aarch64.hint(i32 1) nounwind + ret void +} + +; CHECK-LABEL: hint_yield +; CHECK: yield + +define void @hint_wfe() { +entry: + tail call void @llvm.aarch64.hint(i32 2) nounwind + ret void +} + +; CHECK-LABEL: hint_wfe +; CHECK: wfe + +define void @hint_wfi() { +entry: + tail call void @llvm.aarch64.hint(i32 3) nounwind + ret void +} + +; CHECK-LABEL: hint_wfi +; CHECK: wfi + +define void @hint_sev() { +entry: + tail call void @llvm.aarch64.hint(i32 4) nounwind + ret void +} + +; CHECK-LABEL: hint_sev +; CHECK: sev + +define void @hint_sevl() { +entry: + tail call void @llvm.aarch64.hint(i32 5) nounwind + ret void +} + +; CHECK-LABEL: hint_sevl +; CHECK: sevl + +define void @hint_undefined() { +entry: + tail call void @llvm.aarch64.hint(i32 8) nounwind + ret void +} + +; CHECK-LABEL: hint_undefined +; CHECK: hint #0x8 +