Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 6546036: Combine typed and pixel arrays. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix wrong external element call Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 2691 matching lines...) Expand 10 before | Expand all | Expand 10 after
2702 // Handle store cache miss. 2702 // Handle store cache miss.
2703 __ bind(&miss); 2703 __ bind(&miss);
2704 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); 2704 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss));
2705 __ jmp(ic, RelocInfo::CODE_TARGET); 2705 __ jmp(ic, RelocInfo::CODE_TARGET);
2706 2706
2707 // Return the generated code. 2707 // Return the generated code.
2708 return GetCode(NORMAL, NULL); 2708 return GetCode(NORMAL, NULL);
2709 } 2709 }
2710 2710
2711 2711
2712 MaybeObject* KeyedStoreStubCompiler::CompileStorePixelArray(
2713 JSObject* receiver) {
2714 // ----------- S t a t e -------------
2715 // -- eax : value
2716 // -- ecx : key
2717 // -- edx : receiver
2718 // -- esp[0] : return address
2719 // -----------------------------------
2720 Label miss;
2721
2722 // Check that the map matches.
2723 __ CheckMap(edx, Handle<Map>(receiver->map()), &miss, false);
2724
2725 // Do the load.
2726 GenerateFastPixelArrayStore(masm(),
2727 edx,
2728 ecx,
2729 eax,
2730 edi,
2731 ebx,
2732 true,
2733 &miss,
2734 &miss,
2735 NULL,
2736 &miss);
2737
2738 // Handle store cache miss.
2739 __ bind(&miss);
2740 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss));
2741 __ jmp(ic, RelocInfo::CODE_TARGET);
2742
2743 // Return the generated code.
2744 return GetCode(NORMAL, NULL);
2745 }
2746
2747
2748 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 2712 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
2749 JSObject* object, 2713 JSObject* object,
2750 JSObject* last) { 2714 JSObject* last) {
2751 // ----------- S t a t e ------------- 2715 // ----------- S t a t e -------------
2752 // -- eax : receiver 2716 // -- eax : receiver
2753 // -- ecx : name 2717 // -- ecx : name
2754 // -- esp[0] : return address 2718 // -- esp[0] : return address
2755 // ----------------------------------- 2719 // -----------------------------------
2756 Label miss; 2720 Label miss;
2757 2721
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
3184 __ ret(0); 3148 __ ret(0);
3185 3149
3186 __ bind(&miss); 3150 __ bind(&miss);
3187 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3151 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3188 3152
3189 // Return the generated code. 3153 // Return the generated code.
3190 return GetCode(NORMAL, NULL); 3154 return GetCode(NORMAL, NULL);
3191 } 3155 }
3192 3156
3193 3157
3194 MaybeObject* KeyedLoadStubCompiler::CompileLoadPixelArray(JSObject* receiver) {
3195 // ----------- S t a t e -------------
3196 // -- eax : key
3197 // -- edx : receiver
3198 // -- esp[0] : return address
3199 // -----------------------------------
3200 Label miss;
3201
3202 // Check that the map matches.
3203 __ CheckMap(edx, Handle<Map>(receiver->map()), &miss, false);
3204
3205 GenerateFastPixelArrayLoad(masm(),
3206 edx,
3207 eax,
3208 ecx,
3209 ebx,
3210 eax,
3211 &miss,
3212 &miss,
3213 &miss);
3214
3215 // Handle load cache miss.
3216 __ bind(&miss);
3217 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Miss));
3218 __ jmp(ic, RelocInfo::CODE_TARGET);
3219
3220 // Return the generated code.
3221 return GetCode(NORMAL, NULL);
3222 }
3223
3224
3225 // Specialized stub for constructing objects from functions which only have only 3158 // Specialized stub for constructing objects from functions which only have only
3226 // simple assignments of the form this.x = ...; in their body. 3159 // simple assignments of the form this.x = ...; in their body.
3227 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { 3160 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
3228 // ----------- S t a t e ------------- 3161 // ----------- S t a t e -------------
3229 // -- eax : argc 3162 // -- eax : argc
3230 // -- edi : constructor 3163 // -- edi : constructor
3231 // -- esp[0] : return address 3164 // -- esp[0] : return address
3232 // -- esp[4] : last argument 3165 // -- esp[4] : last argument
3233 // ----------------------------------- 3166 // -----------------------------------
3234 Label generic_stub_call; 3167 Label generic_stub_call;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
3354 Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric); 3287 Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric);
3355 Handle<Code> generic_construct_stub(code); 3288 Handle<Code> generic_construct_stub(code);
3356 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 3289 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
3357 3290
3358 // Return the generated code. 3291 // Return the generated code.
3359 return GetCode(); 3292 return GetCode();
3360 } 3293 }
3361 3294
3362 3295
3363 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( 3296 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
3364 ExternalArrayType array_type, Code::Flags flags) { 3297 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) {
3365 // ----------- S t a t e ------------- 3298 // ----------- S t a t e -------------
3366 // -- eax : key 3299 // -- eax : key
3367 // -- edx : receiver 3300 // -- edx : receiver
3368 // -- esp[0] : return address 3301 // -- esp[0] : return address
3369 // ----------------------------------- 3302 // -----------------------------------
3370 Label slow, failed_allocation; 3303 Label slow, failed_allocation;
3371 3304
3372 // Check that the object isn't a smi. 3305 // Check that the object isn't a smi.
3373 __ test(edx, Immediate(kSmiTagMask)); 3306 __ test(edx, Immediate(kSmiTagMask));
3374 __ j(zero, &slow, not_taken); 3307 __ j(zero, &slow, not_taken);
3375 3308
3376 // Check that the key is a smi. 3309 // Check that the key is a smi.
3377 __ test(eax, Immediate(kSmiTagMask)); 3310 __ test(eax, Immediate(kSmiTagMask));
3378 __ j(not_zero, &slow, not_taken); 3311 __ j(not_zero, &slow, not_taken);
3379 3312
3380 // Get the map of the receiver. 3313 // Check that the map matches.
3381 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 3314 __ CheckMap(edx, Handle<Map>(receiver->map()), &slow, false);
3382 // Check that the receiver does not require access checks. We need
3383 // to check this explicitly since this generic stub does not perform
3384 // map checks.
3385 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
3386 1 << Map::kIsAccessCheckNeeded);
3387 __ j(not_zero, &slow, not_taken);
3388
3389 __ CmpInstanceType(ecx, JS_OBJECT_TYPE);
3390 __ j(not_equal, &slow, not_taken);
3391
3392 // Check that the elements array is the appropriate type of
3393 // ExternalArray.
3394 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); 3315 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
3395 Handle<Map> map(Heap::MapForExternalArrayType(array_type));
3396 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
3397 Immediate(map));
3398 __ j(not_equal, &slow, not_taken);
3399 3316
3400 // eax: key, known to be a smi. 3317 // eax: key, known to be a smi.
3401 // edx: receiver, known to be a JSObject. 3318 // edx: receiver, known to be a JSObject.
3402 // ebx: elements object, known to be an external array. 3319 // ebx: elements object, known to be an external array.
3403 // Check that the index is in range. 3320 // Check that the index is in range.
3404 __ mov(ecx, eax); 3321 __ mov(ecx, eax);
3405 __ SmiUntag(ecx); // Untag the index. 3322 __ SmiUntag(ecx); // Untag the index.
3406 __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset)); 3323 __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset));
3407 // Unsigned comparison catches both negative and too-large values. 3324 // Unsigned comparison catches both negative and too-large values.
3408 __ j(above_equal, &slow); 3325 __ j(above_equal, &slow);
3409
3410 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); 3326 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
3411 // ebx: base pointer of external storage 3327 // ebx: base pointer of external storage
3412 switch (array_type) { 3328 switch (array_type) {
3413 case kExternalByteArray: 3329 case kExternalByteArray:
3414 __ movsx_b(ecx, Operand(ebx, ecx, times_1, 0)); 3330 __ movsx_b(eax, Operand(ebx, ecx, times_1, 0));
3415 break; 3331 break;
3416 case kExternalUnsignedByteArray: 3332 case kExternalUnsignedByteArray:
3417 __ movzx_b(ecx, Operand(ebx, ecx, times_1, 0)); 3333 case kExternalPixelArray:
3334 __ movzx_b(eax, Operand(ebx, ecx, times_1, 0));
3418 break; 3335 break;
3419 case kExternalShortArray: 3336 case kExternalShortArray:
3420 __ movsx_w(ecx, Operand(ebx, ecx, times_2, 0)); 3337 __ movsx_w(eax, Operand(ebx, ecx, times_2, 0));
3421 break; 3338 break;
3422 case kExternalUnsignedShortArray: 3339 case kExternalUnsignedShortArray:
3423 __ movzx_w(ecx, Operand(ebx, ecx, times_2, 0)); 3340 __ movzx_w(eax, Operand(ebx, ecx, times_2, 0));
3424 break; 3341 break;
3425 case kExternalIntArray: 3342 case kExternalIntArray:
3426 case kExternalUnsignedIntArray: 3343 case kExternalUnsignedIntArray:
3427 __ mov(ecx, Operand(ebx, ecx, times_4, 0)); 3344 __ mov(ecx, Operand(ebx, ecx, times_4, 0));
3428 break; 3345 break;
3429 case kExternalFloatArray: 3346 case kExternalFloatArray:
3430 __ fld_s(Operand(ebx, ecx, times_4, 0)); 3347 __ fld_s(Operand(ebx, ecx, times_4, 0));
3431 break; 3348 break;
3432 default: 3349 default:
3433 UNREACHABLE(); 3350 UNREACHABLE();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3488 __ ret(0); 3405 __ ret(0);
3489 } else if (array_type == kExternalFloatArray) { 3406 } else if (array_type == kExternalFloatArray) {
3490 // For the floating-point array type, we need to always allocate a 3407 // For the floating-point array type, we need to always allocate a
3491 // HeapNumber. 3408 // HeapNumber.
3492 __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); 3409 __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation);
3493 // Set the value. 3410 // Set the value.
3494 __ mov(eax, ecx); 3411 __ mov(eax, ecx);
3495 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3412 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
3496 __ ret(0); 3413 __ ret(0);
3497 } else { 3414 } else {
3498 __ mov(eax, ecx);
3499 __ SmiTag(eax); 3415 __ SmiTag(eax);
3500 __ ret(0); 3416 __ ret(0);
3501 } 3417 }
3502 3418
3503 // If we fail allocation of the HeapNumber, we still have a value on 3419 // If we fail allocation of the HeapNumber, we still have a value on
3504 // top of the FPU stack. Remove it. 3420 // top of the FPU stack. Remove it.
3505 __ bind(&failed_allocation); 3421 __ bind(&failed_allocation);
3506 __ ffree(); 3422 __ ffree();
3507 __ fincstp(); 3423 __ fincstp();
3508 // Fall through to slow case. 3424 // Fall through to slow case.
(...skipping 14 matching lines...) Expand all
3523 3439
3524 // Perform tail call to the entry. 3440 // Perform tail call to the entry.
3525 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 3441 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
3526 3442
3527 // Return the generated code. 3443 // Return the generated code.
3528 return GetCode(flags); 3444 return GetCode(flags);
3529 } 3445 }
3530 3446
3531 3447
3532 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( 3448 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
3533 ExternalArrayType array_type, Code::Flags flags) { 3449 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) {
3534 // ----------- S t a t e ------------- 3450 // ----------- S t a t e -------------
3535 // -- eax : value 3451 // -- eax : value
3536 // -- ecx : key 3452 // -- ecx : key
3537 // -- edx : receiver 3453 // -- edx : receiver
3538 // -- esp[0] : return address 3454 // -- esp[0] : return address
3539 // ----------------------------------- 3455 // -----------------------------------
3540 Label slow, check_heap_number; 3456 Label slow, check_heap_number;
3541 3457
3542 // Check that the object isn't a smi. 3458 // Check that the object isn't a smi.
3543 __ test(edx, Immediate(kSmiTagMask)); 3459 __ test(edx, Immediate(kSmiTagMask));
3544 __ j(zero, &slow); 3460 __ j(zero, &slow);
3545 // Get the map from the receiver. 3461
3546 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); 3462 // Check that the map matches.
3547 // Check that the receiver does not require access checks. We need 3463 __ CheckMap(edx, Handle<Map>(receiver->map()), &slow, false);
3548 // to do this because this generic stub does not perform map checks. 3464
3549 __ test_b(FieldOperand(edi, Map::kBitFieldOffset),
3550 1 << Map::kIsAccessCheckNeeded);
3551 __ j(not_zero, &slow);
3552 // Check that the key is a smi. 3465 // Check that the key is a smi.
3553 __ test(ecx, Immediate(kSmiTagMask)); 3466 __ test(ecx, Immediate(kSmiTagMask));
3554 __ j(not_zero, &slow); 3467 __ j(not_zero, &slow);
3555 // Get the instance type from the map of the receiver.
3556 __ CmpInstanceType(edi, JS_OBJECT_TYPE);
3557 __ j(not_equal, &slow);
3558
3559 // Check that the elements array is the appropriate type of
3560 // ExternalArray.
3561 // eax: value
3562 // edx: receiver, a JSObject
3563 // ecx: key, a smi
3564 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3565 __ CheckMap(edi, Handle<Map>(Heap::MapForExternalArrayType(array_type)),
3566 &slow, true);
3567 3468
3568 // Check that the index is in range. 3469 // Check that the index is in range.
3470 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3569 __ mov(ebx, ecx); 3471 __ mov(ebx, ecx);
3570 __ SmiUntag(ebx); 3472 __ SmiUntag(ebx);
3571 __ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset)); 3473 __ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset));
3572 // Unsigned comparison catches both negative and too-large values. 3474 // Unsigned comparison catches both negative and too-large values.
3573 __ j(above_equal, &slow); 3475 __ j(above_equal, &slow);
3574 3476
3575 // Handle both smis and HeapNumbers in the fast path. Go to the 3477 // Handle both smis and HeapNumbers in the fast path. Go to the
3576 // runtime for all other kinds of values. 3478 // runtime for all other kinds of values.
3577 // eax: value 3479 // eax: value
3578 // edx: receiver 3480 // edx: receiver
3579 // ecx: key 3481 // ecx: key
3580 // edi: elements array 3482 // edi: elements array
3581 // ebx: untagged index 3483 // ebx: untagged index
3582 __ test(eax, Immediate(kSmiTagMask)); 3484 __ test(eax, Immediate(kSmiTagMask));
3583 __ j(not_equal, &check_heap_number); 3485 if (array_type == kExternalPixelArray)
3486 __ j(not_equal, &slow);
3487 else
3488 __ j(not_equal, &check_heap_number);
3489
3584 // smi case 3490 // smi case
3585 __ mov(ecx, eax); // Preserve the value in eax. Key is no longer needed. 3491 __ mov(ecx, eax); // Preserve the value in eax. Key is no longer needed.
3586 __ SmiUntag(ecx); 3492 __ SmiUntag(ecx);
3587 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); 3493 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3588 // ecx: base pointer of external storage 3494 // ecx: base pointer of external storage
3589 switch (array_type) { 3495 switch (array_type) {
3496 case kExternalPixelArray:
3497 { // Clamp the value to [0..255].
3498 NearLabel done;
3499 __ test(ecx, Immediate(0xFFFFFF00));
3500 __ j(zero, &done);
3501 __ setcc(negative, ecx); // 1 if negative, 0 if positive.
3502 __ dec_b(ecx); // 0 if negative, 255 if positive.
3503 __ bind(&done);
3504 }
3505 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3506 break;
3590 case kExternalByteArray: 3507 case kExternalByteArray:
3591 case kExternalUnsignedByteArray: 3508 case kExternalUnsignedByteArray:
3592 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3509 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3593 break; 3510 break;
3594 case kExternalShortArray: 3511 case kExternalShortArray:
3595 case kExternalUnsignedShortArray: 3512 case kExternalUnsignedShortArray:
3596 __ mov_w(Operand(edi, ebx, times_2, 0), ecx); 3513 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
3597 break; 3514 break;
3598 case kExternalIntArray: 3515 case kExternalIntArray:
3599 case kExternalUnsignedIntArray: 3516 case kExternalUnsignedIntArray:
3600 __ mov(Operand(edi, ebx, times_4, 0), ecx); 3517 __ mov(Operand(edi, ebx, times_4, 0), ecx);
3601 break; 3518 break;
3602 case kExternalFloatArray: 3519 case kExternalFloatArray:
3603 // Need to perform int-to-float conversion. 3520 // Need to perform int-to-float conversion.
3604 __ push(ecx); 3521 __ push(ecx);
3605 __ fild_s(Operand(esp, 0)); 3522 __ fild_s(Operand(esp, 0));
3606 __ pop(ecx); 3523 __ pop(ecx);
3607 __ fstp_s(Operand(edi, ebx, times_4, 0)); 3524 __ fstp_s(Operand(edi, ebx, times_4, 0));
3608 break; 3525 break;
3609 default: 3526 default:
3610 UNREACHABLE(); 3527 UNREACHABLE();
3611 break; 3528 break;
3612 } 3529 }
3613 __ ret(0); // Return the original value. 3530 __ ret(0); // Return the original value.
3614 3531
3615 __ bind(&check_heap_number); 3532 // TODO(danno): handle heap number -> pixel array conversion
3616 // eax: value 3533 if (array_type != kExternalPixelArray) {
3617 // edx: receiver 3534 __ bind(&check_heap_number);
3618 // ecx: key 3535 // eax: value
3619 // edi: elements array 3536 // edx: receiver
3620 // ebx: untagged index 3537 // ecx: key
3621 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3538 // edi: elements array
3622 Immediate(Factory::heap_number_map())); 3539 // ebx: untagged index
3623 __ j(not_equal, &slow); 3540 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3541 Immediate(Factory::heap_number_map()));
3542 __ j(not_equal, &slow);
3624 3543
3625 // The WebGL specification leaves the behavior of storing NaN and 3544 // The WebGL specification leaves the behavior of storing NaN and
3626 // +/-Infinity into integer arrays basically undefined. For more 3545 // +/-Infinity into integer arrays basically undefined. For more
3627 // reproducible behavior, convert these to zero. 3546 // reproducible behavior, convert these to zero.
3628 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); 3547 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3629 // ebx: untagged index 3548 // ebx: untagged index
3630 // edi: base pointer of external storage 3549 // edi: base pointer of external storage
3631 if (array_type == kExternalFloatArray) { 3550 if (array_type == kExternalFloatArray) {
3632 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3551 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3633 __ fstp_s(Operand(edi, ebx, times_4, 0)); 3552 __ fstp_s(Operand(edi, ebx, times_4, 0));
3634 __ ret(0); 3553 __ ret(0);
3635 } else { 3554 } else {
3636 // Perform float-to-int conversion with truncation (round-to-zero) 3555 // Perform float-to-int conversion with truncation (round-to-zero)
3637 // behavior. 3556 // behavior.
3638 3557
3639 // For the moment we make the slow call to the runtime on 3558 // For the moment we make the slow call to the runtime on
3640 // processors that don't support SSE2. The code in IntegerConvert 3559 // processors that don't support SSE2. The code in IntegerConvert
3641 // (code-stubs-ia32.cc) is roughly what is needed here though the 3560 // (code-stubs-ia32.cc) is roughly what is needed here though the
3642 // conversion failure case does not need to be handled. 3561 // conversion failure case does not need to be handled.
3643 if (CpuFeatures::IsSupported(SSE2)) { 3562 if (CpuFeatures::IsSupported(SSE2)) {
3644 if (array_type != kExternalIntArray && 3563 if (array_type != kExternalIntArray &&
3645 array_type != kExternalUnsignedIntArray) { 3564 array_type != kExternalUnsignedIntArray) {
3646 ASSERT(CpuFeatures::IsSupported(SSE2));
3647 CpuFeatures::Scope scope(SSE2);
3648 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
3649 // ecx: untagged integer value
3650 switch (array_type) {
3651 case kExternalByteArray:
3652 case kExternalUnsignedByteArray:
3653 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3654 break;
3655 case kExternalShortArray:
3656 case kExternalUnsignedShortArray:
3657 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
3658 break;
3659 default:
3660 UNREACHABLE();
3661 break;
3662 }
3663 } else {
3664 if (CpuFeatures::IsSupported(SSE3)) {
3665 CpuFeatures::Scope scope(SSE3);
3666 // fisttp stores values as signed integers. To represent the
3667 // entire range of int and unsigned int arrays, store as a
3668 // 64-bit int and discard the high 32 bits.
3669 // If the value is NaN or +/-infinity, the result is 0x80000000,
3670 // which is automatically zero when taken mod 2^n, n < 32.
3671 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3672 __ sub(Operand(esp), Immediate(2 * kPointerSize));
3673 __ fisttp_d(Operand(esp, 0));
3674 __ pop(ecx);
3675 __ add(Operand(esp), Immediate(kPointerSize));
3676 } else {
3677 ASSERT(CpuFeatures::IsSupported(SSE2)); 3565 ASSERT(CpuFeatures::IsSupported(SSE2));
3678 CpuFeatures::Scope scope(SSE2); 3566 CpuFeatures::Scope scope(SSE2);
3679 // We can easily implement the correct rounding behavior for the 3567 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
3680 // range [0, 2^31-1]. For the time being, to keep this code simple, 3568 // ecx: untagged integer value
3681 // make the slow runtime call for values outside this range. 3569 switch (array_type) {
3682 // Note: we could do better for signed int arrays. 3570 case kExternalPixelArray:
3683 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); 3571 { // Clamp the value to [0..255].
3684 // We will need the key if we have to make the slow runtime call. 3572 NearLabel done;
3685 __ push(ecx); 3573 __ test(ecx, Immediate(0xFFFFFF00));
3686 __ LoadPowerOf2(xmm1, ecx, 31); 3574 __ j(zero, &done);
3687 __ pop(ecx); 3575 __ setcc(negative, ecx); // 1 if negative, 0 if positive.
3688 __ ucomisd(xmm1, xmm0); 3576 __ dec_b(ecx); // 0 if negative, 255 if positive.
3689 __ j(above_equal, &slow); 3577 __ bind(&done);
3690 __ cvttsd2si(ecx, Operand(xmm0)); 3578 }
3579 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3580 case kExternalByteArray:
3581 case kExternalUnsignedByteArray:
3582 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3583 break;
3584 case kExternalShortArray:
3585 case kExternalUnsignedShortArray:
3586 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
3587 break;
3588 default:
3589 UNREACHABLE();
3590 break;
3591 }
3592 } else {
3593 if (CpuFeatures::IsSupported(SSE3)) {
3594 CpuFeatures::Scope scope(SSE3);
3595 // fisttp stores values as signed integers. To represent the
3596 // entire range of int and unsigned int arrays, store as a
3597 // 64-bit int and discard the high 32 bits.
3598 // If the value is NaN or +/-infinity, the result is 0x80000000,
3599 // which is automatically zero when taken mod 2^n, n < 32.
3600 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3601 __ sub(Operand(esp), Immediate(2 * kPointerSize));
3602 __ fisttp_d(Operand(esp, 0));
3603 __ pop(ecx);
3604 __ add(Operand(esp), Immediate(kPointerSize));
3605 } else {
3606 ASSERT(CpuFeatures::IsSupported(SSE2));
3607 CpuFeatures::Scope scope(SSE2);
3608 // We can easily implement the correct rounding behavior for the
3609 // range [0, 2^31-1]. For the time being, to keep this code simple,
3610 // make the slow runtime call for values outside this range.
3611 // Note: we could do better for signed int arrays.
3612 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
3613 // We will need the key if we have to make the slow runtime call.
3614 __ push(ecx);
3615 __ LoadPowerOf2(xmm1, ecx, 31);
3616 __ pop(ecx);
3617 __ ucomisd(xmm1, xmm0);
3618 __ j(above_equal, &slow);
3619 __ cvttsd2si(ecx, Operand(xmm0));
3620 }
3621 // ecx: untagged integer value
3622 __ mov(Operand(edi, ebx, times_4, 0), ecx);
3691 } 3623 }
3692 // ecx: untagged integer value 3624 __ ret(0); // Return original value.
3693 __ mov(Operand(edi, ebx, times_4, 0), ecx);
3694 } 3625 }
3695 __ ret(0); // Return original value.
3696 } 3626 }
3697 } 3627 }
3698 3628
3699 // Slow case: call runtime. 3629 // Slow case: call runtime.
3700 __ bind(&slow); 3630 __ bind(&slow);
3701 // ----------- S t a t e ------------- 3631 // ----------- S t a t e -------------
3702 // -- eax : value 3632 // -- eax : value
3703 // -- ecx : key 3633 // -- ecx : key
3704 // -- edx : receiver 3634 // -- edx : receiver
3705 // -- esp[0] : return address 3635 // -- esp[0] : return address
(...skipping 10 matching lines...) Expand all
3716 3646
3717 return GetCode(flags); 3647 return GetCode(flags);
3718 } 3648 }
3719 3649
3720 3650
3721 #undef __ 3651 #undef __
3722 3652
3723 } } // namespace v8::internal 3653 } } // namespace v8::internal
3724 3654
3725 #endif // V8_TARGET_ARCH_IA32 3655 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698