summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorOliver Stannard <oliver.stannard@arm.com>2016-06-08 15:26:34 +0000
committerOliver Stannard <oliver.stannard@arm.com>2016-06-08 15:26:34 +0000
commitb3378e2f3cd07a8a3e36b8b01e5c7222e38f6f56 (patch)
tree73e1e955fdfc8051ee3a361a893c0d7776d818d6 /llvm/lib/Target
parentc564701fbd62bbd47b001564ace2649c19ae92ce (diff)
downloadbcm5719-llvm-b3378e2f3cd07a8a3e36b8b01e5c7222e38f6f56.tar.gz
bcm5719-llvm-b3378e2f3cd07a8a3e36b8b01e5c7222e38f6f56.zip
[ARM] MSR instructions implicitly set CPSR
The MSR instructions can write to the CPSR, but we did not model this fact, so we could emit them in the middle of IT blocks, changing the condition flags for later instructions in the block. The tests use two calls to llvm.write_register.i32 because it is valid to use these instructions at the end of an IT block, which if conversion does do in some cases. With two calls, the first clobbers the flags, so a branch has to be used to make the second one conditional. Differential Revision: http://reviews.llvm.org/D21139 llvm-svn: 272154
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/ARM/ARMInstrInfo.td2
-rw-r--r--llvm/lib/Target/ARM/ARMInstrThumb2.td2
2 files changed, 4 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]> {
OpenPOWER on IntegriCloud