OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 | 309 |
310 int LCodeGen::ToInteger32(LConstantOperand* op) const { | 310 int LCodeGen::ToInteger32(LConstantOperand* op) const { |
311 Handle<Object> value = chunk_->LookupLiteral(op); | 311 Handle<Object> value = chunk_->LookupLiteral(op); |
312 ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32()); | 312 ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32()); |
313 ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) == | 313 ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) == |
314 value->Number()); | 314 value->Number()); |
315 return static_cast<int32_t>(value->Number()); | 315 return static_cast<int32_t>(value->Number()); |
316 } | 316 } |
317 | 317 |
318 | 318 |
| 319 double LCodeGen::ToDouble(LConstantOperand* op) const { |
| 320 Handle<Object> value = chunk_->LookupLiteral(op); |
| 321 return value->Number(); |
| 322 } |
| 323 |
| 324 |
319 Immediate LCodeGen::ToImmediate(LOperand* op) { | 325 Immediate LCodeGen::ToImmediate(LOperand* op) { |
320 LConstantOperand* const_op = LConstantOperand::cast(op); | 326 LConstantOperand* const_op = LConstantOperand::cast(op); |
321 Handle<Object> literal = chunk_->LookupLiteral(const_op); | 327 Handle<Object> literal = chunk_->LookupLiteral(const_op); |
322 Representation r = chunk_->LookupLiteralRepresentation(const_op); | 328 Representation r = chunk_->LookupLiteralRepresentation(const_op); |
323 if (r.IsInteger32()) { | 329 if (r.IsInteger32()) { |
324 ASSERT(literal->IsNumber()); | 330 ASSERT(literal->IsNumber()); |
325 return Immediate(static_cast<int32_t>(literal->Number())); | 331 return Immediate(static_cast<int32_t>(literal->Number())); |
326 } else if (r.IsDouble()) { | 332 } else if (r.IsDouble()) { |
327 Abort("unsupported double immediate"); | 333 Abort("unsupported double immediate"); |
328 } | 334 } |
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1519 break; | 1525 break; |
1520 case Token::IN: | 1526 case Token::IN: |
1521 case Token::INSTANCEOF: | 1527 case Token::INSTANCEOF: |
1522 default: | 1528 default: |
1523 UNREACHABLE(); | 1529 UNREACHABLE(); |
1524 } | 1530 } |
1525 return cond; | 1531 return cond; |
1526 } | 1532 } |
1527 | 1533 |
1528 | 1534 |
1529 void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) { | |
1530 if (right->IsConstantOperand()) { | |
1531 __ cmp(ToOperand(left), ToImmediate(right)); | |
1532 } else { | |
1533 __ cmp(ToRegister(left), ToOperand(right)); | |
1534 } | |
1535 } | |
1536 | |
1537 | |
1538 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { | 1535 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { |
1539 LOperand* left = instr->InputAt(0); | 1536 LOperand* left = instr->InputAt(0); |
1540 LOperand* right = instr->InputAt(1); | 1537 LOperand* right = instr->InputAt(1); |
1541 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1538 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
1542 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1539 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1540 Condition cc = TokenToCondition(instr->op(), instr->is_double()); |
1543 | 1541 |
1544 if (instr->is_double()) { | 1542 if (left->IsConstantOperand() && right->IsConstantOperand()) { |
1545 // Don't base result on EFLAGS when a NaN is involved. Instead | 1543 // We can statically evaluate the comparison. |
1546 // jump to the false block. | 1544 double left_val = ToDouble(LConstantOperand::cast(left)); |
1547 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); | 1545 double right_val = ToDouble(LConstantOperand::cast(right)); |
1548 __ j(parity_even, chunk_->GetAssemblyLabel(false_block)); | 1546 int next_block = |
| 1547 EvalComparison(instr->op(), left_val, right_val) ? true_block |
| 1548 : false_block; |
| 1549 EmitGoto(next_block); |
1549 } else { | 1550 } else { |
1550 EmitCmpI(left, right); | 1551 if (instr->is_double()) { |
| 1552 // Don't base result on EFLAGS when a NaN is involved. Instead |
| 1553 // jump to the false block. |
| 1554 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); |
| 1555 __ j(parity_even, chunk_->GetAssemblyLabel(false_block)); |
| 1556 } else { |
| 1557 if (right->IsConstantOperand()) { |
| 1558 __ cmp(ToOperand(left), ToImmediate(right)); |
| 1559 } else if (left->IsConstantOperand()) { |
| 1560 __ cmp(ToOperand(right), ToImmediate(left)); |
| 1561 // We transposed the operands. Reverse the condition. |
| 1562 cc = ReverseCondition(cc); |
| 1563 } else { |
| 1564 __ cmp(ToRegister(left), ToOperand(right)); |
| 1565 } |
| 1566 } |
| 1567 EmitBranch(true_block, false_block, cc); |
1551 } | 1568 } |
1552 | |
1553 Condition cc = TokenToCondition(instr->op(), instr->is_double()); | |
1554 EmitBranch(true_block, false_block, cc); | |
1555 } | 1569 } |
1556 | 1570 |
1557 | 1571 |
1558 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { | 1572 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { |
1559 Register left = ToRegister(instr->InputAt(0)); | 1573 Register left = ToRegister(instr->InputAt(0)); |
1560 Operand right = ToOperand(instr->InputAt(1)); | 1574 Operand right = ToOperand(instr->InputAt(1)); |
1561 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1575 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
1562 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1576 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
1563 | 1577 |
1564 __ cmp(left, Operand(right)); | 1578 __ cmp(left, Operand(right)); |
(...skipping 2828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4393 env->deoptimization_index()); | 4407 env->deoptimization_index()); |
4394 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); | 4408 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); |
4395 } | 4409 } |
4396 | 4410 |
4397 | 4411 |
4398 #undef __ | 4412 #undef __ |
4399 | 4413 |
4400 } } // namespace v8::internal | 4414 } } // namespace v8::internal |
4401 | 4415 |
4402 #endif // V8_TARGET_ARCH_IA32 | 4416 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |