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