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 2363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2374 key, | 2374 key, |
2375 times_pointer_size, | 2375 times_pointer_size, |
2376 FixedArray::kHeaderSize)); | 2376 FixedArray::kHeaderSize)); |
2377 | 2377 |
2378 // Check for the hole value. | 2378 // Check for the hole value. |
2379 __ cmp(result, factory()->the_hole_value()); | 2379 __ cmp(result, factory()->the_hole_value()); |
2380 DeoptimizeIf(equal, instr->environment()); | 2380 DeoptimizeIf(equal, instr->environment()); |
2381 } | 2381 } |
2382 | 2382 |
2383 | 2383 |
| 2384 Operand LCodeGen::BuildExternalArrayOperand(LOperand* external_pointer, |
| 2385 LOperand* key, |
| 2386 ExternalArrayType array_type) { |
| 2387 Register external_pointer_reg = ToRegister(external_pointer); |
| 2388 ScaleFactor scale_factor = times_1; |
| 2389 int element_size = 1; |
| 2390 switch (array_type) { |
| 2391 case kExternalByteArray: |
| 2392 case kExternalUnsignedByteArray: |
| 2393 case kExternalPixelArray: |
| 2394 scale_factor = times_1; |
| 2395 element_size = 1; |
| 2396 break; |
| 2397 case kExternalShortArray: |
| 2398 case kExternalUnsignedShortArray: |
| 2399 scale_factor = times_2; |
| 2400 element_size = 2; |
| 2401 break; |
| 2402 case kExternalIntArray: |
| 2403 case kExternalUnsignedIntArray: |
| 2404 case kExternalFloatArray: |
| 2405 scale_factor = times_4; |
| 2406 element_size = 4; |
| 2407 break; |
| 2408 case kExternalDoubleArray: |
| 2409 scale_factor = times_8; |
| 2410 element_size = 8; |
| 2411 break; |
| 2412 } |
| 2413 if (key->IsConstantOperand()) { |
| 2414 int constant_value = ToInteger32(LConstantOperand::cast(key)); |
| 2415 if (constant_value & 0xF0000000) { |
| 2416 Abort("array index constant value too big"); |
| 2417 } |
| 2418 return Operand(external_pointer_reg, constant_value * element_size); |
| 2419 } else { |
| 2420 return Operand(external_pointer_reg, ToRegister(key), scale_factor, 0); |
| 2421 } |
| 2422 } |
| 2423 |
| 2424 |
2384 void LCodeGen::DoLoadKeyedSpecializedArrayElement( | 2425 void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
2385 LLoadKeyedSpecializedArrayElement* instr) { | 2426 LLoadKeyedSpecializedArrayElement* instr) { |
2386 Register external_pointer = ToRegister(instr->external_pointer()); | |
2387 Register key = ToRegister(instr->key()); | |
2388 ExternalArrayType array_type = instr->array_type(); | 2427 ExternalArrayType array_type = instr->array_type(); |
| 2428 Operand operand(BuildExternalArrayOperand(instr->external_pointer(), |
| 2429 instr->key(), array_type)); |
2389 if (array_type == kExternalFloatArray) { | 2430 if (array_type == kExternalFloatArray) { |
2390 XMMRegister result(ToDoubleRegister(instr->result())); | 2431 XMMRegister result(ToDoubleRegister(instr->result())); |
2391 __ movss(result, Operand(external_pointer, key, times_4, 0)); | 2432 __ movss(result, operand); |
2392 __ cvtss2sd(result, result); | 2433 __ cvtss2sd(result, result); |
2393 } else if (array_type == kExternalDoubleArray) { | 2434 } else if (array_type == kExternalDoubleArray) { |
2394 __ movdbl(ToDoubleRegister(instr->result()), | 2435 __ movdbl(ToDoubleRegister(instr->result()), operand); |
2395 Operand(external_pointer, key, times_8, 0)); | |
2396 } else { | 2436 } else { |
2397 Register result(ToRegister(instr->result())); | 2437 Register result(ToRegister(instr->result())); |
2398 switch (array_type) { | 2438 switch (array_type) { |
2399 case kExternalByteArray: | 2439 case kExternalByteArray: |
2400 __ movsx_b(result, Operand(external_pointer, key, times_1, 0)); | 2440 __ movsx_b(result, operand); |
2401 break; | 2441 break; |
2402 case kExternalUnsignedByteArray: | 2442 case kExternalUnsignedByteArray: |
2403 case kExternalPixelArray: | 2443 case kExternalPixelArray: |
2404 __ movzx_b(result, Operand(external_pointer, key, times_1, 0)); | 2444 __ movzx_b(result, operand); |
2405 break; | 2445 break; |
2406 case kExternalShortArray: | 2446 case kExternalShortArray: |
2407 __ movsx_w(result, Operand(external_pointer, key, times_2, 0)); | 2447 __ movsx_w(result, operand); |
2408 break; | 2448 break; |
2409 case kExternalUnsignedShortArray: | 2449 case kExternalUnsignedShortArray: |
2410 __ movzx_w(result, Operand(external_pointer, key, times_2, 0)); | 2450 __ movzx_w(result, operand); |
2411 break; | 2451 break; |
2412 case kExternalIntArray: | 2452 case kExternalIntArray: |
2413 __ mov(result, Operand(external_pointer, key, times_4, 0)); | 2453 __ mov(result, operand); |
2414 break; | 2454 break; |
2415 case kExternalUnsignedIntArray: | 2455 case kExternalUnsignedIntArray: |
2416 __ mov(result, Operand(external_pointer, key, times_4, 0)); | 2456 __ mov(result, operand); |
2417 __ test(result, Operand(result)); | 2457 __ test(result, Operand(result)); |
2418 // TODO(danno): we could be more clever here, perhaps having a special | 2458 // TODO(danno): we could be more clever here, perhaps having a special |
2419 // version of the stub that detects if the overflow case actually | 2459 // version of the stub that detects if the overflow case actually |
2420 // happens, and generate code that returns a double rather than int. | 2460 // happens, and generate code that returns a double rather than int. |
2421 DeoptimizeIf(negative, instr->environment()); | 2461 DeoptimizeIf(negative, instr->environment()); |
2422 break; | 2462 break; |
2423 case kExternalFloatArray: | 2463 case kExternalFloatArray: |
2424 case kExternalDoubleArray: | 2464 case kExternalDoubleArray: |
2425 UNREACHABLE(); | 2465 UNREACHABLE(); |
2426 break; | 2466 break; |
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3090 | 3130 |
3091 | 3131 |
3092 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { | 3132 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { |
3093 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); | 3133 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); |
3094 DeoptimizeIf(above_equal, instr->environment()); | 3134 DeoptimizeIf(above_equal, instr->environment()); |
3095 } | 3135 } |
3096 | 3136 |
3097 | 3137 |
3098 void LCodeGen::DoStoreKeyedSpecializedArrayElement( | 3138 void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
3099 LStoreKeyedSpecializedArrayElement* instr) { | 3139 LStoreKeyedSpecializedArrayElement* instr) { |
3100 Register external_pointer = ToRegister(instr->external_pointer()); | |
3101 Register key = ToRegister(instr->key()); | |
3102 ExternalArrayType array_type = instr->array_type(); | 3140 ExternalArrayType array_type = instr->array_type(); |
| 3141 Operand operand(BuildExternalArrayOperand(instr->external_pointer(), |
| 3142 instr->key(), array_type)); |
3103 if (array_type == kExternalFloatArray) { | 3143 if (array_type == kExternalFloatArray) { |
3104 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); | 3144 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); |
3105 __ movss(Operand(external_pointer, key, times_4, 0), xmm0); | 3145 __ movss(operand, xmm0); |
3106 } else if (array_type == kExternalDoubleArray) { | 3146 } else if (array_type == kExternalDoubleArray) { |
3107 __ movdbl(Operand(external_pointer, key, times_8, 0), | 3147 __ movdbl(operand, ToDoubleRegister(instr->value())); |
3108 ToDoubleRegister(instr->value())); | |
3109 } else { | 3148 } else { |
3110 Register value = ToRegister(instr->value()); | 3149 Register value = ToRegister(instr->value()); |
3111 switch (array_type) { | 3150 switch (array_type) { |
3112 case kExternalPixelArray: { | 3151 case kExternalPixelArray: { |
3113 // Clamp the value to [0..255]. | 3152 // Clamp the value to [0..255]. |
3114 Register temp = ToRegister(instr->TempAt(0)); | 3153 Register temp = ToRegister(instr->TempAt(0)); |
3115 // The dec_b below requires that the clamped value is in a byte | 3154 // The dec_b below requires that the clamped value is in a byte |
3116 // register. eax is an arbitrary choice to satisfy this requirement, we | 3155 // register. eax is an arbitrary choice to satisfy this requirement, we |
3117 // hinted the register allocator to give us eax when building the | 3156 // hinted the register allocator to give us eax when building the |
3118 // instruction. | 3157 // instruction. |
3119 ASSERT(temp.is(eax)); | 3158 ASSERT(temp.is(eax)); |
3120 __ mov(temp, ToRegister(instr->value())); | 3159 __ mov(temp, ToRegister(instr->value())); |
3121 NearLabel done; | 3160 NearLabel done; |
3122 __ test(temp, Immediate(0xFFFFFF00)); | 3161 __ test(temp, Immediate(0xFFFFFF00)); |
3123 __ j(zero, &done); | 3162 __ j(zero, &done); |
3124 __ setcc(negative, temp); // 1 if negative, 0 if positive. | 3163 __ setcc(negative, temp); // 1 if negative, 0 if positive. |
3125 __ dec_b(temp); // 0 if negative, 255 if positive. | 3164 __ dec_b(temp); // 0 if negative, 255 if positive. |
3126 __ bind(&done); | 3165 __ bind(&done); |
3127 __ mov_b(Operand(external_pointer, key, times_1, 0), temp); | 3166 __ mov_b(operand, temp); |
3128 break; | 3167 break; |
3129 } | 3168 } |
3130 case kExternalByteArray: | 3169 case kExternalByteArray: |
3131 case kExternalUnsignedByteArray: | 3170 case kExternalUnsignedByteArray: |
3132 __ mov_b(Operand(external_pointer, key, times_1, 0), value); | 3171 __ mov_b(operand, value); |
3133 break; | 3172 break; |
3134 case kExternalShortArray: | 3173 case kExternalShortArray: |
3135 case kExternalUnsignedShortArray: | 3174 case kExternalUnsignedShortArray: |
3136 __ mov_w(Operand(external_pointer, key, times_2, 0), value); | 3175 __ mov_w(operand, value); |
3137 break; | 3176 break; |
3138 case kExternalIntArray: | 3177 case kExternalIntArray: |
3139 case kExternalUnsignedIntArray: | 3178 case kExternalUnsignedIntArray: |
3140 __ mov(Operand(external_pointer, key, times_4, 0), value); | 3179 __ mov(operand, value); |
3141 break; | 3180 break; |
3142 case kExternalFloatArray: | 3181 case kExternalFloatArray: |
3143 case kExternalDoubleArray: | 3182 case kExternalDoubleArray: |
3144 UNREACHABLE(); | 3183 UNREACHABLE(); |
3145 break; | 3184 break; |
3146 } | 3185 } |
3147 } | 3186 } |
3148 } | 3187 } |
3149 | 3188 |
3150 | 3189 |
(...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4297 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 4336 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
4298 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, &safepoint_generator); | 4337 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, &safepoint_generator); |
4299 } | 4338 } |
4300 | 4339 |
4301 | 4340 |
4302 #undef __ | 4341 #undef __ |
4303 | 4342 |
4304 } } // namespace v8::internal | 4343 } } // namespace v8::internal |
4305 | 4344 |
4306 #endif // V8_TARGET_ARCH_IA32 | 4345 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |