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:
parent
d1aaafd89d
commit
93fe6abc6c
@ -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));
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user