1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

[M68k][GloballSel] Lower outgoing return values in IRTranslator

Implementation of lowerReturn in the IRTranslator for the M68k backend.

Differential Revision: https://reviews.llvm.org/D105332
This commit is contained in:
Sushma Unnibhavi 2021-07-05 11:39:09 -07:00 committed by Min-Yih Hsu
parent 98d2a19fea
commit 44791e33f4
4 changed files with 93 additions and 11 deletions

View File

@ -26,15 +26,59 @@ using namespace llvm;
M68kCallLowering::M68kCallLowering(const M68kTargetLowering &TLI)
: CallLowering(&TLI) {}
struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler {
OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
MachineInstrBuilder MIB)
: OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
void assignValueToReg(Register ValVReg, Register PhysReg,
CCValAssign &VA) override {
MIB.addUse(PhysReg, RegState::Implicit);
Register ExtReg = extendRegister(ValVReg, VA);
MIRBuilder.buildCopy(PhysReg, ExtReg);
}
void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
MachinePointerInfo &MPO, CCValAssign &VA) override {
llvm_unreachable("unimplemented");
}
Register getStackAddress(uint64_t Size, int64_t Offset,
MachinePointerInfo &MPO,
ISD::ArgFlagsTy Flags) override {
llvm_unreachable("unimplemented");
}
MachineInstrBuilder MIB;
};
bool M68kCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
const Value *Val, ArrayRef<Register> VRegs,
FunctionLoweringInfo &FLI,
Register SwiftErrorVReg) const {
if (Val)
return false;
MIRBuilder.buildInstr(M68k::RTS);
return true;
auto MIB = MIRBuilder.buildInstrNoInsert(M68k::RTS);
bool Success = true;
MachineFunction &MF = MIRBuilder.getMF();
const Function &F = MF.getFunction();
MachineRegisterInfo &MRI = MF.getRegInfo();
const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>();
CCAssignFn *AssignFn =
TLI.getCCAssignFn(F.getCallingConv(), true, F.isVarArg());
auto &DL = F.getParent()->getDataLayout();
if (!VRegs.empty()) {
SmallVector<ArgInfo, 8> SplitArgs;
ArgInfo OrigArg{VRegs, Val->getType()};
setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);
splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
OutgoingValueAssigner ArgAssigner(AssignFn);
OutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB);
Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
MIRBuilder, F.getCallingConv(),
F.isVarArg());
}
MIRBuilder.insertInstr(MIB);
return Success;
}
bool M68kCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
@ -56,7 +100,7 @@ bool M68kCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
}
CCAssignFn *AssignFn =
TLI.getCCAssignFnForCall(F.getCallingConv(), false, F.isVarArg());
TLI.getCCAssignFn(F.getCallingConv(), false, F.isVarArg());
IncomingValueAssigner ArgAssigner(AssignFn);
FormalArgHandler ArgHandler(MIRBuilder, MRI);
return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,

View File

@ -3413,8 +3413,10 @@ const char *M68kTargetLowering::getTargetNodeName(unsigned Opcode) const {
}
}
CCAssignFn *M68kTargetLowering::getCCAssignFnForCall(CallingConv::ID CC,
bool Return,
CCAssignFn *M68kTargetLowering::getCCAssignFn(CallingConv::ID CC, bool Return,
bool IsVarArg) const {
if (Return)
return RetCC_M68k_C;
else
return CC_M68k_C;
}

View File

@ -171,7 +171,7 @@ public:
EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *MBB) const override;
CCAssignFn *getCCAssignFnForCall(CallingConv::ID CC, bool Return,
CCAssignFn *getCCAssignFn(CallingConv::ID CC, bool Return,
bool IsVarArg) const;
private:

View File

@ -175,3 +175,39 @@ define void @test_arg_lowering_struct(%struct.A %a) #0 {
; CHECK: RTS
ret void
}
define i8 @test_ret1(i8 %a) {
; CHECK-LABEL: name: test_ret1
; CHECK: bb.1 (%ir-block.0):
; CHECK: [[G_F_I1:%[0-9]+]]:_(p0) = G_FRAME_INDEX
; CHECK: [[G_LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[G_F_I1]](p0)
; CHECK: [[G_TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[G_LOAD1]](s32)
; CHECK: $bd0 = COPY [[G_TRUNC1]](s8)
; CHECK: RTS implicit $bd0
ret i8 %a
}
define i32 @test_ret2(i32 %a) {
; CHECK-LABEL: name: test_ret2
; CHECK: bb.1 (%ir-block.0):
; CHECK: [[G_F_I1:%[0-9]+]]:_(p0) = G_FRAME_INDEX
; CHECK: [[G_LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[G_F_I1]](p0)
; CHECK: $d0 = COPY [[G_LOAD1]](s32)
; CHECK: RTS implicit $d0
ret i32 %a
}
define i64 @test_ret3(i64 %a) {
; CHECK-LABEL: name: test_ret3
; CHECK: bb.1 (%ir-block.0):
; CHECK: [[G_F_I1:%[0-9]+]]:_(p0) = G_FRAME_INDEX
; CHECK: [[G_LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[G_F_I1]](p0)
; CHECK: [[G_F_I2:%[0-9]+]]:_(p0) = G_FRAME_INDEX
; CHECK: [[G_LOAD2:%[0-9]+]]:_(s32) = G_LOAD [[G_F_I2]](p0)
; CHECK: [[G_MERGE_VAL:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[G_LOAD1]](s32), [[G_LOAD2]](s32)
; CHECK: [[G_UNMERGE_VAL1:%[0-9]+]]:_(s32), [[G_UNMERGE_VAL2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[G_MERGE_VAL]](s64)
; CHECK: $d0 = COPY [[G_UNMERGE_VAL1]](s32)
; CHECK: $d1 = COPY [[G_UNMERGE_VAL2]](s32)
; CHECK: RTS implicit $d0, implicit $d1
ret i64 %a
}