ARM: Optimize fixed double arguments

Optimize fixed double arguments to arithmetic Lithium instructions.

TEST=none
BUG=
R=ulan@chromium.org

Review URL: https://codereview.chromium.org/91113003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18118 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 0213fc90
...@@ -1476,11 +1476,11 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -1476,11 +1476,11 @@ void MathPowStub::Generate(MacroAssembler* masm) {
const Register exponent = r2; const Register exponent = r2;
const Register heapnumbermap = r5; const Register heapnumbermap = r5;
const Register heapnumber = r0; const Register heapnumber = r0;
const DwVfpRegister double_base = d1; const DwVfpRegister double_base = d0;
const DwVfpRegister double_exponent = d2; const DwVfpRegister double_exponent = d1;
const DwVfpRegister double_result = d3; const DwVfpRegister double_result = d2;
const DwVfpRegister double_scratch = d0; const DwVfpRegister double_scratch = d3;
const SwVfpRegister single_scratch = s0; const SwVfpRegister single_scratch = s6;
const Register scratch = r9; const Register scratch = r9;
const Register scratch2 = r4; const Register scratch2 = r4;
......
...@@ -758,13 +758,10 @@ LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, ...@@ -758,13 +758,10 @@ LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
ASSERT(instr->left()->representation().IsDouble()); ASSERT(instr->left()->representation().IsDouble());
ASSERT(instr->right()->representation().IsDouble()); ASSERT(instr->right()->representation().IsDouble());
if (op == Token::MOD) { if (op == Token::MOD) {
LOperand* left = UseFixedDouble(instr->left(), d1); LOperand* left = UseFixedDouble(instr->left(), d0);
LOperand* right = UseFixedDouble(instr->right(), d2); LOperand* right = UseFixedDouble(instr->right(), d1);
LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
// We call a C function for double modulo. It can't trigger a GC. We need return MarkAsCall(DefineFixedDouble(result, d0), instr);
// to use fixed result register for the call.
// TODO(fschneider): Allow any register as input registers.
return MarkAsCall(DefineFixedDouble(result, d1), instr);
} else { } else {
LOperand* left = UseRegisterAtStart(instr->left()); LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseRegisterAtStart(instr->right()); LOperand* right = UseRegisterAtStart(instr->right());
...@@ -1269,17 +1266,16 @@ LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { ...@@ -1269,17 +1266,16 @@ LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) {
LOperand* input = UseRegister(instr->value()); LOperand* input = UseRegisterAtStart(instr->value());
LMathSqrt* result = new(zone()) LMathSqrt(input); LMathSqrt* result = new(zone()) LMathSqrt(input);
return DefineAsRegister(result); return DefineAsRegister(result);
} }
LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) { LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) {
LOperand* input = UseFixedDouble(instr->value(), d2); LOperand* input = UseRegisterAtStart(instr->value());
LOperand* temp = FixedTemp(d3); LMathPowHalf* result = new(zone()) LMathPowHalf(input);
LMathPowHalf* result = new(zone()) LMathPowHalf(input, temp); return DefineAsRegister(result);
return DefineFixedDouble(result, d2);
} }
...@@ -1718,12 +1714,12 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) { ...@@ -1718,12 +1714,12 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
// We need to use fixed result register for the call. // We need to use fixed result register for the call.
Representation exponent_type = instr->right()->representation(); Representation exponent_type = instr->right()->representation();
ASSERT(instr->left()->representation().IsDouble()); ASSERT(instr->left()->representation().IsDouble());
LOperand* left = UseFixedDouble(instr->left(), d1); LOperand* left = UseFixedDouble(instr->left(), d0);
LOperand* right = exponent_type.IsDouble() ? LOperand* right = exponent_type.IsDouble() ?
UseFixedDouble(instr->right(), d2) : UseFixedDouble(instr->right(), d1) :
UseFixed(instr->right(), r2); UseFixed(instr->right(), r2);
LPower* result = new(zone()) LPower(left, right); LPower* result = new(zone()) LPower(left, right);
return MarkAsCall(DefineFixedDouble(result, d3), return MarkAsCall(DefineFixedDouble(result, d2),
instr, instr,
CAN_DEOPTIMIZE_EAGERLY); CAN_DEOPTIMIZE_EAGERLY);
} }
......
...@@ -886,15 +886,13 @@ class LMathSqrt V8_FINAL : public LTemplateInstruction<1, 1, 0> { ...@@ -886,15 +886,13 @@ class LMathSqrt V8_FINAL : public LTemplateInstruction<1, 1, 0> {
}; };
class LMathPowHalf V8_FINAL : public LTemplateInstruction<1, 1, 1> { class LMathPowHalf V8_FINAL : public LTemplateInstruction<1, 1, 0> {
public: public:
LMathPowHalf(LOperand* value, LOperand* temp) { explicit LMathPowHalf(LOperand* value) {
inputs_[0] = value; inputs_[0] = value;
temps_[0] = temp;
} }
LOperand* value() { return inputs_[0]; } LOperand* value() { return inputs_[0]; }
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half") DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
}; };
......
...@@ -2164,9 +2164,6 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) { ...@@ -2164,9 +2164,6 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
__ vdiv(result, left, right); __ vdiv(result, left, right);
break; break;
case Token::MOD: { case Token::MOD: {
// Save r0-r3 on the stack.
__ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit());
__ PrepareCallCFunction(0, 2, scratch0()); __ PrepareCallCFunction(0, 2, scratch0());
__ SetCallCDoubleArguments(left, right); __ SetCallCDoubleArguments(left, right);
__ CallCFunction( __ CallCFunction(
...@@ -2174,9 +2171,6 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) { ...@@ -2174,9 +2171,6 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
0, 2); 0, 2);
// Move the result in the double result register. // Move the result in the double result register.
__ GetCFunctionDoubleResult(result); __ GetCFunctionDoubleResult(result);
// Restore r0-r3.
__ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit());
break; break;
} }
default: default:
...@@ -3903,7 +3897,7 @@ void LCodeGen::DoMathSqrt(LMathSqrt* instr) { ...@@ -3903,7 +3897,7 @@ void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
DwVfpRegister input = ToDoubleRegister(instr->value()); DwVfpRegister input = ToDoubleRegister(instr->value());
DwVfpRegister result = ToDoubleRegister(instr->result()); DwVfpRegister result = ToDoubleRegister(instr->result());
DwVfpRegister temp = ToDoubleRegister(instr->temp()); DwVfpRegister temp = double_scratch0();
// Note that according to ECMA-262 15.8.2.13: // Note that according to ECMA-262 15.8.2.13:
// Math.pow(-Infinity, 0.5) == Infinity // Math.pow(-Infinity, 0.5) == Infinity
...@@ -3926,11 +3920,11 @@ void LCodeGen::DoPower(LPower* instr) { ...@@ -3926,11 +3920,11 @@ void LCodeGen::DoPower(LPower* instr) {
// Having marked this as a call, we can use any registers. // Having marked this as a call, we can use any registers.
// Just make sure that the input/output registers are the expected ones. // Just make sure that the input/output registers are the expected ones.
ASSERT(!instr->right()->IsDoubleRegister() || ASSERT(!instr->right()->IsDoubleRegister() ||
ToDoubleRegister(instr->right()).is(d2)); ToDoubleRegister(instr->right()).is(d1));
ASSERT(!instr->right()->IsRegister() || ASSERT(!instr->right()->IsRegister() ||
ToRegister(instr->right()).is(r2)); ToRegister(instr->right()).is(r2));
ASSERT(ToDoubleRegister(instr->left()).is(d1)); ASSERT(ToDoubleRegister(instr->left()).is(d0));
ASSERT(ToDoubleRegister(instr->result()).is(d3)); ASSERT(ToDoubleRegister(instr->result()).is(d2));
if (exponent_type.IsSmi()) { if (exponent_type.IsSmi()) {
MathPowStub stub(MathPowStub::TAGGED); MathPowStub stub(MathPowStub::TAGGED);
......
...@@ -3484,9 +3484,8 @@ void MacroAssembler::PrepareCallCFunction(int num_reg_arguments, ...@@ -3484,9 +3484,8 @@ void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
void MacroAssembler::SetCallCDoubleArguments(DwVfpRegister dreg) { void MacroAssembler::SetCallCDoubleArguments(DwVfpRegister dreg) {
if (use_eabi_hardfloat()) { ASSERT(dreg.is(d0));
Move(d0, dreg); if (!use_eabi_hardfloat()) {
} else {
vmov(r0, r1, dreg); vmov(r0, r1, dreg);
} }
} }
...@@ -3494,16 +3493,9 @@ void MacroAssembler::SetCallCDoubleArguments(DwVfpRegister dreg) { ...@@ -3494,16 +3493,9 @@ void MacroAssembler::SetCallCDoubleArguments(DwVfpRegister dreg) {
void MacroAssembler::SetCallCDoubleArguments(DwVfpRegister dreg1, void MacroAssembler::SetCallCDoubleArguments(DwVfpRegister dreg1,
DwVfpRegister dreg2) { DwVfpRegister dreg2) {
if (use_eabi_hardfloat()) { ASSERT(dreg1.is(d0));
if (dreg2.is(d0)) { ASSERT(dreg2.is(d1));
ASSERT(!dreg1.is(d1)); if (!use_eabi_hardfloat()) {
Move(d1, dreg2);
Move(d0, dreg1);
} else {
Move(d0, dreg1);
Move(d1, dreg2);
}
} else {
vmov(r0, r1, dreg1); vmov(r0, r1, dreg1);
vmov(r2, r3, dreg2); vmov(r2, r3, dreg2);
} }
...@@ -3512,8 +3504,8 @@ void MacroAssembler::SetCallCDoubleArguments(DwVfpRegister dreg1, ...@@ -3512,8 +3504,8 @@ void MacroAssembler::SetCallCDoubleArguments(DwVfpRegister dreg1,
void MacroAssembler::SetCallCDoubleArguments(DwVfpRegister dreg, void MacroAssembler::SetCallCDoubleArguments(DwVfpRegister dreg,
Register reg) { Register reg) {
ASSERT(dreg.is(d0));
if (use_eabi_hardfloat()) { if (use_eabi_hardfloat()) {
Move(d0, dreg);
Move(r0, reg); Move(r0, reg);
} else { } else {
Move(r2, reg); Move(r2, reg);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment