diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-08-27 23:58:52 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-08-27 23:58:52 +0000 |
commit | b24cb8c541c549dbc10633e003c4421532c72e2a (patch) | |
tree | f3205efa2c552f50553c1247ebbc8f4e2bd84069 /llvm/lib/Target/ARM/ARMInstrThumb.td | |
parent | 6100ae120c5d8e3b61e6c17426c84e0a27b90a5c (diff) | |
download | bcm5719-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.td | 47 |
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), |