diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/ARM/ARMCallLowering.cpp | 23 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstructionSelector.cpp | 32 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMLegalizerInfo.cpp | 3 |
3 files changed, 44 insertions, 14 deletions
diff --git a/llvm/lib/Target/ARM/ARMCallLowering.cpp b/llvm/lib/Target/ARM/ARMCallLowering.cpp index dcd26341db0..5a2ded2e4b7 100644 --- a/llvm/lib/Target/ARM/ARMCallLowering.cpp +++ b/llvm/lib/Target/ARM/ARMCallLowering.cpp @@ -122,7 +122,7 @@ struct FormalArgHandler : public CallLowering::ValueHandler { unsigned getStackAddress(uint64_t Size, int64_t Offset, MachinePointerInfo &MPO) override { - assert(Size == 4 && "Unsupported size"); + assert((Size == 1 || Size == 2 || Size == 4) && "Unsupported size"); auto &MFI = MIRBuilder.getMF().getFrameInfo(); @@ -138,7 +138,16 @@ struct FormalArgHandler : public CallLowering::ValueHandler { void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, MachinePointerInfo &MPO, CCValAssign &VA) override { - assert(Size == 4 && "Unsupported size"); + assert((Size == 1 || Size == 2 || Size == 4) && "Unsupported size"); + + if (VA.getLocInfo() == CCValAssign::SExt || + VA.getLocInfo() == CCValAssign::ZExt) { + // If the argument is zero- or sign-extended by the caller, its size + // becomes 4 bytes, so that's what we should load. + Size = 4; + assert(MRI.getType(ValVReg).isScalar() && "Only scalars supported atm"); + MRI.setType(ValVReg, LLT::scalar(32)); + } auto MMO = MIRBuilder.getMF().getMachineMemOperand( MPO, MachineMemOperand::MOLoad, Size, /* Alignment */ 0); @@ -177,18 +186,10 @@ bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, return false; auto &Args = F.getArgumentList(); - unsigned ArgIdx = 0; - for (auto &Arg : Args) { - ArgIdx++; + for (auto &Arg : Args) if (!isSupportedType(DL, TLI, Arg.getType())) return false; - // FIXME: This check as well as ArgIdx are going away as soon as we support - // loading values < 32 bits. - if (ArgIdx > 4 && Arg.getType()->getIntegerBitWidth() != 32) - return false; - } - CCAssignFn *AssignFn = TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg()); diff --git a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp index 4167344337d..538060d4334 100644 --- a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp +++ b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp @@ -85,6 +85,22 @@ static unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size) { llvm_unreachable("Unsupported opcode"); } +/// Select the opcode for simple loads. For types smaller than 32 bits, the +/// value will be zero extended. +static unsigned selectLoadOpCode(unsigned Size) { + switch (Size) { + case 1: + case 8: + return ARM::LDRBi12; + case 16: + return ARM::LDRH; + case 32: + return ARM::LDRi12; + } + + llvm_unreachable("Unsupported size"); +} + bool ARMInstructionSelector::select(MachineInstr &I) const { assert(I.getParent() && "Instruction should be in a basic block!"); assert(I.getParent()->getParent() && "Instruction should be in a function!"); @@ -167,10 +183,22 @@ bool ARMInstructionSelector::select(MachineInstr &I) const { I.setDesc(TII.get(ARM::ADDri)); MIB.addImm(0).add(predOps(ARMCC::AL)).add(condCodeOp()); break; - case G_LOAD: - I.setDesc(TII.get(ARM::LDRi12)); + case G_LOAD: { + LLT ValTy = MRI.getType(I.getOperand(0).getReg()); + const auto ValSize = ValTy.getSizeInBits(); + + if (ValSize != 32 && ValSize != 16 && ValSize != 8 && ValSize != 1) + return false; + + const auto NewOpc = selectLoadOpCode(ValSize); + I.setDesc(TII.get(NewOpc)); + + if (NewOpc == ARM::LDRH) + // LDRH has a funny addressing mode (there's already a FIXME for it). + MIB.addReg(0); MIB.addImm(0).add(predOps(ARMCC::AL)); break; + } default: return false; } diff --git a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp index 7157af1ec16..5f4a549565e 100644 --- a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp +++ b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp @@ -35,7 +35,8 @@ ARMLegalizerInfo::ARMLegalizerInfo() { setAction({G_FRAME_INDEX, p0}, Legal); - setAction({G_LOAD, s32}, Legal); + for (auto Ty : {s1, s8, s16, s32}) + setAction({G_LOAD, Ty}, Legal); setAction({G_LOAD, 1, p0}, Legal); for (auto Ty : {s1, s8, s16, s32}) |