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 |