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

Side by Side Diff: src/arm/stub-cache-arm.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 3101 matching lines...) Expand 10 before | Expand all | Expand 10 after
3112 __ Ret(); 3112 __ Ret();
3113 3113
3114 __ bind(&miss); 3114 __ bind(&miss);
3115 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3115 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3116 3116
3117 // Return the generated code. 3117 // Return the generated code.
3118 return GetCode(NORMAL, NULL); 3118 return GetCode(NORMAL, NULL);
3119 } 3119 }
3120 3120
3121 3121
3122 MaybeObject* KeyedLoadStubCompiler::CompileLoadPixelArray(JSObject* receiver) {
3123 // ----------- S t a t e -------------
3124 // -- lr : return address
3125 // -- r0 : key
3126 // -- r1 : receiver
3127 // -----------------------------------
3128 Label miss;
3129
3130 // Check that the map matches.
3131 __ CheckMap(r1, r2, Handle<Map>(receiver->map()), &miss, false);
3132
3133 GenerateFastPixelArrayLoad(masm(),
3134 r1,
3135 r0,
3136 r2,
3137 r3,
3138 r4,
3139 r5,
3140 r0,
3141 &miss,
3142 &miss,
3143 &miss);
3144
3145 __ bind(&miss);
3146 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Miss));
3147 __ Jump(ic, RelocInfo::CODE_TARGET);
3148
3149 // Return the generated code.
3150 return GetCode(NORMAL, NULL);
3151 }
3152
3153
3154 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, 3122 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
3155 int index, 3123 int index,
3156 Map* transition, 3124 Map* transition,
3157 String* name) { 3125 String* name) {
3158 // ----------- S t a t e ------------- 3126 // ----------- S t a t e -------------
3159 // -- r0 : value 3127 // -- r0 : value
3160 // -- r1 : name 3128 // -- r1 : name
3161 // -- r2 : receiver 3129 // -- r2 : receiver
3162 // -- lr : return address 3130 // -- lr : return address
3163 // ----------------------------------- 3131 // -----------------------------------
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
3252 3220
3253 __ bind(&miss); 3221 __ bind(&miss);
3254 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); 3222 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss));
3255 __ Jump(ic, RelocInfo::CODE_TARGET); 3223 __ Jump(ic, RelocInfo::CODE_TARGET);
3256 3224
3257 // Return the generated code. 3225 // Return the generated code.
3258 return GetCode(NORMAL, NULL); 3226 return GetCode(NORMAL, NULL);
3259 } 3227 }
3260 3228
3261 3229
3262 MaybeObject* KeyedStoreStubCompiler::CompileStorePixelArray(
3263 JSObject* receiver) {
3264 // ----------- S t a t e -------------
3265 // -- r0 : value
3266 // -- r1 : key
3267 // -- r2 : receiver
3268 // -- r3 : scratch
3269 // -- r4 : scratch
3270 // -- r5 : scratch
3271 // -- r6 : scratch
3272 // -- lr : return address
3273 // -----------------------------------
3274 Label miss;
3275
3276 // Check that the map matches.
3277 __ CheckMap(r2, r6, Handle<Map>(receiver->map()), &miss, false);
3278
3279 GenerateFastPixelArrayStore(masm(),
3280 r2,
3281 r1,
3282 r0,
3283 r3,
3284 r4,
3285 r5,
3286 r6,
3287 true,
3288 true,
3289 &miss,
3290 &miss,
3291 NULL,
3292 &miss);
3293
3294 __ bind(&miss);
3295 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss));
3296 __ Jump(ic, RelocInfo::CODE_TARGET);
3297
3298 // Return the generated code.
3299 return GetCode(NORMAL, NULL);
3300 }
3301
3302
3303 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { 3230 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
3304 // ----------- S t a t e ------------- 3231 // ----------- S t a t e -------------
3305 // -- r0 : argc 3232 // -- r0 : argc
3306 // -- r1 : constructor 3233 // -- r1 : constructor
3307 // -- lr : return address 3234 // -- lr : return address
3308 // -- [sp] : last argument 3235 // -- [sp] : last argument
3309 // ----------------------------------- 3236 // -----------------------------------
3310 Label generic_stub_call; 3237 Label generic_stub_call;
3311 3238
3312 // Use r7 for holding undefined which is used in several places below. 3239 // Use r7 for holding undefined which is used in several places below.
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
3457 return false; 3384 return false;
3458 3385
3459 default: 3386 default:
3460 UNREACHABLE(); 3387 UNREACHABLE();
3461 return false; 3388 return false;
3462 } 3389 }
3463 } 3390 }
3464 3391
3465 3392
3466 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( 3393 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
3467 ExternalArrayType array_type, Code::Flags flags) { 3394 JSObject* receiver_object,
3395 ExternalArrayType array_type,
3396 Code::Flags flags) {
3468 // ---------- S t a t e -------------- 3397 // ---------- S t a t e --------------
3469 // -- lr : return address 3398 // -- lr : return address
3470 // -- r0 : key 3399 // -- r0 : key
3471 // -- r1 : receiver 3400 // -- r1 : receiver
3472 // ----------------------------------- 3401 // -----------------------------------
3473 Label slow, failed_allocation; 3402 Label slow, failed_allocation;
3474 3403
3475 Register key = r0; 3404 Register key = r0;
3476 Register receiver = r1; 3405 Register receiver = r1;
3477 3406
3478 // Check that the object isn't a smi 3407 // Check that the object isn't a smi
3479 __ JumpIfSmi(receiver, &slow); 3408 __ JumpIfSmi(receiver, &slow);
3480 3409
3481 // Check that the key is a smi. 3410 // Check that the key is a smi.
3482 __ JumpIfNotSmi(key, &slow); 3411 __ JumpIfNotSmi(key, &slow);
3483 3412
3484 // Check that the object is a JS object. Load map into r2. 3413 // Make sure that we've got the right map.
3485 __ CompareObjectType(receiver, r2, r3, FIRST_JS_OBJECT_TYPE); 3414 __ ldr(r2, FieldMemOperand(receiver, HeapObject::kMapOffset));
3486 __ b(lt, &slow); 3415 __ cmp(r2, Operand(Handle<Map>(receiver_object->map())));
3487
3488 // Check that the receiver does not require access checks. We need
3489 // to check this explicitly since this generic stub does not perform
3490 // map checks.
3491 __ ldrb(r3, FieldMemOperand(r2, Map::kBitFieldOffset));
3492 __ tst(r3, Operand(1 << Map::kIsAccessCheckNeeded));
3493 __ b(ne, &slow); 3416 __ b(ne, &slow);
3494 3417
3495 // Check that the elements array is the appropriate type of
3496 // ExternalArray.
3497 __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset)); 3418 __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
3498 __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); 3419 // r3: elements array
3499 __ LoadRoot(ip, Heap::RootIndexForExternalArrayType(array_type));
3500 __ cmp(r2, ip);
3501 __ b(ne, &slow);
3502 3420
3503 // Check that the index is in range. 3421 // Check that the index is in range.
3504 __ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset)); 3422 __ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset));
3505 __ cmp(ip, Operand(key, ASR, kSmiTagSize)); 3423 __ cmp(ip, Operand(key, ASR, kSmiTagSize));
3506 // Unsigned comparison catches both negative and too-large values. 3424 // Unsigned comparison catches both negative and too-large values.
3507 __ b(lo, &slow); 3425 __ b(lo, &slow);
3508 3426
3509 // r3: elements array
3510 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset)); 3427 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
3511 // r3: base pointer of external storage 3428 // r3: base pointer of external storage
3512 3429
3513 // We are not untagging smi key and instead work with it 3430 // We are not untagging smi key and instead work with it
3514 // as if it was premultiplied by 2. 3431 // as if it was premultiplied by 2.
3515 ASSERT((kSmiTag == 0) && (kSmiTagSize == 1)); 3432 ASSERT((kSmiTag == 0) && (kSmiTagSize == 1));
3516 3433
3517 Register value = r2; 3434 Register value = r2;
3518 switch (array_type) { 3435 switch (array_type) {
3519 case kExternalByteArray: 3436 case kExternalByteArray:
3520 __ ldrsb(value, MemOperand(r3, key, LSR, 1)); 3437 __ ldrsb(value, MemOperand(r3, key, LSR, 1));
3521 break; 3438 break;
3439 case kExternalPixelArray:
3522 case kExternalUnsignedByteArray: 3440 case kExternalUnsignedByteArray:
3523 __ ldrb(value, MemOperand(r3, key, LSR, 1)); 3441 __ ldrb(value, MemOperand(r3, key, LSR, 1));
3524 break; 3442 break;
3525 case kExternalShortArray: 3443 case kExternalShortArray:
3526 __ ldrsh(value, MemOperand(r3, key, LSL, 0)); 3444 __ ldrsh(value, MemOperand(r3, key, LSL, 0));
3527 break; 3445 break;
3528 case kExternalUnsignedShortArray: 3446 case kExternalUnsignedShortArray:
3529 __ ldrh(value, MemOperand(r3, key, LSL, 0)); 3447 __ ldrh(value, MemOperand(r3, key, LSL, 0));
3530 break; 3448 break;
3531 case kExternalIntArray: 3449 case kExternalIntArray:
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
3737 3655
3738 __ Push(r1, r0); 3656 __ Push(r1, r0);
3739 3657
3740 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 3658 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
3741 3659
3742 return GetCode(flags); 3660 return GetCode(flags);
3743 } 3661 }
3744 3662
3745 3663
3746 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( 3664 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
3747 ExternalArrayType array_type, Code::Flags flags) { 3665 JSObject* receiver_object,
3666 ExternalArrayType array_type,
3667 Code::Flags flags) {
3748 // ---------- S t a t e -------------- 3668 // ---------- S t a t e --------------
3749 // -- r0 : value 3669 // -- r0 : value
3750 // -- r1 : key 3670 // -- r1 : key
3751 // -- r2 : receiver 3671 // -- r2 : receiver
3752 // -- lr : return address 3672 // -- lr : return address
3753 // ----------------------------------- 3673 // -----------------------------------
3754 Label slow, check_heap_number; 3674 Label slow, check_heap_number;
3755 3675
3756 // Register usage. 3676 // Register usage.
3757 Register value = r0; 3677 Register value = r0;
3758 Register key = r1; 3678 Register key = r1;
3759 Register receiver = r2; 3679 Register receiver = r2;
3760 // r3 mostly holds the elements array or the destination external array. 3680 // r3 mostly holds the elements array or the destination external array.
3761 3681
3762 // Check that the object isn't a smi. 3682 // Check that the object isn't a smi.
3763 __ JumpIfSmi(receiver, &slow); 3683 __ JumpIfSmi(receiver, &slow);
3764 3684
3765 // Check that the object is a JS object. Load map into r3. 3685 // Make sure that we've got the right map.
3766 __ CompareObjectType(receiver, r3, r4, FIRST_JS_OBJECT_TYPE); 3686 __ ldr(r3, FieldMemOperand(receiver, HeapObject::kMapOffset));
3767 __ b(le, &slow); 3687 __ cmp(r3, Operand(Handle<Map>(receiver_object->map())));
3688 __ b(ne, &slow);
3768 3689
3769 // Check that the receiver does not require access checks. We need 3690 __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
3770 // to do this because this generic stub does not perform map checks.
3771 __ ldrb(ip, FieldMemOperand(r3, Map::kBitFieldOffset));
3772 __ tst(ip, Operand(1 << Map::kIsAccessCheckNeeded));
3773 __ b(ne, &slow);
3774 3691
3775 // Check that the key is a smi. 3692 // Check that the key is a smi.
3776 __ JumpIfNotSmi(key, &slow); 3693 __ JumpIfNotSmi(key, &slow);
3777 3694
3778 // Check that the elements array is the appropriate type of ExternalArray. 3695 // Check that the index is in range
3779 __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset)); 3696 __ SmiUntag(r4, key);
3780 __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset));
3781 __ LoadRoot(ip, Heap::RootIndexForExternalArrayType(array_type));
3782 __ cmp(r4, ip);
3783 __ b(ne, &slow);
3784
3785 // Check that the index is in range.
3786 __ mov(r4, Operand(key, ASR, kSmiTagSize)); // Untag the index.
3787 __ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset)); 3697 __ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset));
3788 __ cmp(r4, ip); 3698 __ cmp(r4, ip);
3789 // Unsigned comparison catches both negative and too-large values. 3699 // Unsigned comparison catches both negative and too-large values.
3790 __ b(hs, &slow); 3700 __ b(hs, &slow);
3791 3701
3792 // Handle both smis and HeapNumbers in the fast path. Go to the 3702 // Handle both smis and HeapNumbers in the fast path. Go to the
3793 // runtime for all other kinds of values. 3703 // runtime for all other kinds of values.
3794 // r3: external array. 3704 // r3: external array.
3795 // r4: key (integer). 3705 // r4: key (integer).
3796 __ JumpIfNotSmi(value, &check_heap_number); 3706 if (array_type == kExternalPixelArray) {
3797 __ mov(r5, Operand(value, ASR, kSmiTagSize)); // Untag the value. 3707 // Float to pixel conversion is only implemented in the runtime for now.
Mads Ager (chromium) 2011/02/21 13:32:27 Float -> Double?
3708 __ JumpIfNotSmi(value, &slow);
3709 } else {
3710 __ JumpIfNotSmi(value, &check_heap_number);
3711 }
3712 __ SmiUntag(r5, value);
3798 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset)); 3713 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
3799 3714
3800 // r3: base pointer of external storage. 3715 // r3: base pointer of external storage.
3801 // r4: key (integer). 3716 // r4: key (integer).
3802 // r5: value (integer). 3717 // r5: value (integer).
3803 switch (array_type) { 3718 switch (array_type) {
3719 case kExternalPixelArray:
3720 // Clamp the value to [0..255].
3721 __ Usat(r5, 8, Operand(r5));
3722 __ strb(r5, MemOperand(r3, r4, LSL, 0));
3723 break;
3804 case kExternalByteArray: 3724 case kExternalByteArray:
3805 case kExternalUnsignedByteArray: 3725 case kExternalUnsignedByteArray:
3806 __ strb(r5, MemOperand(r3, r4, LSL, 0)); 3726 __ strb(r5, MemOperand(r3, r4, LSL, 0));
3807 break; 3727 break;
3808 case kExternalShortArray: 3728 case kExternalShortArray:
3809 case kExternalUnsignedShortArray: 3729 case kExternalUnsignedShortArray:
3810 __ strh(r5, MemOperand(r3, r4, LSL, 1)); 3730 __ strh(r5, MemOperand(r3, r4, LSL, 1));
3811 break; 3731 break;
3812 case kExternalIntArray: 3732 case kExternalIntArray:
3813 case kExternalUnsignedIntArray: 3733 case kExternalUnsignedIntArray:
3814 __ str(r5, MemOperand(r3, r4, LSL, 2)); 3734 __ str(r5, MemOperand(r3, r4, LSL, 2));
3815 break; 3735 break;
3816 case kExternalFloatArray: 3736 case kExternalFloatArray:
3817 // Perform int-to-float conversion and store to memory. 3737 // Perform int-to-float conversion and store to memory.
3818 StoreIntAsFloat(masm(), r3, r4, r5, r6, r7, r9); 3738 StoreIntAsFloat(masm(), r3, r4, r5, r6, r7, r9);
3819 break; 3739 break;
3820 default: 3740 default:
3821 UNREACHABLE(); 3741 UNREACHABLE();
3822 break; 3742 break;
3823 } 3743 }
3824 3744
3825 // Entry registers are intact, r0 holds the value which is the return value. 3745 // Entry registers are intact, r0 holds the value which is the return value.
3826 __ Ret(); 3746 __ Ret();
3827 3747
3828 3748 if (array_type != kExternalPixelArray) {
3829 // r3: external array. 3749 // r3: external array.
3830 // r4: index (integer). 3750 // r4: index (integer).
3831 __ bind(&check_heap_number); 3751 __ bind(&check_heap_number);
3832 __ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE); 3752 __ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE);
3833 __ b(ne, &slow); 3753 __ b(ne, &slow);
3834 3754
3835 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset)); 3755 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
3836 3756
3837 // r3: base pointer of external storage. 3757 // r3: base pointer of external storage.
3838 // r4: key (integer). 3758 // r4: key (integer).
3839 3759
3840 // The WebGL specification leaves the behavior of storing NaN and 3760 // The WebGL specification leaves the behavior of storing NaN and
3841 // +/-Infinity into integer arrays basically undefined. For more 3761 // +/-Infinity into integer arrays basically undefined. For more
3842 // reproducible behavior, convert these to zero. 3762 // reproducible behavior, convert these to zero.
3843 if (CpuFeatures::IsSupported(VFP3)) { 3763 if (CpuFeatures::IsSupported(VFP3)) {
3844 CpuFeatures::Scope scope(VFP3); 3764 CpuFeatures::Scope scope(VFP3);
3845 3765
3846 3766
3847 if (array_type == kExternalFloatArray) { 3767 if (array_type == kExternalFloatArray) {
3848 // vldr requires offset to be a multiple of 4 so we can not 3768 // vldr requires offset to be a multiple of 4 so we can not
3849 // include -kHeapObjectTag into it. 3769 // include -kHeapObjectTag into it.
3850 __ sub(r5, r0, Operand(kHeapObjectTag)); 3770 __ sub(r5, r0, Operand(kHeapObjectTag));
3851 __ vldr(d0, r5, HeapNumber::kValueOffset); 3771 __ vldr(d0, r5, HeapNumber::kValueOffset);
3852 __ add(r5, r3, Operand(r4, LSL, 2)); 3772 __ add(r5, r3, Operand(r4, LSL, 2));
3853 __ vcvt_f32_f64(s0, d0); 3773 __ vcvt_f32_f64(s0, d0);
3854 __ vstr(s0, r5, 0); 3774 __ vstr(s0, r5, 0);
3855 } else {
3856 // Need to perform float-to-int conversion.
3857 // Test for NaN or infinity (both give zero).
3858 __ ldr(r6, FieldMemOperand(value, HeapNumber::kExponentOffset));
3859
3860 // Hoisted load. vldr requires offset to be a multiple of 4 so we can not
3861 // include -kHeapObjectTag into it.
3862 __ sub(r5, value, Operand(kHeapObjectTag));
3863 __ vldr(d0, r5, HeapNumber::kValueOffset);
3864
3865 __ Sbfx(r6, r6, HeapNumber::kExponentShift, HeapNumber::kExponentBits);
3866 // NaNs and Infinities have all-one exponents so they sign extend to -1.
3867 __ cmp(r6, Operand(-1));
3868 __ mov(r5, Operand(0), LeaveCC, eq);
3869
3870 // Not infinity or NaN simply convert to int.
3871 if (IsElementTypeSigned(array_type)) {
3872 __ vcvt_s32_f64(s0, d0, kDefaultRoundToZero, ne);
3873 } else { 3775 } else {
3874 __ vcvt_u32_f64(s0, d0, kDefaultRoundToZero, ne); 3776 // Need to perform float-to-int conversion.
3777 // Test for NaN or infinity (both give zero).
3778 __ ldr(r6, FieldMemOperand(value, HeapNumber::kExponentOffset));
3779
3780 // Hoisted load. vldr requires offset to be a multiple of 4 so we can
3781 // not include -kHeapObjectTag into it.
3782 __ sub(r5, value, Operand(kHeapObjectTag));
3783 __ vldr(d0, r5, HeapNumber::kValueOffset);
3784
3785 __ Sbfx(r6, r6, HeapNumber::kExponentShift, HeapNumber::kExponentBits);
3786 // NaNs and Infinities have all-one exponents so they sign extend to -1.
3787 __ cmp(r6, Operand(-1));
3788 __ mov(r5, Operand(0), LeaveCC, eq);
3789
3790 // Not infinity or NaN simply convert to int.
3791 if (IsElementTypeSigned(array_type)) {
3792 __ vcvt_s32_f64(s0, d0, kDefaultRoundToZero, ne);
3793 } else {
3794 __ vcvt_u32_f64(s0, d0, kDefaultRoundToZero, ne);
3795 }
3796 __ vmov(r5, s0, ne);
3797
3798 switch (array_type) {
3799 case kExternalByteArray:
3800 case kExternalUnsignedByteArray:
3801 __ strb(r5, MemOperand(r3, r4, LSL, 0));
3802 break;
3803 case kExternalShortArray:
3804 case kExternalUnsignedShortArray:
3805 __ strh(r5, MemOperand(r3, r4, LSL, 1));
3806 break;
3807 case kExternalIntArray:
3808 case kExternalUnsignedIntArray:
3809 __ str(r5, MemOperand(r3, r4, LSL, 2));
3810 break;
3811 default:
3812 UNREACHABLE();
3813 break;
3814 }
3875 } 3815 }
3876 __ vmov(r5, s0, ne); 3816
3877
3878 switch (array_type) {
3879 case kExternalByteArray:
3880 case kExternalUnsignedByteArray:
3881 __ strb(r5, MemOperand(r3, r4, LSL, 0));
3882 break;
3883 case kExternalShortArray:
3884 case kExternalUnsignedShortArray:
3885 __ strh(r5, MemOperand(r3, r4, LSL, 1));
3886 break;
3887 case kExternalIntArray:
3888 case kExternalUnsignedIntArray:
3889 __ str(r5, MemOperand(r3, r4, LSL, 2));
3890 break;
3891 default:
3892 UNREACHABLE();
3893 break;
3894 }
3895 }
3896
3897 // Entry registers are intact, r0 holds the value which is the return value.
3898 __ Ret();
3899 } else {
3900 // VFP3 is not available do manual conversions.
3901 __ ldr(r5, FieldMemOperand(value, HeapNumber::kExponentOffset));
3902 __ ldr(r6, FieldMemOperand(value, HeapNumber::kMantissaOffset));
3903
3904 if (array_type == kExternalFloatArray) {
3905 Label done, nan_or_infinity_or_zero;
3906 static const int kMantissaInHiWordShift =
3907 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
3908
3909 static const int kMantissaInLoWordShift =
3910 kBitsPerInt - kMantissaInHiWordShift;
3911
3912 // Test for all special exponent values: zeros, subnormal numbers, NaNs
3913 // and infinities. All these should be converted to 0.
3914 __ mov(r7, Operand(HeapNumber::kExponentMask));
3915 __ and_(r9, r5, Operand(r7), SetCC);
3916 __ b(eq, &nan_or_infinity_or_zero);
3917
3918 __ teq(r9, Operand(r7));
3919 __ mov(r9, Operand(kBinary32ExponentMask), LeaveCC, eq);
3920 __ b(eq, &nan_or_infinity_or_zero);
3921
3922 // Rebias exponent.
3923 __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift));
3924 __ add(r9,
3925 r9,
3926 Operand(kBinary32ExponentBias - HeapNumber::kExponentBias));
3927
3928 __ cmp(r9, Operand(kBinary32MaxExponent));
3929 __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, gt);
3930 __ orr(r5, r5, Operand(kBinary32ExponentMask), LeaveCC, gt);
3931 __ b(gt, &done);
3932
3933 __ cmp(r9, Operand(kBinary32MinExponent));
3934 __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, lt);
3935 __ b(lt, &done);
3936
3937 __ and_(r7, r5, Operand(HeapNumber::kSignMask));
3938 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3939 __ orr(r7, r7, Operand(r5, LSL, kMantissaInHiWordShift));
3940 __ orr(r7, r7, Operand(r6, LSR, kMantissaInLoWordShift));
3941 __ orr(r5, r7, Operand(r9, LSL, kBinary32ExponentShift));
3942
3943 __ bind(&done);
3944 __ str(r5, MemOperand(r3, r4, LSL, 2));
3945 // Entry registers are intact, r0 holds the value which is the return 3817 // Entry registers are intact, r0 holds the value which is the return
3946 // value. 3818 // value.
3947 __ Ret(); 3819 __ Ret();
3948
3949 __ bind(&nan_or_infinity_or_zero);
3950 __ and_(r7, r5, Operand(HeapNumber::kSignMask));
3951 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3952 __ orr(r9, r9, r7);
3953 __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift));
3954 __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift));
3955 __ b(&done);
3956 } else { 3820 } else {
3957 bool is_signed_type = IsElementTypeSigned(array_type); 3821 // VFP3 is not available do manual conversions.
3958 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt; 3822 __ ldr(r5, FieldMemOperand(value, HeapNumber::kExponentOffset));
3959 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000; 3823 __ ldr(r6, FieldMemOperand(value, HeapNumber::kMantissaOffset));
3960 3824
3961 Label done, sign; 3825 if (array_type == kExternalFloatArray) {
3962 3826 Label done, nan_or_infinity_or_zero;
3963 // Test for all special exponent values: zeros, subnormal numbers, NaNs 3827 static const int kMantissaInHiWordShift =
3964 // and infinities. All these should be converted to 0. 3828 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
3965 __ mov(r7, Operand(HeapNumber::kExponentMask)); 3829
3966 __ and_(r9, r5, Operand(r7), SetCC); 3830 static const int kMantissaInLoWordShift =
3967 __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, eq); 3831 kBitsPerInt - kMantissaInHiWordShift;
3968 __ b(eq, &done); 3832
3969 3833 // Test for all special exponent values: zeros, subnormal numbers, NaNs
3970 __ teq(r9, Operand(r7)); 3834 // and infinities. All these should be converted to 0.
3971 __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, eq); 3835 __ mov(r7, Operand(HeapNumber::kExponentMask));
3972 __ b(eq, &done); 3836 __ and_(r9, r5, Operand(r7), SetCC);
3973 3837 __ b(eq, &nan_or_infinity_or_zero);
3974 // Unbias exponent. 3838
3975 __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift)); 3839 __ teq(r9, Operand(r7));
3976 __ sub(r9, r9, Operand(HeapNumber::kExponentBias), SetCC); 3840 __ mov(r9, Operand(kBinary32ExponentMask), LeaveCC, eq);
3977 // If exponent is negative then result is 0. 3841 __ b(eq, &nan_or_infinity_or_zero);
3978 __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, mi); 3842
3979 __ b(mi, &done); 3843 // Rebias exponent.
3980 3844 __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift));
3981 // If exponent is too big then result is minimal value. 3845 __ add(r9,
3982 __ cmp(r9, Operand(meaningfull_bits - 1)); 3846 r9,
3983 __ mov(r5, Operand(min_value), LeaveCC, ge); 3847 Operand(kBinary32ExponentBias - HeapNumber::kExponentBias));
3984 __ b(ge, &done); 3848
3985 3849 __ cmp(r9, Operand(kBinary32MaxExponent));
3986 __ and_(r7, r5, Operand(HeapNumber::kSignMask), SetCC); 3850 __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, gt);
3987 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask)); 3851 __ orr(r5, r5, Operand(kBinary32ExponentMask), LeaveCC, gt);
3988 __ orr(r5, r5, Operand(1u << HeapNumber::kMantissaBitsInTopWord)); 3852 __ b(gt, &done);
3989 3853
3990 __ rsb(r9, r9, Operand(HeapNumber::kMantissaBitsInTopWord), SetCC); 3854 __ cmp(r9, Operand(kBinary32MinExponent));
3991 __ mov(r5, Operand(r5, LSR, r9), LeaveCC, pl); 3855 __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, lt);
3992 __ b(pl, &sign); 3856 __ b(lt, &done);
3993 3857
3994 __ rsb(r9, r9, Operand(0, RelocInfo::NONE)); 3858 __ and_(r7, r5, Operand(HeapNumber::kSignMask));
3995 __ mov(r5, Operand(r5, LSL, r9)); 3859 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3996 __ rsb(r9, r9, Operand(meaningfull_bits)); 3860 __ orr(r7, r7, Operand(r5, LSL, kMantissaInHiWordShift));
3997 __ orr(r5, r5, Operand(r6, LSR, r9)); 3861 __ orr(r7, r7, Operand(r6, LSR, kMantissaInLoWordShift));
3998 3862 __ orr(r5, r7, Operand(r9, LSL, kBinary32ExponentShift));
3999 __ bind(&sign); 3863
4000 __ teq(r7, Operand(0, RelocInfo::NONE)); 3864 __ bind(&done);
4001 __ rsb(r5, r5, Operand(0, RelocInfo::NONE), LeaveCC, ne); 3865 __ str(r5, MemOperand(r3, r4, LSL, 2));
4002 3866 // Entry registers are intact, r0 holds the value which is the return
4003 __ bind(&done); 3867 // value.
4004 switch (array_type) { 3868 __ Ret();
4005 case kExternalByteArray: 3869
4006 case kExternalUnsignedByteArray: 3870 __ bind(&nan_or_infinity_or_zero);
4007 __ strb(r5, MemOperand(r3, r4, LSL, 0)); 3871 __ and_(r7, r5, Operand(HeapNumber::kSignMask));
4008 break; 3872 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
4009 case kExternalShortArray: 3873 __ orr(r9, r9, r7);
4010 case kExternalUnsignedShortArray: 3874 __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift));
4011 __ strh(r5, MemOperand(r3, r4, LSL, 1)); 3875 __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift));
4012 break; 3876 __ b(&done);
4013 case kExternalIntArray: 3877 } else {
4014 case kExternalUnsignedIntArray: 3878 bool is_signed_type = IsElementTypeSigned(array_type);
4015 __ str(r5, MemOperand(r3, r4, LSL, 2)); 3879 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt;
4016 break; 3880 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000;
4017 default: 3881
4018 UNREACHABLE(); 3882 Label done, sign;
4019 break; 3883
3884 // Test for all special exponent values: zeros, subnormal numbers, NaNs
3885 // and infinities. All these should be converted to 0.
3886 __ mov(r7, Operand(HeapNumber::kExponentMask));
3887 __ and_(r9, r5, Operand(r7), SetCC);
3888 __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, eq);
3889 __ b(eq, &done);
3890
3891 __ teq(r9, Operand(r7));
3892 __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, eq);
3893 __ b(eq, &done);
3894
3895 // Unbias exponent.
3896 __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift));
3897 __ sub(r9, r9, Operand(HeapNumber::kExponentBias), SetCC);
3898 // If exponent is negative then result is 0.
3899 __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, mi);
3900 __ b(mi, &done);
3901
3902 // If exponent is too big then result is minimal value.
3903 __ cmp(r9, Operand(meaningfull_bits - 1));
3904 __ mov(r5, Operand(min_value), LeaveCC, ge);
3905 __ b(ge, &done);
3906
3907 __ and_(r7, r5, Operand(HeapNumber::kSignMask), SetCC);
3908 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3909 __ orr(r5, r5, Operand(1u << HeapNumber::kMantissaBitsInTopWord));
3910
3911 __ rsb(r9, r9, Operand(HeapNumber::kMantissaBitsInTopWord), SetCC);
3912 __ mov(r5, Operand(r5, LSR, r9), LeaveCC, pl);
3913 __ b(pl, &sign);
3914
3915 __ rsb(r9, r9, Operand(0, RelocInfo::NONE));
3916 __ mov(r5, Operand(r5, LSL, r9));
3917 __ rsb(r9, r9, Operand(meaningfull_bits));
3918 __ orr(r5, r5, Operand(r6, LSR, r9));
3919
3920 __ bind(&sign);
3921 __ teq(r7, Operand(0, RelocInfo::NONE));
3922 __ rsb(r5, r5, Operand(0, RelocInfo::NONE), LeaveCC, ne);
3923
3924 __ bind(&done);
3925 switch (array_type) {
3926 case kExternalByteArray:
3927 case kExternalUnsignedByteArray:
3928 __ strb(r5, MemOperand(r3, r4, LSL, 0));
3929 break;
3930 case kExternalShortArray:
3931 case kExternalUnsignedShortArray:
3932 __ strh(r5, MemOperand(r3, r4, LSL, 1));
3933 break;
3934 case kExternalIntArray:
3935 case kExternalUnsignedIntArray:
3936 __ str(r5, MemOperand(r3, r4, LSL, 2));
3937 break;
3938 default:
3939 UNREACHABLE();
3940 break;
3941 }
4020 } 3942 }
4021 } 3943 }
4022 } 3944 }
4023 3945
4024 // Slow case: call runtime. 3946 // Slow case: call runtime.
4025 __ bind(&slow); 3947 __ bind(&slow);
4026 3948
4027 // Entry registers are intact. 3949 // Entry registers are intact.
4028 // ---------- S t a t e -------------- 3950 // ---------- S t a t e --------------
4029 // -- r0 : value 3951 // -- r0 : value
4030 // -- r1 : key 3952 // -- r1 : key
4031 // -- r2 : receiver 3953 // -- r2 : receiver
4032 // -- lr : return address 3954 // -- lr : return address
4033 // ----------------------------------- 3955 // -----------------------------------
4034 3956
4035 // Push receiver, key and value for runtime call. 3957 // Push receiver, key and value for runtime call.
4036 __ Push(r2, r1, r0); 3958 __ Push(r2, r1, r0);
4037 3959
4038 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); 3960 __ TailCallRuntime(Runtime::kSetProperty, 3, 1);
4039 3961
4040 return GetCode(flags); 3962 return GetCode(flags);
4041 } 3963 }
4042 3964
4043 3965
4044 #undef __ 3966 #undef __
4045 3967
4046 } } // namespace v8::internal 3968 } } // namespace v8::internal
4047 3969
4048 #endif // V8_TARGET_ARCH_ARM 3970 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698