Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2063653003: LowerCall for MIPS32 (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Removing conflict Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests_lit/llvm2ice_tests/callArgs.ll » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceTargetLoweringMIPS32.cpp
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp
index 68655de975b957750c1c49abb618727c8e661dbc..c3f5a40e59ef9dfb3dbfa3babbbebe06abd1270f 100644
--- a/src/IceTargetLoweringMIPS32.cpp
+++ b/src/IceTargetLoweringMIPS32.cpp
@@ -83,6 +83,12 @@ const char *getRegClassName(RegClass C) {
}
}
+// Value is in bytes. Return Value adjusted to the next highest multiple of the
+// stack alignment.
+uint32_t applyStackAlignment(uint32_t Value) {
+ return Utils::applyAlignment(Value, MIPS32_STACK_ALIGNMENT_BYTES);
+}
+
} // end of anonymous namespace
TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) {}
@@ -1084,11 +1090,75 @@ void TargetMIPS32::lowerBr(const InstBr *Instr) {
}
void TargetMIPS32::lowerCall(const InstCall *Instr) {
- // TODO(rkotler): assign arguments to registers and stack. Also reserve stack.
- if (Instr->getNumArgs()) {
- UnimplementedLoweringError(this, Instr);
- return;
+ NeedsStackAlignment = true;
+
+ // Assign arguments to registers and stack. Also reserve stack.
+ TargetMIPS32::CallingConv CC;
+
+ // Pair of Arg Operand -> GPR number assignments.
+ llvm::SmallVector<std::pair<Operand *, RegNumT>, MIPS32_MAX_GPR_ARG> GPRArgs;
+ llvm::SmallVector<std::pair<Operand *, RegNumT>, MIPS32_MAX_FP_ARG> FPArgs;
+ // Pair of Arg Operand -> stack offset.
+ llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs;
+ size_t ParameterAreaSizeBytes = 16;
+
+ // Classify each argument operand according to the location where the
+ // argument is passed.
+
+ for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) {
+ Operand *Arg = legalizeUndef(Instr->getArg(i));
+ const Type Ty = Arg->getType();
+ bool InReg = false;
+ RegNumT Reg;
+
+ InReg = CC.argInReg(Ty, i, &Reg);
+
+ if (!InReg) {
+ ParameterAreaSizeBytes =
+ applyStackAlignmentTy(ParameterAreaSizeBytes, Ty);
+ StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes));
+ ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty);
+ continue;
+ }
+
+ if (Ty == IceType_i64) {
+ Operand *Lo = loOperand(Arg);
+ Operand *Hi = hiOperand(Arg);
+ GPRArgs.push_back(
+ std::make_pair(Lo, RegMIPS32::getI64PairFirstGPRNum(Reg)));
+ GPRArgs.push_back(
+ std::make_pair(Hi, RegMIPS32::getI64PairSecondGPRNum(Reg)));
+ } else if (isScalarIntegerType(Ty)) {
+ GPRArgs.push_back(std::make_pair(Arg, Reg));
+ } else {
+ FPArgs.push_back(std::make_pair(Arg, Reg));
+ }
+ }
+
+ // Adjust the parameter area so that the stack is aligned. It is assumed that
+ // the stack is already aligned at the start of the calling sequence.
+ ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes);
+
+ // Copy arguments that are passed on the stack to the appropriate stack
+ // locations.
+ Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP);
+ for (auto &StackArg : StackArgs) {
+ ConstantInteger32 *Loc =
+ llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackArg.second));
+ Type Ty = StackArg.first->getType();
+ OperandMIPS32Mem *Addr;
+ constexpr bool SignExt = false;
+ if (OperandMIPS32Mem::canHoldOffset(Ty, SignExt, StackArg.second)) {
+ Addr = OperandMIPS32Mem::create(Func, Ty, SP, Loc);
+ } else {
+ Variable *NewBase = Func->makeVariable(SP->getType());
+ lowerArithmetic(
+ InstArithmetic::create(Func, InstArithmetic::Add, NewBase, SP, Loc));
+ Addr = formMemoryOperand(NewBase, Ty);
+ }
+ lowerStore(InstStore::create(Func, StackArg.first, Addr));
}
+
// Generate the call instruction. Assign its result to a temporary with high
// register allocation weight.
Variable *Dest = Instr->getDest();
@@ -1134,6 +1204,24 @@ void TargetMIPS32::lowerCall(const InstCall *Instr) {
if (!llvm::isa<ConstantRelocatable>(CallTarget)) {
CallTarget = legalize(CallTarget, Legal_Reg);
}
+
+ // Copy arguments to be passed in registers to the appropriate registers.
+ CfgVector<Variable *> RegArgs;
+ for (auto &FPArg : FPArgs) {
+ RegArgs.emplace_back(legalizeToReg(FPArg.first, FPArg.second));
+ }
+ for (auto &GPRArg : GPRArgs) {
+ RegArgs.emplace_back(legalizeToReg(GPRArg.first, GPRArg.second));
+ }
+
+ // Generate a FakeUse of register arguments so that they do not get dead code
+ // eliminated as a result of the FakeKill of scratch registers after the call.
+ // These fake-uses need to be placed here to avoid argument registers from
+ // being used during the legalizeToReg() calls above.
+ for (auto *RegArg : RegArgs) {
+ Context.insert<InstFakeUse>(RegArg);
+ }
+
Inst *NewCall = InstMIPS32Call::create(Func, ReturnReg, CallTarget);
Context.insert(NewCall);
if (ReturnRegHi)
« no previous file with comments | « no previous file | tests_lit/llvm2ice_tests/callArgs.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698