| 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 |