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

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

Issue 14113011: MIPS: Remove soft-float support. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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
« no previous file with comments | « src/mips/macro-assembler-mips.cc ('k') | test/cctest/test-assembler-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1041 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 } 1052 }
1053 1053
1054 1054
1055 // Convert and store int passed in register ival to IEEE 754 single precision 1055 // Convert and store int passed in register ival to IEEE 754 single precision
1056 // floating point value at memory location (dst + 4 * wordoffset) 1056 // floating point value at memory location (dst + 4 * wordoffset)
1057 // If FPU is available use it for conversion. 1057 // If FPU is available use it for conversion.
1058 static void StoreIntAsFloat(MacroAssembler* masm, 1058 static void StoreIntAsFloat(MacroAssembler* masm,
1059 Register dst, 1059 Register dst,
1060 Register wordoffset, 1060 Register wordoffset,
1061 Register ival, 1061 Register ival,
1062 Register fval, 1062 Register scratch1) {
1063 Register scratch1, 1063 __ mtc1(ival, f0);
1064 Register scratch2) { 1064 __ cvt_s_w(f0, f0);
1065 if (CpuFeatures::IsSupported(FPU)) { 1065 __ sll(scratch1, wordoffset, 2);
1066 CpuFeatureScope scope(masm, FPU); 1066 __ addu(scratch1, dst, scratch1);
1067 __ mtc1(ival, f0); 1067 __ swc1(f0, MemOperand(scratch1, 0));
1068 __ cvt_s_w(f0, f0);
1069 __ sll(scratch1, wordoffset, 2);
1070 __ addu(scratch1, dst, scratch1);
1071 __ swc1(f0, MemOperand(scratch1, 0));
1072 } else {
1073 // FPU is not available, do manual conversions.
1074
1075 Label not_special, done;
1076 // Move sign bit from source to destination. This works because the sign
1077 // bit in the exponent word of the double has the same position and polarity
1078 // as the 2's complement sign bit in a Smi.
1079 ASSERT(kBinary32SignMask == 0x80000000u);
1080
1081 __ And(fval, ival, Operand(kBinary32SignMask));
1082 // Negate value if it is negative.
1083 __ subu(scratch1, zero_reg, ival);
1084 __ Movn(ival, scratch1, fval);
1085
1086 // We have -1, 0 or 1, which we treat specially. Register ival contains
1087 // absolute value: it is either equal to 1 (special case of -1 and 1),
1088 // greater than 1 (not a special case) or less than 1 (special case of 0).
1089 __ Branch(&not_special, gt, ival, Operand(1));
1090
1091 // For 1 or -1 we need to or in the 0 exponent (biased).
1092 static const uint32_t exponent_word_for_1 =
1093 kBinary32ExponentBias << kBinary32ExponentShift;
1094
1095 __ Xor(scratch1, ival, Operand(1));
1096 __ li(scratch2, exponent_word_for_1);
1097 __ or_(scratch2, fval, scratch2);
1098 __ Movz(fval, scratch2, scratch1); // Only if ival is equal to 1.
1099 __ Branch(&done);
1100
1101 __ bind(&not_special);
1102 // Count leading zeros.
1103 // Gets the wrong answer for 0, but we already checked for that case above.
1104 Register zeros = scratch2;
1105 __ Clz(zeros, ival);
1106
1107 // Compute exponent and or it into the exponent register.
1108 __ li(scratch1, (kBitsPerInt - 1) + kBinary32ExponentBias);
1109 __ subu(scratch1, scratch1, zeros);
1110
1111 __ sll(scratch1, scratch1, kBinary32ExponentShift);
1112 __ or_(fval, fval, scratch1);
1113
1114 // Shift up the source chopping the top bit off.
1115 __ Addu(zeros, zeros, Operand(1));
1116 // This wouldn't work for 1 and -1 as the shift would be 32 which means 0.
1117 __ sllv(ival, ival, zeros);
1118 // And the top (top 20 bits).
1119 __ srl(scratch1, ival, kBitsPerInt - kBinary32MantissaBits);
1120 __ or_(fval, fval, scratch1);
1121
1122 __ bind(&done);
1123
1124 __ sll(scratch1, wordoffset, 2);
1125 __ addu(scratch1, dst, scratch1);
1126 __ sw(fval, MemOperand(scratch1, 0));
1127 }
1128 } 1068 }
1129 1069
1130 1070
1131 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 1071 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
1132 __ Jump(code, RelocInfo::CODE_TARGET); 1072 __ Jump(code, RelocInfo::CODE_TARGET);
1133 } 1073 }
1134 1074
1135 1075
1136 #undef __ 1076 #undef __
1137 #define __ ACCESS_MASM(masm()) 1077 #define __ ACCESS_MASM(masm())
(...skipping 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after
2170 Handle<JSFunction> function, 2110 Handle<JSFunction> function,
2171 Handle<String> name) { 2111 Handle<String> name) {
2172 // ----------- S t a t e ------------- 2112 // ----------- S t a t e -------------
2173 // -- a2 : function name 2113 // -- a2 : function name
2174 // -- ra : return address 2114 // -- ra : return address
2175 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 2115 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2176 // -- ... 2116 // -- ...
2177 // -- sp[argc * 4] : receiver 2117 // -- sp[argc * 4] : receiver
2178 // ----------------------------------- 2118 // -----------------------------------
2179 2119
2180 if (!CpuFeatures::IsSupported(FPU)) {
2181 return Handle<Code>::null();
2182 }
2183 2120
2184 CpuFeatureScope scope_fpu(masm(), FPU);
2185 const int argc = arguments().immediate(); 2121 const int argc = arguments().immediate();
2186 // If the object is not a JSObject or we got an unexpected number of 2122 // If the object is not a JSObject or we got an unexpected number of
2187 // arguments, bail out to the regular call. 2123 // arguments, bail out to the regular call.
2188 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2124 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2189 2125
2190 Label miss, slow; 2126 Label miss, slow;
2191 GenerateNameCheck(name, &miss); 2127 GenerateNameCheck(name, &miss);
2192 2128
2193 if (cell.is_null()) { 2129 if (cell.is_null()) {
2194 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); 2130 __ lw(a1, MemOperand(sp, 1 * kPointerSize));
(...skipping 1045 matching lines...) Expand 10 before | Expand all | Expand 10 after
3240 3176
3241 // ---------- S t a t e -------------- 3177 // ---------- S t a t e --------------
3242 // -- ra : return address 3178 // -- ra : return address
3243 // -- a0 : key 3179 // -- a0 : key
3244 // -- a1 : receiver 3180 // -- a1 : receiver
3245 // ----------------------------------- 3181 // -----------------------------------
3246 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3182 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3247 } 3183 }
3248 3184
3249 3185
3250 static bool IsElementTypeSigned(ElementsKind elements_kind) {
3251 switch (elements_kind) {
3252 case EXTERNAL_BYTE_ELEMENTS:
3253 case EXTERNAL_SHORT_ELEMENTS:
3254 case EXTERNAL_INT_ELEMENTS:
3255 return true;
3256
3257 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3258 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3259 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3260 case EXTERNAL_PIXEL_ELEMENTS:
3261 return false;
3262
3263 case EXTERNAL_FLOAT_ELEMENTS:
3264 case EXTERNAL_DOUBLE_ELEMENTS:
3265 case FAST_SMI_ELEMENTS:
3266 case FAST_ELEMENTS:
3267 case FAST_DOUBLE_ELEMENTS:
3268 case FAST_HOLEY_SMI_ELEMENTS:
3269 case FAST_HOLEY_ELEMENTS:
3270 case FAST_HOLEY_DOUBLE_ELEMENTS:
3271 case DICTIONARY_ELEMENTS:
3272 case NON_STRICT_ARGUMENTS_ELEMENTS:
3273 UNREACHABLE();
3274 return false;
3275 }
3276 return false;
3277 }
3278
3279
3280 static void GenerateSmiKeyCheck(MacroAssembler* masm, 3186 static void GenerateSmiKeyCheck(MacroAssembler* masm,
3281 Register key, 3187 Register key,
3282 Register scratch0, 3188 Register scratch0,
3283 Register scratch1, 3189 Register scratch1,
3284 FPURegister double_scratch0, 3190 FPURegister double_scratch0,
3285 FPURegister double_scratch1, 3191 FPURegister double_scratch1,
3286 Label* fail) { 3192 Label* fail) {
3287 if (CpuFeatures::IsSupported(FPU)) { 3193 Label key_ok;
3288 CpuFeatureScope scope(masm, FPU); 3194 // Check for smi or a smi inside a heap number. We convert the heap
3289 Label key_ok; 3195 // number and check if the conversion is exact and fits into the smi
3290 // Check for smi or a smi inside a heap number. We convert the heap 3196 // range.
3291 // number and check if the conversion is exact and fits into the smi 3197 __ JumpIfSmi(key, &key_ok);
3292 // range. 3198 __ CheckMap(key,
3293 __ JumpIfSmi(key, &key_ok); 3199 scratch0,
3294 __ CheckMap(key, 3200 Heap::kHeapNumberMapRootIndex,
3295 scratch0, 3201 fail,
3296 Heap::kHeapNumberMapRootIndex, 3202 DONT_DO_SMI_CHECK);
3297 fail, 3203 __ ldc1(double_scratch0, FieldMemOperand(key, HeapNumber::kValueOffset));
3298 DONT_DO_SMI_CHECK); 3204 __ EmitFPUTruncate(kRoundToZero,
3299 __ ldc1(double_scratch0, FieldMemOperand(key, HeapNumber::kValueOffset)); 3205 scratch0,
3300 __ EmitFPUTruncate(kRoundToZero, 3206 double_scratch0,
3301 scratch0, 3207 at,
3302 double_scratch0, 3208 double_scratch1,
3303 at, 3209 scratch1,
3304 double_scratch1, 3210 kCheckForInexactConversion);
3305 scratch1,
3306 kCheckForInexactConversion);
3307 3211
3308 __ Branch(fail, ne, scratch1, Operand(zero_reg)); 3212 __ Branch(fail, ne, scratch1, Operand(zero_reg));
3309 3213
3310 __ SmiTagCheckOverflow(key, scratch0, scratch1); 3214 __ SmiTagCheckOverflow(key, scratch0, scratch1);
3311 __ BranchOnOverflow(fail, scratch1); 3215 __ BranchOnOverflow(fail, scratch1);
3312 __ bind(&key_ok); 3216 __ bind(&key_ok);
3313 } else {
3314 // Check that the key is a smi.
3315 __ JumpIfNotSmi(key, fail);
3316 }
3317 } 3217 }
3318 3218
3319 3219
3320 void KeyedStoreStubCompiler::GenerateStoreExternalArray( 3220 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
3321 MacroAssembler* masm, 3221 MacroAssembler* masm,
3322 ElementsKind elements_kind) { 3222 ElementsKind elements_kind) {
3323 // ---------- S t a t e -------------- 3223 // ---------- S t a t e --------------
3324 // -- a0 : value 3224 // -- a0 : value
3325 // -- a1 : key 3225 // -- a1 : key
3326 // -- a2 : receiver 3226 // -- a2 : receiver
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3397 break; 3297 break;
3398 case EXTERNAL_INT_ELEMENTS: 3298 case EXTERNAL_INT_ELEMENTS:
3399 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3299 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3400 __ sll(t8, key, 1); 3300 __ sll(t8, key, 1);
3401 __ addu(t8, a3, t8); 3301 __ addu(t8, a3, t8);
3402 __ sw(t1, MemOperand(t8, 0)); 3302 __ sw(t1, MemOperand(t8, 0));
3403 break; 3303 break;
3404 case EXTERNAL_FLOAT_ELEMENTS: 3304 case EXTERNAL_FLOAT_ELEMENTS:
3405 // Perform int-to-float conversion and store to memory. 3305 // Perform int-to-float conversion and store to memory.
3406 __ SmiUntag(t0, key); 3306 __ SmiUntag(t0, key);
3407 StoreIntAsFloat(masm, a3, t0, t1, t2, t3, t4); 3307 StoreIntAsFloat(masm, a3, t0, t1, t2);
3408 break; 3308 break;
3409 case EXTERNAL_DOUBLE_ELEMENTS: 3309 case EXTERNAL_DOUBLE_ELEMENTS:
3410 __ sll(t8, key, 2); 3310 __ sll(t8, key, 2);
3411 __ addu(a3, a3, t8); 3311 __ addu(a3, a3, t8);
3412 // a3: effective address of the double element 3312 // a3: effective address of the double element
3413 FloatingPointHelper::Destination destination; 3313 FloatingPointHelper::Destination destination;
3414 if (CpuFeatures::IsSupported(FPU)) { 3314 destination = FloatingPointHelper::kFPURegisters;
3415 destination = FloatingPointHelper::kFPURegisters;
3416 } else {
3417 destination = FloatingPointHelper::kCoreRegisters;
3418 }
3419 FloatingPointHelper::ConvertIntToDouble( 3315 FloatingPointHelper::ConvertIntToDouble(
3420 masm, t1, destination, 3316 masm, t1, destination,
3421 f0, t2, t3, // These are: double_dst, dst_mantissa, dst_exponent. 3317 f0, t2, t3, // These are: double_dst, dst_mantissa, dst_exponent.
3422 t0, f2); // These are: scratch2, single_scratch. 3318 t0, f2); // These are: scratch2, single_scratch.
3423 if (destination == FloatingPointHelper::kFPURegisters) { 3319 __ sdc1(f0, MemOperand(a3, 0));
3424 CpuFeatureScope scope(masm, FPU);
3425 __ sdc1(f0, MemOperand(a3, 0));
3426 } else {
3427 __ sw(t2, MemOperand(a3, 0));
3428 __ sw(t3, MemOperand(a3, Register::kSizeInBytes));
3429 }
3430 break; 3320 break;
3431 case FAST_ELEMENTS: 3321 case FAST_ELEMENTS:
3432 case FAST_SMI_ELEMENTS: 3322 case FAST_SMI_ELEMENTS:
3433 case FAST_DOUBLE_ELEMENTS: 3323 case FAST_DOUBLE_ELEMENTS:
3434 case FAST_HOLEY_ELEMENTS: 3324 case FAST_HOLEY_ELEMENTS:
3435 case FAST_HOLEY_SMI_ELEMENTS: 3325 case FAST_HOLEY_SMI_ELEMENTS:
3436 case FAST_HOLEY_DOUBLE_ELEMENTS: 3326 case FAST_HOLEY_DOUBLE_ELEMENTS:
3437 case DICTIONARY_ELEMENTS: 3327 case DICTIONARY_ELEMENTS:
3438 case NON_STRICT_ARGUMENTS_ELEMENTS: 3328 case NON_STRICT_ARGUMENTS_ELEMENTS:
3439 UNREACHABLE(); 3329 UNREACHABLE();
(...skipping 11 matching lines...) Expand all
3451 __ Branch(&slow, ne, t2, Operand(HEAP_NUMBER_TYPE)); 3341 __ Branch(&slow, ne, t2, Operand(HEAP_NUMBER_TYPE));
3452 3342
3453 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); 3343 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset));
3454 3344
3455 // a3: base pointer of external storage. 3345 // a3: base pointer of external storage.
3456 3346
3457 // The WebGL specification leaves the behavior of storing NaN and 3347 // The WebGL specification leaves the behavior of storing NaN and
3458 // +/-Infinity into integer arrays basically undefined. For more 3348 // +/-Infinity into integer arrays basically undefined. For more
3459 // reproducible behavior, convert these to zero. 3349 // reproducible behavior, convert these to zero.
3460 3350
3461 if (CpuFeatures::IsSupported(FPU)) {
3462 CpuFeatureScope scope(masm, FPU);
3463 3351
3464 __ ldc1(f0, FieldMemOperand(a0, HeapNumber::kValueOffset)); 3352 __ ldc1(f0, FieldMemOperand(a0, HeapNumber::kValueOffset));
3465 3353
3466 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3354 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3467 __ cvt_s_d(f0, f0); 3355 __ cvt_s_d(f0, f0);
3468 __ sll(t8, key, 1); 3356 __ sll(t8, key, 1);
3469 __ addu(t8, a3, t8); 3357 __ addu(t8, a3, t8);
3470 __ swc1(f0, MemOperand(t8, 0)); 3358 __ swc1(f0, MemOperand(t8, 0));
3471 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3359 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3472 __ sll(t8, key, 2); 3360 __ sll(t8, key, 2);
3473 __ addu(t8, a3, t8); 3361 __ addu(t8, a3, t8);
3474 __ sdc1(f0, MemOperand(t8, 0)); 3362 __ sdc1(f0, MemOperand(t8, 0));
3475 } else { 3363 } else {
3476 __ EmitECMATruncate(t3, f0, f2, t2, t1, t5); 3364 __ EmitECMATruncate(t3, f0, f2, t2, t1, t5);
3477 3365
3478 switch (elements_kind) { 3366 switch (elements_kind) {
3479 case EXTERNAL_BYTE_ELEMENTS: 3367 case EXTERNAL_BYTE_ELEMENTS:
3480 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3368 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3481 __ srl(t8, key, 1); 3369 __ srl(t8, key, 1);
3482 __ addu(t8, a3, t8); 3370 __ addu(t8, a3, t8);
3483 __ sb(t3, MemOperand(t8, 0)); 3371 __ sb(t3, MemOperand(t8, 0));
3484 break; 3372 break;
3485 case EXTERNAL_SHORT_ELEMENTS: 3373 case EXTERNAL_SHORT_ELEMENTS:
3486 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3374 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3487 __ addu(t8, a3, key); 3375 __ addu(t8, a3, key);
3488 __ sh(t3, MemOperand(t8, 0)); 3376 __ sh(t3, MemOperand(t8, 0));
3489 break; 3377 break;
3490 case EXTERNAL_INT_ELEMENTS: 3378 case EXTERNAL_INT_ELEMENTS:
3491 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3379 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3492 __ sll(t8, key, 1); 3380 __ sll(t8, key, 1);
3493 __ addu(t8, a3, t8); 3381 __ addu(t8, a3, t8);
3494 __ sw(t3, MemOperand(t8, 0)); 3382 __ sw(t3, MemOperand(t8, 0));
3495 break; 3383 break;
3496 case EXTERNAL_PIXEL_ELEMENTS: 3384 case EXTERNAL_PIXEL_ELEMENTS:
3497 case EXTERNAL_FLOAT_ELEMENTS: 3385 case EXTERNAL_FLOAT_ELEMENTS:
3498 case EXTERNAL_DOUBLE_ELEMENTS: 3386 case EXTERNAL_DOUBLE_ELEMENTS:
3499 case FAST_ELEMENTS: 3387 case FAST_ELEMENTS:
3500 case FAST_SMI_ELEMENTS: 3388 case FAST_SMI_ELEMENTS:
3501 case FAST_DOUBLE_ELEMENTS: 3389 case FAST_DOUBLE_ELEMENTS:
3502 case FAST_HOLEY_ELEMENTS: 3390 case FAST_HOLEY_ELEMENTS:
3503 case FAST_HOLEY_SMI_ELEMENTS: 3391 case FAST_HOLEY_SMI_ELEMENTS:
3504 case FAST_HOLEY_DOUBLE_ELEMENTS: 3392 case FAST_HOLEY_DOUBLE_ELEMENTS:
3505 case DICTIONARY_ELEMENTS: 3393 case DICTIONARY_ELEMENTS:
3506 case NON_STRICT_ARGUMENTS_ELEMENTS: 3394 case NON_STRICT_ARGUMENTS_ELEMENTS:
3507 UNREACHABLE(); 3395 UNREACHABLE();
3508 break; 3396 break;
3509 }
3510 }
3511
3512 // Entry registers are intact, a0 holds the value
3513 // which is the return value.
3514 __ mov(v0, a0);
3515 __ Ret();
3516 } else {
3517 // FPU is not available, do manual conversions.
3518
3519 __ lw(t3, FieldMemOperand(value, HeapNumber::kExponentOffset));
3520 __ lw(t4, FieldMemOperand(value, HeapNumber::kMantissaOffset));
3521
3522 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3523 Label done, nan_or_infinity_or_zero;
3524 static const int kMantissaInHiWordShift =
3525 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
3526
3527 static const int kMantissaInLoWordShift =
3528 kBitsPerInt - kMantissaInHiWordShift;
3529
3530 // Test for all special exponent values: zeros, subnormal numbers, NaNs
3531 // and infinities. All these should be converted to 0.
3532 __ li(t5, HeapNumber::kExponentMask);
3533 __ and_(t6, t3, t5);
3534 __ Branch(&nan_or_infinity_or_zero, eq, t6, Operand(zero_reg));
3535
3536 __ xor_(t1, t6, t5);
3537 __ li(t2, kBinary32ExponentMask);
3538 __ Movz(t6, t2, t1); // Only if t6 is equal to t5.
3539 __ Branch(&nan_or_infinity_or_zero, eq, t1, Operand(zero_reg));
3540
3541 // Rebias exponent.
3542 __ srl(t6, t6, HeapNumber::kExponentShift);
3543 __ Addu(t6,
3544 t6,
3545 Operand(kBinary32ExponentBias - HeapNumber::kExponentBias));
3546
3547 __ li(t1, Operand(kBinary32MaxExponent));
3548 __ Slt(t1, t1, t6);
3549 __ And(t2, t3, Operand(HeapNumber::kSignMask));
3550 __ Or(t2, t2, Operand(kBinary32ExponentMask));
3551 __ Movn(t3, t2, t1); // Only if t6 is gt kBinary32MaxExponent.
3552 __ Branch(&done, gt, t6, Operand(kBinary32MaxExponent));
3553
3554 __ Slt(t1, t6, Operand(kBinary32MinExponent));
3555 __ And(t2, t3, Operand(HeapNumber::kSignMask));
3556 __ Movn(t3, t2, t1); // Only if t6 is lt kBinary32MinExponent.
3557 __ Branch(&done, lt, t6, Operand(kBinary32MinExponent));
3558
3559 __ And(t7, t3, Operand(HeapNumber::kSignMask));
3560 __ And(t3, t3, Operand(HeapNumber::kMantissaMask));
3561 __ sll(t3, t3, kMantissaInHiWordShift);
3562 __ or_(t7, t7, t3);
3563 __ srl(t4, t4, kMantissaInLoWordShift);
3564 __ or_(t7, t7, t4);
3565 __ sll(t6, t6, kBinary32ExponentShift);
3566 __ or_(t3, t7, t6);
3567
3568 __ bind(&done);
3569 __ sll(t9, key, 1);
3570 __ addu(t9, a3, t9);
3571 __ sw(t3, MemOperand(t9, 0));
3572
3573 // Entry registers are intact, a0 holds the value which is the return
3574 // value.
3575 __ mov(v0, a0);
3576 __ Ret();
3577
3578 __ bind(&nan_or_infinity_or_zero);
3579 __ And(t7, t3, Operand(HeapNumber::kSignMask));
3580 __ And(t3, t3, Operand(HeapNumber::kMantissaMask));
3581 __ or_(t6, t6, t7);
3582 __ sll(t3, t3, kMantissaInHiWordShift);
3583 __ or_(t6, t6, t3);
3584 __ srl(t4, t4, kMantissaInLoWordShift);
3585 __ or_(t3, t6, t4);
3586 __ Branch(&done);
3587 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3588 __ sll(t8, key, 2);
3589 __ addu(t8, a3, t8);
3590 // t8: effective address of destination element.
3591 __ sw(t4, MemOperand(t8, 0));
3592 __ sw(t3, MemOperand(t8, Register::kSizeInBytes));
3593 __ mov(v0, a0);
3594 __ Ret();
3595 } else {
3596 bool is_signed_type = IsElementTypeSigned(elements_kind);
3597 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt;
3598 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000;
3599
3600 Label done, sign;
3601
3602 // Test for all special exponent values: zeros, subnormal numbers, NaNs
3603 // and infinities. All these should be converted to 0.
3604 __ li(t5, HeapNumber::kExponentMask);
3605 __ and_(t6, t3, t5);
3606 __ Movz(t3, zero_reg, t6); // Only if t6 is equal to zero.
3607 __ Branch(&done, eq, t6, Operand(zero_reg));
3608
3609 __ xor_(t2, t6, t5);
3610 __ Movz(t3, zero_reg, t2); // Only if t6 is equal to t5.
3611 __ Branch(&done, eq, t6, Operand(t5));
3612
3613 // Unbias exponent.
3614 __ srl(t6, t6, HeapNumber::kExponentShift);
3615 __ Subu(t6, t6, Operand(HeapNumber::kExponentBias));
3616 // If exponent is negative then result is 0.
3617 __ slt(t2, t6, zero_reg);
3618 __ Movn(t3, zero_reg, t2); // Only if exponent is negative.
3619 __ Branch(&done, lt, t6, Operand(zero_reg));
3620
3621 // If exponent is too big then result is minimal value.
3622 __ slti(t1, t6, meaningfull_bits - 1);
3623 __ li(t2, min_value);
3624 __ Movz(t3, t2, t1); // Only if t6 is ge meaningfull_bits - 1.
3625 __ Branch(&done, ge, t6, Operand(meaningfull_bits - 1));
3626
3627 __ And(t5, t3, Operand(HeapNumber::kSignMask));
3628 __ And(t3, t3, Operand(HeapNumber::kMantissaMask));
3629 __ Or(t3, t3, Operand(1u << HeapNumber::kMantissaBitsInTopWord));
3630
3631 __ li(t9, HeapNumber::kMantissaBitsInTopWord);
3632 __ subu(t6, t9, t6);
3633 __ slt(t1, t6, zero_reg);
3634 __ srlv(t2, t3, t6);
3635 __ Movz(t3, t2, t1); // Only if t6 is positive.
3636 __ Branch(&sign, ge, t6, Operand(zero_reg));
3637
3638 __ subu(t6, zero_reg, t6);
3639 __ sllv(t3, t3, t6);
3640 __ li(t9, meaningfull_bits);
3641 __ subu(t6, t9, t6);
3642 __ srlv(t4, t4, t6);
3643 __ or_(t3, t3, t4);
3644
3645 __ bind(&sign);
3646 __ subu(t2, t3, zero_reg);
3647 __ Movz(t3, t2, t5); // Only if t5 is zero.
3648
3649 __ bind(&done);
3650
3651 // Result is in t3.
3652 // This switch block should be exactly the same as above (FPU mode).
3653 switch (elements_kind) {
3654 case EXTERNAL_BYTE_ELEMENTS:
3655 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3656 __ srl(t8, key, 1);
3657 __ addu(t8, a3, t8);
3658 __ sb(t3, MemOperand(t8, 0));
3659 break;
3660 case EXTERNAL_SHORT_ELEMENTS:
3661 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3662 __ addu(t8, a3, key);
3663 __ sh(t3, MemOperand(t8, 0));
3664 break;
3665 case EXTERNAL_INT_ELEMENTS:
3666 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3667 __ sll(t8, key, 1);
3668 __ addu(t8, a3, t8);
3669 __ sw(t3, MemOperand(t8, 0));
3670 break;
3671 case EXTERNAL_PIXEL_ELEMENTS:
3672 case EXTERNAL_FLOAT_ELEMENTS:
3673 case EXTERNAL_DOUBLE_ELEMENTS:
3674 case FAST_ELEMENTS:
3675 case FAST_SMI_ELEMENTS:
3676 case FAST_DOUBLE_ELEMENTS:
3677 case FAST_HOLEY_ELEMENTS:
3678 case FAST_HOLEY_SMI_ELEMENTS:
3679 case FAST_HOLEY_DOUBLE_ELEMENTS:
3680 case DICTIONARY_ELEMENTS:
3681 case NON_STRICT_ARGUMENTS_ELEMENTS:
3682 UNREACHABLE();
3683 break;
3684 }
3685 } 3397 }
3686 } 3398 }
3399
3400 // Entry registers are intact, a0 holds the value
3401 // which is the return value.
3402 __ mov(v0, a0);
3403 __ Ret();
3687 } 3404 }
3688 3405
3689 // Slow case, key and receiver still in a0 and a1. 3406 // Slow case, key and receiver still in a0 and a1.
3690 __ bind(&slow); 3407 __ bind(&slow);
3691 __ IncrementCounter( 3408 __ IncrementCounter(
3692 masm->isolate()->counters()->keyed_load_external_array_slow(), 3409 masm->isolate()->counters()->keyed_load_external_array_slow(),
3693 1, a2, a3); 3410 1, a2, a3);
3694 // Entry registers are intact. 3411 // Entry registers are intact.
3695 // ---------- S t a t e -------------- 3412 // ---------- S t a t e --------------
3696 // -- ra : return address 3413 // -- ra : return address
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
4028 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3745 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
4029 } 3746 }
4030 } 3747 }
4031 3748
4032 3749
4033 #undef __ 3750 #undef __
4034 3751
4035 } } // namespace v8::internal 3752 } } // namespace v8::internal
4036 3753
4037 #endif // V8_TARGET_ARCH_MIPS 3754 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/macro-assembler-mips.cc ('k') | test/cctest/test-assembler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698