mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-03 11:08:32 +00:00
ARM big endian function argument passing
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208316 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
958fcdc21b
commit
c60a59cad3
@ -1293,6 +1293,8 @@ ARMTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
|
||||
InFlag);
|
||||
Chain = Hi.getValue(1);
|
||||
InFlag = Hi.getValue(2);
|
||||
if (!Subtarget->isLittle())
|
||||
std::swap (Lo, Hi);
|
||||
Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
|
||||
|
||||
if (VA.getLocVT() == MVT::v2f64) {
|
||||
@ -1308,6 +1310,8 @@ ARMTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
|
||||
Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InFlag);
|
||||
Chain = Hi.getValue(1);
|
||||
InFlag = Hi.getValue(2);
|
||||
if (!Subtarget->isLittle())
|
||||
std::swap (Lo, Hi);
|
||||
Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
|
||||
Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val,
|
||||
DAG.getConstant(1, MVT::i32));
|
||||
@ -1358,16 +1362,17 @@ void ARMTargetLowering::PassF64ArgInRegs(SDLoc dl, SelectionDAG &DAG,
|
||||
|
||||
SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl,
|
||||
DAG.getVTList(MVT::i32, MVT::i32), Arg);
|
||||
RegsToPass.push_back(std::make_pair(VA.getLocReg(), fmrrd));
|
||||
unsigned id = Subtarget->isLittle() ? 0 : 1;
|
||||
RegsToPass.push_back(std::make_pair(VA.getLocReg(), fmrrd.getValue(id)));
|
||||
|
||||
if (NextVA.isRegLoc())
|
||||
RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), fmrrd.getValue(1)));
|
||||
RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), fmrrd.getValue(1-id)));
|
||||
else {
|
||||
assert(NextVA.isMemLoc());
|
||||
if (!StackPtr.getNode())
|
||||
StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy());
|
||||
|
||||
MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, fmrrd.getValue(1),
|
||||
MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, fmrrd.getValue(1-id),
|
||||
dl, DAG, NextVA,
|
||||
Flags));
|
||||
}
|
||||
@ -2082,6 +2087,7 @@ ARMTargetLowering::LowerReturn(SDValue Chain,
|
||||
SDValue Flag;
|
||||
SmallVector<SDValue, 4> RetOps;
|
||||
RetOps.push_back(Chain); // Operand #0 = Chain (updated below)
|
||||
bool isLittleEndian = Subtarget->isLittle();
|
||||
|
||||
// Copy the result values into the output registers.
|
||||
for (unsigned i = 0, realRVLocIdx = 0;
|
||||
@ -2108,12 +2114,15 @@ ARMTargetLowering::LowerReturn(SDValue Chain,
|
||||
SDValue HalfGPRs = DAG.getNode(ARMISD::VMOVRRD, dl,
|
||||
DAG.getVTList(MVT::i32, MVT::i32), Half);
|
||||
|
||||
Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), HalfGPRs, Flag);
|
||||
Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
|
||||
HalfGPRs.getValue(isLittleEndian ? 0 : 1),
|
||||
Flag);
|
||||
Flag = Chain.getValue(1);
|
||||
RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
|
||||
VA = RVLocs[++i]; // skip ahead to next loc
|
||||
Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
|
||||
HalfGPRs.getValue(1), Flag);
|
||||
HalfGPRs.getValue(isLittleEndian ? 1 : 0),
|
||||
Flag);
|
||||
Flag = Chain.getValue(1);
|
||||
RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
|
||||
VA = RVLocs[++i]; // skip ahead to next loc
|
||||
@ -2126,11 +2135,14 @@ ARMTargetLowering::LowerReturn(SDValue Chain,
|
||||
// available.
|
||||
SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl,
|
||||
DAG.getVTList(MVT::i32, MVT::i32), Arg);
|
||||
Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), fmrrd, Flag);
|
||||
Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
|
||||
fmrrd.getValue(isLittleEndian ? 0 : 1),
|
||||
Flag);
|
||||
Flag = Chain.getValue(1);
|
||||
RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
|
||||
VA = RVLocs[++i]; // skip ahead to next loc
|
||||
Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), fmrrd.getValue(1),
|
||||
Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
|
||||
fmrrd.getValue(isLittleEndian ? 1 : 0),
|
||||
Flag);
|
||||
} else
|
||||
Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Arg, Flag);
|
||||
@ -2661,7 +2673,8 @@ ARMTargetLowering::GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA,
|
||||
Reg = MF.addLiveIn(NextVA.getLocReg(), RC);
|
||||
ArgValue2 = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
|
||||
}
|
||||
|
||||
if (!Subtarget->isLittle())
|
||||
std::swap (ArgValue, ArgValue2);
|
||||
return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, ArgValue, ArgValue2);
|
||||
}
|
||||
|
||||
@ -8314,16 +8327,18 @@ static SDValue PerformSTORECombine(SDNode *N,
|
||||
if (StVal.getNode()->getOpcode() == ARMISD::VMOVDRR &&
|
||||
StVal.getNode()->hasOneUse()) {
|
||||
SelectionDAG &DAG = DCI.DAG;
|
||||
bool isBigEndian = DAG.getTargetLoweringInfo().isBigEndian();
|
||||
SDLoc DL(St);
|
||||
SDValue BasePtr = St->getBasePtr();
|
||||
SDValue NewST1 = DAG.getStore(St->getChain(), DL,
|
||||
StVal.getNode()->getOperand(0), BasePtr,
|
||||
St->getPointerInfo(), St->isVolatile(),
|
||||
StVal.getNode()->getOperand(isBigEndian ? 1 : 0 ),
|
||||
BasePtr, St->getPointerInfo(), St->isVolatile(),
|
||||
St->isNonTemporal(), St->getAlignment());
|
||||
|
||||
SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
|
||||
DAG.getConstant(4, MVT::i32));
|
||||
return DAG.getStore(NewST1.getValue(0), DL, StVal.getNode()->getOperand(1),
|
||||
return DAG.getStore(NewST1.getValue(0), DL,
|
||||
StVal.getNode()->getOperand(isBigEndian ? 0 : 1),
|
||||
OffsetPtr, St->getPointerInfo(), St->isVolatile(),
|
||||
St->isNonTemporal(),
|
||||
std::min(4U, St->getAlignment() / 2));
|
||||
@ -10539,6 +10554,8 @@ Value *ARMTargetLowering::emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
|
||||
|
||||
Value *Lo = Builder.CreateExtractValue(LoHi, 0, "lo");
|
||||
Value *Hi = Builder.CreateExtractValue(LoHi, 1, "hi");
|
||||
if (!Subtarget->isLittle())
|
||||
std::swap (Lo, Hi);
|
||||
Lo = Builder.CreateZExt(Lo, ValTy, "lo64");
|
||||
Hi = Builder.CreateZExt(Hi, ValTy, "hi64");
|
||||
return Builder.CreateOr(
|
||||
@ -10572,6 +10589,8 @@ Value *ARMTargetLowering::emitStoreConditional(IRBuilder<> &Builder, Value *Val,
|
||||
|
||||
Value *Lo = Builder.CreateTrunc(Val, Int32Ty, "lo");
|
||||
Value *Hi = Builder.CreateTrunc(Builder.CreateLShr(Val, 32), Int32Ty, "hi");
|
||||
if (!Subtarget->isLittle())
|
||||
std::swap (Lo, Hi);
|
||||
Addr = Builder.CreateBitCast(Addr, Type::getInt8PtrTy(M->getContext()));
|
||||
return Builder.CreateCall3(Strex, Lo, Hi, Addr);
|
||||
}
|
||||
|
@ -1,12 +1,16 @@
|
||||
; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s
|
||||
; RUN: llc < %s -mtriple=thumbv7-none-linux-gnueabihf -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-THUMB
|
||||
; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE
|
||||
; RUN: llc < %s -mtriple=thumbv7-none-linux-gnueabihf | FileCheck %s --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-LE
|
||||
; RUN: llc < %s -mtriple=armebv7 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE
|
||||
; RUN: llc < %s -mtriple=thumbebv7-none-linux-gnueabihf | FileCheck %s --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-BE
|
||||
|
||||
define i64 @test1(i64* %ptr, i64 %val) {
|
||||
; CHECK-LABEL: test1:
|
||||
; CHECK: dmb {{ish$}}
|
||||
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
|
||||
; CHECK: adds [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK: adc [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-LE: adds [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK-LE: adc [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-BE: adds [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-BE: adc [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
|
||||
; CHECK: cmp
|
||||
; CHECK: bne
|
||||
@ -15,8 +19,10 @@ define i64 @test1(i64* %ptr, i64 %val) {
|
||||
; CHECK-THUMB-LABEL: test1:
|
||||
; CHECK-THUMB: dmb {{ish$}}
|
||||
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
|
||||
; CHECK-THUMB: adds.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB: adc.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-LE: adds.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB-LE: adc.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-BE: adds.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-BE: adc.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
|
||||
; CHECK-THUMB: cmp
|
||||
; CHECK-THUMB: bne
|
||||
@ -30,8 +36,10 @@ define i64 @test2(i64* %ptr, i64 %val) {
|
||||
; CHECK-LABEL: test2:
|
||||
; CHECK: dmb {{ish$}}
|
||||
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
|
||||
; CHECK: subs [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK: sbc [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-LE: subs [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK-LE: sbc [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-BE: subs [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-BE: sbc [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
|
||||
; CHECK: cmp
|
||||
; CHECK: bne
|
||||
@ -40,8 +48,10 @@ define i64 @test2(i64* %ptr, i64 %val) {
|
||||
; CHECK-THUMB-LABEL: test2:
|
||||
; CHECK-THUMB: dmb {{ish$}}
|
||||
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
|
||||
; CHECK-THUMB: subs.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB: sbc.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-LE: subs.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB-LE: sbc.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-BE: subs.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-BE: sbc.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
|
||||
; CHECK-THUMB: cmp
|
||||
; CHECK-THUMB: bne
|
||||
@ -55,8 +65,10 @@ define i64 @test3(i64* %ptr, i64 %val) {
|
||||
; CHECK-LABEL: test3:
|
||||
; CHECK: dmb {{ish$}}
|
||||
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
|
||||
; CHECK-DAG: and [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK-DAG: and [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-LE-DAG: and [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK-LE-DAG: and [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-BE-DAG: and [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-BE-DAG: and [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
|
||||
; CHECK: cmp
|
||||
; CHECK: bne
|
||||
@ -65,8 +77,10 @@ define i64 @test3(i64* %ptr, i64 %val) {
|
||||
; CHECK-THUMB-LABEL: test3:
|
||||
; CHECK-THUMB: dmb {{ish$}}
|
||||
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
|
||||
; CHECK-THUMB-DAG: and.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB-DAG: and.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-LE-DAG: and.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB-LE-DAG: and.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-BE-DAG: and.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-BE-DAG: and.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
|
||||
; CHECK-THUMB: cmp
|
||||
; CHECK-THUMB: bne
|
||||
@ -80,8 +94,10 @@ define i64 @test4(i64* %ptr, i64 %val) {
|
||||
; CHECK-LABEL: test4:
|
||||
; CHECK: dmb {{ish$}}
|
||||
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
|
||||
; CHECK-DAG: orr [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK-DAG: orr [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-LE-DAG: orr [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK-LE-DAG: orr [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-BE-DAG: orr [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-BE-DAG: orr [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
|
||||
; CHECK: cmp
|
||||
; CHECK: bne
|
||||
@ -90,8 +106,10 @@ define i64 @test4(i64* %ptr, i64 %val) {
|
||||
; CHECK-THUMB-LABEL: test4:
|
||||
; CHECK-THUMB: dmb {{ish$}}
|
||||
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
|
||||
; CHECK-THUMB-DAG: orr.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB-DAG: orr.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-LE-DAG: orr.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB-LE-DAG: orr.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-BE-DAG: orr.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-BE-DAG: orr.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
|
||||
; CHECK-THUMB: cmp
|
||||
; CHECK-THUMB: bne
|
||||
@ -105,8 +123,10 @@ define i64 @test5(i64* %ptr, i64 %val) {
|
||||
; CHECK-LABEL: test5:
|
||||
; CHECK: dmb {{ish$}}
|
||||
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
|
||||
; CHECK-DAG: eor [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK-DAG: eor [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-LE-DAG: eor [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK-LE-DAG: eor [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-BE-DAG: eor [[REG4:(r[0-9]?[13579])]], [[REG2]]
|
||||
; CHECK-BE-DAG: eor [[REG3:(r[0-9]?[02468])]], [[REG1]]
|
||||
; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
|
||||
; CHECK: cmp
|
||||
; CHECK: bne
|
||||
@ -115,8 +135,10 @@ define i64 @test5(i64* %ptr, i64 %val) {
|
||||
; CHECK-THUMB-LABEL: test5:
|
||||
; CHECK-THUMB: dmb {{ish$}}
|
||||
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
|
||||
; CHECK-THUMB-DAG: eor.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB-DAG: eor.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-LE-DAG: eor.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB-LE-DAG: eor.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-BE-DAG: eor.w [[REG4:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB-BE-DAG: eor.w [[REG3:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
|
||||
; CHECK-THUMB: cmp
|
||||
; CHECK-THUMB: bne
|
||||
@ -151,8 +173,10 @@ define i64 @test7(i64* %ptr, i64 %val1, i64 %val2) {
|
||||
; CHECK-LABEL: test7:
|
||||
; CHECK: dmb {{ish$}}
|
||||
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
|
||||
; CHECK-DAG: eor [[MISMATCH_LO:r[0-9]+]], [[REG1]], r1
|
||||
; CHECK-DAG: eor [[MISMATCH_HI:r[0-9]+]], [[REG2]], r2
|
||||
; CHECK-LE-DAG: eor [[MISMATCH_LO:r[0-9]+]], [[REG1]], r1
|
||||
; CHECK-LE-DAG: eor [[MISMATCH_HI:r[0-9]+]], [[REG2]], r2
|
||||
; CHECK-BE-DAG: eor [[MISMATCH_LO:r[0-9]+]], [[REG2]], r2
|
||||
; CHECK-BE-DAG: eor [[MISMATCH_HI:r[0-9]+]], [[REG1]], r1
|
||||
; CHECK: orrs {{r[0-9]+}}, [[MISMATCH_LO]], [[MISMATCH_HI]]
|
||||
; CHECK: bne
|
||||
; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}
|
||||
@ -163,8 +187,10 @@ define i64 @test7(i64* %ptr, i64 %val1, i64 %val2) {
|
||||
; CHECK-THUMB-LABEL: test7:
|
||||
; CHECK-THUMB: dmb {{ish$}}
|
||||
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
|
||||
; CHECK-THUMB-DAG: eor.w [[MISMATCH_LO:[a-z0-9]+]], [[REG1]], r2
|
||||
; CHECK-THUMB-DAG: eor.w [[MISMATCH_HI:[a-z0-9]+]], [[REG2]], r3
|
||||
; CHECK-THUMB-LE-DAG: eor.w [[MISMATCH_LO:[a-z0-9]+]], [[REG1]], r2
|
||||
; CHECK-THUMB-LE-DAG: eor.w [[MISMATCH_HI:[a-z0-9]+]], [[REG2]], r3
|
||||
; CHECK-THUMB-BE-DAG: eor.w [[MISMATCH_HI:[a-z0-9]+]], [[REG1]]
|
||||
; CHECK-THUMB-BE-DAG: eor.w [[MISMATCH_LO:[a-z0-9]+]], [[REG2]]
|
||||
; CHECK-THUMB: orrs [[MISMATCH_HI]], [[MISMATCH_LO]]
|
||||
; CHECK-THUMB: bne
|
||||
; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}}
|
||||
@ -220,9 +246,11 @@ define i64 @test10(i64* %ptr, i64 %val) {
|
||||
; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0
|
||||
; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0
|
||||
; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2
|
||||
; CHECK: cmp [[REG1]], r1
|
||||
; CHECK-LE: cmp [[REG1]], r1
|
||||
; CHECK-BE: cmp [[REG2]], r2
|
||||
; CHECK: movwls [[CARRY_LO]], #1
|
||||
; CHECK: cmp [[REG2]], r2
|
||||
; CHECK-LE: cmp [[REG2]], r2
|
||||
; CHECK-BE: cmp [[REG1]], r1
|
||||
; CHECK: movwle [[CARRY_HI]], #1
|
||||
; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]]
|
||||
; CHECK: cmp [[CARRY_HI]], #0
|
||||
@ -237,11 +265,13 @@ define i64 @test10(i64* %ptr, i64 %val) {
|
||||
; CHECK-THUMB-LABEL: test10:
|
||||
; CHECK-THUMB: dmb {{ish$}}
|
||||
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
|
||||
; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0
|
||||
; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0
|
||||
; CHECK-THUMB: cmp [[REG1]], r2
|
||||
; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+|lr]], #0
|
||||
; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+|lr]], #0
|
||||
; CHECK-THUMB-LE: cmp [[REG1]], r2
|
||||
; CHECK-THUMB-BE: cmp [[REG2]], r3
|
||||
; CHECK-THUMB: movls.w [[CARRY_LO]], #1
|
||||
; CHECK-THUMB: cmp [[REG2]], r3
|
||||
; CHECK-THUMB-LE: cmp [[REG2]], r3
|
||||
; CHECK-THUMB-BE: cmp [[REG1]], r2
|
||||
; CHECK-THUMB: movle [[CARRY_HI]], #1
|
||||
; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]]
|
||||
; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
|
||||
@ -265,9 +295,11 @@ define i64 @test11(i64* %ptr, i64 %val) {
|
||||
; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0
|
||||
; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0
|
||||
; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2
|
||||
; CHECK: cmp [[REG1]], r1
|
||||
; CHECK-LE: cmp [[REG1]], r1
|
||||
; CHECK-BE: cmp [[REG2]], r2
|
||||
; CHECK: movwls [[CARRY_LO]], #1
|
||||
; CHECK: cmp [[REG2]], r2
|
||||
; CHECK-LE: cmp [[REG2]], r2
|
||||
; CHECK-BE: cmp [[REG1]], r1
|
||||
; CHECK: movwls [[CARRY_HI]], #1
|
||||
; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]]
|
||||
; CHECK: cmp [[CARRY_HI]], #0
|
||||
@ -279,15 +311,16 @@ define i64 @test11(i64* %ptr, i64 %val) {
|
||||
; CHECK: bne
|
||||
; CHECK: dmb {{ish$}}
|
||||
|
||||
|
||||
; CHECK-THUMB-LABEL: test11:
|
||||
; CHECK-THUMB: dmb {{ish$}}
|
||||
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
|
||||
; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0
|
||||
; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0
|
||||
; CHECK-THUMB: cmp [[REG1]], r2
|
||||
; CHECK-THUMB-LE: cmp [[REG1]], r2
|
||||
; CHECK-THUMB-BE: cmp [[REG2]], r3
|
||||
; CHECK-THUMB: movls.w [[CARRY_LO]], #1
|
||||
; CHECK-THUMB: cmp [[REG2]], r3
|
||||
; CHECK-THUMB-LE: cmp [[REG2]], r3
|
||||
; CHECK-THUMB-BE: cmp [[REG1]], r2
|
||||
; CHECK-THUMB: movls [[CARRY_HI]], #1
|
||||
; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]]
|
||||
; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
|
||||
@ -311,9 +344,11 @@ define i64 @test12(i64* %ptr, i64 %val) {
|
||||
; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0
|
||||
; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0
|
||||
; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2
|
||||
; CHECK: cmp [[REG1]], r1
|
||||
; CHECK-LE: cmp [[REG1]], r1
|
||||
; CHECK-BE: cmp [[REG2]], r2
|
||||
; CHECK: movwhi [[CARRY_LO]], #1
|
||||
; CHECK: cmp [[REG2]], r2
|
||||
; CHECK-LE: cmp [[REG2]], r2
|
||||
; CHECK-BE: cmp [[REG1]], r1
|
||||
; CHECK: movwgt [[CARRY_HI]], #1
|
||||
; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]]
|
||||
; CHECK: cmp [[CARRY_HI]], #0
|
||||
@ -330,9 +365,11 @@ define i64 @test12(i64* %ptr, i64 %val) {
|
||||
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
|
||||
; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0
|
||||
; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0
|
||||
; CHECK-THUMB: cmp [[REG1]], r2
|
||||
; CHECK-THUMB-LE: cmp [[REG1]], r2
|
||||
; CHECK-THUMB-BE: cmp [[REG2]], r3
|
||||
; CHECK-THUMB: movhi.w [[CARRY_LO]], #1
|
||||
; CHECK-THUMB: cmp [[REG2]], r3
|
||||
; CHECK-THUMB-LE: cmp [[REG2]], r3
|
||||
; CHECK-THUMB-BE: cmp [[REG1]], r2
|
||||
; CHECK-THUMB: movgt [[CARRY_HI]], #1
|
||||
; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]]
|
||||
; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
|
||||
@ -356,9 +393,11 @@ define i64 @test13(i64* %ptr, i64 %val) {
|
||||
; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0
|
||||
; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0
|
||||
; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2
|
||||
; CHECK: cmp [[REG1]], r1
|
||||
; CHECK-LE: cmp [[REG1]], r1
|
||||
; CHECK-BE: cmp [[REG2]], r2
|
||||
; CHECK: movwhi [[CARRY_LO]], #1
|
||||
; CHECK: cmp [[REG2]], r2
|
||||
; CHECK-LE: cmp [[REG2]], r2
|
||||
; CHECK-BE: cmp [[REG1]], r1
|
||||
; CHECK: movwhi [[CARRY_HI]], #1
|
||||
; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]]
|
||||
; CHECK: cmp [[CARRY_HI]], #0
|
||||
@ -375,9 +414,11 @@ define i64 @test13(i64* %ptr, i64 %val) {
|
||||
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
|
||||
; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0
|
||||
; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0
|
||||
; CHECK-THUMB: cmp [[REG1]], r2
|
||||
; CHECK-THUMB-LE: cmp [[REG1]], r2
|
||||
; CHECK-THUMB-BE: cmp [[REG2]], r3
|
||||
; CHECK-THUMB: movhi.w [[CARRY_LO]], #1
|
||||
; CHECK-THUMB: cmp [[REG2]], r3
|
||||
; CHECK-THUMB-LE: cmp [[REG2]], r3
|
||||
; CHECK-THUMB-BE: cmp [[REG1]], r2
|
||||
; CHECK-THUMB: movhi [[CARRY_HI]], #1
|
||||
; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]]
|
||||
; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
|
||||
|
@ -1,5 +1,7 @@
|
||||
; RUN: llc -mtriple=armv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ARM
|
||||
; RUN: llc -mtriple=thumbv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-THUMB
|
||||
; RUN: llc -mtriple=armv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE --check-prefix=CHECK-ARM --check-prefix=CHECK-ARM-LE
|
||||
; RUN: llc -mtriple=armebv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE --check-prefix=CHECK-ARM --check-prefix=CHECK-ARM-BE
|
||||
; RUN: llc -mtriple=thumbv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-LE
|
||||
; RUN: llc -mtriple=thumbebv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-BE
|
||||
|
||||
@var8 = global i8 0
|
||||
@var16 = global i16 0
|
||||
@ -87,8 +89,10 @@ define void @test_atomic_load_add_i64(i64 %offset) nounwind {
|
||||
; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
|
||||
; r0, r1 below is a reasonable guess but could change: it certainly comes into the
|
||||
; function there.
|
||||
; CHECK-NEXT: adds{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
|
||||
; CHECK-NEXT: adc{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1
|
||||
; CHECK-LE-NEXT: adds{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
|
||||
; CHECK-LE-NEXT: adc{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1
|
||||
; CHECK-BE-NEXT: adds{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
|
||||
; CHECK-BE-NEXT: adc{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0
|
||||
; CHECK-NEXT: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
|
||||
; CHECK-NEXT: cmp [[STATUS]], #0
|
||||
; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
|
||||
@ -181,8 +185,10 @@ define void @test_atomic_load_sub_i64(i64 %offset) nounwind {
|
||||
; CHECK: ldaexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
|
||||
; r0, r1 below is a reasonable guess but could change: it certainly comes into the
|
||||
; function there.
|
||||
; CHECK-NEXT: subs{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
|
||||
; CHECK-NEXT: sbc{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1
|
||||
; CHECK-LE-NEXT: subs{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
|
||||
; CHECK-LE-NEXT: sbc{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1
|
||||
; CHECK-BE-NEXT: subs{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
|
||||
; CHECK-BE-NEXT: sbc{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0
|
||||
; CHECK-NEXT: stlexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
|
||||
; CHECK-NEXT: cmp [[STATUS]], #0
|
||||
; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
|
||||
@ -275,8 +281,10 @@ define void @test_atomic_load_and_i64(i64 %offset) nounwind {
|
||||
; CHECK: ldaexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
|
||||
; r0, r1 below is a reasonable guess but could change: it certainly comes into the
|
||||
; function there.
|
||||
; CHECK-DAG: and{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0
|
||||
; CHECK-DAG: and{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
|
||||
; CHECK-LE-DAG: and{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
|
||||
; CHECK-LE-DAG: and{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
|
||||
; CHECK-BE-DAG: and{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
|
||||
; CHECK-BE-DAG: and{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
|
||||
; CHECK: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
|
||||
; CHECK-NEXT: cmp [[STATUS]], #0
|
||||
; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
|
||||
@ -369,8 +377,10 @@ define void @test_atomic_load_or_i64(i64 %offset) nounwind {
|
||||
; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
|
||||
; r0, r1 below is a reasonable guess but could change: it certainly comes into the
|
||||
; function there.
|
||||
; CHECK-DAG: orr{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0
|
||||
; CHECK-DAG: orr{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
|
||||
; CHECK-LE-DAG: orr{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
|
||||
; CHECK-LE-DAG: orr{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
|
||||
; CHECK-BE-DAG: orr{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
|
||||
; CHECK-BE-DAG: orr{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
|
||||
; CHECK: stlexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
|
||||
; CHECK-NEXT: cmp [[STATUS]], #0
|
||||
; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
|
||||
@ -463,8 +473,10 @@ define void @test_atomic_load_xor_i64(i64 %offset) nounwind {
|
||||
; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
|
||||
; r0, r1 below is a reasonable guess but could change: it certainly comes into the
|
||||
; function there.
|
||||
; CHECK-DAG: eor{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0
|
||||
; CHECK-DAG: eor{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
|
||||
; CHECK-LE-DAG: eor{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
|
||||
; CHECK-LE-DAG: eor{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
|
||||
; CHECK-BE-DAG: eor{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
|
||||
; CHECK-BE-DAG: eor{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
|
||||
; CHECK: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
|
||||
; CHECK-NEXT: cmp [[STATUS]], #0
|
||||
; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
|
||||
@ -657,10 +669,14 @@ define void @test_atomic_load_min_i64(i64 %offset) nounwind {
|
||||
; function there.
|
||||
; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0
|
||||
; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0
|
||||
; CHECK-ARM: cmp [[OLD1]], r0
|
||||
; CHECK-ARM: movwls [[LOCARRY]], #1
|
||||
; CHECK-ARM: cmp [[OLD2]], r1
|
||||
; CHECK-ARM: movwle [[HICARRY]], #1
|
||||
; CHECK-ARM-LE: cmp [[OLD1]], r0
|
||||
; CHECK-ARM-LE: movwls [[LOCARRY]], #1
|
||||
; CHECK-ARM-LE: cmp [[OLD2]], r1
|
||||
; CHECK-ARM-LE: movwle [[HICARRY]], #1
|
||||
; CHECK-ARM-BE: cmp [[OLD2]], r1
|
||||
; CHECK-ARM-BE: movwls [[LOCARRY]], #1
|
||||
; CHECK-ARM-BE: cmp [[OLD1]], r0
|
||||
; CHECK-ARM-BE: movwle [[HICARRY]], #1
|
||||
; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]]
|
||||
; CHECK-ARM: cmp [[HICARRY]], #0
|
||||
; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
|
||||
@ -771,10 +787,14 @@ define void @test_atomic_load_max_i64(i64 %offset) nounwind {
|
||||
; function there.
|
||||
; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0
|
||||
; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0
|
||||
; CHECK-ARM: cmp [[OLD1]], r0
|
||||
; CHECK-ARM: movwhi [[LOCARRY]], #1
|
||||
; CHECK-ARM: cmp [[OLD2]], r1
|
||||
; CHECK-ARM: movwgt [[HICARRY]], #1
|
||||
; CHECK-ARM-LE: cmp [[OLD1]], r0
|
||||
; CHECK-ARM-LE: movwhi [[LOCARRY]], #1
|
||||
; CHECK-ARM-LE: cmp [[OLD2]], r1
|
||||
; CHECK-ARM-LE: movwgt [[HICARRY]], #1
|
||||
; CHECK-ARM-BE: cmp [[OLD2]], r1
|
||||
; CHECK-ARM-BE: movwhi [[LOCARRY]], #1
|
||||
; CHECK-ARM-BE: cmp [[OLD1]], r0
|
||||
; CHECK-ARM-BE: movwgt [[HICARRY]], #1
|
||||
; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]]
|
||||
; CHECK-ARM: cmp [[HICARRY]], #0
|
||||
; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
|
||||
@ -885,10 +905,14 @@ define void @test_atomic_load_umin_i64(i64 %offset) nounwind {
|
||||
; function there.
|
||||
; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0
|
||||
; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0
|
||||
; CHECK-ARM: cmp [[OLD1]], r0
|
||||
; CHECK-ARM: movwls [[LOCARRY]], #1
|
||||
; CHECK-ARM: cmp [[OLD2]], r1
|
||||
; CHECK-ARM: movwls [[HICARRY]], #1
|
||||
; CHECK-ARM-LE: cmp [[OLD1]], r0
|
||||
; CHECK-ARM-LE: movwls [[LOCARRY]], #1
|
||||
; CHECK-ARM-LE: cmp [[OLD2]], r1
|
||||
; CHECK-ARM-LE: movwls [[HICARRY]], #1
|
||||
; CHECK-ARM-BE: cmp [[OLD2]], r1
|
||||
; CHECK-ARM-BE: movwls [[LOCARRY]], #1
|
||||
; CHECK-ARM-BE: cmp [[OLD1]], r0
|
||||
; CHECK-ARM-BE: movwls [[HICARRY]], #1
|
||||
; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]]
|
||||
; CHECK-ARM: cmp [[HICARRY]], #0
|
||||
; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
|
||||
@ -999,10 +1023,14 @@ define void @test_atomic_load_umax_i64(i64 %offset) nounwind {
|
||||
; function there.
|
||||
; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0
|
||||
; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0
|
||||
; CHECK-ARM: cmp [[OLD1]], r0
|
||||
; CHECK-ARM: movwhi [[LOCARRY]], #1
|
||||
; CHECK-ARM: cmp [[OLD2]], r1
|
||||
; CHECK-ARM: movwhi [[HICARRY]], #1
|
||||
; CHECK-ARM-LE: cmp [[OLD1]], r0
|
||||
; CHECK-ARM-LE: movwhi [[LOCARRY]], #1
|
||||
; CHECK-ARM-LE: cmp [[OLD2]], r1
|
||||
; CHECK-ARM-LE: movwhi [[HICARRY]], #1
|
||||
; CHECK-ARM-BE: cmp [[OLD2]], r1
|
||||
; CHECK-ARM-BE: movwhi [[LOCARRY]], #1
|
||||
; CHECK-ARM-BE: cmp [[OLD1]], r0
|
||||
; CHECK-ARM-BE: movwhi [[HICARRY]], #1
|
||||
; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]]
|
||||
; CHECK-ARM: cmp [[HICARRY]], #0
|
||||
; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
|
||||
@ -1112,9 +1140,12 @@ define void @test_atomic_cmpxchg_i64(i64 %wanted, i64 %new) nounwind {
|
||||
; CHECK: ldrexd [[OLD1:r[0-9]+|lr]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]
|
||||
; r0, r1 below is a reasonable guess but could change: it certainly comes into the
|
||||
; function there.
|
||||
; CHECK-DAG: eor{{(\.w)?}} [[MISMATCH_LO:r[0-9]+|lr]], [[OLD1]], r0
|
||||
; CHECK-DAG: eor{{(\.w)?}} [[MISMATCH_HI:r[0-9]+|lr]], [[OLD2]], r1
|
||||
; CHECK: orrs{{(\.w)?}} {{r[0-9]+}}, [[MISMATCH_LO]], [[MISMATCH_HI]]
|
||||
; CHECK-LE-DAG: eor{{(\.w)?}} [[MISMATCH_LO:r[0-9]+|lr]], [[OLD1]], r0
|
||||
; CHECK-LE-DAG: eor{{(\.w)?}} [[MISMATCH_HI:r[0-9]+|lr]], [[OLD2]], r1
|
||||
; CHECK-LE: orrs{{(\.w)?}} {{r[0-9]+}}, [[MISMATCH_LO]], [[MISMATCH_HI]]
|
||||
; CHECK-BE-DAG: eor{{(\.w)?}} [[MISMATCH_HI:r[0-9]+|lr]], [[OLD2]], r1
|
||||
; CHECK-BE-DAG: eor{{(\.w)?}} [[MISMATCH_LO:r[0-9]+|lr]], [[OLD1]], r0
|
||||
; CHECK-BE: orrs{{(\.w)?}} {{r[0-9]+}}, [[MISMATCH_HI]], [[MISMATCH_LO]]
|
||||
; CHECK-NEXT: bne .LBB{{[0-9]+}}_3
|
||||
; CHECK-NEXT: BB#2:
|
||||
; As above, r2, r3 is a reasonable guess.
|
||||
@ -1151,7 +1182,8 @@ define i8 @test_atomic_load_monotonic_regoff_i8(i64 %base, i64 %off) nounwind {
|
||||
%val = load atomic i8* %addr monotonic, align 1
|
||||
; CHECK-NOT: dmb
|
||||
; CHECK-NOT: mcr
|
||||
; CHECK: ldrb r0, [r0, r2]
|
||||
; CHECK-LE: ldrb r0, [r0, r2]
|
||||
; CHECK-BE: ldrb r0, [r1, r3]
|
||||
; CHECK-NOT: dmb
|
||||
; CHECK-NOT: mcr
|
||||
|
||||
@ -1218,7 +1250,8 @@ define i32 @test_atomic_load_monotonic_regoff_i32(i64 %base, i64 %off) nounwind
|
||||
%val = load atomic i32* %addr monotonic, align 4
|
||||
; CHECK-NOT: dmb
|
||||
; CHECK-NOT: mcr
|
||||
; CHECK: ldr r0, [r0, r2]
|
||||
; CHECK-LE: ldr r0, [r0, r2]
|
||||
; CHECK-BE: ldr r0, [r1, r3]
|
||||
; CHECK-NOT: dmb
|
||||
; CHECK-NOT: mcr
|
||||
|
||||
@ -1259,8 +1292,10 @@ define void @test_atomic_store_monotonic_regoff_i8(i64 %base, i64 %off, i8 %val)
|
||||
%addr = inttoptr i64 %addr_int to i8*
|
||||
|
||||
store atomic i8 %val, i8* %addr monotonic, align 1
|
||||
; CHECK: ldrb{{(\.w)?}} [[VAL:r[0-9]+]], [sp]
|
||||
; CHECK: strb [[VAL]], [r0, r2]
|
||||
; CHECK-LE: ldrb{{(\.w)?}} [[VAL:r[0-9]+]], [sp]
|
||||
; CHECK-LE: strb [[VAL]], [r0, r2]
|
||||
; CHECK-BE: ldrb{{(\.w)?}} [[VAL:r[0-9]+]], [sp, #3]
|
||||
; CHECK-BE: strb [[VAL]], [r1, r3]
|
||||
|
||||
ret void
|
||||
}
|
||||
@ -1328,7 +1363,8 @@ define void @test_atomic_store_monotonic_regoff_i32(i64 %base, i64 %off, i32 %va
|
||||
; CHECK: ldr [[VAL:r[0-9]+]], [sp]
|
||||
; CHECK-NOT: dmb
|
||||
; CHECK-NOT: mcr
|
||||
; CHECK: str [[VAL]], [r0, r2]
|
||||
; CHECK-LE: str [[VAL]], [r0, r2]
|
||||
; CHECK-BE: str [[VAL]], [r1, r3]
|
||||
; CHECK-NOT: dmb
|
||||
; CHECK-NOT: mcr
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
; RUN: llc < %s -mtriple=thumbv7s-apple-ios3.0.0 -mcpu=generic | FileCheck %s
|
||||
; RUN: llc < %s -mtriple=thumbv7s-apple-ios3.0.0 -mcpu=generic | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE
|
||||
; RUN: llc < %s -mtriple=thumbeb -mattr=v7,neon | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE
|
||||
|
||||
; PR15525
|
||||
; CHECK-LABEL: test1:
|
||||
; CHECK: ldr.w [[REG:r[0-9]+]], [sp]
|
||||
; CHECK-NEXT: vmov {{d[0-9]+}}, r1, r2
|
||||
; CHECK-NEXT: vmov {{d[0-9]+}}, r3, [[REG]]
|
||||
; CHECK-LE-NEXT: vmov {{d[0-9]+}}, r1, r2
|
||||
; CHECK-LE-NEXT: vmov {{d[0-9]+}}, r3, [[REG]]
|
||||
; CHECK-BE-NEXT: vmov {{d[0-9]+}}, r2, r1
|
||||
; CHECK-BE-NEXT: vmov {{d[0-9]+}}, [[REG]], r3
|
||||
; CHECK-NEXT: vst1.8 {{{d[0-9]+}}, {{d[0-9]+}}}, [r0]
|
||||
; CHECK-NEXT: bx lr
|
||||
define void @test1(i8* %arg, [4 x i64] %vec.coerce) {
|
||||
|
124
test/CodeGen/ARM/func-argpassing-endian.ll
Normal file
124
test/CodeGen/ARM/func-argpassing-endian.ll
Normal file
@ -0,0 +1,124 @@
|
||||
; RUN: llc -verify-machineinstrs < %s -march=arm -mattr=v7,neon | FileCheck --check-prefix=CHECK --check-prefix=CHECK-LE %s
|
||||
; RUN: llc -verify-machineinstrs < %s -march=armeb -mattr=v7,neon | FileCheck --check-prefix=CHECK --check-prefix=CHECK-BE %s
|
||||
|
||||
@var32 = global i32 0
|
||||
@vardouble = global double 0.0
|
||||
|
||||
define void @arg_longint( i64 %val ) {
|
||||
; CHECK-LABEL: arg_longint:
|
||||
; CHECK-LE: str r0, [r1]
|
||||
; CHECK-BE: str r1, [r0]
|
||||
%tmp = trunc i64 %val to i32
|
||||
store i32 %tmp, i32* @var32
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @arg_double( double %val ) {
|
||||
; CHECK-LABEL: arg_double:
|
||||
; CHECK: strd r0, r1, [r2]
|
||||
store double %val, double* @vardouble
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @arg_v4i32(<4 x i32> %vec ) {
|
||||
; CHECK-LABEL: arg_v4i32:
|
||||
; CHECK-LE: vmov d17, r2, r3
|
||||
; CHECK-LE: vmov d16, r0, r1
|
||||
; CHECK-BE: vmov d17, r3, r2
|
||||
; CHECK-BE: vmov d16, r1, r0
|
||||
; CHECK: vst1.32 {d16[0]}, [r0:32]
|
||||
%tmp = extractelement <4 x i32> %vec, i32 0
|
||||
store i32 %tmp, i32* @var32
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @arg_v2f64(<2 x double> %vec ) {
|
||||
; CHECK-LABEL: arg_v2f64:
|
||||
; CHECK: strd r0, r1, [r2]
|
||||
%tmp = extractelement <2 x double> %vec, i32 0
|
||||
store double %tmp, double* @vardouble
|
||||
ret void
|
||||
}
|
||||
|
||||
define i64 @return_longint() {
|
||||
; CHECK-LABEL: return_longint:
|
||||
; CHECK-LE: mov r0, #42
|
||||
; CHECK-LE: mov r1, #0
|
||||
; CHECK-BE: mov r0, #0
|
||||
; CHECK-BE: mov r1, #42
|
||||
ret i64 42
|
||||
}
|
||||
|
||||
define double @return_double() {
|
||||
; CHECK-LABEL: return_double:
|
||||
; CHECK-LE: vmov r0, r1, d16
|
||||
; CHECK-BE: vmov r1, r0, d16
|
||||
ret double 1.0
|
||||
}
|
||||
|
||||
define <4 x i32> @return_v4i32() {
|
||||
; CHECK-LABEL: return_v4i32:
|
||||
; CHECK-LE: vmov r0, r1, d16
|
||||
; CHECK-LE: vmov r2, r3, d17
|
||||
; CHECK-BE: vmov r1, r0, d16
|
||||
; CHECK-BE: vmov r3, r2, d17
|
||||
ret < 4 x i32> < i32 42, i32 43, i32 44, i32 45 >
|
||||
}
|
||||
|
||||
define <2 x double> @return_v2f64() {
|
||||
; CHECK-LABEL: return_v2f64:
|
||||
; CHECK-LE: vmov r0, r1, d16
|
||||
; CHECK-LE: vmov r2, r3, d17
|
||||
; CHECK-BE: vmov r1, r0, d16
|
||||
; CHECK-BE: vmov r3, r2, d17
|
||||
ret <2 x double> < double 3.14, double 6.28 >
|
||||
}
|
||||
|
||||
define void @caller_arg_longint() {
|
||||
; CHECK-LABEL: caller_arg_longint:
|
||||
; CHECK-LE: mov r0, #42
|
||||
; CHECK-LE: mov r1, #0
|
||||
; CHECK-BE: mov r0, #0
|
||||
; CHECK-BE: mov r1, #42
|
||||
call void @arg_longint( i64 42 )
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @caller_arg_double() {
|
||||
; CHECK-LABEL: caller_arg_double:
|
||||
; CHECK-LE: vmov r0, r1, d16
|
||||
; CHECK-BE: vmov r1, r0, d16
|
||||
call void @arg_double( double 1.0 )
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @caller_return_longint() {
|
||||
; CHECK-LABEL: caller_return_longint:
|
||||
; CHECK-LE: str r0, [r1]
|
||||
; CHECK-BE: str r1, [r0]
|
||||
%val = call i64 @return_longint()
|
||||
%tmp = trunc i64 %val to i32
|
||||
store i32 %tmp, i32* @var32
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @caller_return_double() {
|
||||
; CHECK-LABEL: caller_return_double:
|
||||
; CHECK-LE: vmov d17, r0, r1
|
||||
; CHECK-BE: vmov d17, r1, r0
|
||||
%val = call double @return_double( )
|
||||
%tmp = fadd double %val, 3.14
|
||||
store double %tmp, double* @vardouble
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @caller_return_v2f64() {
|
||||
; CHECK-LABEL: caller_return_v2f64:
|
||||
; CHECK: strd r0, r1, [r2]
|
||||
%val = call <2 x double> @return_v2f64( )
|
||||
%tmp = extractelement <2 x double> %val, i32 0
|
||||
store double %tmp, double* @vardouble
|
||||
ret void
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s
|
||||
; RUN: llc -mtriple=armv7-eabi %s -o - | FileCheck %s --check-prefix=CHECK-V7
|
||||
; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s -check-prefix=CHECK --check-prefix=CHECK-LE
|
||||
; RUN: llc -mtriple=armv7-eabi %s -o - | FileCheck %s --check-prefix=CHECK-V7-LE
|
||||
; RUN: llc -mtriple=armeb-eabi %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE
|
||||
; RUN: llc -mtriple=armebv7-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V7-BE
|
||||
; Check generated signed and unsigned multiply accumulate long.
|
||||
|
||||
define i64 @MACLongTest1(i32 %a, i32 %b, i64 %c) {
|
||||
@ -53,13 +55,18 @@ define i64 @MACLongTest4(i32 %a, i32 %b, i32 %c) {
|
||||
; function, both after the umlal. With it, *some* move has to happen
|
||||
; before the umlal.
|
||||
define i64 @MACLongTest5(i64 %c, i32 %a, i32 %b) {
|
||||
; CHECK-V7-LABEL: MACLongTest5:
|
||||
; CHECK-V7-LABEL: umlal r0, r1, r0, r0
|
||||
; CHECK-V7-LE-LABEL: MACLongTest5:
|
||||
; CHECK-V7-LE-LABEL: umlal r0, r1, r0, r0
|
||||
; CHECK-V7-BE-LABEL: MACLongTest5:
|
||||
; CHECK-V7-BE-LABEL: umlal r1, r0, r1, r1
|
||||
|
||||
; CHECK-LABEL: MACLongTest5:
|
||||
; CHECK: mov [[RDLO:r[0-9]+]], r0
|
||||
; CHECK: umlal [[RDLO]], r1, r0, r0
|
||||
; CHECK: mov r0, [[RDLO]]
|
||||
; CHECK-LE: mov [[RDLO:r[0-9]+]], r0
|
||||
; CHECK-LE: umlal [[RDLO]], r1, r0, r0
|
||||
; CHECK-LE: mov r0, [[RDLO]]
|
||||
; CHECK-BE: mov [[RDLO:r[0-9]+]], r1
|
||||
; CHECK-BE: umlal [[RDLO]], r0, r1, r1
|
||||
; CHECK-BE: mov r1, [[RDLO]]
|
||||
|
||||
%conv.trunc = trunc i64 %c to i32
|
||||
%conv = zext i32 %conv.trunc to i64
|
||||
|
@ -1,11 +1,16 @@
|
||||
; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s
|
||||
; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE
|
||||
; RUN: llc -mtriple=armeb-eabi %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE
|
||||
|
||||
define i64 @f0(i64 %A, i64 %B) {
|
||||
; CHECK-LABEL: f0:
|
||||
; CHECK: lsrs r3, r3, #1
|
||||
; CHECK-NEXT: rrx r2, r2
|
||||
; CHECK-NEXT: subs r0, r0, r2
|
||||
; CHECK-NEXT: sbc r1, r1, r3
|
||||
; CHECK-LE: lsrs r3, r3, #1
|
||||
; CHECK-LE-NEXT: rrx r2, r2
|
||||
; CHECK-LE-NEXT: subs r0, r0, r2
|
||||
; CHECK-LE-NEXT: sbc r1, r1, r3
|
||||
; CHECK-BE: lsrs r2, r2, #1
|
||||
; CHECK-BE-NEXT: rrx r3, r3
|
||||
; CHECK-BE-NEXT: subs r1, r1, r3
|
||||
; CHECK-BE-NEXT: sbc r0, r0, r2
|
||||
%tmp = bitcast i64 %A to i64
|
||||
%tmp2 = lshr i64 %B, 1
|
||||
%tmp3 = sub i64 %tmp, %tmp2
|
||||
@ -14,7 +19,8 @@ define i64 @f0(i64 %A, i64 %B) {
|
||||
|
||||
define i32 @f1(i64 %x, i64 %y) {
|
||||
; CHECK-LABEL: f1:
|
||||
; CHECK: lsl{{.*}}r2
|
||||
; CHECK-LE: lsl{{.*}}r2
|
||||
; CHECK-BE: lsl{{.*}}r3
|
||||
%a = shl i64 %x, %y
|
||||
%b = trunc i64 %a to i32
|
||||
ret i32 %b
|
||||
@ -22,12 +28,20 @@ define i32 @f1(i64 %x, i64 %y) {
|
||||
|
||||
define i32 @f2(i64 %x, i64 %y) {
|
||||
; CHECK-LABEL: f2:
|
||||
; CHECK: lsr{{.*}}r2
|
||||
; CHECK-NEXT: rsb r3, r2, #32
|
||||
; CHECK-NEXT: sub r2, r2, #32
|
||||
; CHECK-NEXT: orr r0, r0, r1, lsl r3
|
||||
; CHECK-NEXT: cmp r2, #0
|
||||
; CHECK-NEXT: asrge r0, r1, r2
|
||||
; CHECK-LE: lsr{{.*}}r2
|
||||
; CHECK-LE-NEXT: rsb r3, r2, #32
|
||||
; CHECK-LE-NEXT: sub r2, r2, #32
|
||||
; CHECK-LE-NEXT: orr r0, r0, r1, lsl r3
|
||||
; CHECK-LE-NEXT: cmp r2, #0
|
||||
; CHECK-LE-NEXT: asrge r0, r1, r2
|
||||
|
||||
; CHECK-BE: lsr{{.*}}r3
|
||||
; CHECK-BE-NEXT: rsb r2, r3, #32
|
||||
; CHECK-BE-NEXT: orr r1, r1, r0, lsl r2
|
||||
; CHECK-BE-NEXT: sub r2, r3, #32
|
||||
; CHECK-BE-NEXT: cmp r2, #0
|
||||
; CHECK-BE-NEXT: asrge r1, r0, r2
|
||||
|
||||
%a = ashr i64 %x, %y
|
||||
%b = trunc i64 %a to i32
|
||||
ret i32 %b
|
||||
@ -35,12 +49,20 @@ define i32 @f2(i64 %x, i64 %y) {
|
||||
|
||||
define i32 @f3(i64 %x, i64 %y) {
|
||||
; CHECK-LABEL: f3:
|
||||
; CHECK: lsr{{.*}}r2
|
||||
; CHECK-NEXT: rsb r3, r2, #32
|
||||
; CHECK-NEXT: sub r2, r2, #32
|
||||
; CHECK-NEXT: orr r0, r0, r1, lsl r3
|
||||
; CHECK-NEXT: cmp r2, #0
|
||||
; CHECK-NEXT: lsrge r0, r1, r2
|
||||
; CHECK-LE: lsr{{.*}}r2
|
||||
; CHECK-LE-NEXT: rsb r3, r2, #32
|
||||
; CHECK-LE-NEXT: sub r2, r2, #32
|
||||
; CHECK-LE-NEXT: orr r0, r0, r1, lsl r3
|
||||
; CHECK-LE-NEXT: cmp r2, #0
|
||||
; CHECK-LE-NEXT: lsrge r0, r1, r2
|
||||
|
||||
; CHECK-BE: lsr{{.*}}r3
|
||||
; CHECK-BE-NEXT: rsb r2, r3, #32
|
||||
; CHECK-BE-NEXT: orr r1, r1, r0, lsl r2
|
||||
; CHECK-BE-NEXT: sub r2, r3, #32
|
||||
; CHECK-BE-NEXT: cmp r2, #0
|
||||
; CHECK-BE-NEXT: lsrge r1, r0, r2
|
||||
|
||||
%a = lshr i64 %x, %y
|
||||
%b = trunc i64 %a to i32
|
||||
ret i32 %b
|
||||
|
@ -1,10 +1,13 @@
|
||||
; RUN: llc -mtriple=arm-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s
|
||||
; RUN: llc -mtriple=arm-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE
|
||||
; RUN: llc -mtriple=armeb-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE
|
||||
|
||||
; 171 = 0x000000ab
|
||||
define i64 @f1(i64 %a) {
|
||||
; CHECK: f1
|
||||
; CHECK: subs r0, r0, #171
|
||||
; CHECK: sbc r1, r1, #0
|
||||
; CHECK-LE: subs r0, r0, #171
|
||||
; CHECK-LE: sbc r1, r1, #0
|
||||
; CHECK-BE: subs r1, r1, #171
|
||||
; CHECK-BE: sbc r0, r0, #0
|
||||
%tmp = sub i64 %a, 171
|
||||
ret i64 %tmp
|
||||
}
|
||||
@ -12,8 +15,10 @@ define i64 @f1(i64 %a) {
|
||||
; 66846720 = 0x03fc0000
|
||||
define i64 @f2(i64 %a) {
|
||||
; CHECK: f2
|
||||
; CHECK: subs r0, r0, #66846720
|
||||
; CHECK: sbc r1, r1, #0
|
||||
; CHECK-LE: subs r0, r0, #66846720
|
||||
; CHECK-LE: sbc r1, r1, #0
|
||||
; CHECK-BE: subs r1, r1, #66846720
|
||||
; CHECK-BE: sbc r0, r0, #0
|
||||
%tmp = sub i64 %a, 66846720
|
||||
ret i64 %tmp
|
||||
}
|
||||
@ -21,8 +26,10 @@ define i64 @f2(i64 %a) {
|
||||
; 734439407618 = 0x000000ab00000002
|
||||
define i64 @f3(i64 %a) {
|
||||
; CHECK: f3
|
||||
; CHECK: subs r0, r0, #2
|
||||
; CHECK: sbc r1, r1, #171
|
||||
; CHECK-LE: subs r0, r0, #2
|
||||
; CHECK-LE: sbc r1, r1, #171
|
||||
; CHECK-BE: subs r1, r1, #2
|
||||
; CHECK-BE: sbc r0, r0, #171
|
||||
%tmp = sub i64 %a, 734439407618
|
||||
ret i64 %tmp
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
; RUN: llc -mtriple=arm-eabi -float-abi=soft -mattr=+neon %s -o - | FileCheck %s
|
||||
; RUN: llc -mtriple=arm-eabi -float-abi=soft -mattr=+neon %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE
|
||||
; RUN: llc -mtriple=armeb-eabi -float-abi=soft -mattr=+neon %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE
|
||||
|
||||
define <16 x i8> @vcombine8(<8 x i8>* %A, <8 x i8>* %B) nounwind {
|
||||
; CHECK: vcombine8
|
||||
; CHECK: vmov r0, r1, d16
|
||||
; CHECK: vmov r2, r3, d17
|
||||
; CHECK-LE: vmov r0, r1, d16
|
||||
; CHECK-LE: vmov r2, r3, d17
|
||||
; CHECK-BE: vmov r1, r0, d16
|
||||
; CHECK-BE: vmov r3, r2, d17
|
||||
%tmp1 = load <8 x i8>* %A
|
||||
%tmp2 = load <8 x i8>* %B
|
||||
%tmp3 = shufflevector <8 x i8> %tmp1, <8 x i8> %tmp2, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
||||
@ -12,8 +15,10 @@ define <16 x i8> @vcombine8(<8 x i8>* %A, <8 x i8>* %B) nounwind {
|
||||
|
||||
define <8 x i16> @vcombine16(<4 x i16>* %A, <4 x i16>* %B) nounwind {
|
||||
; CHECK: vcombine16
|
||||
; CHECK: vmov r0, r1, d16
|
||||
; CHECK: vmov r2, r3, d17
|
||||
; CHECK-LE: vmov r0, r1, d16
|
||||
; CHECK-LE: vmov r2, r3, d17
|
||||
; CHECK-BE: vmov r1, r0, d16
|
||||
; CHECK-BE: vmov r3, r2, d17
|
||||
%tmp1 = load <4 x i16>* %A
|
||||
%tmp2 = load <4 x i16>* %B
|
||||
%tmp3 = shufflevector <4 x i16> %tmp1, <4 x i16> %tmp2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
||||
@ -22,8 +27,10 @@ define <8 x i16> @vcombine16(<4 x i16>* %A, <4 x i16>* %B) nounwind {
|
||||
|
||||
define <4 x i32> @vcombine32(<2 x i32>* %A, <2 x i32>* %B) nounwind {
|
||||
; CHECK: vcombine32
|
||||
; CHECK: vmov r0, r1, d16
|
||||
; CHECK: vmov r2, r3, d17
|
||||
; CHECK-LE: vmov r0, r1, d16
|
||||
; CHECK-LE: vmov r2, r3, d17
|
||||
; CHECK-BE: vmov r1, r0, d16
|
||||
; CHECK-BE: vmov r3, r2, d17
|
||||
%tmp1 = load <2 x i32>* %A
|
||||
%tmp2 = load <2 x i32>* %B
|
||||
%tmp3 = shufflevector <2 x i32> %tmp1, <2 x i32> %tmp2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
||||
@ -32,8 +39,10 @@ define <4 x i32> @vcombine32(<2 x i32>* %A, <2 x i32>* %B) nounwind {
|
||||
|
||||
define <4 x float> @vcombinefloat(<2 x float>* %A, <2 x float>* %B) nounwind {
|
||||
; CHECK: vcombinefloat
|
||||
; CHECK: vmov r0, r1, d16
|
||||
; CHECK: vmov r2, r3, d17
|
||||
; CHECK-LE: vmov r0, r1, d16
|
||||
; CHECK-LE: vmov r2, r3, d17
|
||||
; CHECK-BE: vmov r1, r0, d16
|
||||
; CHECK-BE: vmov r3, r2, d17
|
||||
%tmp1 = load <2 x float>* %A
|
||||
%tmp2 = load <2 x float>* %B
|
||||
%tmp3 = shufflevector <2 x float> %tmp1, <2 x float> %tmp2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
||||
@ -42,8 +51,10 @@ define <4 x float> @vcombinefloat(<2 x float>* %A, <2 x float>* %B) nounwind {
|
||||
|
||||
define <2 x i64> @vcombine64(<1 x i64>* %A, <1 x i64>* %B) nounwind {
|
||||
; CHECK: vcombine64
|
||||
; CHECK: vmov r0, r1, d16
|
||||
; CHECK: vmov r2, r3, d17
|
||||
; CHECK-LE: vmov r0, r1, d16
|
||||
; CHECK-LE: vmov r2, r3, d17
|
||||
; CHECK-BE: vmov r1, r0, d16
|
||||
; CHECK-BE: vmov r3, r2, d17
|
||||
%tmp1 = load <1 x i64>* %A
|
||||
%tmp2 = load <1 x i64>* %B
|
||||
%tmp3 = shufflevector <1 x i64> %tmp1, <1 x i64> %tmp2, <2 x i32> <i32 0, i32 1>
|
||||
@ -56,7 +67,8 @@ define <2 x i64> @vcombine64(<1 x i64>* %A, <1 x i64>* %B) nounwind {
|
||||
define <4 x i16> @vget_low16(<8 x i16>* %A) nounwind {
|
||||
; CHECK: vget_low16
|
||||
; CHECK-NOT: vst
|
||||
; CHECK: vmov r0, r1, d16
|
||||
; CHECK-LE: vmov r0, r1, d16
|
||||
; CHECK-BE: vmov r1, r0, d16
|
||||
%tmp1 = load <8 x i16>* %A
|
||||
%tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
||||
ret <4 x i16> %tmp2
|
||||
@ -65,7 +77,8 @@ define <4 x i16> @vget_low16(<8 x i16>* %A) nounwind {
|
||||
define <8 x i8> @vget_high8(<16 x i8>* %A) nounwind {
|
||||
; CHECK: vget_high8
|
||||
; CHECK-NOT: vst
|
||||
; CHECK: vmov r0, r1, d17
|
||||
; CHECK-LE: vmov r0, r1, d17
|
||||
; CHECK-BE: vmov r1, r0, d17
|
||||
%tmp1 = load <16 x i8>* %A
|
||||
%tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
||||
ret <8 x i8> %tmp2
|
||||
|
Loading…
x
Reference in New Issue
Block a user