OLD | NEW |
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 1657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1668 AllowDeferredHandleDereference smi_check; | 1668 AllowDeferredHandleDereference smi_check; |
1669 if (value->IsSmi()) { | 1669 if (value->IsSmi()) { |
1670 __ li(ToRegister(instr->result()), Operand(value)); | 1670 __ li(ToRegister(instr->result()), Operand(value)); |
1671 } else { | 1671 } else { |
1672 __ LoadHeapObject(ToRegister(instr->result()), | 1672 __ LoadHeapObject(ToRegister(instr->result()), |
1673 Handle<HeapObject>::cast(value)); | 1673 Handle<HeapObject>::cast(value)); |
1674 } | 1674 } |
1675 } | 1675 } |
1676 | 1676 |
1677 | 1677 |
1678 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { | |
1679 Register result = ToRegister(instr->result()); | |
1680 Register array = ToRegister(instr->value()); | |
1681 __ lw(result, FieldMemOperand(array, FixedArrayBase::kLengthOffset)); | |
1682 } | |
1683 | |
1684 | |
1685 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { | 1678 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { |
1686 Register result = ToRegister(instr->result()); | 1679 Register result = ToRegister(instr->result()); |
1687 Register map = ToRegister(instr->value()); | 1680 Register map = ToRegister(instr->value()); |
1688 __ EnumLength(result, map); | 1681 __ EnumLength(result, map); |
1689 } | 1682 } |
1690 | 1683 |
1691 | 1684 |
1692 void LCodeGen::DoElementsKind(LElementsKind* instr) { | 1685 void LCodeGen::DoElementsKind(LElementsKind* instr) { |
1693 Register result = ToRegister(instr->result()); | 1686 Register result = ToRegister(instr->result()); |
1694 Register input = ToRegister(instr->value()); | 1687 Register input = ToRegister(instr->value()); |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1971 int LCodeGen::GetNextEmittedBlock() const { | 1964 int LCodeGen::GetNextEmittedBlock() const { |
1972 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { | 1965 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { |
1973 if (!chunk_->GetLabel(i)->HasReplacement()) return i; | 1966 if (!chunk_->GetLabel(i)->HasReplacement()) return i; |
1974 } | 1967 } |
1975 return -1; | 1968 return -1; |
1976 } | 1969 } |
1977 | 1970 |
1978 template<class InstrType> | 1971 template<class InstrType> |
1979 void LCodeGen::EmitBranch(InstrType instr, | 1972 void LCodeGen::EmitBranch(InstrType instr, |
1980 Condition cc, Register src1, const Operand& src2) { | 1973 Condition cc, Register src1, const Operand& src2) { |
| 1974 int left_block = instr->TrueDestination(chunk_); |
1981 int right_block = instr->FalseDestination(chunk_); | 1975 int right_block = instr->FalseDestination(chunk_); |
1982 int left_block = instr->TrueDestination(chunk_); | |
1983 | 1976 |
1984 int next_block = GetNextEmittedBlock(); | 1977 int next_block = GetNextEmittedBlock(); |
1985 if (right_block == left_block) { | 1978 if (right_block == left_block || cc == al) { |
1986 EmitGoto(left_block); | 1979 EmitGoto(left_block); |
1987 } else if (left_block == next_block) { | 1980 } else if (left_block == next_block) { |
1988 __ Branch(chunk_->GetAssemblyLabel(right_block), | 1981 __ Branch(chunk_->GetAssemblyLabel(right_block), |
1989 NegateCondition(cc), src1, src2); | 1982 NegateCondition(cc), src1, src2); |
1990 } else if (right_block == next_block) { | 1983 } else if (right_block == next_block) { |
1991 __ Branch(chunk_->GetAssemblyLabel(left_block), cc, src1, src2); | 1984 __ Branch(chunk_->GetAssemblyLabel(left_block), cc, src1, src2); |
1992 } else { | 1985 } else { |
1993 __ Branch(chunk_->GetAssemblyLabel(left_block), cc, src1, src2); | 1986 __ Branch(chunk_->GetAssemblyLabel(left_block), cc, src1, src2); |
1994 __ Branch(chunk_->GetAssemblyLabel(right_block)); | 1987 __ Branch(chunk_->GetAssemblyLabel(right_block)); |
1995 } | 1988 } |
(...skipping 19 matching lines...) Expand all Loading... |
2015 __ Branch(chunk_->GetAssemblyLabel(right_block)); | 2008 __ Branch(chunk_->GetAssemblyLabel(right_block)); |
2016 } | 2009 } |
2017 } | 2010 } |
2018 | 2011 |
2019 | 2012 |
2020 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { | 2013 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { |
2021 __ stop("LDebugBreak"); | 2014 __ stop("LDebugBreak"); |
2022 } | 2015 } |
2023 | 2016 |
2024 | 2017 |
| 2018 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) { |
| 2019 Representation r = instr->hydrogen()->value()->representation(); |
| 2020 if (r.IsSmiOrInteger32() || r.IsDouble()) { |
| 2021 EmitBranch(instr, al, zero_reg, Operand(zero_reg)); |
| 2022 } else { |
| 2023 ASSERT(r.IsTagged()); |
| 2024 Register reg = ToRegister(instr->value()); |
| 2025 HType type = instr->hydrogen()->value()->type(); |
| 2026 if (type.IsTaggedNumber()) { |
| 2027 EmitBranch(instr, al, zero_reg, Operand(zero_reg)); |
| 2028 } |
| 2029 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); |
| 2030 __ lw(scratch0(), FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 2031 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
| 2032 EmitBranch(instr, eq, scratch0(), Operand(at)); |
| 2033 } |
| 2034 } |
| 2035 |
| 2036 |
2025 void LCodeGen::DoBranch(LBranch* instr) { | 2037 void LCodeGen::DoBranch(LBranch* instr) { |
2026 Representation r = instr->hydrogen()->value()->representation(); | 2038 Representation r = instr->hydrogen()->value()->representation(); |
2027 if (r.IsInteger32() || r.IsSmi()) { | 2039 if (r.IsInteger32() || r.IsSmi()) { |
2028 ASSERT(!info()->IsStub()); | 2040 ASSERT(!info()->IsStub()); |
2029 Register reg = ToRegister(instr->value()); | 2041 Register reg = ToRegister(instr->value()); |
2030 EmitBranch(instr, ne, reg, Operand(zero_reg)); | 2042 EmitBranch(instr, ne, reg, Operand(zero_reg)); |
2031 } else if (r.IsDouble()) { | 2043 } else if (r.IsDouble()) { |
2032 ASSERT(!info()->IsStub()); | 2044 ASSERT(!info()->IsStub()); |
2033 DoubleRegister reg = ToDoubleRegister(instr->value()); | 2045 DoubleRegister reg = ToDoubleRegister(instr->value()); |
2034 // Test the double value. Zero and NaN are false. | 2046 // Test the double value. Zero and NaN are false. |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2183 break; | 2195 break; |
2184 case Token::IN: | 2196 case Token::IN: |
2185 case Token::INSTANCEOF: | 2197 case Token::INSTANCEOF: |
2186 default: | 2198 default: |
2187 UNREACHABLE(); | 2199 UNREACHABLE(); |
2188 } | 2200 } |
2189 return cond; | 2201 return cond; |
2190 } | 2202 } |
2191 | 2203 |
2192 | 2204 |
2193 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { | 2205 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { |
2194 LOperand* left = instr->left(); | 2206 LOperand* left = instr->left(); |
2195 LOperand* right = instr->right(); | 2207 LOperand* right = instr->right(); |
2196 Condition cond = TokenToCondition(instr->op(), false); | 2208 Condition cond = TokenToCondition(instr->op(), false); |
2197 | 2209 |
2198 if (left->IsConstantOperand() && right->IsConstantOperand()) { | 2210 if (left->IsConstantOperand() && right->IsConstantOperand()) { |
2199 // We can statically evaluate the comparison. | 2211 // We can statically evaluate the comparison. |
2200 double left_val = ToDouble(LConstantOperand::cast(left)); | 2212 double left_val = ToDouble(LConstantOperand::cast(left)); |
2201 double right_val = ToDouble(LConstantOperand::cast(right)); | 2213 double right_val = ToDouble(LConstantOperand::cast(right)); |
2202 int next_block = EvalComparison(instr->op(), left_val, right_val) ? | 2214 int next_block = EvalComparison(instr->op(), left_val, right_val) ? |
2203 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_); | 2215 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_); |
(...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3360 scratch, Operand(FIRST_SPEC_OBJECT_TYPE)); | 3372 scratch, Operand(FIRST_SPEC_OBJECT_TYPE)); |
3361 __ Branch(&receiver_ok); | 3373 __ Branch(&receiver_ok); |
3362 | 3374 |
3363 __ bind(&global_object); | 3375 __ bind(&global_object); |
3364 __ lw(receiver, GlobalObjectOperand()); | 3376 __ lw(receiver, GlobalObjectOperand()); |
3365 __ lw(receiver, | 3377 __ lw(receiver, |
3366 FieldMemOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); | 3378 FieldMemOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); |
3367 __ bind(&receiver_ok); | 3379 __ bind(&receiver_ok); |
3368 } | 3380 } |
3369 | 3381 |
| 3382 |
3370 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { | 3383 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { |
3371 Register receiver = ToRegister(instr->receiver()); | 3384 Register receiver = ToRegister(instr->receiver()); |
3372 Register function = ToRegister(instr->function()); | 3385 Register function = ToRegister(instr->function()); |
3373 Register length = ToRegister(instr->length()); | 3386 Register length = ToRegister(instr->length()); |
3374 Register elements = ToRegister(instr->elements()); | 3387 Register elements = ToRegister(instr->elements()); |
3375 Register scratch = scratch0(); | 3388 Register scratch = scratch0(); |
3376 ASSERT(receiver.is(a0)); // Used for parameter count. | 3389 ASSERT(receiver.is(a0)); // Used for parameter count. |
3377 ASSERT(function.is(a1)); // Required by InvokeFunction. | 3390 ASSERT(function.is(a1)); // Required by InvokeFunction. |
3378 ASSERT(ToRegister(instr->result()).is(v0)); | 3391 ASSERT(ToRegister(instr->result()).is(v0)); |
3379 | 3392 |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3886 // 0x41300000 is the top half of 1.0 x 2^20 as a double. | 3899 // 0x41300000 is the top half of 1.0 x 2^20 as a double. |
3887 __ li(a2, Operand(0x41300000)); | 3900 __ li(a2, Operand(0x41300000)); |
3888 // Move 0x41300000xxxxxxxx (x = random bits in v0) to FPU. | 3901 // Move 0x41300000xxxxxxxx (x = random bits in v0) to FPU. |
3889 __ Move(f12, v0, a2); | 3902 __ Move(f12, v0, a2); |
3890 // Move 0x4130000000000000 to FPU. | 3903 // Move 0x4130000000000000 to FPU. |
3891 __ Move(f14, zero_reg, a2); | 3904 __ Move(f14, zero_reg, a2); |
3892 // Subtract to get the result. | 3905 // Subtract to get the result. |
3893 __ sub_d(f0, f12, f14); | 3906 __ sub_d(f0, f12, f14); |
3894 } | 3907 } |
3895 | 3908 |
| 3909 |
3896 void LCodeGen::DoDeferredRandom(LRandom* instr) { | 3910 void LCodeGen::DoDeferredRandom(LRandom* instr) { |
3897 __ PrepareCallCFunction(1, scratch0()); | 3911 __ PrepareCallCFunction(1, scratch0()); |
3898 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); | 3912 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); |
3899 // Return value is in v0. | 3913 // Return value is in v0. |
3900 } | 3914 } |
3901 | 3915 |
3902 | 3916 |
3903 void LCodeGen::DoMathExp(LMathExp* instr) { | 3917 void LCodeGen::DoMathExp(LMathExp* instr) { |
3904 DoubleRegister input = ToDoubleRegister(instr->value()); | 3918 DoubleRegister input = ToDoubleRegister(instr->value()); |
3905 DoubleRegister result = ToDoubleRegister(instr->result()); | 3919 DoubleRegister result = ToDoubleRegister(instr->result()); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4042 } | 4056 } |
4043 | 4057 |
4044 | 4058 |
4045 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { | 4059 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { |
4046 ASSERT(ToRegister(instr->constructor()).is(a1)); | 4060 ASSERT(ToRegister(instr->constructor()).is(a1)); |
4047 ASSERT(ToRegister(instr->result()).is(v0)); | 4061 ASSERT(ToRegister(instr->result()).is(v0)); |
4048 | 4062 |
4049 __ li(a0, Operand(instr->arity())); | 4063 __ li(a0, Operand(instr->arity())); |
4050 __ li(a2, Operand(instr->hydrogen()->property_cell())); | 4064 __ li(a2, Operand(instr->hydrogen()->property_cell())); |
4051 ElementsKind kind = instr->hydrogen()->elements_kind(); | 4065 ElementsKind kind = instr->hydrogen()->elements_kind(); |
4052 bool disable_allocation_sites = | 4066 AllocationSiteOverrideMode override_mode = |
4053 (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE); | 4067 (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE) |
| 4068 ? DISABLE_ALLOCATION_SITES |
| 4069 : DONT_OVERRIDE; |
| 4070 ContextCheckMode context_mode = CONTEXT_CHECK_NOT_REQUIRED; |
4054 | 4071 |
4055 if (instr->arity() == 0) { | 4072 if (instr->arity() == 0) { |
4056 ArrayNoArgumentConstructorStub stub(kind, disable_allocation_sites); | 4073 ArrayNoArgumentConstructorStub stub(kind, context_mode, override_mode); |
4057 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4074 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
4058 } else if (instr->arity() == 1) { | 4075 } else if (instr->arity() == 1) { |
4059 Label done; | 4076 Label done; |
4060 if (IsFastPackedElementsKind(kind)) { | 4077 if (IsFastPackedElementsKind(kind)) { |
4061 Label packed_case; | 4078 Label packed_case; |
4062 // We might need a change here, | 4079 // We might need a change here, |
4063 // look at the first argument. | 4080 // look at the first argument. |
4064 __ lw(t1, MemOperand(sp, 0)); | 4081 __ lw(t1, MemOperand(sp, 0)); |
4065 __ Branch(&packed_case, eq, t1, Operand(zero_reg)); | 4082 __ Branch(&packed_case, eq, t1, Operand(zero_reg)); |
4066 | 4083 |
4067 ElementsKind holey_kind = GetHoleyElementsKind(kind); | 4084 ElementsKind holey_kind = GetHoleyElementsKind(kind); |
4068 ArraySingleArgumentConstructorStub stub(holey_kind, | 4085 ArraySingleArgumentConstructorStub stub(holey_kind, context_mode, |
4069 disable_allocation_sites); | 4086 override_mode); |
4070 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4087 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
4071 __ jmp(&done); | 4088 __ jmp(&done); |
4072 __ bind(&packed_case); | 4089 __ bind(&packed_case); |
4073 } | 4090 } |
4074 | 4091 |
4075 ArraySingleArgumentConstructorStub stub(kind, disable_allocation_sites); | 4092 ArraySingleArgumentConstructorStub stub(kind, context_mode, override_mode); |
4076 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4093 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
4077 __ bind(&done); | 4094 __ bind(&done); |
4078 } else { | 4095 } else { |
4079 ArrayNArgumentsConstructorStub stub(kind, disable_allocation_sites); | 4096 ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode); |
4080 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4097 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
4081 } | 4098 } |
4082 } | 4099 } |
4083 | 4100 |
4084 | 4101 |
4085 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { | 4102 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { |
4086 CallRuntime(instr->function(), instr->arity(), instr); | 4103 CallRuntime(instr->function(), instr->arity(), instr); |
4087 } | 4104 } |
4088 | 4105 |
4089 | 4106 |
(...skipping 1814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5904 __ Subu(scratch, result, scratch); | 5921 __ Subu(scratch, result, scratch); |
5905 __ lw(result, FieldMemOperand(scratch, | 5922 __ lw(result, FieldMemOperand(scratch, |
5906 FixedArray::kHeaderSize - kPointerSize)); | 5923 FixedArray::kHeaderSize - kPointerSize)); |
5907 __ bind(&done); | 5924 __ bind(&done); |
5908 } | 5925 } |
5909 | 5926 |
5910 | 5927 |
5911 #undef __ | 5928 #undef __ |
5912 | 5929 |
5913 } } // namespace v8::internal | 5930 } } // namespace v8::internal |
OLD | NEW |