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

Unified Diff: src/IceTargetLoweringARM32.cpp

Issue 1474883002: Subzero. ARM32. Pre-lowers calls to ARM32 Helpers. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years, 1 month 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
« src/IceTargetLoweringARM32.h ('K') | « src/IceTargetLoweringARM32.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceTargetLoweringARM32.cpp
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp
index 7eb4e8ad446f540ef10a4f12aa9d8c6cb4a29e33..bd17b84c44ddff195ba2ba721a334a1321c55f48 100644
--- a/src/IceTargetLoweringARM32.cpp
+++ b/src/IceTargetLoweringARM32.cpp
@@ -265,6 +265,52 @@ uint32_t TargetARM32::getCallStackArgumentsSizeBytes(const InstCall *Call) {
return applyStackAlignment(OutArgsSizeBytes);
}
+void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
+ switch (Instr->getKind()) {
+ default:
+ return;
+ case Inst::Arithmetic: {
+ Variable *Dest = Instr->getDest();
+ const Type DestTy = Dest->getType();
+ if (DestTy == IceType_i64) {
+ const InstArithmetic::OpKind Op =
+ llvm::cast<InstArithmetic>(Instr)->getOp();
+ Operand *TargetHelper = nullptr;
+ switch (Op) {
+ default:
+ break;
Jim Stichnoth 2015/11/24 22:24:00 maybe just return here?
John 2015/11/25 16:39:56 Done.
+ case InstArithmetic::Udiv:
+ TargetHelper = Ctx->getConstantExternSym(H_udiv_i64);
+ break;
+ case InstArithmetic::Sdiv:
+ TargetHelper = Ctx->getConstantExternSym(H_sdiv_i64);
+ break;
+ case InstArithmetic::Urem:
+ TargetHelper = Ctx->getConstantExternSym(H_urem_i64);
+ break;
+ case InstArithmetic::Srem:
+ TargetHelper = Ctx->getConstantExternSym(H_srem_i64);
+ break;
+ }
+ if (TargetHelper == nullptr) {
+ return;
+ }
+ ARM32Helpers[TargetHelper] = &TargetARM32::DivRem64Helper;
+ constexpr SizeT MaxArgs = 2;
+ constexpr bool NoTailCall = false;
+ constexpr bool IsTargetHelperCall = true;
+ auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper,
+ NoTailCall, IsTargetHelperCall);
+ Call->addArg(Instr->getSrc(0));
+ Call->addArg(Instr->getSrc(1));
+ Context.insert(Call);
+ Instr->setDeleted();
+ }
+ return;
+ }
+ }
+}
+
void TargetARM32::findMaxStackOutArgsSize() {
// MinNeededOutArgsBytes should be updated if the Target ever creates a
// high-level InstCall that requires more stack bytes.
@@ -1642,6 +1688,27 @@ public:
};
} // end of anonymous namespace
+void TargetARM32::DivRem64Helper(const InstCall *Instr) {
+ Operand *Src0 = Instr->getArg(0);
+ Operand *Src1 = Instr->getArg(1);
+ Int32Operands SrcsLo(loOperand(Src0), loOperand(Src1));
+ Int32Operands SrcsHi(hiOperand(Src0), hiOperand(Src1));
+ // Check for divide by 0 (ARM normally doesn't trap, but we want it to
+ // trap for NaCl). Src1Lo and Src1Hi may have already been legalized to a
+ // register, which will hide a constant source operand. Instead, check
+ // the not-yet-legalized Src1 to optimize-out a divide by 0 check.
+ if (!SrcsLo.swappedOperands() && SrcsLo.hasConstOperand()) {
+ if (SrcsLo.getConstantValue() == 0 && SrcsHi.getConstantValue() == 0) {
+ _trap();
+ return;
+ }
+ } else {
+ Operand *Src1Lo = SrcsLo.unswappedSrc1R(this);
+ Operand *Src1Hi = SrcsHi.unswappedSrc1R(this);
+ div0Check(IceType_i64, Src1Lo, Src1Hi);
+ }
+}
+
void TargetARM32::lowerInt64Arithmetic(InstArithmetic::OpKind Op,
Variable *Dest, Operand *Src0,
Operand *Src1) {
@@ -1662,20 +1729,6 @@ void TargetARM32::lowerInt64Arithmetic(InstArithmetic::OpKind Op,
case InstArithmetic::Sdiv:
case InstArithmetic::Urem:
case InstArithmetic::Srem: {
- // Check for divide by 0 (ARM normally doesn't trap, but we want it to
- // trap for NaCl). Src1Lo and Src1Hi may have already been legalized to a
- // register, which will hide a constant source operand. Instead, check
- // the not-yet-legalized Src1 to optimize-out a divide by 0 check.
- if (!SrcsLo.swappedOperands() && SrcsLo.hasConstOperand()) {
- if (SrcsLo.getConstantValue() == 0 && SrcsHi.getConstantValue() == 0) {
- _trap();
- return;
- }
- } else {
- Operand *Src1Lo = SrcsLo.unswappedSrc1R(this);
- Operand *Src1Hi = SrcsHi.unswappedSrc1R(this);
- div0Check(IceType_i64, Src1Lo, Src1Hi);
- }
// Technically, ARM has its own aeabi routines, but we can use the
// non-aeabi routine as well. LLVM uses __aeabi_ldivmod for div, but uses
// the more standard __moddi3 for rem.
@@ -2682,6 +2735,10 @@ void TargetARM32::lowerBr(const InstBr *Instr) {
}
void TargetARM32::lowerCall(const InstCall *Instr) {
+ Operand *CallTarget = Instr->getCallTarget();
+ if (Instr->isTargetHelperCall()) {
+ (this->*ARM32Helpers[CallTarget])(Instr);
+ }
MaybeLeafFunc = false;
NeedsStackAlignment = true;
@@ -2804,7 +2861,6 @@ void TargetARM32::lowerCall(const InstCall *Instr) {
break;
}
}
- Operand *CallTarget = Instr->getCallTarget();
// TODO(jvoung): Handle sandboxing. const bool NeedSandboxing =
// Ctx->getFlags().getUseSandboxing();
« src/IceTargetLoweringARM32.h ('K') | « src/IceTargetLoweringARM32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698