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

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

Issue 12221064: Implement many KeyedStoreStubs using Crankshaft (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 7 years, 9 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 975 matching lines...) Expand 10 before | Expand all | Expand 10 after
986 Handle<GlobalObject>::cast(current), 986 Handle<GlobalObject>::cast(current),
987 name, 987 name,
988 scratch, 988 scratch,
989 miss); 989 miss);
990 } 990 }
991 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); 991 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
992 } 992 }
993 } 993 }
994 994
995 995
996 // Convert and store int passed in register ival to IEEE 754 single precision
997 // floating point value at memory location (dst + 4 * wordoffset)
998 // If VFP3 is available use it for conversion.
999 static void StoreIntAsFloat(MacroAssembler* masm,
1000 Register dst,
1001 Register wordoffset,
1002 Register ival,
1003 Register fval,
1004 Register scratch1,
1005 Register scratch2) {
1006 if (CpuFeatures::IsSupported(VFP2)) {
1007 CpuFeatureScope scope(masm, VFP2);
1008 __ vmov(s0, ival);
1009 __ add(scratch1, dst, Operand(wordoffset, LSL, 2));
1010 __ vcvt_f32_s32(s0, s0);
1011 __ vstr(s0, scratch1, 0);
1012 } else {
1013 Label not_special, done;
1014 // Move sign bit from source to destination. This works because the sign
1015 // bit in the exponent word of the double has the same position and polarity
1016 // as the 2's complement sign bit in a Smi.
1017 ASSERT(kBinary32SignMask == 0x80000000u);
1018
1019 __ and_(fval, ival, Operand(kBinary32SignMask), SetCC);
1020 // Negate value if it is negative.
1021 __ rsb(ival, ival, Operand::Zero(), LeaveCC, ne);
1022
1023 // We have -1, 0 or 1, which we treat specially. Register ival contains
1024 // absolute value: it is either equal to 1 (special case of -1 and 1),
1025 // greater than 1 (not a special case) or less than 1 (special case of 0).
1026 __ cmp(ival, Operand(1));
1027 __ b(gt, &not_special);
1028
1029 // For 1 or -1 we need to or in the 0 exponent (biased).
1030 static const uint32_t exponent_word_for_1 =
1031 kBinary32ExponentBias << kBinary32ExponentShift;
1032
1033 __ orr(fval, fval, Operand(exponent_word_for_1), LeaveCC, eq);
1034 __ b(&done);
1035
1036 __ bind(&not_special);
1037 // Count leading zeros.
1038 // Gets the wrong answer for 0, but we already checked for that case above.
1039 Register zeros = scratch2;
1040 __ CountLeadingZeros(zeros, ival, scratch1);
1041
1042 // Compute exponent and or it into the exponent register.
1043 __ rsb(scratch1,
1044 zeros,
1045 Operand((kBitsPerInt - 1) + kBinary32ExponentBias));
1046
1047 __ orr(fval,
1048 fval,
1049 Operand(scratch1, LSL, kBinary32ExponentShift));
1050
1051 // Shift up the source chopping the top bit off.
1052 __ add(zeros, zeros, Operand(1));
1053 // This wouldn't work for 1 and -1 as the shift would be 32 which means 0.
1054 __ mov(ival, Operand(ival, LSL, zeros));
1055 // And the top (top 20 bits).
1056 __ orr(fval,
1057 fval,
1058 Operand(ival, LSR, kBitsPerInt - kBinary32MantissaBits));
1059
1060 __ bind(&done);
1061 __ str(fval, MemOperand(dst, wordoffset, LSL, 2));
1062 }
1063 }
1064
1065
1066 #undef __ 996 #undef __
1067 #define __ ACCESS_MASM(masm()) 997 #define __ ACCESS_MASM(masm())
1068 998
1069 999
1070 void StubCompiler::GenerateTailCall(Handle<Code> code) { 1000 void StubCompiler::GenerateTailCall(Handle<Code> code) {
1071 __ Jump(code, RelocInfo::CODE_TARGET); 1001 __ Jump(code, RelocInfo::CODE_TARGET);
1072 } 1002 }
1073 1003
1074 1004
1075 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 1005 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
(...skipping 1978 matching lines...) Expand 10 before | Expand all | Expand 10 after
3054 Handle<Map> receiver_map) { 2984 Handle<Map> receiver_map) {
3055 // ----------- S t a t e ------------- 2985 // ----------- S t a t e -------------
3056 // -- r0 : value 2986 // -- r0 : value
3057 // -- r1 : key 2987 // -- r1 : key
3058 // -- r2 : receiver 2988 // -- r2 : receiver
3059 // -- lr : return address 2989 // -- lr : return address
3060 // -- r3 : scratch 2990 // -- r3 : scratch
3061 // ----------------------------------- 2991 // -----------------------------------
3062 ElementsKind elements_kind = receiver_map->elements_kind(); 2992 ElementsKind elements_kind = receiver_map->elements_kind();
3063 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 2993 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
3064 Handle<Code> stub = 2994 if (receiver_map->has_fast_elements() ||
3065 KeyedStoreElementStub(is_js_array, 2995 receiver_map->has_external_array_elements()) {
3066 elements_kind, 2996 Handle<Code> stub = KeyedStoreFastElementStub(
3067 store_mode_).GetCode(isolate()); 2997 is_js_array,
3068 2998 elements_kind,
3069 __ DispatchMap(r2, r3, receiver_map, stub, DO_SMI_CHECK); 2999 store_mode_).GetCode(isolate());
3000 __ DispatchMap(r2, r3, receiver_map, stub, DO_SMI_CHECK);
3001 } else {
3002 Handle<Code> stub =
3003 KeyedStoreElementStub(is_js_array, elements_kind,
3004 store_mode_).GetCode(isolate());
3005 __ DispatchMap(r2, r3, receiver_map, stub, DO_SMI_CHECK);
3006 }
3070 3007
3071 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 3008 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
3072 __ Jump(ic, RelocInfo::CODE_TARGET); 3009 __ Jump(ic, RelocInfo::CODE_TARGET);
3073 3010
3074 // Return the generated code. 3011 // Return the generated code.
3075 return GetCode(Code::NORMAL, factory()->empty_string()); 3012 return GetCode(Code::NORMAL, factory()->empty_string());
3076 } 3013 }
3077 3014
3078 3015
3079 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 3016 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
3304 // -- r0 : key 3241 // -- r0 : key
3305 // -- r1 : receiver 3242 // -- r1 : receiver
3306 // ----------------------------------- 3243 // -----------------------------------
3307 3244
3308 Handle<Code> miss_ic = 3245 Handle<Code> miss_ic =
3309 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); 3246 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
3310 __ Jump(miss_ic, RelocInfo::CODE_TARGET); 3247 __ Jump(miss_ic, RelocInfo::CODE_TARGET);
3311 } 3248 }
3312 3249
3313 3250
3314 static bool IsElementTypeSigned(ElementsKind elements_kind) {
3315 switch (elements_kind) {
3316 case EXTERNAL_BYTE_ELEMENTS:
3317 case EXTERNAL_SHORT_ELEMENTS:
3318 case EXTERNAL_INT_ELEMENTS:
3319 return true;
3320
3321 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3322 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3323 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3324 case EXTERNAL_PIXEL_ELEMENTS:
3325 return false;
3326
3327 case EXTERNAL_FLOAT_ELEMENTS:
3328 case EXTERNAL_DOUBLE_ELEMENTS:
3329 case FAST_ELEMENTS:
3330 case FAST_SMI_ELEMENTS:
3331 case FAST_DOUBLE_ELEMENTS:
3332 case FAST_HOLEY_ELEMENTS:
3333 case FAST_HOLEY_SMI_ELEMENTS:
3334 case FAST_HOLEY_DOUBLE_ELEMENTS:
3335 case DICTIONARY_ELEMENTS:
3336 case NON_STRICT_ARGUMENTS_ELEMENTS:
3337 UNREACHABLE();
3338 return false;
3339 }
3340 return false;
3341 }
3342
3343
3344 static void GenerateSmiKeyCheck(MacroAssembler* masm, 3251 static void GenerateSmiKeyCheck(MacroAssembler* masm,
3345 Register key, 3252 Register key,
3346 Register scratch0, 3253 Register scratch0,
3347 Register scratch1, 3254 Register scratch1,
3348 DwVfpRegister double_scratch0, 3255 DwVfpRegister double_scratch0,
3349 DwVfpRegister double_scratch1, 3256 DwVfpRegister double_scratch1,
3350 Label* fail) { 3257 Label* fail) {
3351 if (CpuFeatures::IsSupported(VFP2)) { 3258 if (CpuFeatures::IsSupported(VFP2)) {
3352 CpuFeatureScope scope(masm, VFP2); 3259 CpuFeatureScope scope(masm, VFP2);
3353 Label key_ok; 3260 Label key_ok;
(...skipping 13 matching lines...) Expand all
3367 __ TrySmiTag(scratch0, fail, scratch1); 3274 __ TrySmiTag(scratch0, fail, scratch1);
3368 __ mov(key, scratch0); 3275 __ mov(key, scratch0);
3369 __ bind(&key_ok); 3276 __ bind(&key_ok);
3370 } else { 3277 } else {
3371 // Check that the key is a smi. 3278 // Check that the key is a smi.
3372 __ JumpIfNotSmi(key, fail); 3279 __ JumpIfNotSmi(key, fail);
3373 } 3280 }
3374 } 3281 }
3375 3282
3376 3283
3377 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
3378 MacroAssembler* masm,
3379 ElementsKind elements_kind) {
3380 // ---------- S t a t e --------------
3381 // -- r0 : value
3382 // -- r1 : key
3383 // -- r2 : receiver
3384 // -- lr : return address
3385 // -----------------------------------
3386 Label slow, check_heap_number, miss_force_generic;
3387
3388 // Register usage.
3389 Register value = r0;
3390 Register key = r1;
3391 Register receiver = r2;
3392 // r3 mostly holds the elements array or the destination external array.
3393
3394 // This stub is meant to be tail-jumped to, the receiver must already
3395 // have been verified by the caller to not be a smi.
3396
3397 // Check that the key is a smi or a heap number convertible to a smi.
3398 GenerateSmiKeyCheck(masm, key, r4, r5, d1, d2, &miss_force_generic);
3399
3400 __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
3401
3402 // Check that the index is in range
3403 __ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset));
3404 __ cmp(key, ip);
3405 // Unsigned comparison catches both negative and too-large values.
3406 __ b(hs, &miss_force_generic);
3407
3408 // Handle both smis and HeapNumbers in the fast path. Go to the
3409 // runtime for all other kinds of values.
3410 // r3: external array.
3411 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) {
3412 // Double to pixel conversion is only implemented in the runtime for now.
3413 __ JumpIfNotSmi(value, &slow);
3414 } else {
3415 __ JumpIfNotSmi(value, &check_heap_number);
3416 }
3417 __ SmiUntag(r5, value);
3418 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
3419
3420 // r3: base pointer of external storage.
3421 // r5: value (integer).
3422 switch (elements_kind) {
3423 case EXTERNAL_PIXEL_ELEMENTS:
3424 // Clamp the value to [0..255].
3425 __ Usat(r5, 8, Operand(r5));
3426 __ strb(r5, MemOperand(r3, key, LSR, 1));
3427 break;
3428 case EXTERNAL_BYTE_ELEMENTS:
3429 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3430 __ strb(r5, MemOperand(r3, key, LSR, 1));
3431 break;
3432 case EXTERNAL_SHORT_ELEMENTS:
3433 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3434 __ strh(r5, MemOperand(r3, key, LSL, 0));
3435 break;
3436 case EXTERNAL_INT_ELEMENTS:
3437 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3438 __ str(r5, MemOperand(r3, key, LSL, 1));
3439 break;
3440 case EXTERNAL_FLOAT_ELEMENTS:
3441 // Perform int-to-float conversion and store to memory.
3442 __ SmiUntag(r4, key);
3443 StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9);
3444 break;
3445 case EXTERNAL_DOUBLE_ELEMENTS:
3446 __ add(r3, r3, Operand(key, LSL, 2));
3447 // r3: effective address of the double element
3448 FloatingPointHelper::Destination destination;
3449 if (CpuFeatures::IsSupported(VFP2)) {
3450 destination = FloatingPointHelper::kVFPRegisters;
3451 } else {
3452 destination = FloatingPointHelper::kCoreRegisters;
3453 }
3454 FloatingPointHelper::ConvertIntToDouble(
3455 masm, r5, destination,
3456 d0, r6, r7, // These are: double_dst, dst_mantissa, dst_exponent.
3457 r4, s2); // These are: scratch2, single_scratch.
3458 if (destination == FloatingPointHelper::kVFPRegisters) {
3459 CpuFeatureScope scope(masm, VFP2);
3460 __ vstr(d0, r3, 0);
3461 } else {
3462 __ str(r6, MemOperand(r3, 0));
3463 __ str(r7, MemOperand(r3, Register::kSizeInBytes));
3464 }
3465 break;
3466 case FAST_ELEMENTS:
3467 case FAST_SMI_ELEMENTS:
3468 case FAST_DOUBLE_ELEMENTS:
3469 case FAST_HOLEY_ELEMENTS:
3470 case FAST_HOLEY_SMI_ELEMENTS:
3471 case FAST_HOLEY_DOUBLE_ELEMENTS:
3472 case DICTIONARY_ELEMENTS:
3473 case NON_STRICT_ARGUMENTS_ELEMENTS:
3474 UNREACHABLE();
3475 break;
3476 }
3477
3478 // Entry registers are intact, r0 holds the value which is the return value.
3479 __ Ret();
3480
3481 if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) {
3482 // r3: external array.
3483 __ bind(&check_heap_number);
3484 __ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE);
3485 __ b(ne, &slow);
3486
3487 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
3488
3489 // r3: base pointer of external storage.
3490
3491 // The WebGL specification leaves the behavior of storing NaN and
3492 // +/-Infinity into integer arrays basically undefined. For more
3493 // reproducible behavior, convert these to zero.
3494 if (CpuFeatures::IsSupported(VFP2)) {
3495 CpuFeatureScope scope(masm, VFP2);
3496
3497 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3498 // vldr requires offset to be a multiple of 4 so we can not
3499 // include -kHeapObjectTag into it.
3500 __ sub(r5, r0, Operand(kHeapObjectTag));
3501 __ vldr(d0, r5, HeapNumber::kValueOffset);
3502 __ add(r5, r3, Operand(key, LSL, 1));
3503 __ vcvt_f32_f64(s0, d0);
3504 __ vstr(s0, r5, 0);
3505 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3506 __ sub(r5, r0, Operand(kHeapObjectTag));
3507 __ vldr(d0, r5, HeapNumber::kValueOffset);
3508 __ add(r5, r3, Operand(key, LSL, 2));
3509 __ vstr(d0, r5, 0);
3510 } else {
3511 // Hoisted load. vldr requires offset to be a multiple of 4 so we can
3512 // not include -kHeapObjectTag into it.
3513 __ sub(r5, value, Operand(kHeapObjectTag));
3514 __ vldr(d0, r5, HeapNumber::kValueOffset);
3515 __ EmitECMATruncate(r5, d0, d1, r6, r7, r9);
3516
3517 switch (elements_kind) {
3518 case EXTERNAL_BYTE_ELEMENTS:
3519 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3520 __ strb(r5, MemOperand(r3, key, LSR, 1));
3521 break;
3522 case EXTERNAL_SHORT_ELEMENTS:
3523 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3524 __ strh(r5, MemOperand(r3, key, LSL, 0));
3525 break;
3526 case EXTERNAL_INT_ELEMENTS:
3527 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3528 __ str(r5, MemOperand(r3, key, LSL, 1));
3529 break;
3530 case EXTERNAL_PIXEL_ELEMENTS:
3531 case EXTERNAL_FLOAT_ELEMENTS:
3532 case EXTERNAL_DOUBLE_ELEMENTS:
3533 case FAST_ELEMENTS:
3534 case FAST_SMI_ELEMENTS:
3535 case FAST_DOUBLE_ELEMENTS:
3536 case FAST_HOLEY_ELEMENTS:
3537 case FAST_HOLEY_SMI_ELEMENTS:
3538 case FAST_HOLEY_DOUBLE_ELEMENTS:
3539 case DICTIONARY_ELEMENTS:
3540 case NON_STRICT_ARGUMENTS_ELEMENTS:
3541 UNREACHABLE();
3542 break;
3543 }
3544 }
3545
3546 // Entry registers are intact, r0 holds the value which is the return
3547 // value.
3548 __ Ret();
3549 } else {
3550 // VFP3 is not available do manual conversions.
3551 __ ldr(r5, FieldMemOperand(value, HeapNumber::kExponentOffset));
3552 __ ldr(r6, FieldMemOperand(value, HeapNumber::kMantissaOffset));
3553
3554 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3555 Label done, nan_or_infinity_or_zero;
3556 static const int kMantissaInHiWordShift =
3557 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
3558
3559 static const int kMantissaInLoWordShift =
3560 kBitsPerInt - kMantissaInHiWordShift;
3561
3562 // Test for all special exponent values: zeros, subnormal numbers, NaNs
3563 // and infinities. All these should be converted to 0.
3564 __ mov(r7, Operand(HeapNumber::kExponentMask));
3565 __ and_(r9, r5, Operand(r7), SetCC);
3566 __ b(eq, &nan_or_infinity_or_zero);
3567
3568 __ teq(r9, Operand(r7));
3569 __ mov(r9, Operand(kBinary32ExponentMask), LeaveCC, eq);
3570 __ b(eq, &nan_or_infinity_or_zero);
3571
3572 // Rebias exponent.
3573 __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift));
3574 __ add(r9,
3575 r9,
3576 Operand(kBinary32ExponentBias - HeapNumber::kExponentBias));
3577
3578 __ cmp(r9, Operand(kBinary32MaxExponent));
3579 __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, gt);
3580 __ orr(r5, r5, Operand(kBinary32ExponentMask), LeaveCC, gt);
3581 __ b(gt, &done);
3582
3583 __ cmp(r9, Operand(kBinary32MinExponent));
3584 __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, lt);
3585 __ b(lt, &done);
3586
3587 __ and_(r7, r5, Operand(HeapNumber::kSignMask));
3588 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3589 __ orr(r7, r7, Operand(r5, LSL, kMantissaInHiWordShift));
3590 __ orr(r7, r7, Operand(r6, LSR, kMantissaInLoWordShift));
3591 __ orr(r5, r7, Operand(r9, LSL, kBinary32ExponentShift));
3592
3593 __ bind(&done);
3594 __ str(r5, MemOperand(r3, key, LSL, 1));
3595 // Entry registers are intact, r0 holds the value which is the return
3596 // value.
3597 __ Ret();
3598
3599 __ bind(&nan_or_infinity_or_zero);
3600 __ and_(r7, r5, Operand(HeapNumber::kSignMask));
3601 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3602 __ orr(r9, r9, r7);
3603 __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift));
3604 __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift));
3605 __ b(&done);
3606 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3607 __ add(r7, r3, Operand(key, LSL, 2));
3608 // r7: effective address of destination element.
3609 __ str(r6, MemOperand(r7, 0));
3610 __ str(r5, MemOperand(r7, Register::kSizeInBytes));
3611 __ Ret();
3612 } else {
3613 bool is_signed_type = IsElementTypeSigned(elements_kind);
3614 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt;
3615 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000;
3616
3617 Label done, sign;
3618
3619 // Test for all special exponent values: zeros, subnormal numbers, NaNs
3620 // and infinities. All these should be converted to 0.
3621 __ mov(r7, Operand(HeapNumber::kExponentMask));
3622 __ and_(r9, r5, Operand(r7), SetCC);
3623 __ mov(r5, Operand::Zero(), LeaveCC, eq);
3624 __ b(eq, &done);
3625
3626 __ teq(r9, Operand(r7));
3627 __ mov(r5, Operand::Zero(), LeaveCC, eq);
3628 __ b(eq, &done);
3629
3630 // Unbias exponent.
3631 __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift));
3632 __ sub(r9, r9, Operand(HeapNumber::kExponentBias), SetCC);
3633 // If exponent is negative then result is 0.
3634 __ mov(r5, Operand::Zero(), LeaveCC, mi);
3635 __ b(mi, &done);
3636
3637 // If exponent is too big then result is minimal value.
3638 __ cmp(r9, Operand(meaningfull_bits - 1));
3639 __ mov(r5, Operand(min_value), LeaveCC, ge);
3640 __ b(ge, &done);
3641
3642 __ and_(r7, r5, Operand(HeapNumber::kSignMask), SetCC);
3643 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3644 __ orr(r5, r5, Operand(1u << HeapNumber::kMantissaBitsInTopWord));
3645
3646 __ rsb(r9, r9, Operand(HeapNumber::kMantissaBitsInTopWord), SetCC);
3647 __ mov(r5, Operand(r5, LSR, r9), LeaveCC, pl);
3648 __ b(pl, &sign);
3649
3650 __ rsb(r9, r9, Operand::Zero());
3651 __ mov(r5, Operand(r5, LSL, r9));
3652 __ rsb(r9, r9, Operand(meaningfull_bits));
3653 __ orr(r5, r5, Operand(r6, LSR, r9));
3654
3655 __ bind(&sign);
3656 __ teq(r7, Operand::Zero());
3657 __ rsb(r5, r5, Operand::Zero(), LeaveCC, ne);
3658
3659 __ bind(&done);
3660 switch (elements_kind) {
3661 case EXTERNAL_BYTE_ELEMENTS:
3662 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3663 __ strb(r5, MemOperand(r3, key, LSR, 1));
3664 break;
3665 case EXTERNAL_SHORT_ELEMENTS:
3666 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3667 __ strh(r5, MemOperand(r3, key, LSL, 0));
3668 break;
3669 case EXTERNAL_INT_ELEMENTS:
3670 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3671 __ str(r5, MemOperand(r3, key, LSL, 1));
3672 break;
3673 case EXTERNAL_PIXEL_ELEMENTS:
3674 case EXTERNAL_FLOAT_ELEMENTS:
3675 case EXTERNAL_DOUBLE_ELEMENTS:
3676 case FAST_ELEMENTS:
3677 case FAST_SMI_ELEMENTS:
3678 case FAST_DOUBLE_ELEMENTS:
3679 case FAST_HOLEY_ELEMENTS:
3680 case FAST_HOLEY_SMI_ELEMENTS:
3681 case FAST_HOLEY_DOUBLE_ELEMENTS:
3682 case DICTIONARY_ELEMENTS:
3683 case NON_STRICT_ARGUMENTS_ELEMENTS:
3684 UNREACHABLE();
3685 break;
3686 }
3687 }
3688 }
3689 }
3690
3691 // Slow case, key and receiver still in r0 and r1.
3692 __ bind(&slow);
3693 __ IncrementCounter(
3694 masm->isolate()->counters()->keyed_load_external_array_slow(),
3695 1, r2, r3);
3696
3697 // ---------- S t a t e --------------
3698 // -- lr : return address
3699 // -- r0 : key
3700 // -- r1 : receiver
3701 // -----------------------------------
3702 Handle<Code> slow_ic =
3703 masm->isolate()->builtins()->KeyedStoreIC_Slow();
3704 __ Jump(slow_ic, RelocInfo::CODE_TARGET);
3705
3706 // Miss case, call the runtime.
3707 __ bind(&miss_force_generic);
3708
3709 // ---------- S t a t e --------------
3710 // -- lr : return address
3711 // -- r0 : key
3712 // -- r1 : receiver
3713 // -----------------------------------
3714
3715 Handle<Code> miss_ic =
3716 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3717 __ Jump(miss_ic, RelocInfo::CODE_TARGET);
3718 }
3719
3720
3721 void KeyedStoreStubCompiler::GenerateStoreFastElement( 3284 void KeyedStoreStubCompiler::GenerateStoreFastElement(
3722 MacroAssembler* masm, 3285 MacroAssembler* masm,
3723 bool is_js_array, 3286 bool is_js_array,
3724 ElementsKind elements_kind, 3287 ElementsKind elements_kind,
3725 KeyedAccessStoreMode store_mode) { 3288 KeyedAccessStoreMode store_mode) {
3726 // ----------- S t a t e ------------- 3289 // ----------- S t a t e -------------
3727 // -- r0 : value 3290 // -- r0 : value
3728 // -- r1 : key 3291 // -- r1 : key
3729 // -- r2 : receiver 3292 // -- r2 : receiver
3730 // -- lr : return address 3293 // -- lr : return address
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
4048 __ Jump(ic_slow, RelocInfo::CODE_TARGET); 3611 __ Jump(ic_slow, RelocInfo::CODE_TARGET);
4049 } 3612 }
4050 } 3613 }
4051 3614
4052 3615
4053 #undef __ 3616 #undef __
4054 3617
4055 } } // namespace v8::internal 3618 } } // namespace v8::internal
4056 3619
4057 #endif // V8_TARGET_ARCH_ARM 3620 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/ast.h » ('j') | src/code-stubs-hydrogen.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698