MIPS: Refactor Math.min/max to be a single HInstruction.

Port r12265 (7501dd73)

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/10854053
Patch from Akos Palfi <palfia@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12282 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yangguo@chromium.org 2012-08-09 08:28:52 +00:00
parent d1aaafd89d
commit 93fe6abc6c
3 changed files with 95 additions and 1 deletions

View File

@ -1360,6 +1360,68 @@ void LCodeGen::DoAddI(LAddI* instr) {
}
void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
LOperand* left = instr->InputAt(0);
LOperand* right = instr->InputAt(1);
HMathMinMax::Operation operation = instr->hydrogen()->operation();
Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
if (instr->hydrogen()->representation().IsInteger32()) {
Register left_reg = ToRegister(left);
Operand right_op = (right->IsRegister() || right->IsConstantOperand())
? ToOperand(right)
: Operand(EmitLoadRegister(right, at));
Register result_reg = ToRegister(instr->result());
Label return_right, done;
if (!result_reg.is(left_reg)) {
__ Branch(&return_right, NegateCondition(condition), left_reg, right_op);
__ mov(result_reg, left_reg);
__ Branch(&done);
}
__ Branch(&done, condition, left_reg, right_op);
__ bind(&return_right);
__ Addu(result_reg, zero_reg, right_op);
__ bind(&done);
} else {
ASSERT(instr->hydrogen()->representation().IsDouble());
FPURegister left_reg = ToDoubleRegister(left);
FPURegister right_reg = ToDoubleRegister(right);
FPURegister result_reg = ToDoubleRegister(instr->result());
Label check_nan_left, check_zero, return_left, return_right, done;
__ BranchF(&check_zero, &check_nan_left, eq, left_reg, right_reg);
__ BranchF(&return_left, NULL, condition, left_reg, right_reg);
__ Branch(&return_right);
__ bind(&check_zero);
// left == right != 0.
__ BranchF(&return_left, NULL, ne, left_reg, kDoubleRegZero);
// At this point, both left and right are either 0 or -0.
if (operation == HMathMinMax::kMathMin) {
__ neg_d(left_reg, left_reg);
__ sub_d(result_reg, left_reg, right_reg);
__ neg_d(result_reg, result_reg);
} else {
__ add_d(result_reg, left_reg, right_reg);
}
__ Branch(&done);
__ bind(&check_nan_left);
// left == NaN.
__ BranchF(NULL, &return_left, eq, left_reg, left_reg);
__ bind(&return_right);
if (!right_reg.is(result_reg)) {
__ mov_d(result_reg, right_reg);
}
__ Branch(&done);
__ bind(&return_left);
if (!left_reg.is(result_reg)) {
__ mov_d(result_reg, left_reg);
}
__ bind(&done);
}
}
void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
DoubleRegister left = ToDoubleRegister(instr->InputAt(0));
DoubleRegister right = ToDoubleRegister(instr->InputAt(1));

View File

@ -1296,6 +1296,25 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
}
LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
LOperand* left = NULL;
LOperand* right = NULL;
if (instr->representation().IsInteger32()) {
ASSERT(instr->left()->representation().IsInteger32());
ASSERT(instr->right()->representation().IsInteger32());
left = UseRegisterAtStart(instr->LeastConstantOperand());
right = UseOrConstantAtStart(instr->MostConstantOperand());
} else {
ASSERT(instr->representation().IsDouble());
ASSERT(instr->left()->representation().IsDouble());
ASSERT(instr->right()->representation().IsDouble());
left = UseRegisterAtStart(instr->left());
right = UseRegisterAtStart(instr->right());
}
return DefineAsRegister(new(zone()) LMathMinMax(left, right));
}
LInstruction* LChunkBuilder::DoPower(HPower* instr) {
ASSERT(instr->representation().IsDouble());
// We call a C function for double power. It can't trigger a GC.

View File

@ -115,7 +115,6 @@ class LCodeGen;
V(IsStringAndBranch) \
V(IsSmiAndBranch) \
V(IsUndetectableAndBranch) \
V(StringCompareAndBranch) \
V(JSArrayLength) \
V(Label) \
V(LazyBailout) \
@ -132,6 +131,7 @@ class LCodeGen;
V(LoadNamedField) \
V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \
V(MathMinMax) \
V(ModI) \
V(MulI) \
V(NumberTagD) \
@ -162,6 +162,7 @@ class LCodeGen;
V(StringAdd) \
V(StringCharCodeAt) \
V(StringCharFromCode) \
V(StringCompareAndBranch) \
V(StringLength) \
V(SubI) \
V(TaggedToI) \
@ -1049,6 +1050,18 @@ class LAddI: public LTemplateInstruction<1, 2, 0> {
};
class LMathMinMax: public LTemplateInstruction<1, 2, 0> {
public:
LMathMinMax(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "min-max")
DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
};
class LPower: public LTemplateInstruction<1, 2, 0> {
public:
LPower(LOperand* left, LOperand* right) {