| 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 3202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3213 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3213 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 3214 if (constant_key & 0xF0000000) { | 3214 if (constant_key & 0xF0000000) { |
| 3215 Abort(kArrayIndexConstantValueTooBig); | 3215 Abort(kArrayIndexConstantValueTooBig); |
| 3216 } | 3216 } |
| 3217 } else { | 3217 } else { |
| 3218 key = ToRegister(instr->key()); | 3218 key = ToRegister(instr->key()); |
| 3219 } | 3219 } |
| 3220 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3220 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 3221 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 3221 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 3222 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 3222 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 3223 int additional_offset = instr->additional_index() << element_size_shift; | 3223 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) |
| 3224 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag |
| 3225 : 0; |
| 3226 |
| 3224 | 3227 |
| 3225 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 3228 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 3226 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3229 elements_kind == FLOAT32_ELEMENTS || |
| 3230 elements_kind == EXTERNAL_DOUBLE_ELEMENTS || |
| 3231 elements_kind == FLOAT64_ELEMENTS) { |
| 3232 int base_offset = |
| 3233 (instr->additional_index() << element_size_shift) + additional_offset; |
| 3227 DwVfpRegister result = ToDoubleRegister(instr->result()); | 3234 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 3228 Operand operand = key_is_constant | 3235 Operand operand = key_is_constant |
| 3229 ? Operand(constant_key << element_size_shift) | 3236 ? Operand(constant_key << element_size_shift) |
| 3230 : Operand(key, LSL, shift_size); | 3237 : Operand(key, LSL, shift_size); |
| 3231 __ add(scratch0(), external_pointer, operand); | 3238 __ add(scratch0(), external_pointer, operand); |
| 3232 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3239 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 3233 __ vldr(double_scratch0().low(), scratch0(), additional_offset); | 3240 elements_kind == FLOAT32_ELEMENTS) { |
| 3241 __ vldr(double_scratch0().low(), scratch0(), base_offset); |
| 3234 __ vcvt_f64_f32(result, double_scratch0().low()); | 3242 __ vcvt_f64_f32(result, double_scratch0().low()); |
| 3235 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 3243 } else { // loading doubles, not floats. |
| 3236 __ vldr(result, scratch0(), additional_offset); | 3244 __ vldr(result, scratch0(), base_offset); |
| 3237 } | 3245 } |
| 3238 } else { | 3246 } else { |
| 3239 Register result = ToRegister(instr->result()); | 3247 Register result = ToRegister(instr->result()); |
| 3240 MemOperand mem_operand = PrepareKeyedOperand( | 3248 MemOperand mem_operand = PrepareKeyedOperand( |
| 3241 key, external_pointer, key_is_constant, constant_key, | 3249 key, external_pointer, key_is_constant, constant_key, |
| 3242 element_size_shift, shift_size, | 3250 element_size_shift, shift_size, |
| 3243 instr->additional_index(), additional_offset); | 3251 instr->additional_index(), additional_offset); |
| 3244 switch (elements_kind) { | 3252 switch (elements_kind) { |
| 3245 case EXTERNAL_BYTE_ELEMENTS: | 3253 case EXTERNAL_BYTE_ELEMENTS: |
| 3254 case INT8_ELEMENTS: |
| 3246 __ ldrsb(result, mem_operand); | 3255 __ ldrsb(result, mem_operand); |
| 3247 break; | 3256 break; |
| 3248 case EXTERNAL_PIXEL_ELEMENTS: | 3257 case EXTERNAL_PIXEL_ELEMENTS: |
| 3249 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3258 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 3259 case UINT8_ELEMENTS: |
| 3260 case UINT8_CLAMPED_ELEMENTS: |
| 3250 __ ldrb(result, mem_operand); | 3261 __ ldrb(result, mem_operand); |
| 3251 break; | 3262 break; |
| 3252 case EXTERNAL_SHORT_ELEMENTS: | 3263 case EXTERNAL_SHORT_ELEMENTS: |
| 3264 case INT16_ELEMENTS: |
| 3253 __ ldrsh(result, mem_operand); | 3265 __ ldrsh(result, mem_operand); |
| 3254 break; | 3266 break; |
| 3255 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3267 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 3268 case UINT16_ELEMENTS: |
| 3256 __ ldrh(result, mem_operand); | 3269 __ ldrh(result, mem_operand); |
| 3257 break; | 3270 break; |
| 3258 case EXTERNAL_INT_ELEMENTS: | 3271 case EXTERNAL_INT_ELEMENTS: |
| 3272 case INT32_ELEMENTS: |
| 3259 __ ldr(result, mem_operand); | 3273 __ ldr(result, mem_operand); |
| 3260 break; | 3274 break; |
| 3261 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3275 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 3276 case UINT32_ELEMENTS: |
| 3262 __ ldr(result, mem_operand); | 3277 __ ldr(result, mem_operand); |
| 3263 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { | 3278 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { |
| 3264 __ cmp(result, Operand(0x80000000)); | 3279 __ cmp(result, Operand(0x80000000)); |
| 3265 DeoptimizeIf(cs, instr->environment()); | 3280 DeoptimizeIf(cs, instr->environment()); |
| 3266 } | 3281 } |
| 3267 break; | 3282 break; |
| 3283 case FLOAT32_ELEMENTS: |
| 3284 case FLOAT64_ELEMENTS: |
| 3268 case EXTERNAL_FLOAT_ELEMENTS: | 3285 case EXTERNAL_FLOAT_ELEMENTS: |
| 3269 case EXTERNAL_DOUBLE_ELEMENTS: | 3286 case EXTERNAL_DOUBLE_ELEMENTS: |
| 3270 case FAST_HOLEY_DOUBLE_ELEMENTS: | 3287 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 3271 case FAST_HOLEY_ELEMENTS: | 3288 case FAST_HOLEY_ELEMENTS: |
| 3272 case FAST_HOLEY_SMI_ELEMENTS: | 3289 case FAST_HOLEY_SMI_ELEMENTS: |
| 3273 case FAST_DOUBLE_ELEMENTS: | 3290 case FAST_DOUBLE_ELEMENTS: |
| 3274 case FAST_ELEMENTS: | 3291 case FAST_ELEMENTS: |
| 3275 case FAST_SMI_ELEMENTS: | 3292 case FAST_SMI_ELEMENTS: |
| 3276 case DICTIONARY_ELEMENTS: | 3293 case DICTIONARY_ELEMENTS: |
| 3277 case NON_STRICT_ARGUMENTS_ELEMENTS: | 3294 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3355 } else { | 3372 } else { |
| 3356 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | 3373 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); |
| 3357 __ cmp(result, scratch); | 3374 __ cmp(result, scratch); |
| 3358 DeoptimizeIf(eq, instr->environment()); | 3375 DeoptimizeIf(eq, instr->environment()); |
| 3359 } | 3376 } |
| 3360 } | 3377 } |
| 3361 } | 3378 } |
| 3362 | 3379 |
| 3363 | 3380 |
| 3364 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { | 3381 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { |
| 3365 if (instr->is_external()) { | 3382 if (instr->is_typed_elements()) { |
| 3366 DoLoadKeyedExternalArray(instr); | 3383 DoLoadKeyedExternalArray(instr); |
| 3367 } else if (instr->hydrogen()->representation().IsDouble()) { | 3384 } else if (instr->hydrogen()->representation().IsDouble()) { |
| 3368 DoLoadKeyedFixedDoubleArray(instr); | 3385 DoLoadKeyedFixedDoubleArray(instr); |
| 3369 } else { | 3386 } else { |
| 3370 DoLoadKeyedFixedArray(instr); | 3387 DoLoadKeyedFixedArray(instr); |
| 3371 } | 3388 } |
| 3372 } | 3389 } |
| 3373 | 3390 |
| 3374 | 3391 |
| 3375 MemOperand LCodeGen::PrepareKeyedOperand(Register key, | 3392 MemOperand LCodeGen::PrepareKeyedOperand(Register key, |
| 3376 Register base, | 3393 Register base, |
| 3377 bool key_is_constant, | 3394 bool key_is_constant, |
| 3378 int constant_key, | 3395 int constant_key, |
| 3379 int element_size, | 3396 int element_size, |
| 3380 int shift_size, | 3397 int shift_size, |
| 3381 int additional_index, | 3398 int additional_index, |
| 3382 int additional_offset) { | 3399 int additional_offset) { |
| 3383 if (additional_index != 0 && !key_is_constant) { | 3400 int base_offset = (additional_index << element_size) + additional_offset; |
| 3401 if (key_is_constant) { |
| 3402 return MemOperand(base, |
| 3403 base_offset + (constant_key << element_size)); |
| 3404 } |
| 3405 |
| 3406 if (additional_offset != 0) { |
| 3407 __ mov(scratch0(), Operand(base_offset)); |
| 3408 if (shift_size >= 0) { |
| 3409 __ add(scratch0(), scratch0(), Operand(key, LSL, shift_size)); |
| 3410 } else { |
| 3411 ASSERT_EQ(-1, shift_size); |
| 3412 __ add(scratch0(), scratch0(), Operand(key, LSR, 1)); |
| 3413 } |
| 3414 return MemOperand(base, scratch0()); |
| 3415 } |
| 3416 |
| 3417 if (additional_index != 0) { |
| 3384 additional_index *= 1 << (element_size - shift_size); | 3418 additional_index *= 1 << (element_size - shift_size); |
| 3385 __ add(scratch0(), key, Operand(additional_index)); | 3419 __ add(scratch0(), key, Operand(additional_index)); |
| 3386 } | 3420 } |
| 3387 | 3421 |
| 3388 if (key_is_constant) { | |
| 3389 return MemOperand(base, | |
| 3390 (constant_key << element_size) + additional_offset); | |
| 3391 } | |
| 3392 | |
| 3393 if (additional_index == 0) { | 3422 if (additional_index == 0) { |
| 3394 if (shift_size >= 0) { | 3423 if (shift_size >= 0) { |
| 3395 return MemOperand(base, key, LSL, shift_size); | 3424 return MemOperand(base, key, LSL, shift_size); |
| 3396 } else { | 3425 } else { |
| 3397 ASSERT_EQ(-1, shift_size); | 3426 ASSERT_EQ(-1, shift_size); |
| 3398 return MemOperand(base, key, LSR, 1); | 3427 return MemOperand(base, key, LSR, 1); |
| 3399 } | 3428 } |
| 3400 } | 3429 } |
| 3401 | 3430 |
| 3402 if (shift_size >= 0) { | 3431 if (shift_size >= 0) { |
| (...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4248 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4277 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 4249 if (constant_key & 0xF0000000) { | 4278 if (constant_key & 0xF0000000) { |
| 4250 Abort(kArrayIndexConstantValueTooBig); | 4279 Abort(kArrayIndexConstantValueTooBig); |
| 4251 } | 4280 } |
| 4252 } else { | 4281 } else { |
| 4253 key = ToRegister(instr->key()); | 4282 key = ToRegister(instr->key()); |
| 4254 } | 4283 } |
| 4255 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4284 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 4256 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4285 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 4257 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4286 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4258 int additional_offset = instr->additional_index() << element_size_shift; | 4287 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) |
| 4288 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag |
| 4289 : 0; |
| 4259 | 4290 |
| 4260 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 4291 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 4261 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4292 elements_kind == FLOAT32_ELEMENTS || |
| 4293 elements_kind == EXTERNAL_DOUBLE_ELEMENTS || |
| 4294 elements_kind == FLOAT64_ELEMENTS) { |
| 4295 int base_offset = |
| 4296 (instr->additional_index() << element_size_shift) + additional_offset; |
| 4262 Register address = scratch0(); | 4297 Register address = scratch0(); |
| 4263 DwVfpRegister value(ToDoubleRegister(instr->value())); | 4298 DwVfpRegister value(ToDoubleRegister(instr->value())); |
| 4264 if (key_is_constant) { | 4299 if (key_is_constant) { |
| 4265 if (constant_key != 0) { | 4300 if (constant_key != 0) { |
| 4266 __ add(address, external_pointer, | 4301 __ add(address, external_pointer, |
| 4267 Operand(constant_key << element_size_shift)); | 4302 Operand(constant_key << element_size_shift)); |
| 4268 } else { | 4303 } else { |
| 4269 address = external_pointer; | 4304 address = external_pointer; |
| 4270 } | 4305 } |
| 4271 } else { | 4306 } else { |
| 4272 __ add(address, external_pointer, Operand(key, LSL, shift_size)); | 4307 __ add(address, external_pointer, Operand(key, LSL, shift_size)); |
| 4273 } | 4308 } |
| 4274 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4309 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 4310 elements_kind == FLOAT32_ELEMENTS) { |
| 4275 __ vcvt_f32_f64(double_scratch0().low(), value); | 4311 __ vcvt_f32_f64(double_scratch0().low(), value); |
| 4276 __ vstr(double_scratch0().low(), address, additional_offset); | 4312 __ vstr(double_scratch0().low(), address, base_offset); |
| 4277 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 4313 } else { // Storing doubles, not floats. |
| 4278 __ vstr(value, address, additional_offset); | 4314 __ vstr(value, address, base_offset); |
| 4279 } | 4315 } |
| 4280 } else { | 4316 } else { |
| 4281 Register value(ToRegister(instr->value())); | 4317 Register value(ToRegister(instr->value())); |
| 4282 MemOperand mem_operand = PrepareKeyedOperand( | 4318 MemOperand mem_operand = PrepareKeyedOperand( |
| 4283 key, external_pointer, key_is_constant, constant_key, | 4319 key, external_pointer, key_is_constant, constant_key, |
| 4284 element_size_shift, shift_size, | 4320 element_size_shift, shift_size, |
| 4285 instr->additional_index(), additional_offset); | 4321 instr->additional_index(), additional_offset); |
| 4286 switch (elements_kind) { | 4322 switch (elements_kind) { |
| 4287 case EXTERNAL_PIXEL_ELEMENTS: | 4323 case EXTERNAL_PIXEL_ELEMENTS: |
| 4288 case EXTERNAL_BYTE_ELEMENTS: | 4324 case EXTERNAL_BYTE_ELEMENTS: |
| 4289 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 4325 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 4326 case UINT8_ELEMENTS: |
| 4327 case UINT8_CLAMPED_ELEMENTS: |
| 4328 case INT8_ELEMENTS: |
| 4290 __ strb(value, mem_operand); | 4329 __ strb(value, mem_operand); |
| 4291 break; | 4330 break; |
| 4292 case EXTERNAL_SHORT_ELEMENTS: | 4331 case EXTERNAL_SHORT_ELEMENTS: |
| 4293 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 4332 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 4333 case INT16_ELEMENTS: |
| 4334 case UINT16_ELEMENTS: |
| 4294 __ strh(value, mem_operand); | 4335 __ strh(value, mem_operand); |
| 4295 break; | 4336 break; |
| 4296 case EXTERNAL_INT_ELEMENTS: | 4337 case EXTERNAL_INT_ELEMENTS: |
| 4297 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 4338 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 4339 case INT32_ELEMENTS: |
| 4340 case UINT32_ELEMENTS: |
| 4298 __ str(value, mem_operand); | 4341 __ str(value, mem_operand); |
| 4299 break; | 4342 break; |
| 4343 case FLOAT32_ELEMENTS: |
| 4344 case FLOAT64_ELEMENTS: |
| 4300 case EXTERNAL_FLOAT_ELEMENTS: | 4345 case EXTERNAL_FLOAT_ELEMENTS: |
| 4301 case EXTERNAL_DOUBLE_ELEMENTS: | 4346 case EXTERNAL_DOUBLE_ELEMENTS: |
| 4302 case FAST_DOUBLE_ELEMENTS: | 4347 case FAST_DOUBLE_ELEMENTS: |
| 4303 case FAST_ELEMENTS: | 4348 case FAST_ELEMENTS: |
| 4304 case FAST_SMI_ELEMENTS: | 4349 case FAST_SMI_ELEMENTS: |
| 4305 case FAST_HOLEY_DOUBLE_ELEMENTS: | 4350 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 4306 case FAST_HOLEY_ELEMENTS: | 4351 case FAST_HOLEY_ELEMENTS: |
| 4307 case FAST_HOLEY_SMI_ELEMENTS: | 4352 case FAST_HOLEY_SMI_ELEMENTS: |
| 4308 case DICTIONARY_ELEMENTS: | 4353 case DICTIONARY_ELEMENTS: |
| 4309 case NON_STRICT_ARGUMENTS_ELEMENTS: | 4354 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4399 GetLinkRegisterState(), | 4444 GetLinkRegisterState(), |
| 4400 kSaveFPRegs, | 4445 kSaveFPRegs, |
| 4401 EMIT_REMEMBERED_SET, | 4446 EMIT_REMEMBERED_SET, |
| 4402 check_needed); | 4447 check_needed); |
| 4403 } | 4448 } |
| 4404 } | 4449 } |
| 4405 | 4450 |
| 4406 | 4451 |
| 4407 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { | 4452 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { |
| 4408 // By cases: external, fast double | 4453 // By cases: external, fast double |
| 4409 if (instr->is_external()) { | 4454 if (instr->is_typed_elements()) { |
| 4410 DoStoreKeyedExternalArray(instr); | 4455 DoStoreKeyedExternalArray(instr); |
| 4411 } else if (instr->hydrogen()->value()->representation().IsDouble()) { | 4456 } else if (instr->hydrogen()->value()->representation().IsDouble()) { |
| 4412 DoStoreKeyedFixedDoubleArray(instr); | 4457 DoStoreKeyedFixedDoubleArray(instr); |
| 4413 } else { | 4458 } else { |
| 4414 DoStoreKeyedFixedArray(instr); | 4459 DoStoreKeyedFixedArray(instr); |
| 4415 } | 4460 } |
| 4416 } | 4461 } |
| 4417 | 4462 |
| 4418 | 4463 |
| 4419 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 4464 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
| (...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5800 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5845 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
| 5801 __ ldr(result, FieldMemOperand(scratch, | 5846 __ ldr(result, FieldMemOperand(scratch, |
| 5802 FixedArray::kHeaderSize - kPointerSize)); | 5847 FixedArray::kHeaderSize - kPointerSize)); |
| 5803 __ bind(&done); | 5848 __ bind(&done); |
| 5804 } | 5849 } |
| 5805 | 5850 |
| 5806 | 5851 |
| 5807 #undef __ | 5852 #undef __ |
| 5808 | 5853 |
| 5809 } } // namespace v8::internal | 5854 } } // namespace v8::internal |
| OLD | NEW |