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

Unified Diff: src/IceTargetLoweringX8664.cpp

Issue 1543573002: Subzero. X8664. Fixes filetype=asm. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Moar refactoring. Enables xtests. Fixes xtest. Created 5 years 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
Index: src/IceTargetLoweringX8664.cpp
diff --git a/src/IceTargetLoweringX8664.cpp b/src/IceTargetLoweringX8664.cpp
index 3cb82e9f3c79ba1229faabb0a28c07449984ca67..e5d0fb7204804264e494d7ff5283181d24431e25 100644
--- a/src/IceTargetLoweringX8664.cpp
+++ b/src/IceTargetLoweringX8664.cpp
@@ -118,20 +118,22 @@ getRegisterForXmmArgNum(uint32_t ArgNum) {
}
static inline TargetX8664::Traits::RegisterSet::AllRegisters
-getRegisterForGprArgNum(uint32_t ArgNum) {
+getRegisterForGprArgNum(Type Ty, uint32_t ArgNum) {
assert(ArgNum < TargetX8664::Traits::X86_MAX_GPR_ARGS);
static const TargetX8664::Traits::RegisterSet::AllRegisters GprForArgNum[] = {
- TargetX8664::Traits::RegisterSet::Reg_edi,
- TargetX8664::Traits::RegisterSet::Reg_esi,
- TargetX8664::Traits::RegisterSet::Reg_edx,
- TargetX8664::Traits::RegisterSet::Reg_ecx,
- TargetX8664::Traits::RegisterSet::Reg_r8d,
- TargetX8664::Traits::RegisterSet::Reg_r9d,
+ TargetX8664::Traits::RegisterSet::Reg_rdi,
+ TargetX8664::Traits::RegisterSet::Reg_rsi,
+ TargetX8664::Traits::RegisterSet::Reg_rdx,
+ TargetX8664::Traits::RegisterSet::Reg_rcx,
+ TargetX8664::Traits::RegisterSet::Reg_r8,
+ TargetX8664::Traits::RegisterSet::Reg_r9,
};
static_assert(llvm::array_lengthof(GprForArgNum) ==
TargetX8664::TargetX8664::Traits::X86_MAX_GPR_ARGS,
"Mismatch between MAX_GPR_ARGS and GprForArgNum.");
- return GprForArgNum[ArgNum];
+ assert(Ty == IceType_i64 || Ty == IceType_i32);
+ return static_cast<TargetX8664::Traits::RegisterSet::AllRegisters>(
+ TargetX8664::Traits::getGprForType(Ty, GprForArgNum[ArgNum]));
}
// constexprMax returns a (constexpr) max(S0, S1), and it is used for defining
@@ -168,7 +170,7 @@ void TargetX8664::lowerCall(const InstCall *Instr) {
llvm::SmallVector<Operand *, constexprMax(Traits::X86_MAX_XMM_ARGS,
Traits::X86_MAX_GPR_ARGS)>;
OperandList XmmArgs;
- OperandList GprArgs;
+ CfgVector<std::pair<const Type, Operand *>> GprArgs;
OperandList StackArgs, StackArgLocations;
int32_t ParameterAreaSizeBytes = 0;
@@ -186,14 +188,15 @@ void TargetX8664::lowerCall(const InstCall *Instr) {
XmmArgs.push_back(Arg);
} else if (isScalarIntegerType(Ty) &&
GprArgs.size() < Traits::X86_MAX_GPR_ARGS) {
- GprArgs.push_back(Arg);
+ GprArgs.emplace_back(Ty, Arg);
} else {
StackArgs.push_back(Arg);
if (isVectorType(Arg->getType())) {
ParameterAreaSizeBytes =
Traits::applyStackAlignment(ParameterAreaSizeBytes);
}
- Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_rsp);
+ Variable *esp =
+ getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64);
Constant *Loc = Ctx->getConstantInt32(ParameterAreaSizeBytes);
StackArgLocations.push_back(
Traits::X86OperandMem::create(Func, Ty, esp, Loc));
@@ -230,7 +233,29 @@ void TargetX8664::lowerCall(const InstCall *Instr) {
}
for (SizeT i = 0, NumGprArgs = GprArgs.size(); i < NumGprArgs; ++i) {
- Variable *Reg = legalizeToReg(GprArgs[i], getRegisterForGprArgNum(i));
+ const Type SignatureTy = GprArgs[i].first;
+ Operand *Arg = GprArgs[i].second;
+ Variable *Reg =
+ legalizeToReg(Arg, getRegisterForGprArgNum(Arg->getType(), i));
+ assert(SignatureTy == IceType_i64 || SignatureTy == IceType_i32);
+ if (SignatureTy != Arg->getType()) {
+ if (SignatureTy == IceType_i32) {
+ assert(Arg->getType() == IceType_i64);
+ Variable *T = makeReg(
+ IceType_i32, Traits::getGprForType(IceType_i32, Reg->getRegNum()));
+ _mov(T, Reg);
+ Reg = T;
+ } else {
+ // This branch has never been reached, so we leave the assert(false)
+ // here until we figure out how to exercise it.
+ assert(false);
+ assert(Arg->getType() == IceType_i32);
+ Variable *T = makeReg(
+ IceType_i64, Traits::getGprForType(IceType_i64, Reg->getRegNum()));
+ _movzx(T, Reg);
+ Reg = T;
+ }
+ }
Context.insert<InstFakeUse>(Reg);
}
@@ -248,10 +273,15 @@ void TargetX8664::lowerCall(const InstCall *Instr) {
case IceType_i1:
case IceType_i8:
case IceType_i16:
+ // The bitcode should never return an i1, i8, or i16.
+ assert(false);
+ // Fallthrough intended.
case IceType_i32:
- case IceType_i64:
ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_eax);
break;
+ case IceType_i64:
+ ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_rax);
+ break;
case IceType_f32:
case IceType_f64:
case IceType_v4i1:
@@ -267,6 +297,13 @@ void TargetX8664::lowerCall(const InstCall *Instr) {
}
Operand *CallTarget = legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm);
+ if (auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget)) {
+ // x86-64 in Subzero is ILP32. Therefore, CallTarget is i32, but the emitted
+ // call needs a i64 register (for textual asm.)
+ Variable *T = makeReg(IceType_i64);
+ _movzx(T, CallTargetR);
+ CallTarget = T;
+ }
const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing();
if (NeedSandboxing) {
llvm_unreachable("X86-64 Sandboxing codegen not implemented.");
@@ -330,7 +367,7 @@ void TargetX8664::lowerArguments() {
if (NumGprArgs >= Traits::X86_MAX_GPR_ARGS) {
continue;
}
- RegNum = getRegisterForGprArgNum(NumGprArgs);
+ RegNum = getRegisterForGprArgNum(Ty, NumGprArgs);
++NumGprArgs;
RegisterArg = Func->makeVariable(Ty);
}
@@ -359,7 +396,8 @@ void TargetX8664::lowerRet(const InstRet *Inst) {
Reg = legalizeToReg(Src0, Traits::RegisterSet::Reg_xmm0);
} else {
assert(isScalarIntegerType(Src0->getType()));
- _mov(Reg, Src0, Traits::RegisterSet::Reg_eax);
+ _mov(Reg, Src0, Traits::getGprForType(Src0->getType(),
+ Traits::RegisterSet::Reg_rax));
}
}
// Add a ret instruction even if sandboxing is enabled, because addEpilog
@@ -479,8 +517,10 @@ void TargetX8664::addProlog(CfgNode *Node) {
assert((RegsUsed & getRegisterSet(RegSet_FramePointer, RegSet_None))
.count() == 0);
PreservedRegsSizeBytes += typeWidthInBytes(IceType_i64);
- Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_rbp);
- Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_rsp);
+ Variable *ebp =
+ getPhysicalRegister(Traits::RegisterSet::Reg_rbp, IceType_i64);
+ Variable *esp =
+ getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64);
_push(ebp);
_mov(ebp, esp);
// Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode).
@@ -528,7 +568,7 @@ void TargetX8664::addProlog(CfgNode *Node) {
if (PrologEmitsFixedAllocas &&
FixedAllocaAlignBytes > Traits::X86_STACK_ALIGNMENT_BYTES) {
assert(IsEbpBasedFrame);
- _and(getPhysicalRegister(Traits::RegisterSet::Reg_rsp),
+ _and(getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64),
Ctx->getConstantInt32(-FixedAllocaAlignBytes));
}
}
@@ -637,9 +677,11 @@ void TargetX8664::addEpilog(CfgNode *Node) {
Context.init(Node);
Context.setInsertPoint(InsertPoint);
- Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_rsp);
+ Variable *esp =
+ getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64);
if (IsEbpBasedFrame) {
- Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_rbp);
+ Variable *ebp =
+ getPhysicalRegister(Traits::RegisterSet::Reg_rbp, IceType_i64);
// For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake
// use of esp before the assignment of esp=ebp keeps previous esp
// adjustments from being dead-code eliminated.

Powered by Google App Engine
This is Rietveld 408576698