OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2475 // Check for the hole value. | 2475 // Check for the hole value. |
2476 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | 2476 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); |
2477 __ cmp(result, scratch); | 2477 __ cmp(result, scratch); |
2478 DeoptimizeIf(eq, instr->environment()); | 2478 DeoptimizeIf(eq, instr->environment()); |
2479 } | 2479 } |
2480 | 2480 |
2481 | 2481 |
2482 void LCodeGen::DoLoadKeyedSpecializedArrayElement( | 2482 void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
2483 LLoadKeyedSpecializedArrayElement* instr) { | 2483 LLoadKeyedSpecializedArrayElement* instr) { |
2484 Register external_pointer = ToRegister(instr->external_pointer()); | 2484 Register external_pointer = ToRegister(instr->external_pointer()); |
2485 Register key = ToRegister(instr->key()); | 2485 Register key = no_reg; |
2486 ExternalArrayType array_type = instr->array_type(); | 2486 ExternalArrayType array_type = instr->array_type(); |
2487 if (array_type == kExternalFloatArray) { | 2487 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 2488 int constant_key = 0; |
| 2489 if (key_is_constant) { |
| 2490 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 2491 if (constant_key & 0xF0000000) { |
| 2492 Abort("array index constant value too big."); |
| 2493 } |
| 2494 } else { |
| 2495 key = ToRegister(instr->key()); |
| 2496 } |
| 2497 int shift_size = ExternalArrayTypeToShiftSize(array_type); |
| 2498 |
| 2499 if (array_type == kExternalFloatArray || array_type == kExternalDoubleArray) { |
2488 CpuFeatures::Scope scope(VFP3); | 2500 CpuFeatures::Scope scope(VFP3); |
2489 DwVfpRegister result(ToDoubleRegister(instr->result())); | 2501 DwVfpRegister result(ToDoubleRegister(instr->result())); |
2490 __ add(scratch0(), external_pointer, Operand(key, LSL, 2)); | 2502 Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size)) |
2491 __ vldr(result.low(), scratch0(), 0); | 2503 : Operand(key, LSL, shift_size)); |
2492 __ vcvt_f64_f32(result, result.low()); | 2504 __ add(scratch0(), external_pointer, operand); |
2493 } else if (array_type == kExternalDoubleArray) { | 2505 if (array_type == kExternalFloatArray) { |
2494 CpuFeatures::Scope scope(VFP3); | 2506 __ vldr(result.low(), scratch0(), 0); |
2495 DwVfpRegister result(ToDoubleRegister(instr->result())); | 2507 __ vcvt_f64_f32(result, result.low()); |
2496 __ add(scratch0(), external_pointer, Operand(key, LSL, 3)); | 2508 } else { // i.e. array_type == kExternalDoubleArray |
2497 __ vldr(result, scratch0(), 0); | 2509 __ vldr(result, scratch0(), 0); |
| 2510 } |
2498 } else { | 2511 } else { |
2499 Register result(ToRegister(instr->result())); | 2512 Register result(ToRegister(instr->result())); |
| 2513 MemOperand mem_operand(key_is_constant |
| 2514 ? MemOperand(external_pointer, constant_key * (1 << shift_size)) |
| 2515 : MemOperand(external_pointer, key, LSL, shift_size)); |
2500 switch (array_type) { | 2516 switch (array_type) { |
2501 case kExternalByteArray: | 2517 case kExternalByteArray: |
2502 __ ldrsb(result, MemOperand(external_pointer, key)); | 2518 __ ldrsb(result, mem_operand); |
2503 break; | 2519 break; |
2504 case kExternalUnsignedByteArray: | 2520 case kExternalUnsignedByteArray: |
2505 case kExternalPixelArray: | 2521 case kExternalPixelArray: |
2506 __ ldrb(result, MemOperand(external_pointer, key)); | 2522 __ ldrb(result, mem_operand); |
2507 break; | 2523 break; |
2508 case kExternalShortArray: | 2524 case kExternalShortArray: |
2509 __ ldrsh(result, MemOperand(external_pointer, key, LSL, 1)); | 2525 __ ldrsh(result, mem_operand); |
2510 break; | 2526 break; |
2511 case kExternalUnsignedShortArray: | 2527 case kExternalUnsignedShortArray: |
2512 __ ldrh(result, MemOperand(external_pointer, key, LSL, 1)); | 2528 __ ldrh(result, mem_operand); |
2513 break; | 2529 break; |
2514 case kExternalIntArray: | 2530 case kExternalIntArray: |
2515 __ ldr(result, MemOperand(external_pointer, key, LSL, 2)); | 2531 __ ldr(result, mem_operand); |
2516 break; | 2532 break; |
2517 case kExternalUnsignedIntArray: | 2533 case kExternalUnsignedIntArray: |
2518 __ ldr(result, MemOperand(external_pointer, key, LSL, 2)); | 2534 __ ldr(result, mem_operand); |
2519 __ cmp(result, Operand(0x80000000)); | 2535 __ cmp(result, Operand(0x80000000)); |
2520 // TODO(danno): we could be more clever here, perhaps having a special | 2536 // TODO(danno): we could be more clever here, perhaps having a special |
2521 // version of the stub that detects if the overflow case actually | 2537 // version of the stub that detects if the overflow case actually |
2522 // happens, and generate code that returns a double rather than int. | 2538 // happens, and generate code that returns a double rather than int. |
2523 DeoptimizeIf(cs, instr->environment()); | 2539 DeoptimizeIf(cs, instr->environment()); |
2524 break; | 2540 break; |
2525 case kExternalFloatArray: | 2541 case kExternalFloatArray: |
2526 case kExternalDoubleArray: | 2542 case kExternalDoubleArray: |
2527 UNREACHABLE(); | 2543 UNREACHABLE(); |
2528 break; | 2544 break; |
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3238 __ add(key, scratch, Operand(FixedArray::kHeaderSize)); | 3254 __ add(key, scratch, Operand(FixedArray::kHeaderSize)); |
3239 __ RecordWrite(elements, key, value); | 3255 __ RecordWrite(elements, key, value); |
3240 } | 3256 } |
3241 } | 3257 } |
3242 | 3258 |
3243 | 3259 |
3244 void LCodeGen::DoStoreKeyedSpecializedArrayElement( | 3260 void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
3245 LStoreKeyedSpecializedArrayElement* instr) { | 3261 LStoreKeyedSpecializedArrayElement* instr) { |
3246 | 3262 |
3247 Register external_pointer = ToRegister(instr->external_pointer()); | 3263 Register external_pointer = ToRegister(instr->external_pointer()); |
3248 Register key = ToRegister(instr->key()); | 3264 Register key = no_reg; |
3249 ExternalArrayType array_type = instr->array_type(); | 3265 ExternalArrayType array_type = instr->array_type(); |
| 3266 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 3267 int constant_key = 0; |
| 3268 if (key_is_constant) { |
| 3269 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 3270 if (constant_key & 0xF0000000) { |
| 3271 Abort("array index constant value too big."); |
| 3272 } |
| 3273 } else { |
| 3274 key = ToRegister(instr->key()); |
| 3275 } |
| 3276 int shift_size = ExternalArrayTypeToShiftSize(array_type); |
3250 | 3277 |
3251 if (array_type == kExternalFloatArray) { | 3278 if (array_type == kExternalFloatArray || array_type == kExternalDoubleArray) { |
3252 CpuFeatures::Scope scope(VFP3); | 3279 CpuFeatures::Scope scope(VFP3); |
3253 DwVfpRegister value(ToDoubleRegister(instr->value())); | 3280 DwVfpRegister value(ToDoubleRegister(instr->value())); |
3254 __ add(scratch0(), external_pointer, Operand(key, LSL, 2)); | 3281 Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size)) |
3255 __ vcvt_f32_f64(double_scratch0().low(), value); | 3282 : Operand(key, LSL, shift_size)); |
3256 __ vstr(double_scratch0().low(), scratch0(), 0); | 3283 __ add(scratch0(), external_pointer, operand); |
3257 } else if (array_type == kExternalDoubleArray) { | 3284 if (array_type == kExternalFloatArray) { |
3258 CpuFeatures::Scope scope(VFP3); | 3285 __ vcvt_f32_f64(double_scratch0().low(), value); |
3259 DwVfpRegister value(ToDoubleRegister(instr->value())); | 3286 __ vstr(double_scratch0().low(), scratch0(), 0); |
3260 __ add(scratch0(), external_pointer, Operand(key, LSL, 3)); | 3287 } else { // i.e. array_type == kExternalDoubleArray |
3261 __ vstr(value, scratch0(), 0); | 3288 __ vstr(value, scratch0(), 0); |
| 3289 } |
3262 } else { | 3290 } else { |
3263 Register value(ToRegister(instr->value())); | 3291 Register value(ToRegister(instr->value())); |
| 3292 MemOperand mem_operand(key_is_constant |
| 3293 ? MemOperand(external_pointer, constant_key * (1 << shift_size)) |
| 3294 : MemOperand(external_pointer, key, LSL, shift_size)); |
3264 switch (array_type) { | 3295 switch (array_type) { |
3265 case kExternalPixelArray: | 3296 case kExternalPixelArray: |
3266 // Clamp the value to [0..255]. | 3297 // Clamp the value to [0..255]. |
3267 __ Usat(value, 8, Operand(value)); | 3298 __ Usat(value, 8, Operand(value)); |
3268 __ strb(value, MemOperand(external_pointer, key)); | 3299 // Fall through to the next case for the store instruction: |
3269 break; | |
3270 case kExternalByteArray: | 3300 case kExternalByteArray: |
3271 case kExternalUnsignedByteArray: | 3301 case kExternalUnsignedByteArray: |
3272 __ strb(value, MemOperand(external_pointer, key)); | 3302 __ strb(value, mem_operand); |
3273 break; | 3303 break; |
3274 case kExternalShortArray: | 3304 case kExternalShortArray: |
3275 case kExternalUnsignedShortArray: | 3305 case kExternalUnsignedShortArray: |
3276 __ strh(value, MemOperand(external_pointer, key, LSL, 1)); | 3306 __ strh(value, mem_operand); |
3277 break; | 3307 break; |
3278 case kExternalIntArray: | 3308 case kExternalIntArray: |
3279 case kExternalUnsignedIntArray: | 3309 case kExternalUnsignedIntArray: |
3280 __ str(value, MemOperand(external_pointer, key, LSL, 2)); | 3310 __ str(value, mem_operand); |
3281 break; | 3311 break; |
3282 case kExternalFloatArray: | 3312 case kExternalFloatArray: |
3283 case kExternalDoubleArray: | 3313 case kExternalDoubleArray: |
3284 UNREACHABLE(); | 3314 UNREACHABLE(); |
3285 break; | 3315 break; |
3286 } | 3316 } |
3287 } | 3317 } |
3288 } | 3318 } |
3289 | 3319 |
3290 | 3320 |
(...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4309 ASSERT(osr_pc_offset_ == -1); | 4339 ASSERT(osr_pc_offset_ == -1); |
4310 osr_pc_offset_ = masm()->pc_offset(); | 4340 osr_pc_offset_ = masm()->pc_offset(); |
4311 } | 4341 } |
4312 | 4342 |
4313 | 4343 |
4314 | 4344 |
4315 | 4345 |
4316 #undef __ | 4346 #undef __ |
4317 | 4347 |
4318 } } // namespace v8::internal | 4348 } } // namespace v8::internal |
OLD | NEW |