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

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

Issue 13560007: Remove ARM support for soft float (pre-VFP2) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: tweaks Created 7 years, 8 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 953 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 miss); 964 miss);
965 } 965 }
966 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); 966 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
967 } 967 }
968 } 968 }
969 969
970 970
971 // Convert and store int passed in register ival to IEEE 754 single precision 971 // Convert and store int passed in register ival to IEEE 754 single precision
972 // floating point value at memory location (dst + 4 * wordoffset) 972 // floating point value at memory location (dst + 4 * wordoffset)
973 // If VFP3 is available use it for conversion. 973 // If VFP3 is available use it for conversion.
974 static void StoreIntAsFloat(MacroAssembler* masm, 974 static void StoreIntAsFloat(MacroAssembler* masm,
Rodolph Perfetta 2013/04/04 15:30:04 fval and scratch2 are not used anymore, the compil
danno 2013/04/08 19:45:33 Done.
975 Register dst, 975 Register dst,
976 Register wordoffset, 976 Register wordoffset,
977 Register ival, 977 Register ival,
978 Register fval, 978 Register fval,
979 Register scratch1, 979 Register scratch1,
980 Register scratch2) { 980 Register scratch2) {
981 if (CpuFeatures::IsSupported(VFP2)) { 981 __ vmov(s0, ival);
982 CpuFeatureScope scope(masm, VFP2); 982 __ add(scratch1, dst, Operand(wordoffset, LSL, 2));
983 __ vmov(s0, ival); 983 __ vcvt_f32_s32(s0, s0);
984 __ add(scratch1, dst, Operand(wordoffset, LSL, 2)); 984 __ vstr(s0, scratch1, 0);
985 __ vcvt_f32_s32(s0, s0);
986 __ vstr(s0, scratch1, 0);
987 } else {
988 Label not_special, done;
989 // Move sign bit from source to destination. This works because the sign
990 // bit in the exponent word of the double has the same position and polarity
991 // as the 2's complement sign bit in a Smi.
992 ASSERT(kBinary32SignMask == 0x80000000u);
993
994 __ and_(fval, ival, Operand(kBinary32SignMask), SetCC);
995 // Negate value if it is negative.
996 __ rsb(ival, ival, Operand::Zero(), LeaveCC, ne);
997
998 // We have -1, 0 or 1, which we treat specially. Register ival contains
999 // absolute value: it is either equal to 1 (special case of -1 and 1),
1000 // greater than 1 (not a special case) or less than 1 (special case of 0).
1001 __ cmp(ival, Operand(1));
1002 __ b(gt, &not_special);
1003
1004 // For 1 or -1 we need to or in the 0 exponent (biased).
1005 static const uint32_t exponent_word_for_1 =
1006 kBinary32ExponentBias << kBinary32ExponentShift;
1007
1008 __ orr(fval, fval, Operand(exponent_word_for_1), LeaveCC, eq);
1009 __ b(&done);
1010
1011 __ bind(&not_special);
1012 // Count leading zeros.
1013 // Gets the wrong answer for 0, but we already checked for that case above.
1014 Register zeros = scratch2;
1015 __ CountLeadingZeros(zeros, ival, scratch1);
1016
1017 // Compute exponent and or it into the exponent register.
1018 __ rsb(scratch1,
1019 zeros,
1020 Operand((kBitsPerInt - 1) + kBinary32ExponentBias));
1021
1022 __ orr(fval,
1023 fval,
1024 Operand(scratch1, LSL, kBinary32ExponentShift));
1025
1026 // Shift up the source chopping the top bit off.
1027 __ add(zeros, zeros, Operand(1));
1028 // This wouldn't work for 1 and -1 as the shift would be 32 which means 0.
1029 __ mov(ival, Operand(ival, LSL, zeros));
1030 // And the top (top 20 bits).
1031 __ orr(fval,
1032 fval,
1033 Operand(ival, LSR, kBitsPerInt - kBinary32MantissaBits));
1034
1035 __ bind(&done);
1036 __ str(fval, MemOperand(dst, wordoffset, LSL, 2));
1037 }
1038 } 985 }
1039 986
1040 987
1041 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 988 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
1042 __ Jump(code, RelocInfo::CODE_TARGET); 989 __ Jump(code, RelocInfo::CODE_TARGET);
1043 } 990 }
1044 991
1045 992
1046 #undef __ 993 #undef __
1047 #define __ ACCESS_MASM(masm()) 994 #define __ ACCESS_MASM(masm())
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after
2082 Handle<JSFunction> function, 2029 Handle<JSFunction> function,
2083 Handle<String> name) { 2030 Handle<String> name) {
2084 // ----------- S t a t e ------------- 2031 // ----------- S t a t e -------------
2085 // -- r2 : function name 2032 // -- r2 : function name
2086 // -- lr : return address 2033 // -- lr : return address
2087 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 2034 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2088 // -- ... 2035 // -- ...
2089 // -- sp[argc * 4] : receiver 2036 // -- sp[argc * 4] : receiver
2090 // ----------------------------------- 2037 // -----------------------------------
2091 2038
2092 if (!CpuFeatures::IsSupported(VFP2)) {
2093 return Handle<Code>::null();
2094 }
2095
2096 CpuFeatureScope scope_vfp2(masm(), VFP2);
2097 const int argc = arguments().immediate(); 2039 const int argc = arguments().immediate();
2098 // If the object is not a JSObject or we got an unexpected number of 2040 // If the object is not a JSObject or we got an unexpected number of
2099 // arguments, bail out to the regular call. 2041 // arguments, bail out to the regular call.
2100 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2042 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2101 2043
2102 Label miss, slow; 2044 Label miss, slow;
2103 GenerateNameCheck(name, &miss); 2045 GenerateNameCheck(name, &miss);
2104 2046
2105 if (cell.is_null()) { 2047 if (cell.is_null()) {
2106 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); 2048 __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
(...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after
3126 3068
3127 // ---------- S t a t e -------------- 3069 // ---------- S t a t e --------------
3128 // -- lr : return address 3070 // -- lr : return address
3129 // -- r0 : key 3071 // -- r0 : key
3130 // -- r1 : receiver 3072 // -- r1 : receiver
3131 // ----------------------------------- 3073 // -----------------------------------
3132 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3074 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3133 } 3075 }
3134 3076
3135 3077
3136 static bool IsElementTypeSigned(ElementsKind elements_kind) {
3137 switch (elements_kind) {
3138 case EXTERNAL_BYTE_ELEMENTS:
3139 case EXTERNAL_SHORT_ELEMENTS:
3140 case EXTERNAL_INT_ELEMENTS:
3141 return true;
3142
3143 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3144 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3145 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3146 case EXTERNAL_PIXEL_ELEMENTS:
3147 return false;
3148
3149 case EXTERNAL_FLOAT_ELEMENTS:
3150 case EXTERNAL_DOUBLE_ELEMENTS:
3151 case FAST_ELEMENTS:
3152 case FAST_SMI_ELEMENTS:
3153 case FAST_DOUBLE_ELEMENTS:
3154 case FAST_HOLEY_ELEMENTS:
3155 case FAST_HOLEY_SMI_ELEMENTS:
3156 case FAST_HOLEY_DOUBLE_ELEMENTS:
3157 case DICTIONARY_ELEMENTS:
3158 case NON_STRICT_ARGUMENTS_ELEMENTS:
3159 UNREACHABLE();
3160 return false;
3161 }
3162 return false;
3163 }
3164
3165
3166 static void GenerateSmiKeyCheck(MacroAssembler* masm, 3078 static void GenerateSmiKeyCheck(MacroAssembler* masm,
3167 Register key, 3079 Register key,
3168 Register scratch0, 3080 Register scratch0,
3169 Register scratch1, 3081 Register scratch1,
3170 DwVfpRegister double_scratch0, 3082 DwVfpRegister double_scratch0,
3171 DwVfpRegister double_scratch1, 3083 DwVfpRegister double_scratch1,
3172 Label* fail) { 3084 Label* fail) {
3173 if (CpuFeatures::IsSupported(VFP2)) { 3085 Label key_ok;
3174 CpuFeatureScope scope(masm, VFP2); 3086 // Check for smi or a smi inside a heap number. We convert the heap
3175 Label key_ok; 3087 // number and check if the conversion is exact and fits into the smi
3176 // Check for smi or a smi inside a heap number. We convert the heap 3088 // range.
3177 // number and check if the conversion is exact and fits into the smi 3089 __ JumpIfSmi(key, &key_ok);
3178 // range. 3090 __ CheckMap(key,
3179 __ JumpIfSmi(key, &key_ok); 3091 scratch0,
3180 __ CheckMap(key, 3092 Heap::kHeapNumberMapRootIndex,
3181 scratch0, 3093 fail,
3182 Heap::kHeapNumberMapRootIndex, 3094 DONT_DO_SMI_CHECK);
3183 fail, 3095 __ sub(ip, key, Operand(kHeapObjectTag));
3184 DONT_DO_SMI_CHECK); 3096 __ vldr(double_scratch0, ip, HeapNumber::kValueOffset);
3185 __ sub(ip, key, Operand(kHeapObjectTag)); 3097 __ TryDoubleToInt32Exact(scratch0, double_scratch0, double_scratch1);
3186 __ vldr(double_scratch0, ip, HeapNumber::kValueOffset); 3098 __ b(ne, fail);
3187 __ TryDoubleToInt32Exact(scratch0, double_scratch0, double_scratch1); 3099 __ TrySmiTag(scratch0, fail, scratch1);
3188 __ b(ne, fail); 3100 __ mov(key, scratch0);
3189 __ TrySmiTag(scratch0, fail, scratch1); 3101 __ bind(&key_ok);
3190 __ mov(key, scratch0);
3191 __ bind(&key_ok);
3192 } else {
3193 // Check that the key is a smi.
3194 __ JumpIfNotSmi(key, fail);
3195 }
3196 } 3102 }
3197 3103
3198 3104
3199 void KeyedStoreStubCompiler::GenerateStoreExternalArray( 3105 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
3200 MacroAssembler* masm, 3106 MacroAssembler* masm,
3201 ElementsKind elements_kind) { 3107 ElementsKind elements_kind) {
3202 // ---------- S t a t e -------------- 3108 // ---------- S t a t e --------------
3203 // -- r0 : value 3109 // -- r0 : value
3204 // -- r1 : key 3110 // -- r1 : key
3205 // -- r2 : receiver 3111 // -- r2 : receiver
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
3261 break; 3167 break;
3262 case EXTERNAL_FLOAT_ELEMENTS: 3168 case EXTERNAL_FLOAT_ELEMENTS:
3263 // Perform int-to-float conversion and store to memory. 3169 // Perform int-to-float conversion and store to memory.
3264 __ SmiUntag(r4, key); 3170 __ SmiUntag(r4, key);
3265 StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9); 3171 StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9);
3266 break; 3172 break;
3267 case EXTERNAL_DOUBLE_ELEMENTS: 3173 case EXTERNAL_DOUBLE_ELEMENTS:
3268 __ add(r3, r3, Operand(key, LSL, 2)); 3174 __ add(r3, r3, Operand(key, LSL, 2));
3269 // r3: effective address of the double element 3175 // r3: effective address of the double element
3270 FloatingPointHelper::Destination destination; 3176 FloatingPointHelper::Destination destination;
3271 if (CpuFeatures::IsSupported(VFP2)) { 3177 destination = FloatingPointHelper::kVFPRegisters;
3272 destination = FloatingPointHelper::kVFPRegisters;
3273 } else {
3274 destination = FloatingPointHelper::kCoreRegisters;
3275 }
3276 FloatingPointHelper::ConvertIntToDouble( 3178 FloatingPointHelper::ConvertIntToDouble(
3277 masm, r5, destination, 3179 masm, r5, destination,
3278 d0, r6, r7, // These are: double_dst, dst_mantissa, dst_exponent. 3180 d0, r6, r7, // These are: double_dst, dst_mantissa, dst_exponent.
3279 r4, s2); // These are: scratch2, single_scratch. 3181 r4, s2); // These are: scratch2, single_scratch.
3280 if (destination == FloatingPointHelper::kVFPRegisters) { 3182 __ vstr(d0, r3, 0);
3281 CpuFeatureScope scope(masm, VFP2);
3282 __ vstr(d0, r3, 0);
3283 } else {
3284 __ str(r6, MemOperand(r3, 0));
3285 __ str(r7, MemOperand(r3, Register::kSizeInBytes));
3286 }
3287 break; 3183 break;
3288 case FAST_ELEMENTS: 3184 case FAST_ELEMENTS:
3289 case FAST_SMI_ELEMENTS: 3185 case FAST_SMI_ELEMENTS:
3290 case FAST_DOUBLE_ELEMENTS: 3186 case FAST_DOUBLE_ELEMENTS:
3291 case FAST_HOLEY_ELEMENTS: 3187 case FAST_HOLEY_ELEMENTS:
3292 case FAST_HOLEY_SMI_ELEMENTS: 3188 case FAST_HOLEY_SMI_ELEMENTS:
3293 case FAST_HOLEY_DOUBLE_ELEMENTS: 3189 case FAST_HOLEY_DOUBLE_ELEMENTS:
3294 case DICTIONARY_ELEMENTS: 3190 case DICTIONARY_ELEMENTS:
3295 case NON_STRICT_ARGUMENTS_ELEMENTS: 3191 case NON_STRICT_ARGUMENTS_ELEMENTS:
3296 UNREACHABLE(); 3192 UNREACHABLE();
3297 break; 3193 break;
3298 } 3194 }
3299 3195
3300 // Entry registers are intact, r0 holds the value which is the return value. 3196 // Entry registers are intact, r0 holds the value which is the return value.
3301 __ Ret(); 3197 __ Ret();
3302 3198
3303 if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) { 3199 if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) {
3304 // r3: external array. 3200 // r3: external array.
3305 __ bind(&check_heap_number); 3201 __ bind(&check_heap_number);
3306 __ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE); 3202 __ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE);
3307 __ b(ne, &slow); 3203 __ b(ne, &slow);
3308 3204
3309 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset)); 3205 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
3310 3206
3311 // r3: base pointer of external storage. 3207 // r3: base pointer of external storage.
3312 3208
3313 // The WebGL specification leaves the behavior of storing NaN and 3209 // The WebGL specification leaves the behavior of storing NaN and
3314 // +/-Infinity into integer arrays basically undefined. For more 3210 // +/-Infinity into integer arrays basically undefined. For more
3315 // reproducible behavior, convert these to zero. 3211 // reproducible behavior, convert these to zero.
3316 if (CpuFeatures::IsSupported(VFP2)) {
3317 CpuFeatureScope scope(masm, VFP2);
3318 3212
3319 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3213 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3320 // vldr requires offset to be a multiple of 4 so we can not 3214 // vldr requires offset to be a multiple of 4 so we can not
3321 // include -kHeapObjectTag into it. 3215 // include -kHeapObjectTag into it.
3322 __ sub(r5, r0, Operand(kHeapObjectTag)); 3216 __ sub(r5, r0, Operand(kHeapObjectTag));
3323 __ vldr(d0, r5, HeapNumber::kValueOffset); 3217 __ vldr(d0, r5, HeapNumber::kValueOffset);
3324 __ add(r5, r3, Operand(key, LSL, 1)); 3218 __ add(r5, r3, Operand(key, LSL, 1));
3325 __ vcvt_f32_f64(s0, d0); 3219 __ vcvt_f32_f64(s0, d0);
3326 __ vstr(s0, r5, 0); 3220 __ vstr(s0, r5, 0);
3327 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3221 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3328 __ sub(r5, r0, Operand(kHeapObjectTag)); 3222 __ sub(r5, r0, Operand(kHeapObjectTag));
3329 __ vldr(d0, r5, HeapNumber::kValueOffset); 3223 __ vldr(d0, r5, HeapNumber::kValueOffset);
3330 __ add(r5, r3, Operand(key, LSL, 2)); 3224 __ add(r5, r3, Operand(key, LSL, 2));
3331 __ vstr(d0, r5, 0); 3225 __ vstr(d0, r5, 0);
3332 } else { 3226 } else {
3333 // Hoisted load. vldr requires offset to be a multiple of 4 so we can 3227 // Hoisted load. vldr requires offset to be a multiple of 4 so we can
3334 // not include -kHeapObjectTag into it. 3228 // not include -kHeapObjectTag into it.
3335 __ sub(r5, value, Operand(kHeapObjectTag)); 3229 __ sub(r5, value, Operand(kHeapObjectTag));
3336 __ vldr(d0, r5, HeapNumber::kValueOffset); 3230 __ vldr(d0, r5, HeapNumber::kValueOffset);
3337 __ ECMAToInt32VFP(r5, d0, d1, r6, r7, r9); 3231 __ ECMAToInt32VFP(r5, d0, d1, r6, r7, r9);
3338 3232
3339 switch (elements_kind) { 3233 switch (elements_kind) {
3340 case EXTERNAL_BYTE_ELEMENTS: 3234 case EXTERNAL_BYTE_ELEMENTS:
3341 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3235 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3342 __ strb(r5, MemOperand(r3, key, LSR, 1)); 3236 __ strb(r5, MemOperand(r3, key, LSR, 1));
3343 break; 3237 break;
3344 case EXTERNAL_SHORT_ELEMENTS: 3238 case EXTERNAL_SHORT_ELEMENTS:
3345 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3239 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3346 __ strh(r5, MemOperand(r3, key, LSL, 0)); 3240 __ strh(r5, MemOperand(r3, key, LSL, 0));
3347 break; 3241 break;
3348 case EXTERNAL_INT_ELEMENTS: 3242 case EXTERNAL_INT_ELEMENTS:
3349 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3243 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3350 __ str(r5, MemOperand(r3, key, LSL, 1)); 3244 __ str(r5, MemOperand(r3, key, LSL, 1));
3351 break; 3245 break;
3352 case EXTERNAL_PIXEL_ELEMENTS: 3246 case EXTERNAL_PIXEL_ELEMENTS:
3353 case EXTERNAL_FLOAT_ELEMENTS: 3247 case EXTERNAL_FLOAT_ELEMENTS:
3354 case EXTERNAL_DOUBLE_ELEMENTS: 3248 case EXTERNAL_DOUBLE_ELEMENTS:
3355 case FAST_ELEMENTS: 3249 case FAST_ELEMENTS:
3356 case FAST_SMI_ELEMENTS: 3250 case FAST_SMI_ELEMENTS:
3357 case FAST_DOUBLE_ELEMENTS: 3251 case FAST_DOUBLE_ELEMENTS:
3358 case FAST_HOLEY_ELEMENTS: 3252 case FAST_HOLEY_ELEMENTS:
3359 case FAST_HOLEY_SMI_ELEMENTS: 3253 case FAST_HOLEY_SMI_ELEMENTS:
3360 case FAST_HOLEY_DOUBLE_ELEMENTS: 3254 case FAST_HOLEY_DOUBLE_ELEMENTS:
3361 case DICTIONARY_ELEMENTS: 3255 case DICTIONARY_ELEMENTS:
3362 case NON_STRICT_ARGUMENTS_ELEMENTS: 3256 case NON_STRICT_ARGUMENTS_ELEMENTS:
3363 UNREACHABLE(); 3257 UNREACHABLE();
3364 break; 3258 break;
3365 }
3366 } 3259 }
3367 3260
Rodolph Perfetta 2013/04/04 15:30:04 the if (elements_kind == EXTERNAL_FLOAT_ELEMENTS)
danno 2013/04/08 19:45:33 Done.
3368 // Entry registers are intact, r0 holds the value which is the return 3261 // Entry registers are intact, r0 holds the value which is the return
3369 // value. 3262 // value.
3370 __ Ret(); 3263 __ Ret();
3371 } else {
3372 // VFP3 is not available do manual conversions.
3373 __ ldr(r5, FieldMemOperand(value, HeapNumber::kExponentOffset));
3374 __ ldr(r6, FieldMemOperand(value, HeapNumber::kMantissaOffset));
3375
3376 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3377 Label done, nan_or_infinity_or_zero;
3378 static const int kMantissaInHiWordShift =
3379 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
3380
3381 static const int kMantissaInLoWordShift =
3382 kBitsPerInt - kMantissaInHiWordShift;
3383
3384 // Test for all special exponent values: zeros, subnormal numbers, NaNs
3385 // and infinities. All these should be converted to 0.
3386 __ mov(r7, Operand(HeapNumber::kExponentMask));
3387 __ and_(r9, r5, Operand(r7), SetCC);
3388 __ b(eq, &nan_or_infinity_or_zero);
3389
3390 __ teq(r9, Operand(r7));
3391 __ mov(r9, Operand(kBinary32ExponentMask), LeaveCC, eq);
3392 __ b(eq, &nan_or_infinity_or_zero);
3393
3394 // Rebias exponent.
3395 __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift));
3396 __ add(r9,
3397 r9,
3398 Operand(kBinary32ExponentBias - HeapNumber::kExponentBias));
3399
3400 __ cmp(r9, Operand(kBinary32MaxExponent));
3401 __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, gt);
3402 __ orr(r5, r5, Operand(kBinary32ExponentMask), LeaveCC, gt);
3403 __ b(gt, &done);
3404
3405 __ cmp(r9, Operand(kBinary32MinExponent));
3406 __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, lt);
3407 __ b(lt, &done);
3408
3409 __ and_(r7, r5, Operand(HeapNumber::kSignMask));
3410 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3411 __ orr(r7, r7, Operand(r5, LSL, kMantissaInHiWordShift));
3412 __ orr(r7, r7, Operand(r6, LSR, kMantissaInLoWordShift));
3413 __ orr(r5, r7, Operand(r9, LSL, kBinary32ExponentShift));
3414
3415 __ bind(&done);
3416 __ str(r5, MemOperand(r3, key, LSL, 1));
3417 // Entry registers are intact, r0 holds the value which is the return
3418 // value.
3419 __ Ret();
3420
3421 __ bind(&nan_or_infinity_or_zero);
3422 __ and_(r7, r5, Operand(HeapNumber::kSignMask));
3423 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3424 __ orr(r9, r9, r7);
3425 __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift));
3426 __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift));
3427 __ b(&done);
3428 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3429 __ add(r7, r3, Operand(key, LSL, 2));
3430 // r7: effective address of destination element.
3431 __ str(r6, MemOperand(r7, 0));
3432 __ str(r5, MemOperand(r7, Register::kSizeInBytes));
3433 __ Ret();
3434 } else {
3435 bool is_signed_type = IsElementTypeSigned(elements_kind);
3436 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt;
3437 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000;
3438
3439 Label done, sign;
3440
3441 // Test for all special exponent values: zeros, subnormal numbers, NaNs
3442 // and infinities. All these should be converted to 0.
3443 __ mov(r7, Operand(HeapNumber::kExponentMask));
3444 __ and_(r9, r5, Operand(r7), SetCC);
3445 __ mov(r5, Operand::Zero(), LeaveCC, eq);
3446 __ b(eq, &done);
3447
3448 __ teq(r9, Operand(r7));
3449 __ mov(r5, Operand::Zero(), LeaveCC, eq);
3450 __ b(eq, &done);
3451
3452 // Unbias exponent.
3453 __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift));
3454 __ sub(r9, r9, Operand(HeapNumber::kExponentBias), SetCC);
3455 // If exponent is negative then result is 0.
3456 __ mov(r5, Operand::Zero(), LeaveCC, mi);
3457 __ b(mi, &done);
3458
3459 // If exponent is too big then result is minimal value.
3460 __ cmp(r9, Operand(meaningfull_bits - 1));
3461 __ mov(r5, Operand(min_value), LeaveCC, ge);
3462 __ b(ge, &done);
3463
3464 __ and_(r7, r5, Operand(HeapNumber::kSignMask), SetCC);
3465 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask));
3466 __ orr(r5, r5, Operand(1u << HeapNumber::kMantissaBitsInTopWord));
3467
3468 __ rsb(r9, r9, Operand(HeapNumber::kMantissaBitsInTopWord), SetCC);
3469 __ mov(r5, Operand(r5, LSR, r9), LeaveCC, pl);
3470 __ b(pl, &sign);
3471
3472 __ rsb(r9, r9, Operand::Zero());
3473 __ mov(r5, Operand(r5, LSL, r9));
3474 __ rsb(r9, r9, Operand(meaningfull_bits));
3475 __ orr(r5, r5, Operand(r6, LSR, r9));
3476
3477 __ bind(&sign);
3478 __ teq(r7, Operand::Zero());
3479 __ rsb(r5, r5, Operand::Zero(), LeaveCC, ne);
3480
3481 __ bind(&done);
3482 switch (elements_kind) {
3483 case EXTERNAL_BYTE_ELEMENTS:
3484 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3485 __ strb(r5, MemOperand(r3, key, LSR, 1));
3486 break;
3487 case EXTERNAL_SHORT_ELEMENTS:
3488 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3489 __ strh(r5, MemOperand(r3, key, LSL, 0));
3490 break;
3491 case EXTERNAL_INT_ELEMENTS:
3492 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3493 __ str(r5, MemOperand(r3, key, LSL, 1));
3494 break;
3495 case EXTERNAL_PIXEL_ELEMENTS:
3496 case EXTERNAL_FLOAT_ELEMENTS:
3497 case EXTERNAL_DOUBLE_ELEMENTS:
3498 case FAST_ELEMENTS:
3499 case FAST_SMI_ELEMENTS:
3500 case FAST_DOUBLE_ELEMENTS:
3501 case FAST_HOLEY_ELEMENTS:
3502 case FAST_HOLEY_SMI_ELEMENTS:
3503 case FAST_HOLEY_DOUBLE_ELEMENTS:
3504 case DICTIONARY_ELEMENTS:
3505 case NON_STRICT_ARGUMENTS_ELEMENTS:
3506 UNREACHABLE();
3507 break;
3508 }
3509 }
3510 } 3264 }
3511 } 3265 }
3512 3266
3513 // Slow case, key and receiver still in r0 and r1. 3267 // Slow case, key and receiver still in r0 and r1.
3514 __ bind(&slow); 3268 __ bind(&slow);
3515 __ IncrementCounter( 3269 __ IncrementCounter(
3516 masm->isolate()->counters()->keyed_load_external_array_slow(), 3270 masm->isolate()->counters()->keyed_load_external_array_slow(),
3517 1, r2, r3); 3271 1, r2, r3);
3518 3272
3519 // ---------- S t a t e -------------- 3273 // ---------- S t a t e --------------
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
3855 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3609 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3856 } 3610 }
3857 } 3611 }
3858 3612
3859 3613
3860 #undef __ 3614 #undef __
3861 3615
3862 } } // namespace v8::internal 3616 } } // namespace v8::internal
3863 3617
3864 #endif // V8_TARGET_ARCH_ARM 3618 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698