summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMInstrThumb.td
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-08-27 23:58:52 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-08-27 23:58:52 +0000
commitb24cb8c541c549dbc10633e003c4421532c72e2a (patch)
treef3205efa2c552f50553c1247ebbc8f4e2bd84069 /llvm/lib/Target/ARM/ARMInstrThumb.td
parent6100ae120c5d8e3b61e6c17426c84e0a27b90a5c (diff)
downloadbcm5719-llvm-b24cb8c541c549dbc10633e003c4421532c72e2a.tar.gz
bcm5719-llvm-b24cb8c541c549dbc10633e003c4421532c72e2a.zip
Add ATOMIC_LDR* pseudo-instructions to model atomic_load on ARM.
It is not safe to use normal LDR instructions because they may be reordered by the scheduler. The ATOMIC_LDR pseudos have a mayStore flag that prevents reordering. Atomic loads are also prevented from participating in rematerialization and load folding. llvm-svn: 162713
Diffstat (limited to 'llvm/lib/Target/ARM/ARMInstrThumb.td')
-rw-r--r--llvm/lib/Target/ARM/ARMInstrThumb.td47
1 files changed, 41 insertions, 6 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td
index e171f8b0929..bad7740c72b 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb.td
@@ -681,6 +681,41 @@ def tSTRspi : T1pIs<(outs), (ins tGPR:$Rt, t_addrmode_sp:$addr), IIC_iStore_i,
let Inst{7-0} = addr;
}
+// Atomic loads. These pseudos expand to the loads above, but the have mayStore
+// = 1 so they can't be reordered.
+let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in {
+let AM = AddrModeT1_1 in {
+def ATOMIC_tLDRBi : tPseudoExpand<(outs tGPR:$Rt),
+ (ins t_addrmode_is1:$addr, pred:$p),
+ 2, IIC_iLoad_bh_i, [],
+ (tLDRBi tGPR:$Rt, t_addrmode_is1:$addr, pred:$p)>;
+def ATOMIC_tLDRBr : tPseudoExpand<(outs tGPR:$Rt),
+ (ins t_addrmode_rrs1:$addr, pred:$p),
+ 2, IIC_iLoad_bh_r, [],
+ (tLDRBr tGPR:$Rt, t_addrmode_rrs1:$addr, pred:$p)>;
+}
+let AM = AddrModeT1_2 in {
+def ATOMIC_tLDRHi : tPseudoExpand<(outs tGPR:$Rt),
+ (ins t_addrmode_is2:$addr, pred:$p),
+ 2, IIC_iLoad_bh_i, [],
+ (tLDRHi tGPR:$Rt, t_addrmode_is2:$addr, pred:$p)>;
+def ATOMIC_tLDRHr : tPseudoExpand<(outs tGPR:$Rt),
+ (ins t_addrmode_rrs2:$addr, pred:$p),
+ 2, IIC_iLoad_bh_r, [],
+ (tLDRHr tGPR:$Rt, t_addrmode_rrs2:$addr, pred:$p)>;
+}
+let AM = AddrModeT1_4 in {
+def ATOMIC_tLDRi : tPseudoExpand<(outs tGPR:$Rt),
+ (ins t_addrmode_is4:$addr, pred:$p),
+ 2, IIC_iLoad_i, [],
+ (tLDRi tGPR:$Rt, t_addrmode_is4:$addr, pred:$p)>;
+def ATOMIC_tLDRr : tPseudoExpand<(outs tGPR:$Rt),
+ (ins t_addrmode_rrs4:$addr, pred:$p),
+ 2, IIC_iLoad_r, [],
+ (tLDRr tGPR:$Rt, t_addrmode_rrs4:$addr, pred:$p)>;
+}
+}
+
//===----------------------------------------------------------------------===//
// Load / store multiple Instructions.
//
@@ -1334,17 +1369,17 @@ def : T1Pat<(sextloadi16 t_addrmode_is2:$addr),
(tASRri (tLSLri (tLDRHi t_addrmode_is2:$addr), 16), 16)>;
def : T1Pat<(atomic_load_8 t_addrmode_is1:$src),
- (tLDRBi t_addrmode_is1:$src)>;
+ (ATOMIC_tLDRBi t_addrmode_is1:$src)>;
def : T1Pat<(atomic_load_8 t_addrmode_rrs1:$src),
- (tLDRBr t_addrmode_rrs1:$src)>;
+ (ATOMIC_tLDRBr t_addrmode_rrs1:$src)>;
def : T1Pat<(atomic_load_16 t_addrmode_is2:$src),
- (tLDRHi t_addrmode_is2:$src)>;
+ (ATOMIC_tLDRHi t_addrmode_is2:$src)>;
def : T1Pat<(atomic_load_16 t_addrmode_rrs2:$src),
- (tLDRHr t_addrmode_rrs2:$src)>;
+ (ATOMIC_tLDRHr t_addrmode_rrs2:$src)>;
def : T1Pat<(atomic_load_32 t_addrmode_is4:$src),
- (tLDRi t_addrmode_is4:$src)>;
+ (ATOMIC_tLDRi t_addrmode_is4:$src)>;
def : T1Pat<(atomic_load_32 t_addrmode_rrs4:$src),
- (tLDRr t_addrmode_rrs4:$src)>;
+ (ATOMIC_tLDRr t_addrmode_rrs4:$src)>;
def : T1Pat<(atomic_store_8 t_addrmode_is1:$ptr, tGPR:$val),
(tSTRBi tGPR:$val, t_addrmode_is1:$ptr)>;
def : T1Pat<(atomic_store_8 t_addrmode_rrs1:$ptr, tGPR:$val),
OpenPOWER on IntegriCloud