Revision: 18780
Author: [email protected]
Date: Thu Jan 23 13:53:20 2014 UTC
Log: A64: Implement LMathFloorOfDiv and enable the instruction in
hydrogen
BUG=314606
[email protected], [email protected]
Review URL: https://codereview.chromium.org/145273005
http://code.google.com/p/v8/source/detail?r=18780
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/hydrogen-instructions.cc
=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.cc Thu Jan 23 13:51:32
2014 UTC
+++ /branches/experimental/a64/src/a64/lithium-a64.cc Thu Jan 23 13:53:20
2014 UTC
@@ -1690,10 +1690,48 @@
LOperand* map = UseRegisterAtStart(instr->value());
return DefineAsRegister(new(zone()) LMapEnumLength(map));
}
+
+
+HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue*
dividend) {
+ // A value with an integer representation does not need to be
transformed.
+ if (dividend->representation().IsInteger32()) {
+ return dividend;
+ // A change from an integer32 can be replaced by the integer32 value.
+ } else if (dividend->IsChange() &&
+ HChange::cast(dividend)->from().IsInteger32()) {
+ return HChange::cast(dividend)->value();
+ }
+ return NULL;
+}
+
+
+HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor)
{
+ // A value with an integer representation does not need to be
transformed.
+ if (divisor->representation().IsInteger32()) {
+ return divisor;
+ // A change from an integer32 can be replaced by the integer32 value.
+ } else if (divisor->IsChange() &&
+ HChange::cast(divisor)->from().IsInteger32()) {
+ return HChange::cast(divisor)->value();
+ }
+
+ if (divisor->IsConstant() &&
HConstant::cast(divisor)->HasInteger32Value()) {
+ HConstant* constant_val = HConstant::cast(divisor);
+ return constant_val->CopyToRepresentation(Representation::Integer32(),
+ divisor->block()->zone());
+ }
+
+ return NULL;
+}
LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
- UNIMPLEMENTED_INSTRUCTION();
+ HValue* right = instr->right();
+ LOperand* dividend = UseRegister(instr->left());
+ LOperand* divisor = UseRegister(right);
+ LOperand* remainder = TempRegister();
+ return AssignEnvironment(DefineAsRegister(
+ new(zone()) LMathFloorOfDiv(dividend, divisor, remainder)));
}
=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.h Thu Jan 23 13:51:32
2014 UTC
+++ /branches/experimental/a64/src/a64/lithium-a64.h Thu Jan 23 13:53:20
2014 UTC
@@ -139,6 +139,7 @@
V(MathAbsTagged) \
V(MathExp) \
V(MathFloor) \
+ V(MathFloorOfDiv) \
V(MathLog) \
V(MathMinMax) \
V(MathPowHalf) \
@@ -1835,6 +1836,25 @@
};
+class LMathFloorOfDiv : public LTemplateInstruction<1, 2, 1> {
+ public:
+ LMathFloorOfDiv(LOperand* left,
+ LOperand* right,
+ LOperand* temp = NULL) {
+ inputs_[0] = left;
+ inputs_[1] = right;
+ temps_[0] = temp;
+ }
+
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div")
+ DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+};
+
+
class LMathLog: public LUnaryMathOperation<0> {
public:
explicit LMathLog(LOperand* value) : LUnaryMathOperation<0>(value) { }
=======================================
--- /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Thu Jan 23
13:51:32 2014 UTC
+++ /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Thu Jan 23
13:53:20 2014 UTC
@@ -3587,6 +3587,49 @@
__ Bind(&done);
}
+
+
+void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
+ const Register result = ToRegister32(instr->result());
+ const Register left = ToRegister32(instr->left());
+ const Register right = ToRegister32(instr->right());
+ const Register remainder = ToRegister32(instr->temp());
+
+ // Check for x / 0.
+ DeoptimizeIfZero(right, instr->environment());
+
+ // Check for (kMinInt / -1).
+ if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+ __ Cmp(left, kMinInt);
+ __ Ccmp(right, -1, ZFlag, eq);
+ DeoptimizeIf(eq, instr->environment());
+ }
+
+ // Check for (0 / -x) that will produce negative zero.
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ __ Cmp(right, 0);
+ __ Ccmp(left, 0, ZFlag, mi);
+ // "right" can't be null because the code would have already been
+ // deoptimized. The Z flag is set only if (right < 0) and (left == 0).
+ // In this case we need to deoptimize to produce a -0.
+ DeoptimizeIf(eq, instr->environment());
+ }
+
+ Label done;
+ __ Sdiv(result, left, right);
+ // If both operands have the same sign then we are done.
+ __ Eor(remainder, left, Operand(right));
+ __ Tbz(remainder, kWSignBit, &done);
+
+ // Check if the result needs to be corrected.
+ __ Mul(remainder, result, right);
+ __ Sub(remainder, remainder, left);
+ __ Cmp(remainder, 0);
+ __ B(eq, &done);
+ __ Sub(result, result, Operand(1));
+
+ __ Bind(&done);
+}
void LCodeGen::DoMathLog(LMathLog* instr) {
=======================================
--- /branches/experimental/a64/src/hydrogen-instructions.cc Wed Jan 22
11:44:47 2014 UTC
+++ /branches/experimental/a64/src/hydrogen-instructions.cc Thu Jan 23
13:53:20 2014 UTC
@@ -1526,7 +1526,7 @@
if (value()->representation().IsInteger32()) return value();
#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_IA32) || \
- defined(V8_TARGET_ARCH_X64)
+ defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_A64)
if (value()->IsDiv() && (value()->UseCount() == 1)) {
// TODO(2038): Implement this optimization for non ARM architectures.
HDiv* hdiv = HDiv::cast(value());
--
--
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.