From 2bd1262a3299ca9c9ac936df6d17f52858d21ef8 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Thu, 22 May 2014 04:46:46 +0000 Subject: [PATCH] ARM: introduce llvm.arm.undefined intrinsic This intrinsic permits the emission of platform specific undefined sequences. ARM has reserved the 0xde opcode which takes a single integer parameter (ignored by the CPU). This permits the operating system to implement custom behaviour on this trap. The llvm.arm.undefined intrinsic is meant to provide a means for generating the target specific behaviour from the frontend. This is particularly useful for Windows on ARM which has made use of a series of these special opcodes. llvm-svn: 209390 --- llvm/include/llvm/IR/IntrinsicsARM.td | 5 +++++ llvm/lib/Target/ARM/ARMInstrInfo.td | 2 +- llvm/lib/Target/ARM/ARMInstrThumb.td | 4 ++-- llvm/lib/Target/ARM/ARMInstrThumb2.td | 4 ++-- llvm/test/CodeGen/ARM/undefined.ll | 14 ++++++++++++++ 5 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 llvm/test/CodeGen/ARM/undefined.ll diff --git a/llvm/include/llvm/IR/IntrinsicsARM.td b/llvm/include/llvm/IR/IntrinsicsARM.td index b8ba9291a7af..d19d7b82fafe 100644 --- a/llvm/include/llvm/IR/IntrinsicsARM.td +++ b/llvm/include/llvm/IR/IntrinsicsARM.td @@ -125,6 +125,11 @@ def int_arm_crc32cw : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], def int_arm_hint : Intrinsic<[], [llvm_i32_ty]>; +//===----------------------------------------------------------------------===// +// UND (reserved undefined sequence) + +def int_arm_undefined : Intrinsic<[], [llvm_i32_ty]>; + //===----------------------------------------------------------------------===// // Advanced SIMD (NEON) diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index f642893161c3..718d5da9d05a 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -1969,7 +1969,7 @@ def DBG : AI<(outs), (ins imm0_15:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt", // A8.8.247 UDF - Undefined (Encoding A1) def UDF : AInoP<(outs), (ins imm0_65535:$imm16), MiscFrm, NoItinerary, - "udf", "\t$imm16", []> { + "udf", "\t$imm16", [(int_arm_undefined imm0_65535:$imm16)]> { bits<16> imm16; let Inst{31-28} = 0b1110; // AL let Inst{27-25} = 0b011; diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td index ff3832d98b5e..e17f73af03ec 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb.td @@ -1194,8 +1194,8 @@ def tTST : // A8.6.230 Sched<[WriteALU]>; // A8.8.247 UDF - Undefined (Encoding T1) -def tUDF : TI<(outs), (ins imm0_255:$imm8), IIC_Br, "udf\t$imm8", []>, - Encoding16 { +def tUDF : TI<(outs), (ins imm0_255:$imm8), IIC_Br, "udf\t$imm8", + [(int_arm_undefined imm0_255:$imm8)]>, Encoding16 { bits<8> imm8; let Inst{15-12} = 0b1101; let Inst{11-8} = 0b1110; diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index 28f528a510e9..c30d6abbb299 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -2408,8 +2408,8 @@ def t2UBFX: T2TwoRegBitFI< } // A8.8.247 UDF - Undefined (Encoding T2) -def t2UDF - : T2XI<(outs), (ins imm0_65535:$imm16), IIC_Br, "udf.w\t$imm16", []> { +def t2UDF : T2XI<(outs), (ins imm0_65535:$imm16), IIC_Br, "udf.w\t$imm16", + [(int_arm_undefined imm0_65535:$imm16)]> { bits<16> imm16; let Inst{31-29} = 0b111; let Inst{28-27} = 0b10; diff --git a/llvm/test/CodeGen/ARM/undefined.ll b/llvm/test/CodeGen/ARM/undefined.ll new file mode 100644 index 000000000000..86422fb54412 --- /dev/null +++ b/llvm/test/CodeGen/ARM/undefined.ll @@ -0,0 +1,14 @@ +; 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.undefined(i32) nounwind + +define void @undefined_trap() { +entry: + tail call void @llvm.arm.undefined(i32 254) + ret void +} + +; CHECK-LABEL: undefined_trap +; CHECK: udf #254