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 3194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3205 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3205 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
3206 if (constant_key & 0xF0000000) { | 3206 if (constant_key & 0xF0000000) { |
3207 Abort(kArrayIndexConstantValueTooBig); | 3207 Abort(kArrayIndexConstantValueTooBig); |
3208 } | 3208 } |
3209 } else { | 3209 } else { |
3210 key = ToRegister(instr->key()); | 3210 key = ToRegister(instr->key()); |
3211 } | 3211 } |
3212 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3212 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
3213 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 3213 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
3214 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 3214 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
3215 int additional_offset = instr->additional_index() << element_size_shift; | 3215 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) |
3216 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag | |
3217 : 0; | |
3218 | |
3216 | 3219 |
3217 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 3220 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
3218 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3221 elements_kind == FLOAT32_ELEMENTS || |
3222 elements_kind == EXTERNAL_DOUBLE_ELEMENTS || | |
3223 elements_kind == FLOAT64_ELEMENTS) { | |
3224 int base_offset = | |
3225 (instr->additional_index() << element_size_shift) + additional_offset; | |
3219 DwVfpRegister result = ToDoubleRegister(instr->result()); | 3226 DwVfpRegister result = ToDoubleRegister(instr->result()); |
3220 Operand operand = key_is_constant | 3227 Operand operand = key_is_constant |
3221 ? Operand(constant_key << element_size_shift) | 3228 ? Operand(constant_key << element_size_shift) |
3222 : Operand(key, LSL, shift_size); | 3229 : Operand(key, LSL, shift_size); |
3223 __ add(scratch0(), external_pointer, operand); | 3230 __ add(scratch0(), external_pointer, operand); |
3224 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3231 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
3225 __ vldr(double_scratch0().low(), scratch0(), additional_offset); | 3232 elements_kind == FLOAT32_ELEMENTS) { |
3233 __ vldr(double_scratch0().low(), scratch0(), base_offset); | |
3226 __ vcvt_f64_f32(result, double_scratch0().low()); | 3234 __ vcvt_f64_f32(result, double_scratch0().low()); |
3227 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 3235 } else { // loading doubles, not floats. |
3228 __ vldr(result, scratch0(), additional_offset); | 3236 __ vldr(result, scratch0(), base_offset); |
3229 } | 3237 } |
3230 } else { | 3238 } else { |
3231 Register result = ToRegister(instr->result()); | 3239 Register result = ToRegister(instr->result()); |
3232 MemOperand mem_operand = PrepareKeyedOperand( | 3240 MemOperand mem_operand = PrepareKeyedOperand( |
3233 key, external_pointer, key_is_constant, constant_key, | 3241 key, external_pointer, key_is_constant, constant_key, |
3234 element_size_shift, shift_size, | 3242 element_size_shift, shift_size, |
3235 instr->additional_index(), additional_offset); | 3243 instr->additional_index(), additional_offset); |
3236 switch (elements_kind) { | 3244 switch (elements_kind) { |
3237 case EXTERNAL_BYTE_ELEMENTS: | 3245 case EXTERNAL_BYTE_ELEMENTS: |
3246 case INT8_ELEMENTS: | |
3238 __ ldrsb(result, mem_operand); | 3247 __ ldrsb(result, mem_operand); |
3239 break; | 3248 break; |
3240 case EXTERNAL_PIXEL_ELEMENTS: | 3249 case EXTERNAL_PIXEL_ELEMENTS: |
3241 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3250 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3251 case UINT8_ELEMENTS: | |
3252 case UINT8_CLAMPED_ELEMENTS: | |
3242 __ ldrb(result, mem_operand); | 3253 __ ldrb(result, mem_operand); |
3243 break; | 3254 break; |
3244 case EXTERNAL_SHORT_ELEMENTS: | 3255 case EXTERNAL_SHORT_ELEMENTS: |
3256 case INT16_ELEMENTS: | |
3245 __ ldrsh(result, mem_operand); | 3257 __ ldrsh(result, mem_operand); |
3246 break; | 3258 break; |
3247 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3259 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3260 case UINT16_ELEMENTS: | |
3248 __ ldrh(result, mem_operand); | 3261 __ ldrh(result, mem_operand); |
3249 break; | 3262 break; |
3250 case EXTERNAL_INT_ELEMENTS: | 3263 case EXTERNAL_INT_ELEMENTS: |
3264 case INT32_ELEMENTS: | |
3251 __ ldr(result, mem_operand); | 3265 __ ldr(result, mem_operand); |
3252 break; | 3266 break; |
3253 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3267 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3268 case UINT32_ELEMENTS: | |
3254 __ ldr(result, mem_operand); | 3269 __ ldr(result, mem_operand); |
3255 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { | 3270 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { |
3256 __ cmp(result, Operand(0x80000000)); | 3271 __ cmp(result, Operand(0x80000000)); |
3257 DeoptimizeIf(cs, instr->environment()); | 3272 DeoptimizeIf(cs, instr->environment()); |
3258 } | 3273 } |
3259 break; | 3274 break; |
3275 case FLOAT32_ELEMENTS: | |
3276 case FLOAT64_ELEMENTS: | |
3260 case EXTERNAL_FLOAT_ELEMENTS: | 3277 case EXTERNAL_FLOAT_ELEMENTS: |
3261 case EXTERNAL_DOUBLE_ELEMENTS: | 3278 case EXTERNAL_DOUBLE_ELEMENTS: |
3262 case FAST_HOLEY_DOUBLE_ELEMENTS: | 3279 case FAST_HOLEY_DOUBLE_ELEMENTS: |
3263 case FAST_HOLEY_ELEMENTS: | 3280 case FAST_HOLEY_ELEMENTS: |
3264 case FAST_HOLEY_SMI_ELEMENTS: | 3281 case FAST_HOLEY_SMI_ELEMENTS: |
3265 case FAST_DOUBLE_ELEMENTS: | 3282 case FAST_DOUBLE_ELEMENTS: |
3266 case FAST_ELEMENTS: | 3283 case FAST_ELEMENTS: |
3267 case FAST_SMI_ELEMENTS: | 3284 case FAST_SMI_ELEMENTS: |
3268 case DICTIONARY_ELEMENTS: | 3285 case DICTIONARY_ELEMENTS: |
3269 case NON_STRICT_ARGUMENTS_ELEMENTS: | 3286 case NON_STRICT_ARGUMENTS_ELEMENTS: |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3347 } else { | 3364 } else { |
3348 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | 3365 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); |
3349 __ cmp(result, scratch); | 3366 __ cmp(result, scratch); |
3350 DeoptimizeIf(eq, instr->environment()); | 3367 DeoptimizeIf(eq, instr->environment()); |
3351 } | 3368 } |
3352 } | 3369 } |
3353 } | 3370 } |
3354 | 3371 |
3355 | 3372 |
3356 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { | 3373 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { |
3357 if (instr->is_external()) { | 3374 if (instr->is_external() || instr->is_fixed_typed_array()) { |
Toon Verwaest
2014/01/16 10:54:51
Perhaps we should add a helper method that wraps i
Dmitry Lomov (no reviews)
2014/01/16 13:52:18
Done.
| |
3358 DoLoadKeyedExternalArray(instr); | 3375 DoLoadKeyedExternalArray(instr); |
3359 } else if (instr->hydrogen()->representation().IsDouble()) { | 3376 } else if (instr->hydrogen()->representation().IsDouble()) { |
3360 DoLoadKeyedFixedDoubleArray(instr); | 3377 DoLoadKeyedFixedDoubleArray(instr); |
3361 } else { | 3378 } else { |
3362 DoLoadKeyedFixedArray(instr); | 3379 DoLoadKeyedFixedArray(instr); |
3363 } | 3380 } |
3364 } | 3381 } |
3365 | 3382 |
3366 | 3383 |
3367 MemOperand LCodeGen::PrepareKeyedOperand(Register key, | 3384 MemOperand LCodeGen::PrepareKeyedOperand(Register key, |
3368 Register base, | 3385 Register base, |
3369 bool key_is_constant, | 3386 bool key_is_constant, |
3370 int constant_key, | 3387 int constant_key, |
3371 int element_size, | 3388 int element_size, |
3372 int shift_size, | 3389 int shift_size, |
3373 int additional_index, | 3390 int additional_index, |
3374 int additional_offset) { | 3391 int additional_offset) { |
3375 if (additional_index != 0 && !key_is_constant) { | 3392 int base_offset = (additional_index << element_size) + additional_offset; |
3393 if (key_is_constant) { | |
3394 return MemOperand(base, | |
3395 base_offset + (constant_key << element_size)); | |
3396 } | |
3397 | |
3398 if (additional_offset != 0) { | |
3399 __ mov(scratch0(), Operand(base_offset)); | |
3400 if (shift_size >= 0) { | |
3401 __ add(scratch0(), scratch0(), Operand(key, LSL, shift_size)); | |
3402 } else { | |
3403 ASSERT_EQ(-1, shift_size); | |
3404 __ add(scratch0(), scratch0(), Operand(key, LSR, 1)); | |
3405 } | |
3406 return MemOperand(base, scratch0()); | |
3407 } | |
3408 | |
3409 if (additional_index != 0) { | |
3376 additional_index *= 1 << (element_size - shift_size); | 3410 additional_index *= 1 << (element_size - shift_size); |
3377 __ add(scratch0(), key, Operand(additional_index)); | 3411 __ add(scratch0(), key, Operand(additional_index)); |
3378 } | 3412 } |
3379 | 3413 |
3380 if (key_is_constant) { | |
3381 return MemOperand(base, | |
3382 (constant_key << element_size) + additional_offset); | |
3383 } | |
3384 | |
3385 if (additional_index == 0) { | 3414 if (additional_index == 0) { |
3386 if (shift_size >= 0) { | 3415 if (shift_size >= 0) { |
3387 return MemOperand(base, key, LSL, shift_size); | 3416 return MemOperand(base, key, LSL, shift_size); |
3388 } else { | 3417 } else { |
3389 ASSERT_EQ(-1, shift_size); | 3418 ASSERT_EQ(-1, shift_size); |
3390 return MemOperand(base, key, LSR, 1); | 3419 return MemOperand(base, key, LSR, 1); |
3391 } | 3420 } |
3392 } | 3421 } |
3393 | 3422 |
3394 if (shift_size >= 0) { | 3423 if (shift_size >= 0) { |
(...skipping 864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4259 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4288 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
4260 if (constant_key & 0xF0000000) { | 4289 if (constant_key & 0xF0000000) { |
4261 Abort(kArrayIndexConstantValueTooBig); | 4290 Abort(kArrayIndexConstantValueTooBig); |
4262 } | 4291 } |
4263 } else { | 4292 } else { |
4264 key = ToRegister(instr->key()); | 4293 key = ToRegister(instr->key()); |
4265 } | 4294 } |
4266 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4295 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
4267 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4296 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
4268 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4297 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
4269 int additional_offset = instr->additional_index() << element_size_shift; | 4298 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) |
4299 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag | |
4300 : 0; | |
4270 | 4301 |
4271 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 4302 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
4272 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4303 elements_kind == FLOAT32_ELEMENTS || |
4304 elements_kind == EXTERNAL_DOUBLE_ELEMENTS || | |
4305 elements_kind == FLOAT64_ELEMENTS) { | |
4306 int base_offset = | |
4307 (instr->additional_index() << element_size_shift) + additional_offset; | |
4273 Register address = scratch0(); | 4308 Register address = scratch0(); |
4274 DwVfpRegister value(ToDoubleRegister(instr->value())); | 4309 DwVfpRegister value(ToDoubleRegister(instr->value())); |
4275 if (key_is_constant) { | 4310 if (key_is_constant) { |
4276 if (constant_key != 0) { | 4311 if (constant_key != 0) { |
4277 __ add(address, external_pointer, | 4312 __ add(address, external_pointer, |
4278 Operand(constant_key << element_size_shift)); | 4313 Operand(constant_key << element_size_shift)); |
4279 } else { | 4314 } else { |
4280 address = external_pointer; | 4315 address = external_pointer; |
4281 } | 4316 } |
4282 } else { | 4317 } else { |
4283 __ add(address, external_pointer, Operand(key, LSL, shift_size)); | 4318 __ add(address, external_pointer, Operand(key, LSL, shift_size)); |
4284 } | 4319 } |
4285 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4320 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
4321 elements_kind == FLOAT32_ELEMENTS) { | |
4286 __ vcvt_f32_f64(double_scratch0().low(), value); | 4322 __ vcvt_f32_f64(double_scratch0().low(), value); |
4287 __ vstr(double_scratch0().low(), address, additional_offset); | 4323 __ vstr(double_scratch0().low(), address, base_offset); |
4288 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 4324 } else { // Storing doubles, not floats. |
4289 __ vstr(value, address, additional_offset); | 4325 __ vstr(value, address, base_offset); |
4290 } | 4326 } |
4291 } else { | 4327 } else { |
4292 Register value(ToRegister(instr->value())); | 4328 Register value(ToRegister(instr->value())); |
4293 MemOperand mem_operand = PrepareKeyedOperand( | 4329 MemOperand mem_operand = PrepareKeyedOperand( |
4294 key, external_pointer, key_is_constant, constant_key, | 4330 key, external_pointer, key_is_constant, constant_key, |
4295 element_size_shift, shift_size, | 4331 element_size_shift, shift_size, |
4296 instr->additional_index(), additional_offset); | 4332 instr->additional_index(), additional_offset); |
4297 switch (elements_kind) { | 4333 switch (elements_kind) { |
4298 case EXTERNAL_PIXEL_ELEMENTS: | 4334 case EXTERNAL_PIXEL_ELEMENTS: |
4299 case EXTERNAL_BYTE_ELEMENTS: | 4335 case EXTERNAL_BYTE_ELEMENTS: |
4300 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 4336 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
4337 case UINT8_ELEMENTS: | |
4338 case UINT8_CLAMPED_ELEMENTS: | |
4339 case INT8_ELEMENTS: | |
4301 __ strb(value, mem_operand); | 4340 __ strb(value, mem_operand); |
4302 break; | 4341 break; |
4303 case EXTERNAL_SHORT_ELEMENTS: | 4342 case EXTERNAL_SHORT_ELEMENTS: |
4304 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 4343 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
4344 case INT16_ELEMENTS: | |
4345 case UINT16_ELEMENTS: | |
4305 __ strh(value, mem_operand); | 4346 __ strh(value, mem_operand); |
4306 break; | 4347 break; |
4307 case EXTERNAL_INT_ELEMENTS: | 4348 case EXTERNAL_INT_ELEMENTS: |
4308 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 4349 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
4350 case INT32_ELEMENTS: | |
4351 case UINT32_ELEMENTS: | |
4309 __ str(value, mem_operand); | 4352 __ str(value, mem_operand); |
4310 break; | 4353 break; |
4354 case FLOAT32_ELEMENTS: | |
4355 case FLOAT64_ELEMENTS: | |
4311 case EXTERNAL_FLOAT_ELEMENTS: | 4356 case EXTERNAL_FLOAT_ELEMENTS: |
4312 case EXTERNAL_DOUBLE_ELEMENTS: | 4357 case EXTERNAL_DOUBLE_ELEMENTS: |
4313 case FAST_DOUBLE_ELEMENTS: | 4358 case FAST_DOUBLE_ELEMENTS: |
4314 case FAST_ELEMENTS: | 4359 case FAST_ELEMENTS: |
4315 case FAST_SMI_ELEMENTS: | 4360 case FAST_SMI_ELEMENTS: |
4316 case FAST_HOLEY_DOUBLE_ELEMENTS: | 4361 case FAST_HOLEY_DOUBLE_ELEMENTS: |
4317 case FAST_HOLEY_ELEMENTS: | 4362 case FAST_HOLEY_ELEMENTS: |
4318 case FAST_HOLEY_SMI_ELEMENTS: | 4363 case FAST_HOLEY_SMI_ELEMENTS: |
4319 case DICTIONARY_ELEMENTS: | 4364 case DICTIONARY_ELEMENTS: |
4320 case NON_STRICT_ARGUMENTS_ELEMENTS: | 4365 case NON_STRICT_ARGUMENTS_ELEMENTS: |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4410 GetLinkRegisterState(), | 4455 GetLinkRegisterState(), |
4411 kSaveFPRegs, | 4456 kSaveFPRegs, |
4412 EMIT_REMEMBERED_SET, | 4457 EMIT_REMEMBERED_SET, |
4413 check_needed); | 4458 check_needed); |
4414 } | 4459 } |
4415 } | 4460 } |
4416 | 4461 |
4417 | 4462 |
4418 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { | 4463 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { |
4419 // By cases: external, fast double | 4464 // By cases: external, fast double |
4420 if (instr->is_external()) { | 4465 if (instr->is_external() || instr->is_fixed_typed_array()) { |
4421 DoStoreKeyedExternalArray(instr); | 4466 DoStoreKeyedExternalArray(instr); |
4422 } else if (instr->hydrogen()->value()->representation().IsDouble()) { | 4467 } else if (instr->hydrogen()->value()->representation().IsDouble()) { |
4423 DoStoreKeyedFixedDoubleArray(instr); | 4468 DoStoreKeyedFixedDoubleArray(instr); |
4424 } else { | 4469 } else { |
4425 DoStoreKeyedFixedArray(instr); | 4470 DoStoreKeyedFixedArray(instr); |
4426 } | 4471 } |
4427 } | 4472 } |
4428 | 4473 |
4429 | 4474 |
4430 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 4475 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
(...skipping 1381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5812 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5857 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
5813 __ ldr(result, FieldMemOperand(scratch, | 5858 __ ldr(result, FieldMemOperand(scratch, |
5814 FixedArray::kHeaderSize - kPointerSize)); | 5859 FixedArray::kHeaderSize - kPointerSize)); |
5815 __ bind(&done); | 5860 __ bind(&done); |
5816 } | 5861 } |
5817 | 5862 |
5818 | 5863 |
5819 #undef __ | 5864 #undef __ |
5820 | 5865 |
5821 } } // namespace v8::internal | 5866 } } // namespace v8::internal |
OLD | NEW |