forked from OSchip/llvm-project
[ARM] Add ARMv8-A semaphore/atomic instructions to ARMv8-M Baseline/Mainline
llvm-svn: 257882
This commit is contained in:
parent
a1189106d5
commit
433c22e35c
|
@ -393,7 +393,7 @@ def ARMv8mBaseline : Architecture<"armv8-m.base", "ARMv8mBaseline",
|
|||
FeatureNoARM,
|
||||
FeatureDB,
|
||||
FeatureHWDiv,
|
||||
FeatureV7Exclusives,
|
||||
FeatureV7Clrex,
|
||||
FeatureAcquireRelease,
|
||||
FeatureMClass]>;
|
||||
|
||||
|
|
|
@ -3056,7 +3056,7 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) {
|
|||
SDLoc dl(N);
|
||||
SDValue Chain = N->getOperand(0);
|
||||
SDValue MemAddr = N->getOperand(2);
|
||||
bool isThumb = Subtarget->isThumb() && Subtarget->hasThumb2();
|
||||
bool isThumb = Subtarget->isThumb() && Subtarget->hasV8MBaselineOps();
|
||||
|
||||
bool IsAcquire = IntNo == Intrinsic::arm_ldaexd;
|
||||
unsigned NewOpc = isThumb ? (IsAcquire ? ARM::t2LDAEXD : ARM::t2LDREXD)
|
||||
|
|
|
@ -839,7 +839,8 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
|||
// non-atomic form.
|
||||
if (TM.Options.ThreadModel == ThreadModel::Single)
|
||||
setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand);
|
||||
else if (Subtarget->hasAnyDataBarrier() && !Subtarget->isThumb1Only()) {
|
||||
else if (Subtarget->hasAnyDataBarrier() && (!Subtarget->isThumb() ||
|
||||
Subtarget->hasV8MBaselineOps())) {
|
||||
// ATOMIC_FENCE needs custom lowering; the others should have been expanded
|
||||
// to ldrex/strex loops already.
|
||||
setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
|
||||
|
|
|
@ -3291,15 +3291,18 @@ let mayLoad = 1 in {
|
|||
def t2LDREXB : T2I_ldrex<0b0100, (outs rGPR:$Rt), (ins addr_offset_none:$addr),
|
||||
AddrModeNone, 4, NoItinerary,
|
||||
"ldrexb", "\t$Rt, $addr", "",
|
||||
[(set rGPR:$Rt, (ldrex_1 addr_offset_none:$addr))]>;
|
||||
[(set rGPR:$Rt, (ldrex_1 addr_offset_none:$addr))]>,
|
||||
Requires<[IsThumb, HasV8MBaseline]>;
|
||||
def t2LDREXH : T2I_ldrex<0b0101, (outs rGPR:$Rt), (ins addr_offset_none:$addr),
|
||||
AddrModeNone, 4, NoItinerary,
|
||||
"ldrexh", "\t$Rt, $addr", "",
|
||||
[(set rGPR:$Rt, (ldrex_2 addr_offset_none:$addr))]>;
|
||||
[(set rGPR:$Rt, (ldrex_2 addr_offset_none:$addr))]>,
|
||||
Requires<[IsThumb, HasV8MBaseline]>;
|
||||
def t2LDREX : Thumb2I<(outs rGPR:$Rt), (ins t2addrmode_imm0_1020s4:$addr),
|
||||
AddrModeNone, 4, NoItinerary,
|
||||
"ldrex", "\t$Rt, $addr", "",
|
||||
[(set rGPR:$Rt, (ldrex_4 t2addrmode_imm0_1020s4:$addr))]> {
|
||||
[(set rGPR:$Rt, (ldrex_4 t2addrmode_imm0_1020s4:$addr))]>,
|
||||
Requires<[IsThumb, HasV8MBaseline]> {
|
||||
bits<4> Rt;
|
||||
bits<12> addr;
|
||||
let Inst{31-27} = 0b11101;
|
||||
|
@ -3363,20 +3366,23 @@ def t2STREXB : T2I_strex<0b0100, (outs rGPR:$Rd),
|
|||
AddrModeNone, 4, NoItinerary,
|
||||
"strexb", "\t$Rd, $Rt, $addr", "",
|
||||
[(set rGPR:$Rd,
|
||||
(strex_1 rGPR:$Rt, addr_offset_none:$addr))]>;
|
||||
(strex_1 rGPR:$Rt, addr_offset_none:$addr))]>,
|
||||
Requires<[IsThumb, HasV8MBaseline]>;
|
||||
def t2STREXH : T2I_strex<0b0101, (outs rGPR:$Rd),
|
||||
(ins rGPR:$Rt, addr_offset_none:$addr),
|
||||
AddrModeNone, 4, NoItinerary,
|
||||
"strexh", "\t$Rd, $Rt, $addr", "",
|
||||
[(set rGPR:$Rd,
|
||||
(strex_2 rGPR:$Rt, addr_offset_none:$addr))]>;
|
||||
(strex_2 rGPR:$Rt, addr_offset_none:$addr))]>,
|
||||
Requires<[IsThumb, HasV8MBaseline]>;
|
||||
|
||||
def t2STREX : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt,
|
||||
t2addrmode_imm0_1020s4:$addr),
|
||||
AddrModeNone, 4, NoItinerary,
|
||||
"strex", "\t$Rd, $Rt, $addr", "",
|
||||
[(set rGPR:$Rd,
|
||||
(strex_4 rGPR:$Rt, t2addrmode_imm0_1020s4:$addr))]> {
|
||||
(strex_4 rGPR:$Rt, t2addrmode_imm0_1020s4:$addr))]>,
|
||||
Requires<[IsThumb, HasV8MBaseline]> {
|
||||
bits<4> Rd;
|
||||
bits<4> Rt;
|
||||
bits<12> addr;
|
||||
|
@ -3456,13 +3462,17 @@ def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "", [(int_arm_clrex)]>,
|
|||
}
|
||||
|
||||
def : T2Pat<(and (ldrex_1 addr_offset_none:$addr), 0xff),
|
||||
(t2LDREXB addr_offset_none:$addr)>;
|
||||
(t2LDREXB addr_offset_none:$addr)>,
|
||||
Requires<[IsThumb, HasV8MBaseline]>;
|
||||
def : T2Pat<(and (ldrex_2 addr_offset_none:$addr), 0xffff),
|
||||
(t2LDREXH addr_offset_none:$addr)>;
|
||||
(t2LDREXH addr_offset_none:$addr)>,
|
||||
Requires<[IsThumb, HasV8MBaseline]>;
|
||||
def : T2Pat<(strex_1 (and GPR:$Rt, 0xff), addr_offset_none:$addr),
|
||||
(t2STREXB GPR:$Rt, addr_offset_none:$addr)>;
|
||||
(t2STREXB GPR:$Rt, addr_offset_none:$addr)>,
|
||||
Requires<[IsThumb, HasV8MBaseline]>;
|
||||
def : T2Pat<(strex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr),
|
||||
(t2STREXH GPR:$Rt, addr_offset_none:$addr)>;
|
||||
(t2STREXH GPR:$Rt, addr_offset_none:$addr)>,
|
||||
Requires<[IsThumb, HasV8MBaseline]>;
|
||||
|
||||
def : T2Pat<(and (ldaex_1 addr_offset_none:$addr), 0xff),
|
||||
(t2LDAEXB addr_offset_none:$addr)>,
|
||||
|
|
|
@ -336,7 +336,7 @@ bool ARMSubtarget::enablePostRAScheduler() const {
|
|||
}
|
||||
|
||||
bool ARMSubtarget::enableAtomicExpand() const {
|
||||
return hasAnyDataBarrier() && !isThumb1Only();
|
||||
return hasAnyDataBarrier() && (!isThumb() || hasV8MBaselineOps());
|
||||
}
|
||||
|
||||
bool ARMSubtarget::useStride4VFPs(const MachineFunction &MF) const {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
; RUN: llc < %s -mtriple=thumbv7m-none-eabi -mcpu=cortex-m4 | FileCheck %s
|
||||
; RUN: llc < %s -mtriple=thumbv8m.main-none-eabi | FileCheck %s
|
||||
; RUN: llc < %s -mtriple=thumbv8m.base-none-eabi | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: f0:
|
||||
; CHECK-NOT: ldrexd
|
||||
|
|
|
@ -41,6 +41,37 @@ sdiv r1, r2, r3
|
|||
// CHECK: udiv r1, r2, r3 @ encoding: [0xb2,0xfb,0xf3,0xf1]
|
||||
udiv r1, r2, r3
|
||||
|
||||
// 'Exclusives from ARMv7-M'
|
||||
|
||||
// CHECK: clrex @ encoding: [0xbf,0xf3,0x2f,0x8f]
|
||||
clrex
|
||||
|
||||
// CHECK: ldrex r1, [r2, #4] @ encoding: [0x52,0xe8,0x01,0x1f]
|
||||
ldrex r1, [r2, #4]
|
||||
|
||||
// CHECK: ldrexb r1, [r2] @ encoding: [0xd2,0xe8,0x4f,0x1f]
|
||||
ldrexb r1, [r2]
|
||||
|
||||
// CHECK: ldrexh r1, [r2] @ encoding: [0xd2,0xe8,0x5f,0x1f]
|
||||
ldrexh r1, [r2]
|
||||
|
||||
// UNDEF-BASELINE: error: instruction requires: !armv*m thumb2
|
||||
// UNDEF-MAINLINE: error: instruction requires: !armv*m
|
||||
ldrexd r0, r1, [r2]
|
||||
|
||||
// CHECK: strex r1, r2, [r3, #4] @ encoding: [0x43,0xe8,0x01,0x21]
|
||||
strex r1, r2, [r3, #4]
|
||||
|
||||
// CHECK: strexb r1, r2, [r3] @ encoding: [0xc3,0xe8,0x41,0x2f]
|
||||
strexb r1, r2, [r3]
|
||||
|
||||
// CHECK: strexh r1, r2, [r3] @ encoding: [0xc3,0xe8,0x51,0x2f]
|
||||
strexh r1, r2, [r3]
|
||||
|
||||
// UNDEF-BASELINE: error: instruction requires: !armv*m thumb2
|
||||
// UNDEF-MAINLINE: error: instruction requires: !armv*m
|
||||
strexd r0, r1, r2, [r3]
|
||||
|
||||
// 'XO generation'
|
||||
|
||||
// CHECK: movw r1, #65535 @ encoding: [0x4f,0xf6,0xff,0x71]
|
||||
|
@ -48,3 +79,47 @@ movw r1, #0xffff
|
|||
|
||||
// CHECK: movt r1, #65535 @ encoding: [0xcf,0xf6,0xff,0x71]
|
||||
movt r1, #0xffff
|
||||
|
||||
// 'Acquire/Release from ARMv8-A'
|
||||
|
||||
// CHECK: lda r1, [r2] @ encoding: [0xd2,0xe8,0xaf,0x1f]
|
||||
lda r1, [r2]
|
||||
|
||||
// CHECK: ldab r1, [r2] @ encoding: [0xd2,0xe8,0x8f,0x1f]
|
||||
ldab r1, [r2]
|
||||
|
||||
// CHECK: ldah r1, [r2] @ encoding: [0xd2,0xe8,0x9f,0x1f]
|
||||
ldah r1, [r2]
|
||||
|
||||
// CHECK: stl r1, [r3] @ encoding: [0xc3,0xe8,0xaf,0x1f]
|
||||
stl r1, [r3]
|
||||
|
||||
// CHECK: stlb r1, [r3] @ encoding: [0xc3,0xe8,0x8f,0x1f]
|
||||
stlb r1, [r3]
|
||||
|
||||
// CHECK: stlh r1, [r3] @ encoding: [0xc3,0xe8,0x9f,0x1f]
|
||||
stlh r1, [r3]
|
||||
|
||||
// CHECK: ldaex r1, [r2] @ encoding: [0xd2,0xe8,0xef,0x1f]
|
||||
ldaex r1, [r2]
|
||||
|
||||
// CHECK: ldaexb r1, [r2] @ encoding: [0xd2,0xe8,0xcf,0x1f]
|
||||
ldaexb r1, [r2]
|
||||
|
||||
// CHECK: ldaexh r1, [r2] @ encoding: [0xd2,0xe8,0xdf,0x1f]
|
||||
ldaexh r1, [r2]
|
||||
|
||||
// UNDEF: error: instruction requires: !armv*m
|
||||
ldaexd r0, r1, [r2]
|
||||
|
||||
// CHECK: stlex r1, r2, [r3] @ encoding: [0xc3,0xe8,0xe1,0x2f]
|
||||
stlex r1, r2, [r3]
|
||||
|
||||
// CHECK: stlexb r1, r2, [r3] @ encoding: [0xc3,0xe8,0xc1,0x2f]
|
||||
stlexb r1, r2, [r3]
|
||||
|
||||
// CHECK: stlexh r1, r2, [r3] @ encoding: [0xc3,0xe8,0xd1,0x2f]
|
||||
stlexh r1, r2, [r3]
|
||||
|
||||
// UNDEF: error: instruction requires: !armv*m
|
||||
stlexd r0, r1, r2, [r2]
|
||||
|
|
Loading…
Reference in New Issue