Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -1335,6 +1335,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) { @@ -1350,6 +1352,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)); @@ -1400,16 +1404,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() == 0) 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)); } @@ -2123,6 +2128,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; @@ -2149,12 +2155,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 @@ -2167,11 +2176,14 @@ // available. SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl, DAG.getVTList(MVT::i32, MVT::i32), &Arg, 1); - 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); @@ -2703,7 +2715,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); } @@ -6517,6 +6530,7 @@ static_cast(MI->getOperand(IsCmpxchg ? 7 : 5).getImm()); DebugLoc dl = MI->getDebugLoc(); bool isThumb2 = Subtarget->isThumb2(); + bool isLittleEndian = Subtarget->isLittle(); MachineRegisterInfo &MRI = BB->getParent()->getRegInfo(); if (isThumb2) { @@ -6571,8 +6585,10 @@ // Load if (isThumb2) { AddDefaultPred(BuildMI(BB, dl, TII->get(ldrOpc)) - .addReg(destlo, RegState::Define) - .addReg(desthi, RegState::Define) + .addReg(isLittleEndian ? destlo : desthi, + RegState::Define) + .addReg(isLittleEndian ? desthi : destlo, + RegState::Define) .addReg(ptr)); } else { unsigned GPRPair0 = MRI.createVirtualRegister(&ARM::GPRPairRegClass); @@ -6581,9 +6597,9 @@ .addReg(ptr)); // Copy r2/r3 into dest. (This copy will normally be coalesced.) BuildMI(BB, dl, TII->get(TargetOpcode::COPY), destlo) - .addReg(GPRPair0, 0, ARM::gsub_0); + .addReg(GPRPair0, 0, isLittleEndian ? ARM::gsub_0 : ARM::gsub_1); BuildMI(BB, dl, TII->get(TargetOpcode::COPY), desthi) - .addReg(GPRPair0, 0, ARM::gsub_1); + .addReg(GPRPair0, 0, isLittleEndian ? ARM::gsub_1 : ARM::gsub_0); } unsigned StoreLo, StoreHi; @@ -6637,8 +6653,12 @@ if (isThumb2) { MRI.constrainRegClass(StoreLo, &ARM::rGPRRegClass); MRI.constrainRegClass(StoreHi, &ARM::rGPRRegClass); - AddDefaultPred(BuildMI(BB, dl, TII->get(strOpc), storesuccess) - .addReg(StoreLo).addReg(StoreHi).addReg(ptr)); + if (isLittleEndian) + AddDefaultPred(BuildMI(BB, dl, TII->get(strOpc), storesuccess) + .addReg(StoreLo).addReg(StoreHi).addReg(ptr)); + else + AddDefaultPred(BuildMI(BB, dl, TII->get(strOpc), storesuccess) + .addReg(StoreHi).addReg(StoreLo).addReg(ptr)); } else { // Marshal a pair... unsigned StorePair = MRI.createVirtualRegister(&ARM::GPRPairRegClass); @@ -6648,11 +6668,11 @@ BuildMI(BB, dl, TII->get(TargetOpcode::INSERT_SUBREG), r1) .addReg(UndefPair) .addReg(StoreLo) - .addImm(ARM::gsub_0); + .addImm(isLittleEndian ? ARM::gsub_0 : ARM::gsub_1); BuildMI(BB, dl, TII->get(TargetOpcode::INSERT_SUBREG), StorePair) .addReg(r1) .addReg(StoreHi) - .addImm(ARM::gsub_1); + .addImm(isLittleEndian ? ARM::gsub_1 : ARM::gsub_0); // ...and store it AddDefaultPred(BuildMI(BB, dl, TII->get(strOpc), storesuccess) @@ -6687,6 +6707,8 @@ AtomicOrdering Ord = static_cast(MI->getOperand(3).getImm()); DebugLoc dl = MI->getDebugLoc(); bool isThumb2 = Subtarget->isThumb2(); + if(!Subtarget->isLittle()) + std::swap(destlo, desthi); MachineRegisterInfo &MRI = BB->getParent()->getRegInfo(); if (isThumb2) { @@ -9040,16 +9062,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)); 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 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-LE +; RUN: llc < %s -mtriple=armeb -mcpu=cortex-a8 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE +; RUN: llc < %s -mtriple=thumbeb -mcpu=cortex-a8 -verify-machineinstrs | 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: and [[REG3:(r[0-9]?[02468])]], [[REG1]] -; CHECK: and [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-LE: and [[REG3:(r[0-9]?[02468])]], [[REG1]] +; CHECK-LE: and [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE: and [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE: 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: and.w [[REG3:[a-z0-9]+]], [[REG1]] -; CHECK-THUMB: and.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-LE: and.w [[REG3:[a-z0-9]+]], [[REG1]] +; CHECK-THUMB-LE: and.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE: and.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE: 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: orr [[REG3:(r[0-9]?[02468])]], [[REG1]] -; CHECK: orr [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-LE: orr [[REG3:(r[0-9]?[02468])]], [[REG1]] +; CHECK-LE: orr [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE: orr [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE: 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: orr.w [[REG3:[a-z0-9]+]], [[REG1]] -; CHECK-THUMB: orr.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-LE: orr.w [[REG3:[a-z0-9]+]], [[REG1]] +; CHECK-THUMB-LE: orr.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE: orr.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE: 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: eor [[REG3:(r[0-9]?[02468])]], [[REG1]] -; CHECK: eor [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-LE: eor [[REG3:(r[0-9]?[02468])]], [[REG1]] +; CHECK-LE: eor [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE: eor [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE: 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: eor.w [[REG3:[a-z0-9]+]], [[REG1]] -; CHECK-THUMB: eor.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-LE: eor.w [[REG3:[a-z0-9]+]], [[REG1]] +; CHECK-THUMB-LE: eor.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE: eor.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE: 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: cmp [[REG1]] -; CHECK: cmpeq [[REG2]] +; CHECK-LE: cmp [[REG1]] +; CHECK-LE: cmpeq [[REG2]] +; CHECK-BE: cmp [[REG2]] +; CHECK-BE: cmpeq [[REG1]] ; CHECK: bne ; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}} ; CHECK: cmp @@ -162,9 +186,11 @@ ; CHECK-THUMB-LABEL: test7: ; CHECK-THUMB: dmb {{ish$}} ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] -; CHECK-THUMB: cmp [[REG1]] +; CHECK-THUMB-LE: cmp [[REG1]] +; CHECK-THUMB-BE: cmp [[REG2]] ; CHECK-THUMB: it eq -; CHECK-THUMB: cmpeq [[REG2]] +; CHECK-THUMB-LE: cmpeq [[REG2]] +; CHECK-THUMB-BE: cmpeq [[REG1]] ; CHECK-THUMB: bne ; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}} ; CHECK-THUMB: cmp @@ -216,8 +242,10 @@ ; CHECK-LABEL: test10: ; CHECK: dmb {{ish$}} ; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] -; CHECK: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] -; CHECK: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] +; CHECK-LE: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] +; CHECK-LE: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] +; CHECK-BE: subs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] +; CHECK-BE: sbcs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] ; CHECK: blt ; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK: cmp @@ -227,8 +255,10 @@ ; CHECK-THUMB-LABEL: test10: ; CHECK-THUMB: dmb {{ish$}} ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] -; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] -; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB-LE: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] +; CHECK-THUMB-LE: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB-BE: subs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB-BE: sbcs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] ; CHECK-THUMB: blt ; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK-THUMB: cmp @@ -243,8 +273,10 @@ ; CHECK-LABEL: test11: ; CHECK: dmb {{ish$}} ; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] -; CHECK: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] -; CHECK: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] +; CHECK-LE: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] +; CHECK-LE: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] +; CHECK-BE: subs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] +; CHECK-BE: sbcs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] ; CHECK: blo ; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK: cmp @@ -255,8 +287,10 @@ ; CHECK-THUMB-LABEL: test11: ; CHECK-THUMB: dmb {{ish$}} ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] -; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] -; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB-LE: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] +; CHECK-THUMB-LE: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB-BE: subs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB-BE: sbcs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] ; CHECK-THUMB: blo ; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK-THUMB: cmp @@ -271,8 +305,10 @@ ; CHECK-LABEL: test12: ; CHECK: dmb {{ish$}} ; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] -; CHECK: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] -; CHECK: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] +; CHECK-LE: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] +; CHECK-LE: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] +; CHECK-BE: subs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] +; CHECK-BE: sbcs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] ; CHECK: bge ; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK: cmp @@ -282,8 +318,10 @@ ; CHECK-THUMB-LABEL: test12: ; CHECK-THUMB: dmb {{ish$}} ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] -; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] -; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB-LE: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] +; CHECK-THUMB-LE: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB-BE: subs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB-BE: sbcs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] ; CHECK-THUMB: bge ; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK-THUMB: cmp @@ -298,8 +336,10 @@ ; CHECK-LABEL: test13: ; CHECK: dmb {{ish$}} ; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] -; CHECK: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] -; CHECK: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] +; CHECK-LE: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] +; CHECK-LE: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] +; CHECK-BE: subs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] +; CHECK-BE: sbcs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] ; CHECK: bhs ; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK: cmp @@ -309,8 +349,10 @@ ; CHECK-THUMB-LABEL: test13: ; CHECK-THUMB: dmb {{ish$}} ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] -; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] -; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB-LE: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] +; CHECK-THUMB-LE: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB-BE: subs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB-BE: sbcs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] ; CHECK-THUMB: bhs ; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK-THUMB: cmp 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 -; RUN: llc -mtriple=thumbv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s +; RaUN: llc -mtriple=armv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck -check-prefix=CHECK -check-prefix=CHECK-LE %s +; RaUN: llc -mtriple=thumbv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck -check-prefix=CHECK -check-prefix=CHECK-LE %s +; RaUN: llc -mtriple=armeb-none-linux-gnu -mcpu=cortex-a53 -verify-machineinstrs < %s | FileCheck -check-prefix=CHECK -check-prefix=CHECK-BE %s +; RUN: llc -mtriple=thumbeb-none-linux-gnu -mcpu=cortex-a53 -verify-machineinstrs < %s | FileCheck -check-prefix=CHECK -check-prefix=CHECK-BE %s @var8 = global i8 0 @var16 = global i16 0 @@ -82,13 +84,14 @@ ; CHECK-NOT: mcr ; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64 ; CHECK: movt r[[ADDR]], :upper16:var64 - ; CHECK: .LBB{{[0-9]+}}_1: ; CHECK-NEXT: 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 [[NEW1:r[0-9]+]], r[[OLD1]], r0 -; CHECK-NEXT: adc{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-LE-NEXT: adds [[NEW1:r[0-9]+]], r[[OLD1]], r0 +; CHECK-LE-NEXT: adc{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-BE-NEXT: adds [[NEW2:r[0-9]+]], 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 +184,10 @@ ; CHECK-NEXT: 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 [[NEW1:r[0-9]+]], r[[OLD1]], r0 -; CHECK-NEXT: sbc{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-LE-NEXT: subs [[NEW1:r[0-9]+]], r[[OLD1]], r0 +; CHECK-LE-NEXT: sbc{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-BE-NEXT: subs [[NEW2:r[0-9]+]], 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 +280,10 @@ ; CHECK-NEXT: 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: and{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0 -; CHECK-NEXT: and{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-LE-NEXT: and{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0 +; CHECK-LE-NEXT: and{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-BE-NEXT: and{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-BE-NEXT: and{{(\.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 @@ -369,8 +376,10 @@ ; CHECK-NEXT: 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: orr{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0 -; CHECK-NEXT: orr{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-LE-NEXT: orr{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0 +; CHECK-LE-NEXT: orr{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-BE-NEXT: orr{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-BE-NEXT: orr{{(\.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 @@ -463,8 +472,10 @@ ; CHECK-NEXT: 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: eor{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0 -; CHECK-NEXT: eor{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-LE-NEXT: eor{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0 +; CHECK-LE-NEXT: eor{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-BE-NEXT: eor{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-BE-NEXT: eor{{(\.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 @@ -650,13 +661,14 @@ ; CHECK-NOT: mcr ; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64 ; CHECK: movt r[[ADDR]], :upper16:var64 - ; CHECK: .LBB{{[0-9]+}}_1: ; CHECK-NEXT: 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 [[NEW:r[0-9]+]], r[[OLD1]], r0 -; CHECK-NEXT: sbcs{{(\.w)?}} [[NEW]], r[[OLD2]], r1 +; CHECK-LE-NEXT: subs [[NEW:r[0-9]+]], r[[OLD1]], r0 +; CHECK-LE-NEXT: sbcs{{(\.w)?}} [[NEW]], r[[OLD2]], r1 +; CHECK-BE-NEXT: subs [[NEW:r[0-9]+]], r[[OLD2]], r1 +; CHECK-BE-NEXT: sbcs{{(\.w)?}} [[NEW]], r[[OLD1]], r0 ; CHECK-NEXT: blt .LBB{{[0-9]+}}_3 ; CHECK-NEXT: BB#2: ; CHECK-NEXT: stlexd [[STATUS:r[0-9]+]], r0, r1, [r[[ADDR]]] @@ -760,8 +772,10 @@ ; CHECK-NEXT: 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: subs [[NEW:r[0-9]+]], r[[OLD1]], r0 -; CHECK-NEXT: sbcs{{(\.w)?}} [[NEW]], r[[OLD2]], r1 +; CHECK-LE-NEXT: subs [[NEW:r[0-9]+]], r[[OLD1]], r0 +; CHECK-LE-NEXT: sbcs{{(\.w)?}} [[NEW]], r[[OLD2]], r1 +; CHECK-BE-NEXT: subs [[NEW:r[0-9]+]], r[[OLD2]], r1 +; CHECK-BE-NEXT: sbcs{{(\.w)?}} [[NEW]], r[[OLD1]], r0 ; CHECK-NEXT: bge .LBB{{[0-9]+}}_3 ; CHECK-NEXT: BB#2: ; CHECK-NEXT: strexd [[STATUS:r[0-9]+]], r0, r1, [r[[ADDR]]] @@ -865,8 +879,10 @@ ; CHECK-NEXT: 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 [[NEW:r[0-9]+]], r[[OLD1]], r0 -; CHECK-NEXT: sbcs{{(\.w)?}} [[NEW]], r[[OLD2]], r1 +; CHECK-LE-NEXT: subs [[NEW:r[0-9]+]], r[[OLD1]], r0 +; CHECK-LE-NEXT: sbcs{{(\.w)?}} [[NEW]], r[[OLD2]], r1 +; CHECK-BE-NEXT: subs [[NEW:r[0-9]+]], r[[OLD2]], r1 +; CHECK-BE-NEXT: sbcs{{(\.w)?}} [[NEW]], r[[OLD1]], r0 ; CHECK-NEXT: blo .LBB{{[0-9]+}}_3 ; CHECK-NEXT: BB#2: ; CHECK-NEXT: stlexd [[STATUS:r[0-9]+]], r0, r1, [r[[ADDR]]] @@ -970,8 +986,10 @@ ; CHECK-NEXT: 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: subs [[NEW:r[0-9]+]], r[[OLD1]], r0 -; CHECK-NEXT: sbcs{{(\.w)?}} [[NEW]], r[[OLD2]], r1 +; CHECK-LE-NEXT: subs [[NEW:r[0-9]+]], r[[OLD1]], r0 +; CHECK-LE-NEXT: sbcs{{(\.w)?}} [[NEW]], r[[OLD2]], r1 +; CHECK-BE-NEXT: subs [[NEW:r[0-9]+]], r[[OLD2]], r1 +; CHECK-BE-NEXT: sbcs{{(\.w)?}} [[NEW]], r[[OLD1]], r0 ; CHECK-NEXT: bhs .LBB{{[0-9]+}}_3 ; CHECK-NEXT: BB#2: ; CHECK-NEXT: stlexd [[STATUS:r[0-9]+]], r0, r1, [r[[ADDR]]] @@ -985,6 +1003,8 @@ ret i64 %old } + + define i8 @test_atomic_cmpxchg_i8(i8 %wanted, i8 %new) nounwind { ; CHECK-LABEL: test_atomic_cmpxchg_i8: %old = cmpxchg i8* @var8, i8 %wanted, i8 %new acquire acquire @@ -1075,9 +1095,11 @@ ; CHECK-NEXT: 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-NEXT: cmp [[OLD1]], r0 +; CHECK-LE-NEXT: cmp [[OLD1]], r0 +; CHECK-BE-NEXT: cmp [[OLD2]], r1 ; Thumb mode: it eq -; CHECK: cmpeq [[OLD2]], r1 +; CHECK-LE: cmpeq [[OLD2]], r1 +; CHECK-BE: cmpeq [[OLD1]], r0 ; CHECK-NEXT: bne .LBB{{[0-9]+}}_3 ; CHECK-NEXT: BB#2: ; As above, r2, r3 is a reasonable guess. @@ -1114,7 +1136,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 @@ -1181,7 +1204,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 @@ -1191,7 +1215,7 @@ define i64 @test_atomic_load_seq_cst_i64() nounwind { ; CHECK-LABEL: test_atomic_load_seq_cst_i64: %val = load atomic i64* @var64 seq_cst, align 8 -; CHECK-NOT: dmb +; CHECK-NOT: dmb/ ; CHECK-NOT: mcr ; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64 ; CHECK-NOT: dmb @@ -1222,8 +1246,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 } @@ -1291,7 +1317,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,8 @@ -; RUN: llc < %s -march=arm | FileCheck %s -; RUN: llc < %s -mtriple=armv7 | FileCheck %s --check-prefix=CHECK-V7 +; RUN: llc < %s -march=arm | FileCheck %s -check-prefix=CHECK --check-prefix=CHECK-LE +; RUN: llc < %s -mtriple=armv7 | FileCheck %s --check-prefix=CHECK-V7-LE +; RUN: llc < %s -march=armeb | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE +; RUN: llc < %s -mtriple=armebv7 | 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 +56,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 < %s -march=arm | FileCheck %s +; RxUN: llc < %s -march=arm | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE +; RUN: llc < %s -march=armeb | 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 -march=arm -mcpu=cortex-a8 < %s | FileCheck %s +; RUN: llc -march=arm -mcpu=cortex-a8 < %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE +; RUN: llc -march=armeb -mcpu=cortex-a8 < %s | 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 < %s -march=arm -float-abi=soft -mattr=+neon | FileCheck %s +; RUN: llc < %s -march=arm -float-abi=soft -mattr=+neon | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE +; RUN: llc < %s -march=armeb -float-abi=soft -mattr=v7,neon | 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