Index: include/llvm/IR/IntrinsicsARM.td =================================================================== --- include/llvm/IR/IntrinsicsARM.td +++ include/llvm/IR/IntrinsicsARM.td @@ -124,6 +124,8 @@ // HINT def int_arm_sevl : Intrinsic<[], []>; +def int_arm_hint : Intrinsic<[], [llvm_i32_ty]>; + //===----------------------------------------------------------------------===// // Advanced SIMD (NEON) Index: lib/Target/ARM/ARMInstrInfo.td =================================================================== --- lib/Target/ARM/ARMInstrInfo.td +++ lib/Target/ARM/ARMInstrInfo.td @@ -1842,6 +1842,13 @@ def : Pat<(int_arm_sevl), (HINT 5)>; +def : Pat<(int_arm_hint 0), (HINT 0)>; +def : Pat<(int_arm_hint 1), (HINT 1)>; +def : Pat<(int_arm_hint 2), (HINT 2)>; +def : Pat<(int_arm_hint 3), (HINT 3)>; +def : Pat<(int_arm_hint 4), (HINT 4)>; +def : Pat<(int_arm_hint 5), (HINT 5)>; + def SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel", "\t$Rd, $Rn, $Rm", []>, Requires<[IsARM, HasV6]> { bits<4> Rd; Index: lib/Target/ARM/ARMInstrThumb.td =================================================================== --- lib/Target/ARM/ARMInstrThumb.td +++ lib/Target/ARM/ARMInstrThumb.td @@ -288,8 +288,16 @@ def : tInstAlias<"sevl$p", (tHINT 5, pred:$p)> { let Predicates = [IsThumb2, HasV8]; } + def : T2Pat<(int_arm_sevl), (tHINT 5)>; +def : T2Pat<(int_arm_hint 0), (tHINT 0)>; +def : T2Pat<(int_arm_hint 1), (tHINT 1)>; +def : T2Pat<(int_arm_hint 2), (tHINT 2)>; +def : T2Pat<(int_arm_hint 3), (tHINT 3)>; +def : T2Pat<(int_arm_hint 4), (tHINT 4)>; +def : T2Pat<(int_arm_hint 5), (tHINT 5)>; + // The imm operand $val can be used by a debugger to store more information // about the breakpoint. def tBKPT : T1I<(outs), (ins imm0_255:$val), NoItinerary, "bkpt\t$val", Index: lib/Target/ARM/ARMInstrThumb2.td =================================================================== --- lib/Target/ARM/ARMInstrThumb2.td +++ lib/Target/ARM/ARMInstrThumb2.td @@ -3687,6 +3687,13 @@ let Predicates = [IsThumb2, HasV8]; } +def : Pat<(int_arm_hint 0), (t2HINT 0)>; +def : Pat<(int_arm_hint 1), (t2HINT 1)>; +def : Pat<(int_arm_hint 2), (t2HINT 2)>; +def : Pat<(int_arm_hint 3), (t2HINT 3)>; +def : Pat<(int_arm_hint 4), (t2HINT 4)>; +def : Pat<(int_arm_hint 5), (t2HINT 5)>; + def t2DBG : T2I<(outs), (ins imm0_15:$opt), NoItinerary, "dbg", "\t$opt", []> { bits<4> opt; let Inst{31-20} = 0b111100111010; Index: test/CodeGen/ARM/hints.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/hints.ll @@ -0,0 +1,54 @@ +; RUN: llc -mtriple armv7-eabi -o - %s | FileCheck %s +; RUN: llc -mtriple thumb-eabi -mcpu arm1156t2-s -o - %s | FileCheck %s +; RUN: llc -mtriple thumbv7-eabi -o - %s | FileCheck %s + +declare void @llvm.arm.hint(i32) nounwind + +define void @hint_nop() { + tail call void @llvm.arm.hint(i32 0) nounwind + ret void +} + +; CHECK-LABEL: hint_nop +; CHECK: nop + +define void @hint_yield() { + tail call void @llvm.arm.hint(i32 1) nounwind + ret void +} + +; CHECK-LABEL: hint_yield +; CHECK: yield + +define void @hint_wfe() { + tail call void @llvm.arm.hint(i32 2) nounwind + ret void +} + +; CHECK-LABEL: hint_wfe +; CHECK: wfe + +define void @hint_wfi() { + tail call void @llvm.arm.hint(i32 3) nounwind + ret void +} + +; CHECK-LABEL: hint_wfi +; CHECK: wfi + +define void @hint_sev() { + tail call void @llvm.arm.hint(i32 4) nounwind + ret void +} + +; CHECK-LABEL: hint_sev +; CHECK: sev + +define void @hint_sevl() { + tail call void @llvm.arm.hint(i32 5) nounwind + ret void +} + +; CHECK-LABEL: hint_sevl +; CHECK: hint #5 +