Index: llvm/lib/Target/M68k/GlSel/M68kCallLowering.h =================================================================== --- llvm/lib/Target/M68k/GlSel/M68kCallLowering.h +++ llvm/lib/Target/M68k/GlSel/M68kCallLowering.h @@ -44,6 +44,33 @@ bool enableBigEndian() const override; }; +class M68kIncomingValueHandler : public CallLowering::IncomingValueHandler { +public: + M68kIncomingValueHandler(MachineIRBuilder &MIRBuilder, + MachineRegisterInfo &MRI) + : CallLowering::IncomingValueHandler(MIRBuilder, MRI) {} + + uint64_t StackUsed; + +private: + void assignValueToReg(Register ValVReg, Register PhysReg, + CCValAssign &VA) override; + + void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size, + MachinePointerInfo &MPO, CCValAssign &VA) override; + + Register getStackAddress(uint64_t Size, int64_t Offset, + MachinePointerInfo &MPO, + ISD::ArgFlagsTy Flags) override; +}; + +class FormalArgHandler : public M68kIncomingValueHandler { + +public: + FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI) + : M68kIncomingValueHandler(MIRBuilder, MRI) {} +}; + } // end namespace llvm #endif // LLVM_LIB_TARGET_M68K_GLSEL_M68KCALLLOWERING_H Index: llvm/lib/Target/M68k/GlSel/M68kCallLowering.cpp =================================================================== --- llvm/lib/Target/M68k/GlSel/M68kCallLowering.cpp +++ llvm/lib/Target/M68k/GlSel/M68kCallLowering.cpp @@ -15,12 +15,25 @@ #include "M68kCallLowering.h" #include "M68kISelLowering.h" #include "M68kInstrInfo.h" +#include "M68kSubtarget.h" +#include "M68kTargetMachine.h" +#include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/GlobalISel/CallLowering.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" +#include "llvm/CodeGen/TargetCallingConv.h" + using namespace llvm; M68kCallLowering::M68kCallLowering(const M68kTargetLowering &TLI) : CallLowering(&TLI) {} +static bool isSupportedType(const DataLayout DL, const M68kTargetLowering &TLI, + Type *T) { + EVT VT = TLI.getValueType(DL, T); + return VT.isSimple() && VT.isInteger() && + VT.getSimpleVT().getSizeInBits() == 32; +} + bool M68kCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, ArrayRef VRegs, FunctionLoweringInfo &FLI, @@ -37,10 +50,58 @@ ArrayRef> VRegs, FunctionLoweringInfo &FLI) const { - if (F.arg_empty()) - return true; + MachineFunction &MF = MIRBuilder.getMF(); + MachineRegisterInfo &MRI = MF.getRegInfo(); + const auto &DL = F.getParent()->getDataLayout(); + auto &TLI = *getTLI(); - return false; + for (const auto &Arg : F.args()) + if (!isSupportedType(DL, TLI, Arg.getType())) + return false; + + SmallVector SplitArgs; + unsigned I = 0; + for (const auto &Arg : F.args()) { + ArgInfo OrigArg{VRegs[I], Arg}; + setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F); + ++I; + } + + CCAssignFn *AssignFn = + TLI.ccAssignFnForCall(F.getCallingConv(), false, F.isVarArg()); + IncomingValueAssigner ArgAssigner(AssignFn); + FormalArgHandler ArgHandler(MIRBuilder, MRI); + return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs, + MIRBuilder, F.getCallingConv(), + F.isVarArg()); +} + +void M68kIncomingValueHandler::assignValueToReg(Register ValVReg, + Register PhysReg, + CCValAssign &VA) { + assert(VA.isRegLoc() && "Value shouldn't be assigned to reg"); + assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?"); + + assert(VA.getValVT().getSizeInBits() == 32 && "Unsupported value size"); + assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size"); + MIRBuilder.getMRI()->addLiveIn(PhysReg); + MIRBuilder.getMBB().addLiveIn(PhysReg); + IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA); +} + +void M68kIncomingValueHandler::assignValueToAddress(Register ValVReg, + Register Addr, + uint64_t Size, + MachinePointerInfo &MPO, + CCValAssign &VA) { + llvm_unreachable("Don't know how to assign a value to an address yet"); +} + +Register M68kIncomingValueHandler::getStackAddress(uint64_t Size, + int64_t Offset, + MachinePointerInfo &MPO, + ISD::ArgFlagsTy Flags) { + llvm_unreachable("Don't know how to get a stack address yet"); } bool M68kCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, Index: llvm/lib/Target/M68k/M68kISelLowering.h =================================================================== --- llvm/lib/Target/M68k/M68kISelLowering.h +++ llvm/lib/Target/M68k/M68kISelLowering.h @@ -171,6 +171,9 @@ EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override; + CCAssignFn *ccAssignFnForCall(CallingConv::ID CC, bool Return, + bool IsVarArg) const; + private: unsigned GetAlignedArgumentStackSize(unsigned StackSize, SelectionDAG &DAG) const; Index: llvm/lib/Target/M68k/M68kISelLowering.cpp =================================================================== --- llvm/lib/Target/M68k/M68kISelLowering.cpp +++ llvm/lib/Target/M68k/M68kISelLowering.cpp @@ -3412,3 +3412,9 @@ return NULL; } } + +CCAssignFn *M68kTargetLowering::ccAssignFnForCall(CallingConv::ID CC, + bool Return, + bool IsVarArg) const { + return CC_M68k_C; +} Index: llvm/test/CodeGen/M68k/GlobalISel/irtranslator-ret.ll =================================================================== --- llvm/test/CodeGen/M68k/GlobalISel/irtranslator-ret.ll +++ llvm/test/CodeGen/M68k/GlobalISel/irtranslator-ret.ll @@ -5,3 +5,10 @@ define void @noArgRetVoid() { ret void } + +; CHECK-LABEL: name: test_arg_lowering +; CHECK: bb.1 (%ir-block.0): +; CHECK: RTS +define void @test_arg_lowering(i32 %x, i32 %y) { + ret void +} \ No newline at end of file