Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -1293,6 +1293,8 @@ 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 @@ 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 @@ 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 @@ SDValue Flag; SmallVector 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 @@ 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 @@ // 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 @@ 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); } @@ -8303,16 +8316,18 @@ 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)); @@ -10528,6 +10543,8 @@ 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( @@ -10561,6 +10578,8 @@ 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); } Index: test/CodeGen/ARM/atomic-64bit.ll =================================================================== --- test/CodeGen/ARM/atomic-64bit.ll +++ test/CodeGen/ARM/atomic-64bit.ll @@ -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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 Index: test/CodeGen/ARM/atomic-ops-v8.ll =================================================================== --- test/CodeGen/ARM/atomic-ops-v8.ll +++ test/CodeGen/ARM/atomic-ops-v8.ll @@ -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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ %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 @@ %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 @@ %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 @@ ; 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 Index: test/CodeGen/ARM/dagcombine-concatvector.ll =================================================================== --- test/CodeGen/ARM/dagcombine-concatvector.ll +++ test/CodeGen/ARM/dagcombine-concatvector.ll @@ -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 -march=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) { Index: test/CodeGen/ARM/func-argpassing-endian.ll =================================================================== --- test/CodeGen/ARM/func-argpassing-endian.ll +++ test/CodeGen/ARM/func-argpassing-endian.ll @@ -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 +} + + Index: test/CodeGen/ARM/longMAC.ll =================================================================== --- test/CodeGen/ARM/longMAC.ll +++ test/CodeGen/ARM/longMAC.ll @@ -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 @@ ; 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 Index: test/CodeGen/ARM/long_shift.ll =================================================================== --- test/CodeGen/ARM/long_shift.ll +++ test/CodeGen/ARM/long_shift.ll @@ -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 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 @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 @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 Index: test/CodeGen/ARM/sub.ll =================================================================== --- test/CodeGen/ARM/sub.ll +++ test/CodeGen/ARM/sub.ll @@ -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 @@ ; 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 @@ ; 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 } Index: test/CodeGen/ARM/vcombine.ll =================================================================== --- test/CodeGen/ARM/vcombine.ll +++ test/CodeGen/ARM/vcombine.ll @@ -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> @@ -12,8 +15,10 @@ 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> @@ -22,8 +27,10 @@ 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> @@ -32,8 +39,10 @@ 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> @@ -42,8 +51,10 @@ 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> @@ -56,7 +67,8 @@ 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> ret <4 x i16> %tmp2 @@ -65,7 +77,8 @@ 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> ret <8 x i8> %tmp2