Chromium Code Reviews| Index: src/ia32/lithium-codegen-ia32.cc |
| =================================================================== |
| --- src/ia32/lithium-codegen-ia32.cc (revision 9243) |
| +++ src/ia32/lithium-codegen-ia32.cc (working copy) |
| @@ -317,6 +317,12 @@ |
| } |
| +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); |
| @@ -1527,32 +1533,40 @@ |
| } |
| -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(ToOperand(left), ToImmediate(right)); |
|
William Hesse
2011/10/20 10:28:40
If the immediate value is 0, this can also be test
Alexandre
2011/10/20 10:59:49
I forgot to change it to tst for Intel.
I intentio
|
| + } 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); |
| } |