Chromium Code Reviews| Index: src/x64/lithium-codegen-x64.cc |
| =================================================================== |
| --- src/x64/lithium-codegen-x64.cc (revision 9243) |
| +++ src/x64/lithium-codegen-x64.cc (working copy) |
| @@ -368,6 +368,12 @@ |
| } |
| +double LCodeGen::ToDouble(LConstantOperand* op) const { |
| + Handle<Object> value = chunk_->LookupLiteral(op); |
| + return value->Number(); |
| +} |
| + |
| + |
| Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { |
| Handle<Object> literal = chunk_->LookupLiteral(op); |
| ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged()); |
| @@ -1520,39 +1526,47 @@ |
| } |
| -void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) { |
| - if (right->IsConstantOperand()) { |
| - int32_t value = ToInteger32(LConstantOperand::cast(right)); |
| - if (left->IsRegister()) { |
| - __ cmpl(ToRegister(left), Immediate(value)); |
| - } else { |
| - __ cmpl(ToOperand(left), Immediate(value)); |
| - } |
| - } else if (right->IsRegister()) { |
| - __ cmpl(ToRegister(left), ToRegister(right)); |
| - } else { |
| - __ cmpl(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 { |
| + int32_t value; |
| + if (right->IsConstantOperand()) { |
| + value = ToInteger32(LConstantOperand::cast(right)); |
| + __ cmpl(ToRegister(left), Immediate(value)); |
| + } else if (left->IsConstantOperand()) { |
| + value = ToInteger32(LConstantOperand::cast(left)); |
| + if (right->IsRegister()) { |
| + __ cmpl(ToRegister(right), Immediate(value)); |
| + } else { |
| + __ cmpl(ToOperand(right), Immediate(value)); |
| + } |
| + // We transposed the operands. Reverse the condition. |
| + cc = ReverseCondition(cc); |
| + } else { |
| + __ cmpl(ToRegister(left), ToOperand(right)); |
|
William Hesse
2011/10/20 10:28:40
The register and memory operand cases for right mu
|
| + } |
| + } |
| + EmitBranch(true_block, false_block, cc); |
| } |
| - |
| - Condition cc = TokenToCondition(instr->op(), instr->is_double()); |
| - EmitBranch(true_block, false_block, cc); |
| } |