summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/ARM/ARMCallLowering.cpp23
-rw-r--r--llvm/lib/Target/ARM/ARMInstructionSelector.cpp32
-rw-r--r--llvm/lib/Target/ARM/ARMLegalizerInfo.cpp3
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})
OpenPOWER on IntegriCloud