Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(356)

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 20070005: Adding Smi support to Add, Sub, Mul, and Bitwise (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed nit Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-gap-resolver-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 638 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 return ToX87Register(op->index()); 649 return ToX87Register(op->index());
650 } 650 }
651 651
652 652
653 XMMRegister LCodeGen::ToDoubleRegister(LOperand* op) const { 653 XMMRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
654 ASSERT(op->IsDoubleRegister()); 654 ASSERT(op->IsDoubleRegister());
655 return ToDoubleRegister(op->index()); 655 return ToDoubleRegister(op->index());
656 } 656 }
657 657
658 658
659 int LCodeGen::ToInteger32(LConstantOperand* op) const { 659 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const {
660 HConstant* constant = chunk_->LookupConstant(op); 660 return ToRepresentation(op, Representation::Integer32());
661 return constant->Integer32Value();
662 } 661 }
663 662
664 663
664 int32_t LCodeGen::ToRepresentation(LConstantOperand* op,
665 const Representation& r) const {
666 HConstant* constant = chunk_->LookupConstant(op);
667 int32_t value = constant->Integer32Value();
668 if (r.IsInteger32()) return value;
669 ASSERT(r.IsSmiOrTagged());
670 return reinterpret_cast<int32_t>(Smi::FromInt(value));
671 }
672
673
665 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { 674 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
666 HConstant* constant = chunk_->LookupConstant(op); 675 HConstant* constant = chunk_->LookupConstant(op);
667 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); 676 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
668 return constant->handle(); 677 return constant->handle();
669 } 678 }
670 679
671 680
672 double LCodeGen::ToDouble(LConstantOperand* op) const { 681 double LCodeGen::ToDouble(LConstantOperand* op) const {
673 HConstant* constant = chunk_->LookupConstant(op); 682 HConstant* constant = chunk_->LookupConstant(op);
674 ASSERT(constant->HasDoubleValue()); 683 ASSERT(constant->HasDoubleValue());
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after
1612 __ shl(left, 4); 1621 __ shl(left, 4);
1613 break; 1622 break;
1614 default: 1623 default:
1615 __ imul(left, left, constant); 1624 __ imul(left, left, constant);
1616 break; 1625 break;
1617 } 1626 }
1618 } else { 1627 } else {
1619 __ imul(left, left, constant); 1628 __ imul(left, left, constant);
1620 } 1629 }
1621 } else { 1630 } else {
1631 if (instr->hydrogen()->representation().IsSmi()) {
1632 __ SmiUntag(left);
1633 }
1622 __ imul(left, ToOperand(right)); 1634 __ imul(left, ToOperand(right));
1623 } 1635 }
1624 1636
1625 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1637 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1626 DeoptimizeIf(overflow, instr->environment()); 1638 DeoptimizeIf(overflow, instr->environment());
1627 } 1639 }
1628 1640
1629 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1641 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1630 // Bail out if the result is supposed to be negative zero. 1642 // Bail out if the result is supposed to be negative zero.
1631 Label done; 1643 Label done;
(...skipping 16 matching lines...) Expand all
1648 } 1660 }
1649 1661
1650 1662
1651 void LCodeGen::DoBitI(LBitI* instr) { 1663 void LCodeGen::DoBitI(LBitI* instr) {
1652 LOperand* left = instr->left(); 1664 LOperand* left = instr->left();
1653 LOperand* right = instr->right(); 1665 LOperand* right = instr->right();
1654 ASSERT(left->Equals(instr->result())); 1666 ASSERT(left->Equals(instr->result()));
1655 ASSERT(left->IsRegister()); 1667 ASSERT(left->IsRegister());
1656 1668
1657 if (right->IsConstantOperand()) { 1669 if (right->IsConstantOperand()) {
1658 int right_operand = ToInteger32(LConstantOperand::cast(right)); 1670 int right_operand = ToRepresentation(LConstantOperand::cast(right),
1671 instr->hydrogen()->representation());
1659 switch (instr->op()) { 1672 switch (instr->op()) {
1660 case Token::BIT_AND: 1673 case Token::BIT_AND:
1661 __ and_(ToRegister(left), right_operand); 1674 __ and_(ToRegister(left), right_operand);
1662 break; 1675 break;
1663 case Token::BIT_OR: 1676 case Token::BIT_OR:
1664 __ or_(ToRegister(left), right_operand); 1677 __ or_(ToRegister(left), right_operand);
1665 break; 1678 break;
1666 case Token::BIT_XOR: 1679 case Token::BIT_XOR:
1667 __ xor_(ToRegister(left), right_operand); 1680 __ xor_(ToRegister(left), right_operand);
1668 break; 1681 break;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1759 } 1772 }
1760 } 1773 }
1761 1774
1762 1775
1763 void LCodeGen::DoSubI(LSubI* instr) { 1776 void LCodeGen::DoSubI(LSubI* instr) {
1764 LOperand* left = instr->left(); 1777 LOperand* left = instr->left();
1765 LOperand* right = instr->right(); 1778 LOperand* right = instr->right();
1766 ASSERT(left->Equals(instr->result())); 1779 ASSERT(left->Equals(instr->result()));
1767 1780
1768 if (right->IsConstantOperand()) { 1781 if (right->IsConstantOperand()) {
1769 __ sub(ToOperand(left), ToInteger32Immediate(right)); 1782 __ sub(ToOperand(left),
1783 ToImmediate(right, instr->hydrogen()->representation()));
1770 } else { 1784 } else {
1771 __ sub(ToRegister(left), ToOperand(right)); 1785 __ sub(ToRegister(left), ToOperand(right));
1772 } 1786 }
1773 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1787 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1774 DeoptimizeIf(overflow, instr->environment()); 1788 DeoptimizeIf(overflow, instr->environment());
1775 } 1789 }
1776 } 1790 }
1777 1791
1778 1792
1779 void LCodeGen::DoConstantI(LConstantI* instr) { 1793 void LCodeGen::DoConstantI(LConstantI* instr) {
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 } 1986 }
1973 } 1987 }
1974 1988
1975 1989
1976 void LCodeGen::DoAddI(LAddI* instr) { 1990 void LCodeGen::DoAddI(LAddI* instr) {
1977 LOperand* left = instr->left(); 1991 LOperand* left = instr->left();
1978 LOperand* right = instr->right(); 1992 LOperand* right = instr->right();
1979 1993
1980 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { 1994 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
1981 if (right->IsConstantOperand()) { 1995 if (right->IsConstantOperand()) {
1982 int32_t offset = ToInteger32(LConstantOperand::cast(right)); 1996 int32_t offset = ToRepresentation(LConstantOperand::cast(right),
1997 instr->hydrogen()->representation());
1983 __ lea(ToRegister(instr->result()), MemOperand(ToRegister(left), offset)); 1998 __ lea(ToRegister(instr->result()), MemOperand(ToRegister(left), offset));
1984 } else { 1999 } else {
1985 Operand address(ToRegister(left), ToRegister(right), times_1, 0); 2000 Operand address(ToRegister(left), ToRegister(right), times_1, 0);
1986 __ lea(ToRegister(instr->result()), address); 2001 __ lea(ToRegister(instr->result()), address);
1987 } 2002 }
1988 } else { 2003 } else {
1989 if (right->IsConstantOperand()) { 2004 if (right->IsConstantOperand()) {
1990 __ add(ToOperand(left), ToInteger32Immediate(right)); 2005 __ add(ToOperand(left),
2006 ToImmediate(right, instr->hydrogen()->representation()));
1991 } else { 2007 } else {
1992 __ add(ToRegister(left), ToOperand(right)); 2008 __ add(ToRegister(left), ToOperand(right));
1993 } 2009 }
1994 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 2010 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1995 DeoptimizeIf(overflow, instr->environment()); 2011 DeoptimizeIf(overflow, instr->environment());
1996 } 2012 }
1997 } 2013 }
1998 } 2014 }
1999 2015
2000 2016
2001 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { 2017 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
2002 CpuFeatureScope scope(masm(), SSE2); 2018 CpuFeatureScope scope(masm(), SSE2);
2003 LOperand* left = instr->left(); 2019 LOperand* left = instr->left();
2004 LOperand* right = instr->right(); 2020 LOperand* right = instr->right();
2005 ASSERT(left->Equals(instr->result())); 2021 ASSERT(left->Equals(instr->result()));
2006 HMathMinMax::Operation operation = instr->hydrogen()->operation(); 2022 HMathMinMax::Operation operation = instr->hydrogen()->operation();
2007 if (instr->hydrogen()->representation().IsInteger32()) { 2023 if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
2008 Label return_left; 2024 Label return_left;
2009 Condition condition = (operation == HMathMinMax::kMathMin) 2025 Condition condition = (operation == HMathMinMax::kMathMin)
2010 ? less_equal 2026 ? less_equal
2011 : greater_equal; 2027 : greater_equal;
2012 if (right->IsConstantOperand()) { 2028 if (right->IsConstantOperand()) {
2013 Operand left_op = ToOperand(left); 2029 Operand left_op = ToOperand(left);
2014 Immediate right_imm = ToInteger32Immediate(right); 2030 Immediate immediate = ToImmediate(LConstantOperand::cast(instr->right()),
2015 __ cmp(left_op, right_imm); 2031 instr->hydrogen()->representation());
2032 __ cmp(left_op, immediate);
2016 __ j(condition, &return_left, Label::kNear); 2033 __ j(condition, &return_left, Label::kNear);
2017 __ mov(left_op, right_imm); 2034 __ mov(left_op, immediate);
2018 } else { 2035 } else {
2019 Register left_reg = ToRegister(left); 2036 Register left_reg = ToRegister(left);
2020 Operand right_op = ToOperand(right); 2037 Operand right_op = ToOperand(right);
2021 __ cmp(left_reg, right_op); 2038 __ cmp(left_reg, right_op);
2022 __ j(condition, &return_left, Label::kNear); 2039 __ j(condition, &return_left, Label::kNear);
2023 __ mov(left_reg, right_op); 2040 __ mov(left_reg, right_op);
2024 } 2041 }
2025 __ bind(&return_left); 2042 __ bind(&return_left);
2026 } else { 2043 } else {
2027 ASSERT(instr->hydrogen()->representation().IsDouble()); 2044 ASSERT(instr->hydrogen()->representation().IsDouble());
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
2375 EmitGoto(next_block); 2392 EmitGoto(next_block);
2376 } else { 2393 } else {
2377 if (instr->is_double()) { 2394 if (instr->is_double()) {
2378 CpuFeatureScope scope(masm(), SSE2); 2395 CpuFeatureScope scope(masm(), SSE2);
2379 // Don't base result on EFLAGS when a NaN is involved. Instead 2396 // Don't base result on EFLAGS when a NaN is involved. Instead
2380 // jump to the false block. 2397 // jump to the false block.
2381 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); 2398 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
2382 __ j(parity_even, instr->FalseLabel(chunk_)); 2399 __ j(parity_even, instr->FalseLabel(chunk_));
2383 } else { 2400 } else {
2384 if (right->IsConstantOperand()) { 2401 if (right->IsConstantOperand()) {
2385 int32_t const_value = ToInteger32(LConstantOperand::cast(right)); 2402 __ cmp(ToOperand(left),
2386 if (instr->hydrogen_value()->representation().IsSmi()) { 2403 ToImmediate(right, instr->hydrogen()->representation()));
2387 __ cmp(ToOperand(left), Immediate(Smi::FromInt(const_value)));
2388 } else {
2389 __ cmp(ToOperand(left), Immediate(const_value));
2390 }
2391 } else if (left->IsConstantOperand()) { 2404 } else if (left->IsConstantOperand()) {
2392 int32_t const_value = ToInteger32(LConstantOperand::cast(left)); 2405 __ cmp(ToOperand(right),
2393 if (instr->hydrogen_value()->representation().IsSmi()) { 2406 ToImmediate(left, instr->hydrogen()->representation()));
2394 __ cmp(ToOperand(right), Immediate(Smi::FromInt(const_value)));
2395 } else {
2396 __ cmp(ToOperand(right), Immediate(const_value));
2397 }
2398 // We transposed the operands. Reverse the condition. 2407 // We transposed the operands. Reverse the condition.
2399 cc = ReverseCondition(cc); 2408 cc = ReverseCondition(cc);
2400 } else { 2409 } else {
2401 __ cmp(ToRegister(left), ToOperand(right)); 2410 __ cmp(ToRegister(left), ToOperand(right));
2402 } 2411 }
2403 } 2412 }
2404 EmitBranch(instr, cc); 2413 EmitBranch(instr, cc);
2405 } 2414 }
2406 } 2415 }
2407 2416
(...skipping 2036 matching lines...) Expand 10 before | Expand all | Expand 10 after
4444 ? isolate()->builtins()->StoreIC_Initialize_Strict() 4453 ? isolate()->builtins()->StoreIC_Initialize_Strict()
4445 : isolate()->builtins()->StoreIC_Initialize(); 4454 : isolate()->builtins()->StoreIC_Initialize();
4446 CallCode(ic, RelocInfo::CODE_TARGET, instr); 4455 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4447 } 4456 }
4448 4457
4449 4458
4450 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 4459 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4451 if (instr->hydrogen()->skip_check()) return; 4460 if (instr->hydrogen()->skip_check()) return;
4452 4461
4453 if (instr->index()->IsConstantOperand()) { 4462 if (instr->index()->IsConstantOperand()) {
4454 int constant_index = 4463 Immediate immediate =
4455 ToInteger32(LConstantOperand::cast(instr->index())); 4464 ToImmediate(LConstantOperand::cast(instr->index()),
4456 if (instr->hydrogen()->length()->representation().IsSmi()) { 4465 instr->hydrogen()->length()->representation());
4457 __ cmp(ToOperand(instr->length()), 4466 __ cmp(ToOperand(instr->length()), immediate);
4458 Immediate(Smi::FromInt(constant_index)));
4459 } else {
4460 __ cmp(ToOperand(instr->length()), Immediate(constant_index));
4461 }
4462 DeoptimizeIf(below_equal, instr->environment()); 4467 DeoptimizeIf(below_equal, instr->environment());
4463 } else { 4468 } else {
4464 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); 4469 __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
4465 DeoptimizeIf(above_equal, instr->environment()); 4470 DeoptimizeIf(above_equal, instr->environment());
4466 } 4471 }
4467 } 4472 }
4468 4473
4469 4474
4470 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4475 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4471 ElementsKind elements_kind = instr->elements_kind(); 4476 ElementsKind elements_kind = instr->elements_kind();
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
4615 instr->elements(), 4620 instr->elements(),
4616 instr->key(), 4621 instr->key(),
4617 instr->hydrogen()->key()->representation(), 4622 instr->hydrogen()->key()->representation(),
4618 FAST_ELEMENTS, 4623 FAST_ELEMENTS,
4619 FixedArray::kHeaderSize - kHeapObjectTag, 4624 FixedArray::kHeaderSize - kHeapObjectTag,
4620 instr->additional_index()); 4625 instr->additional_index());
4621 if (instr->value()->IsRegister()) { 4626 if (instr->value()->IsRegister()) {
4622 __ mov(operand, ToRegister(instr->value())); 4627 __ mov(operand, ToRegister(instr->value()));
4623 } else { 4628 } else {
4624 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4629 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4625 if (IsInteger32(operand_value)) { 4630 if (IsSmi(operand_value)) {
4626 Smi* smi_value = Smi::FromInt(ToInteger32(operand_value)); 4631 Immediate immediate = ToImmediate(operand_value, Representation::Smi());
4627 __ mov(operand, Immediate(smi_value)); 4632 __ mov(operand, immediate);
4628 } else { 4633 } else {
4634 ASSERT(!IsInteger32(operand_value));
4629 Handle<Object> handle_value = ToHandle(operand_value); 4635 Handle<Object> handle_value = ToHandle(operand_value);
4630 __ mov(operand, handle_value); 4636 __ mov(operand, handle_value);
4631 } 4637 }
4632 } 4638 }
4633 4639
4634 if (instr->hydrogen()->NeedsWriteBarrier()) { 4640 if (instr->hydrogen()->NeedsWriteBarrier()) {
4635 ASSERT(instr->value()->IsRegister()); 4641 ASSERT(instr->value()->IsRegister());
4636 Register value = ToRegister(instr->value()); 4642 Register value = ToRegister(instr->value());
4637 ASSERT(!instr->key()->IsConstantOperand()); 4643 ASSERT(!instr->key()->IsConstantOperand());
4638 SmiCheck check_needed = 4644 SmiCheck check_needed =
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
4781 // result register contain a valid pointer because it is already 4787 // result register contain a valid pointer because it is already
4782 // contained in the register pointer map. 4788 // contained in the register pointer map.
4783 __ Set(result, Immediate(0)); 4789 __ Set(result, Immediate(0));
4784 4790
4785 PushSafepointRegistersScope scope(this); 4791 PushSafepointRegistersScope scope(this);
4786 __ push(string); 4792 __ push(string);
4787 // Push the index as a smi. This is safe because of the checks in 4793 // Push the index as a smi. This is safe because of the checks in
4788 // DoStringCharCodeAt above. 4794 // DoStringCharCodeAt above.
4789 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); 4795 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
4790 if (instr->index()->IsConstantOperand()) { 4796 if (instr->index()->IsConstantOperand()) {
4791 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 4797 Immediate immediate = ToImmediate(LConstantOperand::cast(instr->index()),
4792 __ push(Immediate(Smi::FromInt(const_index))); 4798 Representation::Smi());
4799 __ push(immediate);
4793 } else { 4800 } else {
4794 Register index = ToRegister(instr->index()); 4801 Register index = ToRegister(instr->index());
4795 __ SmiTag(index); 4802 __ SmiTag(index);
4796 __ push(index); 4803 __ push(index);
4797 } 4804 }
4798 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, 4805 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2,
4799 instr, instr->context()); 4806 instr, instr->context());
4800 __ AssertSmi(eax); 4807 __ AssertSmi(eax);
4801 __ SmiUntag(eax); 4808 __ SmiUntag(eax);
4802 __ StoreToSafepointRegisterSlot(result, eax); 4809 __ StoreToSafepointRegisterSlot(result, eax);
(...skipping 1695 matching lines...) Expand 10 before | Expand all | Expand 10 after
6498 FixedArray::kHeaderSize - kPointerSize)); 6505 FixedArray::kHeaderSize - kPointerSize));
6499 __ bind(&done); 6506 __ bind(&done);
6500 } 6507 }
6501 6508
6502 6509
6503 #undef __ 6510 #undef __
6504 6511
6505 } } // namespace v8::internal 6512 } } // namespace v8::internal
6506 6513
6507 #endif // V8_TARGET_ARCH_IA32 6514 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-gap-resolver-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698