OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/cpu-profiler.h" | 9 #include "src/cpu-profiler.h" |
10 #include "src/hydrogen-osr.h" | 10 #include "src/hydrogen-osr.h" |
(...skipping 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1208 | 1208 |
1209 // TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI. | 1209 // TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI. |
1210 void LCodeGen::DoDivI(LDivI* instr) { | 1210 void LCodeGen::DoDivI(LDivI* instr) { |
1211 HBinaryOperation* hdiv = instr->hydrogen(); | 1211 HBinaryOperation* hdiv = instr->hydrogen(); |
1212 Register dividend = ToRegister(instr->dividend()); | 1212 Register dividend = ToRegister(instr->dividend()); |
1213 Register divisor = ToRegister(instr->divisor()); | 1213 Register divisor = ToRegister(instr->divisor()); |
1214 const Register result = ToRegister(instr->result()); | 1214 const Register result = ToRegister(instr->result()); |
1215 | 1215 |
1216 // On MIPS div is asynchronous - it will run in the background while we | 1216 // On MIPS div is asynchronous - it will run in the background while we |
1217 // check for special cases. | 1217 // check for special cases. |
1218 __ Div(result, dividend, divisor); | 1218 __ Ddiv(result, dividend, divisor); |
1219 | 1219 |
1220 // Check for x / 0. | 1220 // Check for x / 0. |
1221 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { | 1221 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { |
1222 DeoptimizeIf(eq, instr, Deoptimizer::kDivisionByZero, divisor, | 1222 DeoptimizeIf(eq, instr, Deoptimizer::kDivisionByZero, divisor, |
1223 Operand(zero_reg)); | 1223 Operand(zero_reg)); |
1224 } | 1224 } |
1225 | 1225 |
1226 // Check for (0 / -x) that will produce negative zero. | 1226 // Check for (0 / -x) that will produce negative zero. |
1227 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1227 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1228 Label left_not_zero; | 1228 Label left_not_zero; |
(...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2277 | 2277 |
2278 if (expected.Contains(ToBooleanStub::SYMBOL)) { | 2278 if (expected.Contains(ToBooleanStub::SYMBOL)) { |
2279 // Symbol value -> true. | 2279 // Symbol value -> true. |
2280 const Register scratch = scratch1(); | 2280 const Register scratch = scratch1(); |
2281 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); | 2281 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); |
2282 __ Branch(instr->TrueLabel(chunk_), eq, scratch, Operand(SYMBOL_TYPE)); | 2282 __ Branch(instr->TrueLabel(chunk_), eq, scratch, Operand(SYMBOL_TYPE)); |
2283 } | 2283 } |
2284 | 2284 |
2285 if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { | 2285 if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { |
2286 // Symbol value -> true. | 2286 // Symbol value -> true. |
| 2287 Label not_simd; |
2287 const Register scratch = scratch1(); | 2288 const Register scratch = scratch1(); |
2288 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); | 2289 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); |
2289 __ Branch(instr->TrueLabel(chunk_), eq, scratch, | 2290 __ Branch(¬_simd, lt, at, Operand(FIRST_SIMD_VALUE_TYPE)); |
2290 Operand(FLOAT32X4_TYPE)); | 2291 __ Branch(instr->TrueLabel(chunk_), le, scratch, |
| 2292 Operand(LAST_SIMD_VALUE_TYPE)); |
| 2293 __ bind(¬_simd); |
2291 } | 2294 } |
2292 | 2295 |
2293 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 2296 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { |
2294 // heap number -> false iff +0, -0, or NaN. | 2297 // heap number -> false iff +0, -0, or NaN. |
2295 DoubleRegister dbl_scratch = double_scratch0(); | 2298 DoubleRegister dbl_scratch = double_scratch0(); |
2296 Label not_heap_number; | 2299 Label not_heap_number; |
2297 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 2300 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
2298 __ Branch(¬_heap_number, ne, map, Operand(at)); | 2301 __ Branch(¬_heap_number, ne, map, Operand(at)); |
2299 __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); | 2302 __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); |
2300 __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), | 2303 __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2996 CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(), | 2999 CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(), |
2997 SLOPPY, PREMONOMORPHIC).code(); | 3000 SLOPPY, PREMONOMORPHIC).code(); |
2998 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3001 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
2999 } | 3002 } |
3000 | 3003 |
3001 | 3004 |
3002 void LCodeGen::DoLoadGlobalViaContext(LLoadGlobalViaContext* instr) { | 3005 void LCodeGen::DoLoadGlobalViaContext(LLoadGlobalViaContext* instr) { |
3003 DCHECK(ToRegister(instr->context()).is(cp)); | 3006 DCHECK(ToRegister(instr->context()).is(cp)); |
3004 DCHECK(ToRegister(instr->result()).is(v0)); | 3007 DCHECK(ToRegister(instr->result()).is(v0)); |
3005 | 3008 |
3006 int const slot = instr->slot_index(); | 3009 __ li(LoadGlobalViaContextDescriptor::DepthRegister(), |
3007 int const depth = instr->depth(); | 3010 Operand(Smi::FromInt(instr->depth()))); |
3008 if (depth <= LoadGlobalViaContextStub::kMaximumDepth) { | 3011 __ li(LoadGlobalViaContextDescriptor::SlotRegister(), |
3009 __ li(LoadGlobalViaContextDescriptor::SlotRegister(), Operand(slot)); | 3012 Operand(Smi::FromInt(instr->slot_index()))); |
3010 Handle<Code> stub = | 3013 __ li(LoadGlobalViaContextDescriptor::NameRegister(), Operand(instr->name())); |
3011 CodeFactory::LoadGlobalViaContext(isolate(), depth).code(); | 3014 |
3012 CallCode(stub, RelocInfo::CODE_TARGET, instr); | 3015 Handle<Code> stub = |
3013 } else { | 3016 CodeFactory::LoadGlobalViaContext(isolate(), instr->depth()).code(); |
3014 __ Push(Smi::FromInt(slot)); | 3017 CallCode(stub, RelocInfo::CODE_TARGET, instr); |
3015 __ CallRuntime(Runtime::kLoadGlobalViaContext, 1); | |
3016 } | |
3017 } | 3018 } |
3018 | 3019 |
3019 | 3020 |
3020 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 3021 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
3021 Register context = ToRegister(instr->context()); | 3022 Register context = ToRegister(instr->context()); |
3022 Register result = ToRegister(instr->result()); | 3023 Register result = ToRegister(instr->result()); |
3023 | 3024 |
3024 __ ld(result, ContextOperand(context, instr->slot_index())); | 3025 __ ld(result, ContextOperand(context, instr->slot_index())); |
3025 if (instr->hydrogen()->RequiresHoleCheck()) { | 3026 if (instr->hydrogen()->RequiresHoleCheck()) { |
3026 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 3027 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3224 } | 3225 } |
3225 } else { | 3226 } else { |
3226 key = ToRegister(instr->key()); | 3227 key = ToRegister(instr->key()); |
3227 } | 3228 } |
3228 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3229 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
3229 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 3230 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
3230 ? (element_size_shift - (kSmiTagSize + kSmiShiftSize)) | 3231 ? (element_size_shift - (kSmiTagSize + kSmiShiftSize)) |
3231 : element_size_shift; | 3232 : element_size_shift; |
3232 int base_offset = instr->base_offset(); | 3233 int base_offset = instr->base_offset(); |
3233 | 3234 |
3234 if (elements_kind == FLOAT32_ELEMENTS || elements_kind == FLOAT64_ELEMENTS) { | 3235 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 3236 elements_kind == FLOAT32_ELEMENTS || |
| 3237 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
| 3238 elements_kind == FLOAT64_ELEMENTS) { |
3235 FPURegister result = ToDoubleRegister(instr->result()); | 3239 FPURegister result = ToDoubleRegister(instr->result()); |
3236 if (key_is_constant) { | 3240 if (key_is_constant) { |
3237 __ Daddu(scratch0(), external_pointer, | 3241 __ Daddu(scratch0(), external_pointer, |
3238 constant_key << element_size_shift); | 3242 constant_key << element_size_shift); |
3239 } else { | 3243 } else { |
3240 if (shift_size < 0) { | 3244 if (shift_size < 0) { |
3241 if (shift_size == -32) { | 3245 if (shift_size == -32) { |
3242 __ dsra32(scratch0(), key, 0); | 3246 __ dsra32(scratch0(), key, 0); |
3243 } else { | 3247 } else { |
3244 __ dsra(scratch0(), key, -shift_size); | 3248 __ dsra(scratch0(), key, -shift_size); |
3245 } | 3249 } |
3246 } else { | 3250 } else { |
3247 __ dsll(scratch0(), key, shift_size); | 3251 __ dsll(scratch0(), key, shift_size); |
3248 } | 3252 } |
3249 __ Daddu(scratch0(), scratch0(), external_pointer); | 3253 __ Daddu(scratch0(), scratch0(), external_pointer); |
3250 } | 3254 } |
3251 if (elements_kind == FLOAT32_ELEMENTS) { | 3255 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 3256 elements_kind == FLOAT32_ELEMENTS) { |
3252 __ lwc1(result, MemOperand(scratch0(), base_offset)); | 3257 __ lwc1(result, MemOperand(scratch0(), base_offset)); |
3253 __ cvt_d_s(result, result); | 3258 __ cvt_d_s(result, result); |
3254 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 3259 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
3255 __ ldc1(result, MemOperand(scratch0(), base_offset)); | 3260 __ ldc1(result, MemOperand(scratch0(), base_offset)); |
3256 } | 3261 } |
3257 } else { | 3262 } else { |
3258 Register result = ToRegister(instr->result()); | 3263 Register result = ToRegister(instr->result()); |
3259 MemOperand mem_operand = PrepareKeyedOperand( | 3264 MemOperand mem_operand = PrepareKeyedOperand( |
3260 key, external_pointer, key_is_constant, constant_key, | 3265 key, external_pointer, key_is_constant, constant_key, |
3261 element_size_shift, shift_size, base_offset); | 3266 element_size_shift, shift_size, base_offset); |
3262 switch (elements_kind) { | 3267 switch (elements_kind) { |
| 3268 case EXTERNAL_INT8_ELEMENTS: |
3263 case INT8_ELEMENTS: | 3269 case INT8_ELEMENTS: |
3264 __ lb(result, mem_operand); | 3270 __ lb(result, mem_operand); |
3265 break; | 3271 break; |
| 3272 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: |
| 3273 case EXTERNAL_UINT8_ELEMENTS: |
3266 case UINT8_ELEMENTS: | 3274 case UINT8_ELEMENTS: |
3267 case UINT8_CLAMPED_ELEMENTS: | 3275 case UINT8_CLAMPED_ELEMENTS: |
3268 __ lbu(result, mem_operand); | 3276 __ lbu(result, mem_operand); |
3269 break; | 3277 break; |
| 3278 case EXTERNAL_INT16_ELEMENTS: |
3270 case INT16_ELEMENTS: | 3279 case INT16_ELEMENTS: |
3271 __ lh(result, mem_operand); | 3280 __ lh(result, mem_operand); |
3272 break; | 3281 break; |
| 3282 case EXTERNAL_UINT16_ELEMENTS: |
3273 case UINT16_ELEMENTS: | 3283 case UINT16_ELEMENTS: |
3274 __ lhu(result, mem_operand); | 3284 __ lhu(result, mem_operand); |
3275 break; | 3285 break; |
| 3286 case EXTERNAL_INT32_ELEMENTS: |
3276 case INT32_ELEMENTS: | 3287 case INT32_ELEMENTS: |
3277 __ lw(result, mem_operand); | 3288 __ lw(result, mem_operand); |
3278 break; | 3289 break; |
| 3290 case EXTERNAL_UINT32_ELEMENTS: |
3279 case UINT32_ELEMENTS: | 3291 case UINT32_ELEMENTS: |
3280 __ lw(result, mem_operand); | 3292 __ lw(result, mem_operand); |
3281 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { | 3293 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { |
3282 DeoptimizeIf(Ugreater_equal, instr, Deoptimizer::kNegativeValue, | 3294 DeoptimizeIf(Ugreater_equal, instr, Deoptimizer::kNegativeValue, |
3283 result, Operand(0x80000000)); | 3295 result, Operand(0x80000000)); |
3284 } | 3296 } |
3285 break; | 3297 break; |
3286 case FLOAT32_ELEMENTS: | 3298 case FLOAT32_ELEMENTS: |
3287 case FLOAT64_ELEMENTS: | 3299 case FLOAT64_ELEMENTS: |
| 3300 case EXTERNAL_FLOAT32_ELEMENTS: |
| 3301 case EXTERNAL_FLOAT64_ELEMENTS: |
3288 case FAST_DOUBLE_ELEMENTS: | 3302 case FAST_DOUBLE_ELEMENTS: |
3289 case FAST_ELEMENTS: | 3303 case FAST_ELEMENTS: |
3290 case FAST_SMI_ELEMENTS: | 3304 case FAST_SMI_ELEMENTS: |
3291 case FAST_HOLEY_DOUBLE_ELEMENTS: | 3305 case FAST_HOLEY_DOUBLE_ELEMENTS: |
3292 case FAST_HOLEY_ELEMENTS: | 3306 case FAST_HOLEY_ELEMENTS: |
3293 case FAST_HOLEY_SMI_ELEMENTS: | 3307 case FAST_HOLEY_SMI_ELEMENTS: |
3294 case DICTIONARY_ELEMENTS: | 3308 case DICTIONARY_ELEMENTS: |
3295 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 3309 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
3296 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 3310 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
3297 UNREACHABLE(); | 3311 UNREACHABLE(); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3415 DeoptimizeIf(ne, instr, Deoptimizer::kHole, result, | 3429 DeoptimizeIf(ne, instr, Deoptimizer::kHole, result, |
3416 Operand(Smi::FromInt(Isolate::kArrayProtectorValid))); | 3430 Operand(Smi::FromInt(Isolate::kArrayProtectorValid))); |
3417 } | 3431 } |
3418 __ LoadRoot(result, Heap::kUndefinedValueRootIndex); | 3432 __ LoadRoot(result, Heap::kUndefinedValueRootIndex); |
3419 __ bind(&done); | 3433 __ bind(&done); |
3420 } | 3434 } |
3421 } | 3435 } |
3422 | 3436 |
3423 | 3437 |
3424 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { | 3438 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { |
3425 if (instr->is_fixed_typed_array()) { | 3439 if (instr->is_typed_elements()) { |
3426 DoLoadKeyedExternalArray(instr); | 3440 DoLoadKeyedExternalArray(instr); |
3427 } else if (instr->hydrogen()->representation().IsDouble()) { | 3441 } else if (instr->hydrogen()->representation().IsDouble()) { |
3428 DoLoadKeyedFixedDoubleArray(instr); | 3442 DoLoadKeyedFixedDoubleArray(instr); |
3429 } else { | 3443 } else { |
3430 DoLoadKeyedFixedArray(instr); | 3444 DoLoadKeyedFixedArray(instr); |
3431 } | 3445 } |
3432 } | 3446 } |
3433 | 3447 |
3434 | 3448 |
3435 MemOperand LCodeGen::PrepareKeyedOperand(Register key, | 3449 MemOperand LCodeGen::PrepareKeyedOperand(Register key, |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3679 // If there is no frame, the context must be in cp. | 3693 // If there is no frame, the context must be in cp. |
3680 DCHECK(result.is(cp)); | 3694 DCHECK(result.is(cp)); |
3681 } | 3695 } |
3682 } | 3696 } |
3683 | 3697 |
3684 | 3698 |
3685 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { | 3699 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { |
3686 DCHECK(ToRegister(instr->context()).is(cp)); | 3700 DCHECK(ToRegister(instr->context()).is(cp)); |
3687 __ li(scratch0(), instr->hydrogen()->pairs()); | 3701 __ li(scratch0(), instr->hydrogen()->pairs()); |
3688 __ li(scratch1(), Operand(Smi::FromInt(instr->hydrogen()->flags()))); | 3702 __ li(scratch1(), Operand(Smi::FromInt(instr->hydrogen()->flags()))); |
3689 __ Push(scratch0(), scratch1()); | 3703 // The context is the first argument. |
3690 CallRuntime(Runtime::kDeclareGlobals, 2, instr); | 3704 __ Push(cp, scratch0(), scratch1()); |
| 3705 CallRuntime(Runtime::kDeclareGlobals, 3, instr); |
3691 } | 3706 } |
3692 | 3707 |
3693 | 3708 |
3694 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 3709 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
3695 int formal_parameter_count, int arity, | 3710 int formal_parameter_count, int arity, |
3696 LInstruction* instr) { | 3711 LInstruction* instr) { |
3697 bool dont_adapt_arguments = | 3712 bool dont_adapt_arguments = |
3698 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 3713 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
3699 bool can_invoke_directly = | 3714 bool can_invoke_directly = |
3700 dont_adapt_arguments || formal_parameter_count == arity; | 3715 dont_adapt_arguments || formal_parameter_count == arity; |
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4383 instr->hydrogen()->initialization_state()).code(); | 4398 instr->hydrogen()->initialization_state()).code(); |
4384 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 4399 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
4385 } | 4400 } |
4386 | 4401 |
4387 | 4402 |
4388 void LCodeGen::DoStoreGlobalViaContext(LStoreGlobalViaContext* instr) { | 4403 void LCodeGen::DoStoreGlobalViaContext(LStoreGlobalViaContext* instr) { |
4389 DCHECK(ToRegister(instr->context()).is(cp)); | 4404 DCHECK(ToRegister(instr->context()).is(cp)); |
4390 DCHECK(ToRegister(instr->value()) | 4405 DCHECK(ToRegister(instr->value()) |
4391 .is(StoreGlobalViaContextDescriptor::ValueRegister())); | 4406 .is(StoreGlobalViaContextDescriptor::ValueRegister())); |
4392 | 4407 |
4393 int const slot = instr->slot_index(); | 4408 __ li(StoreGlobalViaContextDescriptor::DepthRegister(), |
4394 int const depth = instr->depth(); | 4409 Operand(Smi::FromInt(instr->depth()))); |
4395 if (depth <= StoreGlobalViaContextStub::kMaximumDepth) { | 4410 __ li(StoreGlobalViaContextDescriptor::SlotRegister(), |
4396 __ li(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot)); | 4411 Operand(Smi::FromInt(instr->slot_index()))); |
4397 Handle<Code> stub = CodeFactory::StoreGlobalViaContext( | 4412 __ li(StoreGlobalViaContextDescriptor::NameRegister(), |
4398 isolate(), depth, instr->language_mode()) | 4413 Operand(instr->name())); |
4399 .code(); | 4414 |
4400 CallCode(stub, RelocInfo::CODE_TARGET, instr); | 4415 Handle<Code> stub = CodeFactory::StoreGlobalViaContext( |
4401 } else { | 4416 isolate(), instr->depth(), instr->language_mode()) |
4402 __ Push(Smi::FromInt(slot)); | 4417 .code(); |
4403 __ Push(StoreGlobalViaContextDescriptor::ValueRegister()); | 4418 CallCode(stub, RelocInfo::CODE_TARGET, instr); |
4404 __ CallRuntime(is_strict(language_mode()) | |
4405 ? Runtime::kStoreGlobalViaContext_Strict | |
4406 : Runtime::kStoreGlobalViaContext_Sloppy, | |
4407 2); | |
4408 } | |
4409 } | 4419 } |
4410 | 4420 |
4411 | 4421 |
4412 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { | 4422 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { |
4413 Condition cc = instr->hydrogen()->allow_equality() ? hi : hs; | 4423 Condition cc = instr->hydrogen()->allow_equality() ? hi : hs; |
4414 Operand operand((int64_t)0); | 4424 Operand operand((int64_t)0); |
4415 Register reg; | 4425 Register reg; |
4416 if (instr->index()->IsConstantOperand()) { | 4426 if (instr->index()->IsConstantOperand()) { |
4417 operand = ToOperand(instr->index()); | 4427 operand = ToOperand(instr->index()); |
4418 reg = ToRegister(instr->length()); | 4428 reg = ToRegister(instr->length()); |
(...skipping 26 matching lines...) Expand all Loading... |
4445 } | 4455 } |
4446 } else { | 4456 } else { |
4447 key = ToRegister(instr->key()); | 4457 key = ToRegister(instr->key()); |
4448 } | 4458 } |
4449 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4459 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
4450 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4460 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
4451 ? (element_size_shift - (kSmiTagSize + kSmiShiftSize)) | 4461 ? (element_size_shift - (kSmiTagSize + kSmiShiftSize)) |
4452 : element_size_shift; | 4462 : element_size_shift; |
4453 int base_offset = instr->base_offset(); | 4463 int base_offset = instr->base_offset(); |
4454 | 4464 |
4455 if (elements_kind == FLOAT32_ELEMENTS || elements_kind == FLOAT64_ELEMENTS) { | 4465 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 4466 elements_kind == FLOAT32_ELEMENTS || |
| 4467 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
| 4468 elements_kind == FLOAT64_ELEMENTS) { |
4456 Register address = scratch0(); | 4469 Register address = scratch0(); |
4457 FPURegister value(ToDoubleRegister(instr->value())); | 4470 FPURegister value(ToDoubleRegister(instr->value())); |
4458 if (key_is_constant) { | 4471 if (key_is_constant) { |
4459 if (constant_key != 0) { | 4472 if (constant_key != 0) { |
4460 __ Daddu(address, external_pointer, | 4473 __ Daddu(address, external_pointer, |
4461 Operand(constant_key << element_size_shift)); | 4474 Operand(constant_key << element_size_shift)); |
4462 } else { | 4475 } else { |
4463 address = external_pointer; | 4476 address = external_pointer; |
4464 } | 4477 } |
4465 } else { | 4478 } else { |
4466 if (shift_size < 0) { | 4479 if (shift_size < 0) { |
4467 if (shift_size == -32) { | 4480 if (shift_size == -32) { |
4468 __ dsra32(address, key, 0); | 4481 __ dsra32(address, key, 0); |
4469 } else { | 4482 } else { |
4470 __ dsra(address, key, -shift_size); | 4483 __ dsra(address, key, -shift_size); |
4471 } | 4484 } |
4472 } else { | 4485 } else { |
4473 __ dsll(address, key, shift_size); | 4486 __ dsll(address, key, shift_size); |
4474 } | 4487 } |
4475 __ Daddu(address, external_pointer, address); | 4488 __ Daddu(address, external_pointer, address); |
4476 } | 4489 } |
4477 | 4490 |
4478 if (elements_kind == FLOAT32_ELEMENTS) { | 4491 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 4492 elements_kind == FLOAT32_ELEMENTS) { |
4479 __ cvt_s_d(double_scratch0(), value); | 4493 __ cvt_s_d(double_scratch0(), value); |
4480 __ swc1(double_scratch0(), MemOperand(address, base_offset)); | 4494 __ swc1(double_scratch0(), MemOperand(address, base_offset)); |
4481 } else { // Storing doubles, not floats. | 4495 } else { // Storing doubles, not floats. |
4482 __ sdc1(value, MemOperand(address, base_offset)); | 4496 __ sdc1(value, MemOperand(address, base_offset)); |
4483 } | 4497 } |
4484 } else { | 4498 } else { |
4485 Register value(ToRegister(instr->value())); | 4499 Register value(ToRegister(instr->value())); |
4486 MemOperand mem_operand = PrepareKeyedOperand( | 4500 MemOperand mem_operand = PrepareKeyedOperand( |
4487 key, external_pointer, key_is_constant, constant_key, | 4501 key, external_pointer, key_is_constant, constant_key, |
4488 element_size_shift, shift_size, | 4502 element_size_shift, shift_size, |
4489 base_offset); | 4503 base_offset); |
4490 switch (elements_kind) { | 4504 switch (elements_kind) { |
| 4505 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: |
| 4506 case EXTERNAL_INT8_ELEMENTS: |
| 4507 case EXTERNAL_UINT8_ELEMENTS: |
4491 case UINT8_ELEMENTS: | 4508 case UINT8_ELEMENTS: |
4492 case UINT8_CLAMPED_ELEMENTS: | 4509 case UINT8_CLAMPED_ELEMENTS: |
4493 case INT8_ELEMENTS: | 4510 case INT8_ELEMENTS: |
4494 __ sb(value, mem_operand); | 4511 __ sb(value, mem_operand); |
4495 break; | 4512 break; |
| 4513 case EXTERNAL_INT16_ELEMENTS: |
| 4514 case EXTERNAL_UINT16_ELEMENTS: |
4496 case INT16_ELEMENTS: | 4515 case INT16_ELEMENTS: |
4497 case UINT16_ELEMENTS: | 4516 case UINT16_ELEMENTS: |
4498 __ sh(value, mem_operand); | 4517 __ sh(value, mem_operand); |
4499 break; | 4518 break; |
| 4519 case EXTERNAL_INT32_ELEMENTS: |
| 4520 case EXTERNAL_UINT32_ELEMENTS: |
4500 case INT32_ELEMENTS: | 4521 case INT32_ELEMENTS: |
4501 case UINT32_ELEMENTS: | 4522 case UINT32_ELEMENTS: |
4502 __ sw(value, mem_operand); | 4523 __ sw(value, mem_operand); |
4503 break; | 4524 break; |
4504 case FLOAT32_ELEMENTS: | 4525 case FLOAT32_ELEMENTS: |
4505 case FLOAT64_ELEMENTS: | 4526 case FLOAT64_ELEMENTS: |
| 4527 case EXTERNAL_FLOAT32_ELEMENTS: |
| 4528 case EXTERNAL_FLOAT64_ELEMENTS: |
4506 case FAST_DOUBLE_ELEMENTS: | 4529 case FAST_DOUBLE_ELEMENTS: |
4507 case FAST_ELEMENTS: | 4530 case FAST_ELEMENTS: |
4508 case FAST_SMI_ELEMENTS: | 4531 case FAST_SMI_ELEMENTS: |
4509 case FAST_HOLEY_DOUBLE_ELEMENTS: | 4532 case FAST_HOLEY_DOUBLE_ELEMENTS: |
4510 case FAST_HOLEY_ELEMENTS: | 4533 case FAST_HOLEY_ELEMENTS: |
4511 case FAST_HOLEY_SMI_ELEMENTS: | 4534 case FAST_HOLEY_SMI_ELEMENTS: |
4512 case DICTIONARY_ELEMENTS: | 4535 case DICTIONARY_ELEMENTS: |
4513 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 4536 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
4514 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 4537 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
4515 UNREACHABLE(); | 4538 UNREACHABLE(); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4622 kSaveFPRegs, | 4645 kSaveFPRegs, |
4623 EMIT_REMEMBERED_SET, | 4646 EMIT_REMEMBERED_SET, |
4624 check_needed, | 4647 check_needed, |
4625 instr->hydrogen()->PointersToHereCheckForValue()); | 4648 instr->hydrogen()->PointersToHereCheckForValue()); |
4626 } | 4649 } |
4627 } | 4650 } |
4628 | 4651 |
4629 | 4652 |
4630 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { | 4653 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { |
4631 // By cases: external, fast double | 4654 // By cases: external, fast double |
4632 if (instr->is_fixed_typed_array()) { | 4655 if (instr->is_typed_elements()) { |
4633 DoStoreKeyedExternalArray(instr); | 4656 DoStoreKeyedExternalArray(instr); |
4634 } else if (instr->hydrogen()->value()->representation().IsDouble()) { | 4657 } else if (instr->hydrogen()->value()->representation().IsDouble()) { |
4635 DoStoreKeyedFixedDoubleArray(instr); | 4658 DoStoreKeyedFixedDoubleArray(instr); |
4636 } else { | 4659 } else { |
4637 DoStoreKeyedFixedArray(instr); | 4660 DoStoreKeyedFixedArray(instr); |
4638 } | 4661 } |
4639 } | 4662 } |
4640 | 4663 |
4641 | 4664 |
4642 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 4665 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
(...skipping 1232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5875 *cmp2 = Operand(SYMBOL_TYPE); | 5898 *cmp2 = Operand(SYMBOL_TYPE); |
5876 final_branch_condition = eq; | 5899 final_branch_condition = eq; |
5877 | 5900 |
5878 } else if (String::Equals(type_name, factory->float32x4_string())) { | 5901 } else if (String::Equals(type_name, factory->float32x4_string())) { |
5879 __ JumpIfSmi(input, false_label); | 5902 __ JumpIfSmi(input, false_label); |
5880 __ GetObjectType(input, input, scratch); | 5903 __ GetObjectType(input, input, scratch); |
5881 *cmp1 = scratch; | 5904 *cmp1 = scratch; |
5882 *cmp2 = Operand(FLOAT32X4_TYPE); | 5905 *cmp2 = Operand(FLOAT32X4_TYPE); |
5883 final_branch_condition = eq; | 5906 final_branch_condition = eq; |
5884 | 5907 |
| 5908 } else if (String::Equals(type_name, factory->int32x4_string())) { |
| 5909 __ JumpIfSmi(input, false_label); |
| 5910 __ GetObjectType(input, input, scratch); |
| 5911 *cmp1 = scratch; |
| 5912 *cmp2 = Operand(INT32X4_TYPE); |
| 5913 final_branch_condition = eq; |
| 5914 |
| 5915 } else if (String::Equals(type_name, factory->bool32x4_string())) { |
| 5916 __ JumpIfSmi(input, false_label); |
| 5917 __ GetObjectType(input, input, scratch); |
| 5918 *cmp1 = scratch; |
| 5919 *cmp2 = Operand(BOOL32X4_TYPE); |
| 5920 final_branch_condition = eq; |
| 5921 |
| 5922 } else if (String::Equals(type_name, factory->int16x8_string())) { |
| 5923 __ JumpIfSmi(input, false_label); |
| 5924 __ GetObjectType(input, input, scratch); |
| 5925 *cmp1 = scratch; |
| 5926 *cmp2 = Operand(INT16X8_TYPE); |
| 5927 final_branch_condition = eq; |
| 5928 |
| 5929 } else if (String::Equals(type_name, factory->bool16x8_string())) { |
| 5930 __ JumpIfSmi(input, false_label); |
| 5931 __ GetObjectType(input, input, scratch); |
| 5932 *cmp1 = scratch; |
| 5933 *cmp2 = Operand(BOOL16X8_TYPE); |
| 5934 final_branch_condition = eq; |
| 5935 |
| 5936 } else if (String::Equals(type_name, factory->int8x16_string())) { |
| 5937 __ JumpIfSmi(input, false_label); |
| 5938 __ GetObjectType(input, input, scratch); |
| 5939 *cmp1 = scratch; |
| 5940 *cmp2 = Operand(INT8X16_TYPE); |
| 5941 final_branch_condition = eq; |
| 5942 |
| 5943 } else if (String::Equals(type_name, factory->bool8x16_string())) { |
| 5944 __ JumpIfSmi(input, false_label); |
| 5945 __ GetObjectType(input, input, scratch); |
| 5946 *cmp1 = scratch; |
| 5947 *cmp2 = Operand(BOOL8X16_TYPE); |
| 5948 final_branch_condition = eq; |
| 5949 |
5885 } else if (String::Equals(type_name, factory->boolean_string())) { | 5950 } else if (String::Equals(type_name, factory->boolean_string())) { |
5886 __ LoadRoot(at, Heap::kTrueValueRootIndex); | 5951 __ LoadRoot(at, Heap::kTrueValueRootIndex); |
5887 __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input)); | 5952 __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input)); |
5888 __ LoadRoot(at, Heap::kFalseValueRootIndex); | 5953 __ LoadRoot(at, Heap::kFalseValueRootIndex); |
5889 *cmp1 = at; | 5954 *cmp1 = at; |
5890 *cmp2 = Operand(input); | 5955 *cmp2 = Operand(input); |
5891 final_branch_condition = eq; | 5956 final_branch_condition = eq; |
5892 | 5957 |
5893 } else if (String::Equals(type_name, factory->undefined_string())) { | 5958 } else if (String::Equals(type_name, factory->undefined_string())) { |
5894 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 5959 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6241 __ Push(at, ToRegister(instr->function())); | 6306 __ Push(at, ToRegister(instr->function())); |
6242 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6307 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
6243 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6308 RecordSafepoint(Safepoint::kNoLazyDeopt); |
6244 } | 6309 } |
6245 | 6310 |
6246 | 6311 |
6247 #undef __ | 6312 #undef __ |
6248 | 6313 |
6249 } // namespace internal | 6314 } // namespace internal |
6250 } // namespace v8 | 6315 } // namespace v8 |
OLD | NEW |