Revision: 18823
Author: [email protected]
Date: Fri Jan 24 13:24:18 2014 UTC
Log: A64: Implement LModI for ARM A64.
BUG=none
[email protected]
Review URL: https://codereview.chromium.org/145273014
http://code.google.com/p/v8/source/detail?r=18823
Modified:
/branches/experimental/a64/src/a64/lithium-a64.cc
/branches/experimental/a64/src/a64/lithium-a64.h
/branches/experimental/a64/src/a64/lithium-codegen-a64.cc
=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.cc Fri Jan 24 11:30:56
2014 UTC
+++ /branches/experimental/a64/src/a64/lithium-a64.cc Fri Jan 24 13:24:18
2014 UTC
@@ -1761,16 +1761,37 @@
}
-LInstruction* LChunkBuilder::DoMod(HMod* instr) {
- if (instr->representation().IsInteger32()) {
- ASSERT(instr->left()->representation().IsInteger32());
- ASSERT(instr->right()->representation().IsInteger32());
+LInstruction* LChunkBuilder::DoMod(HMod* hmod) {
+ HValue* hleft = hmod->left();
+ HValue* hright = hmod->right();
+
+ if (hmod->representation().IsInteger32()) {
+ ASSERT(hleft->representation().IsInteger32());
+ ASSERT(hleft->representation().IsInteger32());
+ LOperand* left_op;
+ LOperand* right_op;
+
+ if (hmod->HasPowerOf2Divisor()) {
+ left_op = UseRegisterAtStart(hleft);
+ right_op = UseConstant(hright);
+ } else {
+ right_op = UseRegister(hright);
+ left_op = UseRegister(hleft);
+ }
+
+ LModI* lmod = new(zone()) LModI(left_op, right_op);
+
+ if (hmod->right()->CanBeZero() ||
+ (hmod->CheckFlag(HValue::kBailoutOnMinusZero) &&
+ hmod->left()->CanBeNegative() && hmod->CanBeZero())) {
+ AssignEnvironment(lmod);
+ }
+ return DefineAsRegister(lmod);
- UNIMPLEMENTED_INSTRUCTION();
- } else if (instr->representation().IsSmiOrTagged()) {
- UNIMPLEMENTED_INSTRUCTION();
+ } else if (hmod->representation().IsSmiOrTagged()) {
+ return DoArithmeticT(Token::MOD, hmod);
} else {
- return DoArithmeticD(Token::MOD, instr);
+ return DoArithmeticD(Token::MOD, hmod);
}
}
=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.h Thu Jan 23 18:07:26
2014 UTC
+++ /branches/experimental/a64/src/a64/lithium-a64.h Fri Jan 24 13:24:18
2014 UTC
@@ -148,6 +148,7 @@
V(MathSin) \
V(MathSqrt) \
V(MathTan) \
+ V(ModI) \
V(MulConstI) \
V(MulI) \
V(NumberTagD) \
@@ -1926,6 +1927,21 @@
};
+class LModI: public LTemplateInstruction<1, 2, 0> {
+ public:
+ LModI(LOperand* left, LOperand* right) {
+ inputs_[0] = left;
+ inputs_[1] = right;
+ }
+
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
+ DECLARE_HYDROGEN_ACCESSOR(Mod)
+};
+
+
class LMulConstI: public LTemplateInstruction<1, 2, 0> {
public:
LMulConstI(LOperand* left, LConstantOperand* right) {
=======================================
--- /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Fri Jan 24
11:30:56 2014 UTC
+++ /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Fri Jan 24
13:24:18 2014 UTC
@@ -3801,6 +3801,64 @@
}
}
}
+
+
+void LCodeGen::DoModI(LModI* instr) {
+ HMod* hmod = instr->hydrogen();
+ HValue* hleft = hmod->left();
+ HValue* hright = hmod->right();
+
+ Label done;
+ Register result = ToRegister32(instr->result());
+ Register dividend = ToRegister32(instr->left());
+
+ bool need_minus_zero_check =
(hmod->CheckFlag(HValue::kBailoutOnMinusZero) &&
+ hleft->CanBeNegative() &&
hmod->CanBeZero());
+
+ if (hmod->HasPowerOf2Divisor()) {
+ // Note: The code below even works when right contains kMinInt.
+ int32_t divisor = Abs(hright->GetInteger32Constant());
+
+ if (hleft->CanBeNegative()) {
+ __ Cmp(dividend, 0);
+ __ Cneg(result, dividend, mi);
+ __ And(result, result, divisor - 1);
+ __ Cneg(result, result, mi);
+ if (need_minus_zero_check) {
+ __ Cbnz(result, &done);
+ // The result is 0. Deoptimize if the dividend was negative.
+ DeoptimizeIf(mi, instr->environment());
+ }
+ } else {
+ __ And(result, dividend, divisor - 1);
+ }
+
+ } else {
+ Label deopt;
+ Register divisor = ToRegister32(instr->right());
+ // Compute:
+ // modulo = dividend - quotient * divisor
+ __ Sdiv(result, dividend, divisor);
+ if (hright->CanBeZero()) {
+ // Combine the deoptimization sites.
+ Label ok;
+ __ Cbnz(divisor, &ok);
+ __ Bind(&deopt);
+ Deoptimize(instr->environment());
+ __ Bind(&ok);
+ }
+ __ Msub(result, result, divisor, dividend);
+ if (need_minus_zero_check) {
+ __ Cbnz(result, &done);
+ if (deopt.is_bound()) {
+ __ Tbnz(dividend, kWSignBit, &deopt);
+ } else {
+ DeoptimizeIfNegative(dividend, instr->environment());
+ }
+ }
+ }
+ __ Bind(&done);
+}
void LCodeGen::DoMulConstI(LMulConstI* instr) {
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.