| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 3074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3085 | 3085 |
| 3086 GenerateLoadFunctionPrototype(masm(), a1, a2, a3, &miss); | 3086 GenerateLoadFunctionPrototype(masm(), a1, a2, a3, &miss); |
| 3087 __ bind(&miss); | 3087 __ bind(&miss); |
| 3088 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); | 3088 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); |
| 3089 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3089 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3090 | 3090 |
| 3091 return GetCode(CALLBACKS, name); | 3091 return GetCode(CALLBACKS, name); |
| 3092 } | 3092 } |
| 3093 | 3093 |
| 3094 | 3094 |
| 3095 MaybeObject* KeyedLoadStubCompiler::CompileLoadFastElement(Map* receiver_map) { | 3095 MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { |
| 3096 // ----------- S t a t e ------------- | 3096 // ----------- S t a t e ------------- |
| 3097 // -- ra : return address | 3097 // -- ra : return address |
| 3098 // -- a0 : key | 3098 // -- a0 : key |
| 3099 // -- a1 : receiver | 3099 // -- a1 : receiver |
| 3100 // ----------------------------------- | 3100 // ----------------------------------- |
| 3101 MaybeObject* maybe_stub = KeyedLoadFastElementStub().TryGetCode(); | 3101 MaybeObject* maybe_stub; |
| 3102 if (receiver_map->has_fast_elements()) { |
| 3103 maybe_stub = KeyedLoadFastElementStub().TryGetCode(); |
| 3104 } else { |
| 3105 ASSERT(receiver_map->has_external_array_elements()); |
| 3106 JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); |
| 3107 maybe_stub = KeyedLoadExternalArrayStub(elements_kind).TryGetCode(); |
| 3108 } |
| 3102 Code* stub; | 3109 Code* stub; |
| 3103 if (!maybe_stub->To(&stub)) return maybe_stub; | 3110 if (!maybe_stub->To(&stub)) return maybe_stub; |
| 3104 __ DispatchMap(a1, | 3111 __ DispatchMap(a1, |
| 3105 a2, | 3112 a2, |
| 3106 Handle<Map>(receiver_map), | 3113 Handle<Map>(receiver_map), |
| 3107 Handle<Code>(stub), | 3114 Handle<Code>(stub), |
| 3108 DO_SMI_CHECK); | 3115 DO_SMI_CHECK); |
| 3109 | 3116 |
| 3110 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); | 3117 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); |
| 3111 __ Jump(ic, RelocInfo::CODE_TARGET); | 3118 __ Jump(ic, RelocInfo::CODE_TARGET); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3174 | 3181 |
| 3175 __ DecrementCounter(counters->keyed_store_field(), 1, a3, t0); | 3182 __ DecrementCounter(counters->keyed_store_field(), 1, a3, t0); |
| 3176 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); | 3183 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); |
| 3177 __ Jump(ic, RelocInfo::CODE_TARGET); | 3184 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 3178 | 3185 |
| 3179 // Return the generated code. | 3186 // Return the generated code. |
| 3180 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 3187 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
| 3181 } | 3188 } |
| 3182 | 3189 |
| 3183 | 3190 |
| 3184 MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement( | 3191 MaybeObject* KeyedStoreStubCompiler::CompileStoreElement( |
| 3185 Map* receiver_map) { | 3192 Map* receiver_map) { |
| 3186 // ----------- S t a t e ------------- | 3193 // ----------- S t a t e ------------- |
| 3187 // -- a0 : value | 3194 // -- a0 : value |
| 3188 // -- a1 : key | 3195 // -- a1 : key |
| 3189 // -- a2 : receiver | 3196 // -- a2 : receiver |
| 3190 // -- ra : return address | 3197 // -- ra : return address |
| 3191 // -- a3 : scratch | 3198 // -- a3 : scratch |
| 3192 // ----------------------------------- | 3199 // ----------------------------------- |
| 3193 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; | 3200 MaybeObject* maybe_stub; |
| 3194 MaybeObject* maybe_stub = | 3201 if (receiver_map->has_fast_elements()) { |
| 3195 KeyedStoreFastElementStub(is_js_array).TryGetCode(); | 3202 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; |
| 3203 maybe_stub = KeyedStoreFastElementStub(is_js_array).TryGetCode(); |
| 3204 } else { |
| 3205 ASSERT(receiver_map->has_external_array_elements()); |
| 3206 JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); |
| 3207 maybe_stub = KeyedStoreExternalArrayStub(elements_kind).TryGetCode(); |
| 3208 } |
| 3196 Code* stub; | 3209 Code* stub; |
| 3197 if (!maybe_stub->To(&stub)) return maybe_stub; | 3210 if (!maybe_stub->To(&stub)) return maybe_stub; |
| 3198 __ DispatchMap(a2, | 3211 __ DispatchMap(a2, |
| 3199 a3, | 3212 a3, |
| 3200 Handle<Map>(receiver_map), | 3213 Handle<Map>(receiver_map), |
| 3201 Handle<Code>(stub), | 3214 Handle<Code>(stub), |
| 3202 DO_SMI_CHECK); | 3215 DO_SMI_CHECK); |
| 3203 | 3216 |
| 3204 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 3217 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
| 3205 __ Jump(ic, RelocInfo::CODE_TARGET); | 3218 __ Jump(ic, RelocInfo::CODE_TARGET); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3382 __ bind(&generic_stub_call); | 3395 __ bind(&generic_stub_call); |
| 3383 Handle<Code> generic_construct_stub = | 3396 Handle<Code> generic_construct_stub = |
| 3384 masm()->isolate()->builtins()->JSConstructStubGeneric(); | 3397 masm()->isolate()->builtins()->JSConstructStubGeneric(); |
| 3385 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 3398 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
| 3386 | 3399 |
| 3387 // Return the generated code. | 3400 // Return the generated code. |
| 3388 return GetCode(); | 3401 return GetCode(); |
| 3389 } | 3402 } |
| 3390 | 3403 |
| 3391 | 3404 |
| 3392 MaybeObject* ExternalArrayLoadStubCompiler::CompileLoad( | |
| 3393 JSObject*receiver, ExternalArrayType array_type) { | |
| 3394 // ----------- S t a t e ------------- | |
| 3395 // -- ra : return address | |
| 3396 // -- a0 : key | |
| 3397 // -- a1 : receiver | |
| 3398 // ----------------------------------- | |
| 3399 MaybeObject* maybe_stub = | |
| 3400 KeyedLoadExternalArrayStub(array_type).TryGetCode(); | |
| 3401 Code* stub; | |
| 3402 if (!maybe_stub->To(&stub)) return maybe_stub; | |
| 3403 __ DispatchMap(a1, | |
| 3404 a2, | |
| 3405 Handle<Map>(receiver->map()), | |
| 3406 Handle<Code>(stub), | |
| 3407 DO_SMI_CHECK); | |
| 3408 | |
| 3409 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); | |
| 3410 __ Jump(ic, RelocInfo::CODE_TARGET); | |
| 3411 | |
| 3412 // Return the generated code. | |
| 3413 return GetCode(); | |
| 3414 } | |
| 3415 | |
| 3416 | |
| 3417 MaybeObject* ExternalArrayStoreStubCompiler::CompileStore( | |
| 3418 JSObject* receiver, ExternalArrayType array_type) { | |
| 3419 // ----------- S t a t e ------------- | |
| 3420 // -- a0 : value | |
| 3421 // -- a1 : name | |
| 3422 // -- a2 : receiver | |
| 3423 // -- ra : return address | |
| 3424 // ----------------------------------- | |
| 3425 MaybeObject* maybe_stub = | |
| 3426 KeyedStoreExternalArrayStub(array_type).TryGetCode(); | |
| 3427 Code* stub; | |
| 3428 if (!maybe_stub->To(&stub)) return maybe_stub; | |
| 3429 __ DispatchMap(a2, | |
| 3430 a3, | |
| 3431 Handle<Map>(receiver->map()), | |
| 3432 Handle<Code>(stub), | |
| 3433 DO_SMI_CHECK); | |
| 3434 | |
| 3435 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | |
| 3436 __ Jump(ic, RelocInfo::CODE_TARGET); | |
| 3437 | |
| 3438 return GetCode(); | |
| 3439 } | |
| 3440 | |
| 3441 | |
| 3442 #undef __ | 3405 #undef __ |
| 3443 #define __ ACCESS_MASM(masm) | 3406 #define __ ACCESS_MASM(masm) |
| 3444 | 3407 |
| 3445 | 3408 |
| 3446 static bool IsElementTypeSigned(ExternalArrayType array_type) { | 3409 static bool IsElementTypeSigned(JSObject::ElementsKind elements_kind) { |
| 3447 switch (array_type) { | 3410 switch (elements_kind) { |
| 3448 case kExternalByteArray: | 3411 case JSObject::EXTERNAL_BYTE_ELEMENTS: |
| 3449 case kExternalShortArray: | 3412 case JSObject::EXTERNAL_SHORT_ELEMENTS: |
| 3450 case kExternalIntArray: | 3413 case JSObject::EXTERNAL_INT_ELEMENTS: |
| 3451 return true; | 3414 return true; |
| 3452 | 3415 |
| 3453 case kExternalUnsignedByteArray: | 3416 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 3454 case kExternalUnsignedShortArray: | 3417 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 3455 case kExternalUnsignedIntArray: | 3418 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 3419 case JSObject::EXTERNAL_PIXEL_ELEMENTS: |
| 3456 return false; | 3420 return false; |
| 3457 | 3421 |
| 3458 default: | 3422 case JSObject::EXTERNAL_FLOAT_ELEMENTS: |
| 3423 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: |
| 3424 case JSObject::FAST_ELEMENTS: |
| 3425 case JSObject::FAST_DOUBLE_ELEMENTS: |
| 3426 case JSObject::DICTIONARY_ELEMENTS: |
| 3459 UNREACHABLE(); | 3427 UNREACHABLE(); |
| 3460 return false; | 3428 return false; |
| 3461 } | 3429 } |
| 3430 return false; |
| 3462 } | 3431 } |
| 3463 | 3432 |
| 3464 | 3433 |
| 3465 void KeyedLoadStubCompiler::GenerateLoadExternalArray( | 3434 void KeyedLoadStubCompiler::GenerateLoadExternalArray( |
| 3466 MacroAssembler* masm, | 3435 MacroAssembler* masm, |
| 3467 ExternalArrayType array_type) { | 3436 JSObject::ElementsKind elements_kind) { |
| 3468 // ---------- S t a t e -------------- | 3437 // ---------- S t a t e -------------- |
| 3469 // -- ra : return address | 3438 // -- ra : return address |
| 3470 // -- a0 : key | 3439 // -- a0 : key |
| 3471 // -- a1 : receiver | 3440 // -- a1 : receiver |
| 3472 // ----------------------------------- | 3441 // ----------------------------------- |
| 3473 Label miss_force_generic, slow, failed_allocation; | 3442 Label miss_force_generic, slow, failed_allocation; |
| 3474 | 3443 |
| 3475 Register key = a0; | 3444 Register key = a0; |
| 3476 Register receiver = a1; | 3445 Register receiver = a1; |
| 3477 | 3446 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3491 __ Branch(&miss_force_generic, Uless, t1, Operand(t2)); | 3460 __ Branch(&miss_force_generic, Uless, t1, Operand(t2)); |
| 3492 | 3461 |
| 3493 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); | 3462 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); |
| 3494 // a3: base pointer of external storage | 3463 // a3: base pointer of external storage |
| 3495 | 3464 |
| 3496 // We are not untagging smi key and instead work with it | 3465 // We are not untagging smi key and instead work with it |
| 3497 // as if it was premultiplied by 2. | 3466 // as if it was premultiplied by 2. |
| 3498 ASSERT((kSmiTag == 0) && (kSmiTagSize == 1)); | 3467 ASSERT((kSmiTag == 0) && (kSmiTagSize == 1)); |
| 3499 | 3468 |
| 3500 Register value = a2; | 3469 Register value = a2; |
| 3501 switch (array_type) { | 3470 switch (elements_kind) { |
| 3502 case kExternalByteArray: | 3471 case JSObject::EXTERNAL_BYTE_ELEMENTS: |
| 3503 __ srl(t2, key, 1); | 3472 __ srl(t2, key, 1); |
| 3504 __ addu(t3, a3, t2); | 3473 __ addu(t3, a3, t2); |
| 3505 __ lb(value, MemOperand(t3, 0)); | 3474 __ lb(value, MemOperand(t3, 0)); |
| 3506 break; | 3475 break; |
| 3507 case kExternalPixelArray: | 3476 case JSObject::EXTERNAL_PIXEL_ELEMENTS: |
| 3508 case kExternalUnsignedByteArray: | 3477 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 3509 __ srl(t2, key, 1); | 3478 __ srl(t2, key, 1); |
| 3510 __ addu(t3, a3, t2); | 3479 __ addu(t3, a3, t2); |
| 3511 __ lbu(value, MemOperand(t3, 0)); | 3480 __ lbu(value, MemOperand(t3, 0)); |
| 3512 break; | 3481 break; |
| 3513 case kExternalShortArray: | 3482 case JSObject::EXTERNAL_SHORT_ELEMENTS: |
| 3514 __ addu(t3, a3, key); | 3483 __ addu(t3, a3, key); |
| 3515 __ lh(value, MemOperand(t3, 0)); | 3484 __ lh(value, MemOperand(t3, 0)); |
| 3516 break; | 3485 break; |
| 3517 case kExternalUnsignedShortArray: | 3486 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 3518 __ addu(t3, a3, key); | 3487 __ addu(t3, a3, key); |
| 3519 __ lhu(value, MemOperand(t3, 0)); | 3488 __ lhu(value, MemOperand(t3, 0)); |
| 3520 break; | 3489 break; |
| 3521 case kExternalIntArray: | 3490 case JSObject::EXTERNAL_INT_ELEMENTS: |
| 3522 case kExternalUnsignedIntArray: | 3491 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 3523 __ sll(t2, key, 1); | 3492 __ sll(t2, key, 1); |
| 3524 __ addu(t3, a3, t2); | 3493 __ addu(t3, a3, t2); |
| 3525 __ lw(value, MemOperand(t3, 0)); | 3494 __ lw(value, MemOperand(t3, 0)); |
| 3526 break; | 3495 break; |
| 3527 case kExternalFloatArray: | 3496 case JSObject::EXTERNAL_FLOAT_ELEMENTS: |
| 3528 __ sll(t3, t2, 2); | 3497 __ sll(t3, t2, 2); |
| 3529 __ addu(t3, a3, t3); | 3498 __ addu(t3, a3, t3); |
| 3530 if (CpuFeatures::IsSupported(FPU)) { | 3499 if (CpuFeatures::IsSupported(FPU)) { |
| 3531 CpuFeatures::Scope scope(FPU); | 3500 CpuFeatures::Scope scope(FPU); |
| 3532 __ lwc1(f0, MemOperand(t3, 0)); | 3501 __ lwc1(f0, MemOperand(t3, 0)); |
| 3533 } else { | 3502 } else { |
| 3534 __ lw(value, MemOperand(t3, 0)); | 3503 __ lw(value, MemOperand(t3, 0)); |
| 3535 } | 3504 } |
| 3536 break; | 3505 break; |
| 3537 case kExternalDoubleArray: | 3506 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: |
| 3538 __ sll(t2, key, 2); | 3507 __ sll(t2, key, 2); |
| 3539 __ addu(t3, a3, t2); | 3508 __ addu(t3, a3, t2); |
| 3540 if (CpuFeatures::IsSupported(FPU)) { | 3509 if (CpuFeatures::IsSupported(FPU)) { |
| 3541 CpuFeatures::Scope scope(FPU); | 3510 CpuFeatures::Scope scope(FPU); |
| 3542 __ ldc1(f0, MemOperand(t3, 0)); | 3511 __ ldc1(f0, MemOperand(t3, 0)); |
| 3543 } else { | 3512 } else { |
| 3544 // t3: pointer to the beginning of the double we want to load. | 3513 // t3: pointer to the beginning of the double we want to load. |
| 3545 __ lw(a2, MemOperand(t3, 0)); | 3514 __ lw(a2, MemOperand(t3, 0)); |
| 3546 __ lw(a3, MemOperand(t3, Register::kSizeInBytes)); | 3515 __ lw(a3, MemOperand(t3, Register::kSizeInBytes)); |
| 3547 } | 3516 } |
| 3548 break; | 3517 break; |
| 3549 default: | 3518 case JSObject::FAST_ELEMENTS: |
| 3519 case JSObject::FAST_DOUBLE_ELEMENTS: |
| 3520 case JSObject::DICTIONARY_ELEMENTS: |
| 3550 UNREACHABLE(); | 3521 UNREACHABLE(); |
| 3551 break; | 3522 break; |
| 3552 } | 3523 } |
| 3553 | 3524 |
| 3554 // For integer array types: | 3525 // For integer array types: |
| 3555 // a2: value | 3526 // a2: value |
| 3556 // For float array type: | 3527 // For float array type: |
| 3557 // f0: value (if FPU is supported) | 3528 // f0: value (if FPU is supported) |
| 3558 // a2: value (if FPU is not supported) | 3529 // a2: value (if FPU is not supported) |
| 3559 // For double array type: | 3530 // For double array type: |
| 3560 // f0: value (if FPU is supported) | 3531 // f0: value (if FPU is supported) |
| 3561 // a2/a3: value (if FPU is not supported) | 3532 // a2/a3: value (if FPU is not supported) |
| 3562 | 3533 |
| 3563 if (array_type == kExternalIntArray) { | 3534 if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) { |
| 3564 // For the Int and UnsignedInt array types, we need to see whether | 3535 // For the Int and UnsignedInt array types, we need to see whether |
| 3565 // the value can be represented in a Smi. If not, we need to convert | 3536 // the value can be represented in a Smi. If not, we need to convert |
| 3566 // it to a HeapNumber. | 3537 // it to a HeapNumber. |
| 3567 Label box_int; | 3538 Label box_int; |
| 3568 __ Subu(t3, value, Operand(0xC0000000)); // Non-smi value gives neg result. | 3539 __ Subu(t3, value, Operand(0xC0000000)); // Non-smi value gives neg result. |
| 3569 __ Branch(&box_int, lt, t3, Operand(zero_reg)); | 3540 __ Branch(&box_int, lt, t3, Operand(zero_reg)); |
| 3570 // Tag integer as smi and return it. | 3541 // Tag integer as smi and return it. |
| 3571 __ sll(v0, value, kSmiTagSize); | 3542 __ sll(v0, value, kSmiTagSize); |
| 3572 __ Ret(); | 3543 __ Ret(); |
| 3573 | 3544 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3595 dest, | 3566 dest, |
| 3596 f0, | 3567 f0, |
| 3597 dst1, | 3568 dst1, |
| 3598 dst2, | 3569 dst2, |
| 3599 t1, | 3570 t1, |
| 3600 f2); | 3571 f2); |
| 3601 __ sw(dst1, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); | 3572 __ sw(dst1, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); |
| 3602 __ sw(dst2, FieldMemOperand(v0, HeapNumber::kExponentOffset)); | 3573 __ sw(dst2, FieldMemOperand(v0, HeapNumber::kExponentOffset)); |
| 3603 __ Ret(); | 3574 __ Ret(); |
| 3604 } | 3575 } |
| 3605 } else if (array_type == kExternalUnsignedIntArray) { | 3576 } else if (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
| 3606 // The test is different for unsigned int values. Since we need | 3577 // The test is different for unsigned int values. Since we need |
| 3607 // the value to be in the range of a positive smi, we can't | 3578 // the value to be in the range of a positive smi, we can't |
| 3608 // handle either of the top two bits being set in the value. | 3579 // handle either of the top two bits being set in the value. |
| 3609 if (CpuFeatures::IsSupported(FPU)) { | 3580 if (CpuFeatures::IsSupported(FPU)) { |
| 3610 CpuFeatures::Scope scope(FPU); | 3581 CpuFeatures::Scope scope(FPU); |
| 3611 Label pl_box_int; | 3582 Label pl_box_int; |
| 3612 __ And(t2, value, Operand(0xC0000000)); | 3583 __ And(t2, value, Operand(0xC0000000)); |
| 3613 __ Branch(&pl_box_int, ne, t2, Operand(zero_reg)); | 3584 __ Branch(&pl_box_int, ne, t2, Operand(zero_reg)); |
| 3614 | 3585 |
| 3615 // It can fit in an Smi. | 3586 // It can fit in an Smi. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3666 // space. | 3637 // space. |
| 3667 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex); | 3638 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex); |
| 3668 __ AllocateHeapNumber(t2, t3, t5, t6, &slow); | 3639 __ AllocateHeapNumber(t2, t3, t5, t6, &slow); |
| 3669 | 3640 |
| 3670 __ sw(hiword, FieldMemOperand(t2, HeapNumber::kExponentOffset)); | 3641 __ sw(hiword, FieldMemOperand(t2, HeapNumber::kExponentOffset)); |
| 3671 __ sw(loword, FieldMemOperand(t2, HeapNumber::kMantissaOffset)); | 3642 __ sw(loword, FieldMemOperand(t2, HeapNumber::kMantissaOffset)); |
| 3672 | 3643 |
| 3673 __ mov(v0, t2); | 3644 __ mov(v0, t2); |
| 3674 __ Ret(); | 3645 __ Ret(); |
| 3675 } | 3646 } |
| 3676 } else if (array_type == kExternalFloatArray) { | 3647 } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { |
| 3677 // For the floating-point array type, we need to always allocate a | 3648 // For the floating-point array type, we need to always allocate a |
| 3678 // HeapNumber. | 3649 // HeapNumber. |
| 3679 if (CpuFeatures::IsSupported(FPU)) { | 3650 if (CpuFeatures::IsSupported(FPU)) { |
| 3680 CpuFeatures::Scope scope(FPU); | 3651 CpuFeatures::Scope scope(FPU); |
| 3681 // Allocate a HeapNumber for the result. Don't use a0 and a1 as | 3652 // Allocate a HeapNumber for the result. Don't use a0 and a1 as |
| 3682 // AllocateHeapNumber clobbers all registers - also when jumping due to | 3653 // AllocateHeapNumber clobbers all registers - also when jumping due to |
| 3683 // exhausted young space. | 3654 // exhausted young space. |
| 3684 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex); | 3655 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex); |
| 3685 __ AllocateHeapNumber(v0, t3, t5, t6, &slow); | 3656 __ AllocateHeapNumber(v0, t3, t5, t6, &slow); |
| 3686 // The float (single) value is already in fpu reg f0 (if we use float). | 3657 // The float (single) value is already in fpu reg f0 (if we use float). |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3733 | 3704 |
| 3734 __ srl(t0, t4, kMantissaShiftForHiWord); | 3705 __ srl(t0, t4, kMantissaShiftForHiWord); |
| 3735 __ or_(a2, a2, t0); | 3706 __ or_(a2, a2, t0); |
| 3736 __ sll(a0, t4, kMantissaShiftForLoWord); | 3707 __ sll(a0, t4, kMantissaShiftForLoWord); |
| 3737 | 3708 |
| 3738 __ sw(a2, FieldMemOperand(v0, HeapNumber::kExponentOffset)); | 3709 __ sw(a2, FieldMemOperand(v0, HeapNumber::kExponentOffset)); |
| 3739 __ sw(a0, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); | 3710 __ sw(a0, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); |
| 3740 __ Ret(); | 3711 __ Ret(); |
| 3741 } | 3712 } |
| 3742 | 3713 |
| 3743 } else if (array_type == kExternalDoubleArray) { | 3714 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { |
| 3744 if (CpuFeatures::IsSupported(FPU)) { | 3715 if (CpuFeatures::IsSupported(FPU)) { |
| 3745 CpuFeatures::Scope scope(FPU); | 3716 CpuFeatures::Scope scope(FPU); |
| 3746 // Allocate a HeapNumber for the result. Don't use a0 and a1 as | 3717 // Allocate a HeapNumber for the result. Don't use a0 and a1 as |
| 3747 // AllocateHeapNumber clobbers all registers - also when jumping due to | 3718 // AllocateHeapNumber clobbers all registers - also when jumping due to |
| 3748 // exhausted young space. | 3719 // exhausted young space. |
| 3749 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex); | 3720 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex); |
| 3750 __ AllocateHeapNumber(v0, t3, t5, t6, &slow); | 3721 __ AllocateHeapNumber(v0, t3, t5, t6, &slow); |
| 3751 // The double value is already in f0 | 3722 // The double value is already in f0 |
| 3752 __ sdc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset)); | 3723 __ sdc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset)); |
| 3753 __ Ret(); | 3724 __ Ret(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3787 | 3758 |
| 3788 __ bind(&miss_force_generic); | 3759 __ bind(&miss_force_generic); |
| 3789 Code* stub = masm->isolate()->builtins()->builtin( | 3760 Code* stub = masm->isolate()->builtins()->builtin( |
| 3790 Builtins::kKeyedLoadIC_MissForceGeneric); | 3761 Builtins::kKeyedLoadIC_MissForceGeneric); |
| 3791 __ Jump(Handle<Code>(stub), RelocInfo::CODE_TARGET); | 3762 __ Jump(Handle<Code>(stub), RelocInfo::CODE_TARGET); |
| 3792 } | 3763 } |
| 3793 | 3764 |
| 3794 | 3765 |
| 3795 void KeyedStoreStubCompiler::GenerateStoreExternalArray( | 3766 void KeyedStoreStubCompiler::GenerateStoreExternalArray( |
| 3796 MacroAssembler* masm, | 3767 MacroAssembler* masm, |
| 3797 ExternalArrayType array_type) { | 3768 JSObject::ElementsKind elements_kind) { |
| 3798 // ---------- S t a t e -------------- | 3769 // ---------- S t a t e -------------- |
| 3799 // -- a0 : value | 3770 // -- a0 : value |
| 3800 // -- a1 : key | 3771 // -- a1 : key |
| 3801 // -- a2 : receiver | 3772 // -- a2 : receiver |
| 3802 // -- ra : return address | 3773 // -- ra : return address |
| 3803 // ----------------------------------- | 3774 // ----------------------------------- |
| 3804 | 3775 |
| 3805 Label slow, check_heap_number, miss_force_generic; | 3776 Label slow, check_heap_number, miss_force_generic; |
| 3806 | 3777 |
| 3807 // Register usage. | 3778 // Register usage. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3822 __ SmiUntag(t0, key); | 3793 __ SmiUntag(t0, key); |
| 3823 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset)); | 3794 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset)); |
| 3824 // Unsigned comparison catches both negative and too-large values. | 3795 // Unsigned comparison catches both negative and too-large values. |
| 3825 __ Branch(&miss_force_generic, Ugreater_equal, t0, Operand(t1)); | 3796 __ Branch(&miss_force_generic, Ugreater_equal, t0, Operand(t1)); |
| 3826 | 3797 |
| 3827 // Handle both smis and HeapNumbers in the fast path. Go to the | 3798 // Handle both smis and HeapNumbers in the fast path. Go to the |
| 3828 // runtime for all other kinds of values. | 3799 // runtime for all other kinds of values. |
| 3829 // a3: external array. | 3800 // a3: external array. |
| 3830 // t0: key (integer). | 3801 // t0: key (integer). |
| 3831 | 3802 |
| 3832 if (array_type == kExternalPixelArray) { | 3803 if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) { |
| 3833 // Double to pixel conversion is only implemented in the runtime for now. | 3804 // Double to pixel conversion is only implemented in the runtime for now. |
| 3834 __ JumpIfNotSmi(value, &slow); | 3805 __ JumpIfNotSmi(value, &slow); |
| 3835 } else { | 3806 } else { |
| 3836 __ JumpIfNotSmi(value, &check_heap_number); | 3807 __ JumpIfNotSmi(value, &check_heap_number); |
| 3837 } | 3808 } |
| 3838 __ SmiUntag(t1, value); | 3809 __ SmiUntag(t1, value); |
| 3839 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); | 3810 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); |
| 3840 | 3811 |
| 3841 // a3: base pointer of external storage. | 3812 // a3: base pointer of external storage. |
| 3842 // t0: key (integer). | 3813 // t0: key (integer). |
| 3843 // t1: value (integer). | 3814 // t1: value (integer). |
| 3844 | 3815 |
| 3845 switch (array_type) { | 3816 switch (elements_kind) { |
| 3846 case kExternalPixelArray: { | 3817 case JSObject::EXTERNAL_PIXEL_ELEMENTS: { |
| 3847 // Clamp the value to [0..255]. | 3818 // Clamp the value to [0..255]. |
| 3848 // v0 is used as a scratch register here. | 3819 // v0 is used as a scratch register here. |
| 3849 Label done; | 3820 Label done; |
| 3850 __ li(v0, Operand(255)); | 3821 __ li(v0, Operand(255)); |
| 3851 // Normal branch: nop in delay slot. | 3822 // Normal branch: nop in delay slot. |
| 3852 __ Branch(&done, gt, t1, Operand(v0)); | 3823 __ Branch(&done, gt, t1, Operand(v0)); |
| 3853 // Use delay slot in this branch. | 3824 // Use delay slot in this branch. |
| 3854 __ Branch(USE_DELAY_SLOT, &done, lt, t1, Operand(zero_reg)); | 3825 __ Branch(USE_DELAY_SLOT, &done, lt, t1, Operand(zero_reg)); |
| 3855 __ mov(v0, zero_reg); // In delay slot. | 3826 __ mov(v0, zero_reg); // In delay slot. |
| 3856 __ mov(v0, t1); // Value is in range 0..255. | 3827 __ mov(v0, t1); // Value is in range 0..255. |
| 3857 __ bind(&done); | 3828 __ bind(&done); |
| 3858 __ mov(t1, v0); | 3829 __ mov(t1, v0); |
| 3859 __ addu(t8, a3, t0); | 3830 __ addu(t8, a3, t0); |
| 3860 __ sb(t1, MemOperand(t8, 0)); | 3831 __ sb(t1, MemOperand(t8, 0)); |
| 3861 } | 3832 } |
| 3862 break; | 3833 break; |
| 3863 case kExternalByteArray: | 3834 case JSObject::EXTERNAL_BYTE_ELEMENTS: |
| 3864 case kExternalUnsignedByteArray: | 3835 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 3865 __ addu(t8, a3, t0); | 3836 __ addu(t8, a3, t0); |
| 3866 __ sb(t1, MemOperand(t8, 0)); | 3837 __ sb(t1, MemOperand(t8, 0)); |
| 3867 break; | 3838 break; |
| 3868 case kExternalShortArray: | 3839 case JSObject::EXTERNAL_SHORT_ELEMENTS: |
| 3869 case kExternalUnsignedShortArray: | 3840 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 3870 __ sll(t8, t0, 1); | 3841 __ sll(t8, t0, 1); |
| 3871 __ addu(t8, a3, t8); | 3842 __ addu(t8, a3, t8); |
| 3872 __ sh(t1, MemOperand(t8, 0)); | 3843 __ sh(t1, MemOperand(t8, 0)); |
| 3873 break; | 3844 break; |
| 3874 case kExternalIntArray: | 3845 case JSObject::EXTERNAL_INT_ELEMENTS: |
| 3875 case kExternalUnsignedIntArray: | 3846 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 3876 __ sll(t8, t0, 2); | 3847 __ sll(t8, t0, 2); |
| 3877 __ addu(t8, a3, t8); | 3848 __ addu(t8, a3, t8); |
| 3878 __ sw(t1, MemOperand(t8, 0)); | 3849 __ sw(t1, MemOperand(t8, 0)); |
| 3879 break; | 3850 break; |
| 3880 case kExternalFloatArray: | 3851 case JSObject::EXTERNAL_FLOAT_ELEMENTS: |
| 3881 // Perform int-to-float conversion and store to memory. | 3852 // Perform int-to-float conversion and store to memory. |
| 3882 StoreIntAsFloat(masm, a3, t0, t1, t2, t3, t4); | 3853 StoreIntAsFloat(masm, a3, t0, t1, t2, t3, t4); |
| 3883 break; | 3854 break; |
| 3884 case kExternalDoubleArray: | 3855 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: |
| 3885 __ sll(t8, t0, 3); | 3856 __ sll(t8, t0, 3); |
| 3886 __ addu(a3, a3, t8); | 3857 __ addu(a3, a3, t8); |
| 3887 // a3: effective address of the double element | 3858 // a3: effective address of the double element |
| 3888 FloatingPointHelper::Destination destination; | 3859 FloatingPointHelper::Destination destination; |
| 3889 if (CpuFeatures::IsSupported(FPU)) { | 3860 if (CpuFeatures::IsSupported(FPU)) { |
| 3890 destination = FloatingPointHelper::kFPURegisters; | 3861 destination = FloatingPointHelper::kFPURegisters; |
| 3891 } else { | 3862 } else { |
| 3892 destination = FloatingPointHelper::kCoreRegisters; | 3863 destination = FloatingPointHelper::kCoreRegisters; |
| 3893 } | 3864 } |
| 3894 FloatingPointHelper::ConvertIntToDouble( | 3865 FloatingPointHelper::ConvertIntToDouble( |
| 3895 masm, t1, destination, | 3866 masm, t1, destination, |
| 3896 f0, t2, t3, // These are: double_dst, dst1, dst2. | 3867 f0, t2, t3, // These are: double_dst, dst1, dst2. |
| 3897 t0, f2); // These are: scratch2, single_scratch. | 3868 t0, f2); // These are: scratch2, single_scratch. |
| 3898 if (destination == FloatingPointHelper::kFPURegisters) { | 3869 if (destination == FloatingPointHelper::kFPURegisters) { |
| 3899 CpuFeatures::Scope scope(FPU); | 3870 CpuFeatures::Scope scope(FPU); |
| 3900 __ sdc1(f0, MemOperand(a3, 0)); | 3871 __ sdc1(f0, MemOperand(a3, 0)); |
| 3901 } else { | 3872 } else { |
| 3902 __ sw(t2, MemOperand(a3, 0)); | 3873 __ sw(t2, MemOperand(a3, 0)); |
| 3903 __ sw(t3, MemOperand(a3, Register::kSizeInBytes)); | 3874 __ sw(t3, MemOperand(a3, Register::kSizeInBytes)); |
| 3904 } | 3875 } |
| 3905 break; | 3876 break; |
| 3906 default: | 3877 case JSObject::FAST_ELEMENTS: |
| 3878 case JSObject::FAST_DOUBLE_ELEMENTS: |
| 3879 case JSObject::DICTIONARY_ELEMENTS: |
| 3907 UNREACHABLE(); | 3880 UNREACHABLE(); |
| 3908 break; | 3881 break; |
| 3909 } | 3882 } |
| 3910 | 3883 |
| 3911 // Entry registers are intact, a0 holds the value which is the return value. | 3884 // Entry registers are intact, a0 holds the value which is the return value. |
| 3912 __ mov(v0, value); | 3885 __ mov(v0, value); |
| 3913 __ Ret(); | 3886 __ Ret(); |
| 3914 | 3887 |
| 3915 if (array_type != kExternalPixelArray) { | 3888 if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) { |
| 3916 // a3: external array. | 3889 // a3: external array. |
| 3917 // t0: index (integer). | 3890 // t0: index (integer). |
| 3918 __ bind(&check_heap_number); | 3891 __ bind(&check_heap_number); |
| 3919 __ GetObjectType(value, t1, t2); | 3892 __ GetObjectType(value, t1, t2); |
| 3920 __ Branch(&slow, ne, t2, Operand(HEAP_NUMBER_TYPE)); | 3893 __ Branch(&slow, ne, t2, Operand(HEAP_NUMBER_TYPE)); |
| 3921 | 3894 |
| 3922 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); | 3895 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); |
| 3923 | 3896 |
| 3924 // a3: base pointer of external storage. | 3897 // a3: base pointer of external storage. |
| 3925 // t0: key (integer). | 3898 // t0: key (integer). |
| 3926 | 3899 |
| 3927 // The WebGL specification leaves the behavior of storing NaN and | 3900 // The WebGL specification leaves the behavior of storing NaN and |
| 3928 // +/-Infinity into integer arrays basically undefined. For more | 3901 // +/-Infinity into integer arrays basically undefined. For more |
| 3929 // reproducible behavior, convert these to zero. | 3902 // reproducible behavior, convert these to zero. |
| 3930 | 3903 |
| 3931 if (CpuFeatures::IsSupported(FPU)) { | 3904 if (CpuFeatures::IsSupported(FPU)) { |
| 3932 CpuFeatures::Scope scope(FPU); | 3905 CpuFeatures::Scope scope(FPU); |
| 3933 | 3906 |
| 3934 __ ldc1(f0, FieldMemOperand(a0, HeapNumber::kValueOffset)); | 3907 __ ldc1(f0, FieldMemOperand(a0, HeapNumber::kValueOffset)); |
| 3935 | 3908 |
| 3936 if (array_type == kExternalFloatArray) { | 3909 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { |
| 3937 __ cvt_s_d(f0, f0); | 3910 __ cvt_s_d(f0, f0); |
| 3938 __ sll(t8, t0, 2); | 3911 __ sll(t8, t0, 2); |
| 3939 __ addu(t8, a3, t8); | 3912 __ addu(t8, a3, t8); |
| 3940 __ swc1(f0, MemOperand(t8, 0)); | 3913 __ swc1(f0, MemOperand(t8, 0)); |
| 3941 } else if (array_type == kExternalDoubleArray) { | 3914 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { |
| 3942 __ sll(t8, t0, 3); | 3915 __ sll(t8, t0, 3); |
| 3943 __ addu(t8, a3, t8); | 3916 __ addu(t8, a3, t8); |
| 3944 __ sdc1(f0, MemOperand(t8, 0)); | 3917 __ sdc1(f0, MemOperand(t8, 0)); |
| 3945 } else { | 3918 } else { |
| 3946 __ EmitECMATruncate(t3, f0, f2, t2, t1, t5); | 3919 __ EmitECMATruncate(t3, f0, f2, t2, t1, t5); |
| 3947 | 3920 |
| 3948 switch (array_type) { | 3921 switch (elements_kind) { |
| 3949 case kExternalByteArray: | 3922 case JSObject::EXTERNAL_BYTE_ELEMENTS: |
| 3950 case kExternalUnsignedByteArray: | 3923 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 3951 __ addu(t8, a3, t0); | 3924 __ addu(t8, a3, t0); |
| 3952 __ sb(t3, MemOperand(t8, 0)); | 3925 __ sb(t3, MemOperand(t8, 0)); |
| 3953 break; | 3926 break; |
| 3954 case kExternalShortArray: | 3927 case JSObject::EXTERNAL_SHORT_ELEMENTS: |
| 3955 case kExternalUnsignedShortArray: | 3928 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 3956 __ sll(t8, t0, 1); | 3929 __ sll(t8, t0, 1); |
| 3957 __ addu(t8, a3, t8); | 3930 __ addu(t8, a3, t8); |
| 3958 __ sh(t3, MemOperand(t8, 0)); | 3931 __ sh(t3, MemOperand(t8, 0)); |
| 3959 break; | 3932 break; |
| 3960 case kExternalIntArray: | 3933 case JSObject::EXTERNAL_INT_ELEMENTS: |
| 3961 case kExternalUnsignedIntArray: | 3934 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 3962 __ sll(t8, t0, 2); | 3935 __ sll(t8, t0, 2); |
| 3963 __ addu(t8, a3, t8); | 3936 __ addu(t8, a3, t8); |
| 3964 __ sw(t3, MemOperand(t8, 0)); | 3937 __ sw(t3, MemOperand(t8, 0)); |
| 3965 break; | 3938 break; |
| 3966 default: | 3939 case JSObject::EXTERNAL_PIXEL_ELEMENTS: |
| 3940 case JSObject::EXTERNAL_FLOAT_ELEMENTS: |
| 3941 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: |
| 3942 case JSObject::FAST_ELEMENTS: |
| 3943 case JSObject::FAST_DOUBLE_ELEMENTS: |
| 3944 case JSObject::DICTIONARY_ELEMENTS: |
| 3967 UNREACHABLE(); | 3945 UNREACHABLE(); |
| 3968 break; | 3946 break; |
| 3969 } | 3947 } |
| 3970 } | 3948 } |
| 3971 | 3949 |
| 3972 // Entry registers are intact, a0 holds the value | 3950 // Entry registers are intact, a0 holds the value |
| 3973 // which is the return value. | 3951 // which is the return value. |
| 3974 __ mov(v0, value); | 3952 __ mov(v0, value); |
| 3975 __ Ret(); | 3953 __ Ret(); |
| 3976 } else { | 3954 } else { |
| 3977 // FPU is not available, do manual conversions. | 3955 // FPU is not available, do manual conversions. |
| 3978 | 3956 |
| 3979 __ lw(t3, FieldMemOperand(value, HeapNumber::kExponentOffset)); | 3957 __ lw(t3, FieldMemOperand(value, HeapNumber::kExponentOffset)); |
| 3980 __ lw(t4, FieldMemOperand(value, HeapNumber::kMantissaOffset)); | 3958 __ lw(t4, FieldMemOperand(value, HeapNumber::kMantissaOffset)); |
| 3981 | 3959 |
| 3982 if (array_type == kExternalFloatArray) { | 3960 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { |
| 3983 Label done, nan_or_infinity_or_zero; | 3961 Label done, nan_or_infinity_or_zero; |
| 3984 static const int kMantissaInHiWordShift = | 3962 static const int kMantissaInHiWordShift = |
| 3985 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord; | 3963 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord; |
| 3986 | 3964 |
| 3987 static const int kMantissaInLoWordShift = | 3965 static const int kMantissaInLoWordShift = |
| 3988 kBitsPerInt - kMantissaInHiWordShift; | 3966 kBitsPerInt - kMantissaInHiWordShift; |
| 3989 | 3967 |
| 3990 // Test for all special exponent values: zeros, subnormal numbers, NaNs | 3968 // Test for all special exponent values: zeros, subnormal numbers, NaNs |
| 3991 // and infinities. All these should be converted to 0. | 3969 // and infinities. All these should be converted to 0. |
| 3992 __ li(t5, HeapNumber::kExponentMask); | 3970 __ li(t5, HeapNumber::kExponentMask); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4037 | 4015 |
| 4038 __ bind(&nan_or_infinity_or_zero); | 4016 __ bind(&nan_or_infinity_or_zero); |
| 4039 __ And(t7, t3, Operand(HeapNumber::kSignMask)); | 4017 __ And(t7, t3, Operand(HeapNumber::kSignMask)); |
| 4040 __ And(t3, t3, Operand(HeapNumber::kMantissaMask)); | 4018 __ And(t3, t3, Operand(HeapNumber::kMantissaMask)); |
| 4041 __ or_(t6, t6, t7); | 4019 __ or_(t6, t6, t7); |
| 4042 __ sll(t3, t3, kMantissaInHiWordShift); | 4020 __ sll(t3, t3, kMantissaInHiWordShift); |
| 4043 __ or_(t6, t6, t3); | 4021 __ or_(t6, t6, t3); |
| 4044 __ srl(t4, t4, kMantissaInLoWordShift); | 4022 __ srl(t4, t4, kMantissaInLoWordShift); |
| 4045 __ or_(t3, t6, t4); | 4023 __ or_(t3, t6, t4); |
| 4046 __ Branch(&done); | 4024 __ Branch(&done); |
| 4047 } else if (array_type == kExternalDoubleArray) { | 4025 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { |
| 4048 __ sll(t8, t0, 3); | 4026 __ sll(t8, t0, 3); |
| 4049 __ addu(t8, a3, t8); | 4027 __ addu(t8, a3, t8); |
| 4050 // t8: effective address of destination element. | 4028 // t8: effective address of destination element. |
| 4051 __ sw(t4, MemOperand(t8, 0)); | 4029 __ sw(t4, MemOperand(t8, 0)); |
| 4052 __ sw(t3, MemOperand(t8, Register::kSizeInBytes)); | 4030 __ sw(t3, MemOperand(t8, Register::kSizeInBytes)); |
| 4053 __ Ret(); | 4031 __ Ret(); |
| 4054 } else { | 4032 } else { |
| 4055 bool is_signed_type = IsElementTypeSigned(array_type); | 4033 bool is_signed_type = IsElementTypeSigned(elements_kind); |
| 4056 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt; | 4034 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt; |
| 4057 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000; | 4035 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000; |
| 4058 | 4036 |
| 4059 Label done, sign; | 4037 Label done, sign; |
| 4060 | 4038 |
| 4061 // Test for all special exponent values: zeros, subnormal numbers, NaNs | 4039 // Test for all special exponent values: zeros, subnormal numbers, NaNs |
| 4062 // and infinities. All these should be converted to 0. | 4040 // and infinities. All these should be converted to 0. |
| 4063 __ li(t5, HeapNumber::kExponentMask); | 4041 __ li(t5, HeapNumber::kExponentMask); |
| 4064 __ and_(t6, t3, t5); | 4042 __ and_(t6, t3, t5); |
| 4065 __ movz(t3, zero_reg, t6); // Only if t6 is equal to zero. | 4043 __ movz(t3, zero_reg, t6); // Only if t6 is equal to zero. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4102 __ or_(t3, t3, t4); | 4080 __ or_(t3, t3, t4); |
| 4103 | 4081 |
| 4104 __ bind(&sign); | 4082 __ bind(&sign); |
| 4105 __ subu(t2, t3, zero_reg); | 4083 __ subu(t2, t3, zero_reg); |
| 4106 __ movz(t3, t2, t5); // Only if t5 is zero. | 4084 __ movz(t3, t2, t5); // Only if t5 is zero. |
| 4107 | 4085 |
| 4108 __ bind(&done); | 4086 __ bind(&done); |
| 4109 | 4087 |
| 4110 // Result is in t3. | 4088 // Result is in t3. |
| 4111 // This switch block should be exactly the same as above (FPU mode). | 4089 // This switch block should be exactly the same as above (FPU mode). |
| 4112 switch (array_type) { | 4090 switch (elements_kind) { |
| 4113 case kExternalByteArray: | 4091 case JSObject::EXTERNAL_BYTE_ELEMENTS: |
| 4114 case kExternalUnsignedByteArray: | 4092 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 4115 __ addu(t8, a3, t0); | 4093 __ addu(t8, a3, t0); |
| 4116 __ sb(t3, MemOperand(t8, 0)); | 4094 __ sb(t3, MemOperand(t8, 0)); |
| 4117 break; | 4095 break; |
| 4118 case kExternalShortArray: | 4096 case JSObject::EXTERNAL_SHORT_ELEMENTS: |
| 4119 case kExternalUnsignedShortArray: | 4097 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 4120 __ sll(t8, t0, 1); | 4098 __ sll(t8, t0, 1); |
| 4121 __ addu(t8, a3, t8); | 4099 __ addu(t8, a3, t8); |
| 4122 __ sh(t3, MemOperand(t8, 0)); | 4100 __ sh(t3, MemOperand(t8, 0)); |
| 4123 break; | 4101 break; |
| 4124 case kExternalIntArray: | 4102 case JSObject::EXTERNAL_INT_ELEMENTS: |
| 4125 case kExternalUnsignedIntArray: | 4103 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 4126 __ sll(t8, t0, 2); | 4104 __ sll(t8, t0, 2); |
| 4127 __ addu(t8, a3, t8); | 4105 __ addu(t8, a3, t8); |
| 4128 __ sw(t3, MemOperand(t8, 0)); | 4106 __ sw(t3, MemOperand(t8, 0)); |
| 4129 break; | 4107 break; |
| 4130 default: | 4108 case JSObject::EXTERNAL_PIXEL_ELEMENTS: |
| 4109 case JSObject::EXTERNAL_FLOAT_ELEMENTS: |
| 4110 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: |
| 4111 case JSObject::FAST_ELEMENTS: |
| 4112 case JSObject::FAST_DOUBLE_ELEMENTS: |
| 4113 case JSObject::DICTIONARY_ELEMENTS: |
| 4131 UNREACHABLE(); | 4114 UNREACHABLE(); |
| 4132 break; | 4115 break; |
| 4133 } | 4116 } |
| 4134 } | 4117 } |
| 4135 } | 4118 } |
| 4136 } | 4119 } |
| 4137 | 4120 |
| 4138 // Slow case, key and receiver still in a0 and a1. | 4121 // Slow case, key and receiver still in a0 and a1. |
| 4139 __ bind(&slow); | 4122 __ bind(&slow); |
| 4140 __ IncrementCounter( | 4123 __ IncrementCounter( |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4266 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 4249 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
| 4267 __ Jump(ic, RelocInfo::CODE_TARGET); | 4250 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 4268 } | 4251 } |
| 4269 | 4252 |
| 4270 | 4253 |
| 4271 #undef __ | 4254 #undef __ |
| 4272 | 4255 |
| 4273 } } // namespace v8::internal | 4256 } } // namespace v8::internal |
| 4274 | 4257 |
| 4275 #endif // V8_TARGET_ARCH_MIPS | 4258 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |