summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/ARM/ARMInstrInfo.td2
-rw-r--r--llvm/lib/Target/ARM/ARMInstrThumb2.td2
-rw-r--r--llvm/test/CodeGen/ARM/msr-it-block.ll55
3 files changed, 59 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index c7f113dc178..37db70dfbbb 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -5233,6 +5233,7 @@ def MRSbanked : ABI<0b0001, (outs GPRnopc:$Rd), (ins banked_reg:$banked),
// to distinguish between them. The mask operand contains the special register
// (R Bit) in bit 4 and bits 3-0 contains the mask with the fields to be
// accessed in the special register.
+let Defs = [CPSR] in
def MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary,
"msr", "\t$mask, $Rn", []> {
bits<5> mask;
@@ -5247,6 +5248,7 @@ def MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary,
let Inst{3-0} = Rn;
}
+let Defs = [CPSR] in
def MSRi : ABI<0b0011, (outs), (ins msr_mask:$mask, mod_imm:$imm), NoItinerary,
"msr", "\t$mask, $imm", []> {
bits<5> mask;
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index 4473d88d36e..c642ad90c2d 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -4083,6 +4083,7 @@ def t2MRS_M : T2I<(outs rGPR:$Rd), (ins msr_mask:$SYSm), NoItinerary,
// same and the assembly parser has no way to distinguish between them. The mask
// operand contains the special register (R Bit) in bit 4 and bits 3-0 contains
// the mask with the fields to be accessed in the special register.
+let Defs = [CPSR] in
def t2MSR_AR : T2I<(outs), (ins msr_mask:$mask, rGPR:$Rn),
NoItinerary, "msr", "\t$mask, $Rn", []>,
Requires<[IsThumb2,IsNotMClass]> {
@@ -4118,6 +4119,7 @@ def t2MSRbanked : T2I<(outs), (ins banked_reg:$banked, rGPR:$Rn),
// M class MSR.
//
// Move from ARM core register to Special Register
+let Defs = [CPSR] in
def t2MSR_M : T2I<(outs), (ins msr_mask:$SYSm, rGPR:$Rn),
NoItinerary, "msr", "\t$SYSm, $Rn", []>,
Requires<[IsThumb,IsMClass]> {
diff --git a/llvm/test/CodeGen/ARM/msr-it-block.ll b/llvm/test/CodeGen/ARM/msr-it-block.ll
new file mode 100644
index 00000000000..0f9ff6b29d7
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/msr-it-block.ll
@@ -0,0 +1,55 @@
+; RUN: llc < %s -mtriple=thumbv6m-none-eabi | FileCheck %s --check-prefix=V6M --check-prefix=CHECK
+; RUN: llc < %s -mtriple=thumbv7m-none-eabi | FileCheck %s --check-prefix=V7M --check-prefix=CHECK
+; RUN: llc < %s -mtriple=thumbv7a-none-eabi | FileCheck %s --check-prefix=V7A --check-prefix=CHECK
+; RUN: llc < %s -mtriple=armv7a-none-eabi | FileCheck %s --check-prefix=V7A --check-prefix=CHECK
+
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "armv7a-arm-none-eabi"
+
+define void @test_const(i32 %val) {
+; CHECK-LABEL: test_const:
+entry:
+ %cmp = icmp eq i32 %val, 0
+ br i1 %cmp, label %write_reg, label %exit
+
+write_reg:
+ tail call void @llvm.write_register.i32(metadata !0, i32 0)
+ tail call void @llvm.write_register.i32(metadata !0, i32 0)
+; V6M: msr apsr, {{r[0-9]+}}
+; V6M: msr apsr, {{r[0-9]+}}
+; V7M: msr apsr_nzcvq, {{r[0-9]+}}
+; V7M: msr apsr_nzcvq, {{r[0-9]+}}
+; V7A: msr APSR_nzcvqg, {{r[0-9]+}}
+; V7A: msr APSR_nzcvqg, {{r[0-9]+}}
+ br label %exit
+
+exit:
+ ret void
+}
+
+define void @test_var(i32 %val, i32 %apsr) {
+; CHECK-LABEL: test_var:
+entry:
+ %cmp = icmp eq i32 %val, 0
+ br i1 %cmp, label %write_reg, label %exit
+
+write_reg:
+ tail call void @llvm.write_register.i32(metadata !0, i32 %apsr)
+ tail call void @llvm.write_register.i32(metadata !0, i32 %apsr)
+; V6M: msr apsr, {{r[0-9]+}}
+; V6M: msr apsr, {{r[0-9]+}}
+; V7M: msr apsr_nzcvq, {{r[0-9]+}}
+; V7M: msr apsr_nzcvq, {{r[0-9]+}}
+; V7A: msr APSR_nzcvqg, {{r[0-9]+}}
+; V7A: msr APSR_nzcvqg, {{r[0-9]+}}
+ br label %exit
+
+exit:
+ ret void
+}
+
+
+declare void @llvm.write_register.i32(metadata, i32)
+
+!0 = !{!"apsr"}
OpenPOWER on IntegriCloud