From 04f826c0625a9701dd941fa0fb5db110f5971421 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 25 Apr 2014 17:24:24 +0000 Subject: [PATCH] ARM: provide a new generic hint intrinsic Introduce the llvm.arm.hint(i32) intrinsic that can be used to inject hints into the instruction stream. This is particularly useful for generating IR from a compiler where the user may inject an intrinsic (e.g. __yield). These are then pattern substituted into the correct instruction which already existed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207242 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/IntrinsicsARM.td | 1 + lib/Target/ARM/ARMInstrInfo.td | 3 +- lib/Target/ARM/ARMInstrThumb.td | 3 +- lib/Target/ARM/ARMInstrThumb2.td | 3 +- test/CodeGen/ARM/hints.ll | 69 ++++++++++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 test/CodeGen/ARM/hints.ll diff --git a/include/llvm/IR/IntrinsicsARM.td b/include/llvm/IR/IntrinsicsARM.td index 482f98ef895..d50f17acdc0 100644 --- a/include/llvm/IR/IntrinsicsARM.td +++ b/include/llvm/IR/IntrinsicsARM.td @@ -123,6 +123,7 @@ def int_arm_crc32cw : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], //===----------------------------------------------------------------------===// // HINT def int_arm_sevl : Intrinsic<[], []>; +def int_arm_hint : Intrinsic<[], [llvm_i32_ty]>; //===----------------------------------------------------------------------===// // Advanced SIMD (NEON) diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index c27ffeed890..ad88bf0ba6b 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -1827,7 +1827,8 @@ PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, } def HINT : AI<(outs), (ins imm0_239:$imm), MiscFrm, NoItinerary, - "hint", "\t$imm", []>, Requires<[IsARM, HasV6]> { + "hint", "\t$imm", [(int_arm_hint imm0_239:$imm)]>, + Requires<[IsARM, HasV6]> { bits<8> imm; let Inst{27-8} = 0b00110010000011110000; let Inst{7-0} = imm; diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 754295f93fd..ed72d24a811 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -269,7 +269,8 @@ class T1SystemEncoding opc> let Inst{7-0} = opc; } -def tHINT : T1pI<(outs), (ins imm0_15:$imm), NoItinerary, "hint", "\t$imm", []>, +def tHINT : T1pI<(outs), (ins imm0_15:$imm), NoItinerary, "hint", "\t$imm", + [(int_arm_hint imm0_15:$imm)]>, T1SystemEncoding<0x00>, Requires<[IsThumb, HasV6M]> { bits<4> imm; diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index c30bf697623..1e4aa0d6abe 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -3671,7 +3671,8 @@ def : t2InstAlias<"cps.w $mode", (t2CPS1p imm0_31:$mode), 0>; // A6.3.4 Branches and miscellaneous control // Table A6-14 Change Processor State, and hint instructions -def t2HINT : T2I<(outs), (ins imm0_239:$imm), NoItinerary, "hint", ".w\t$imm",[]> { +def t2HINT : T2I<(outs), (ins imm0_239:$imm), NoItinerary, "hint", ".w\t$imm", + [(int_arm_hint imm0_239:$imm)]> { bits<8> imm; let Inst{31-3} = 0b11110011101011111000000000000; let Inst{7-0} = imm; diff --git a/test/CodeGen/ARM/hints.ll b/test/CodeGen/ARM/hints.ll new file mode 100644 index 00000000000..18abbbecaaf --- /dev/null +++ b/test/CodeGen/ARM/hints.ll @@ -0,0 +1,69 @@ +; RUN: llc -mtriple armv7-eabi -o - %s | FileCheck %s +; RUN: llc -mtriple thumbv6m-eabi -o - %s | FileCheck %s +; RUN: llc -mtriple thumbv7-eabi -o - %s | FileCheck %s + +declare void @llvm.arm.hint(i32) nounwind + +define void @hint_nop() { +entry: + tail call void @llvm.arm.hint(i32 0) nounwind + ret void +} + +; CHECK-LABEL: hint_nop +; CHECK: nop + +define void @hint_yield() { +entry: + tail call void @llvm.arm.hint(i32 1) nounwind + ret void +} + +; CHECK-LABEL: hint_yield +; CHECK: yield + +define void @hint_wfe() { +entry: + tail call void @llvm.arm.hint(i32 2) nounwind + ret void +} + +; CHECK-LABEL: hint_wfe +; CHECK: wfe + +define void @hint_wfi() { +entry: + tail call void @llvm.arm.hint(i32 3) nounwind + ret void +} + +; CHECK-LABEL: hint_wfi +; CHECK: wfi + +define void @hint_sev() { +entry: + tail call void @llvm.arm.hint(i32 4) nounwind + ret void +} + +; CHECK-LABEL: hint_sev +; CHECK: sev + +define void @hint_sevl() { +entry: + tail call void @llvm.arm.hint(i32 5) nounwind + ret void +} + +; CHECK-LABEL: hint_sevl +; CHECK: hint #5 + +define void @hint_undefined() { +entry: + tail call void @llvm.arm.hint(i32 8) nounwind + ret void +} + +; CHECK-LABEL: hint_undefined +; CHECK: hint #8 +