| Index: src/ia32/lithium-codegen-ia32.cc
|
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
|
| index 3d519fba4c02f13a3394132b65ba28e317dbb92d..5016778d23c7fac88499f6c8ab83283da8a95f62 100644
|
| --- a/src/ia32/lithium-codegen-ia32.cc
|
| +++ b/src/ia32/lithium-codegen-ia32.cc
|
| @@ -355,6 +355,12 @@ int LCodeGen::ToInteger32(LConstantOperand* op) const {
|
| }
|
|
|
|
|
| +double LCodeGen::ToDouble(LConstantOperand* op) const {
|
| + Handle<Object> value = chunk_->LookupLiteral(op);
|
| + return value->Number();
|
| +}
|
| +
|
| +
|
| Immediate LCodeGen::ToImmediate(LOperand* op) {
|
| LConstantOperand* const_op = LConstantOperand::cast(op);
|
| Handle<Object> literal = chunk_->LookupLiteral(const_op);
|
| @@ -1574,32 +1580,40 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
|
| }
|
|
|
|
|
| -void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) {
|
| - if (right->IsConstantOperand()) {
|
| - __ cmp(ToOperand(left), ToImmediate(right));
|
| - } else {
|
| - __ cmp(ToRegister(left), ToOperand(right));
|
| - }
|
| -}
|
| -
|
| -
|
| void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
|
| LOperand* left = instr->InputAt(0);
|
| LOperand* right = instr->InputAt(1);
|
| int false_block = chunk_->LookupDestination(instr->false_block_id());
|
| int true_block = chunk_->LookupDestination(instr->true_block_id());
|
| + Condition cc = TokenToCondition(instr->op(), instr->is_double());
|
|
|
| - if (instr->is_double()) {
|
| - // Don't base result on EFLAGS when a NaN is involved. Instead
|
| - // jump to the false block.
|
| - __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
|
| - __ j(parity_even, chunk_->GetAssemblyLabel(false_block));
|
| + if (left->IsConstantOperand() && right->IsConstantOperand()) {
|
| + // We can statically evaluate the comparison.
|
| + double left_val = ToDouble(LConstantOperand::cast(left));
|
| + double right_val = ToDouble(LConstantOperand::cast(right));
|
| + int next_block =
|
| + EvalComparison(instr->op(), left_val, right_val) ? true_block
|
| + : false_block;
|
| + EmitGoto(next_block);
|
| } else {
|
| - EmitCmpI(left, right);
|
| + if (instr->is_double()) {
|
| + // Don't base result on EFLAGS when a NaN is involved. Instead
|
| + // jump to the false block.
|
| + __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
|
| + __ j(parity_even, chunk_->GetAssemblyLabel(false_block));
|
| + } else {
|
| + if (right->IsConstantOperand()) {
|
| + __ cmp(ToRegister(left), ToImmediate(right));
|
| + } else if (left->IsConstantOperand()) {
|
| + __ cmp(ToOperand(right), ToImmediate(left));
|
| + // We transposed the operands. Reverse the condition.
|
| + cc = ReverseCondition(cc);
|
| + } else {
|
| + __ cmp(ToRegister(left), ToOperand(right));
|
| + }
|
| + }
|
| + EmitBranch(true_block, false_block, cc);
|
| }
|
| -
|
| - Condition cc = TokenToCondition(instr->op(), instr->is_double());
|
| - EmitBranch(true_block, false_block, cc);
|
| }
|
|
|
|
|
|
|