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 4382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4393 bool is_js_array) { | 4393 bool is_js_array) { |
4394 // ----------- S t a t e ------------- | 4394 // ----------- S t a t e ------------- |
4395 // -- r0 : value | 4395 // -- r0 : value |
4396 // -- r1 : key | 4396 // -- r1 : key |
4397 // -- r2 : receiver | 4397 // -- r2 : receiver |
4398 // -- lr : return address | 4398 // -- lr : return address |
4399 // -- r3 : scratch | 4399 // -- r3 : scratch |
4400 // -- r4 : scratch | 4400 // -- r4 : scratch |
4401 // -- r5 : scratch | 4401 // -- r5 : scratch |
4402 // ----------------------------------- | 4402 // ----------------------------------- |
4403 Label miss_force_generic, smi_value, is_nan, maybe_nan, have_double_value; | 4403 Label miss_force_generic; |
4404 | 4404 |
4405 Register value_reg = r0; | 4405 Register value_reg = r0; |
4406 Register key_reg = r1; | 4406 Register key_reg = r1; |
4407 Register receiver_reg = r2; | 4407 Register receiver_reg = r2; |
4408 Register scratch = r3; | 4408 Register elements_reg = r3; |
4409 Register elements_reg = r4; | 4409 Register scratch1 = r4; |
4410 Register mantissa_reg = r5; | 4410 Register scratch2 = r5; |
4411 Register exponent_reg = r6; | 4411 Register scratch3 = r6; |
4412 Register scratch4 = r7; | 4412 Register scratch4 = r7; |
4413 | 4413 |
4414 // This stub is meant to be tail-jumped to, the receiver must already | 4414 // This stub is meant to be tail-jumped to, the receiver must already |
4415 // have been verified by the caller to not be a smi. | 4415 // have been verified by the caller to not be a smi. |
4416 __ JumpIfNotSmi(key_reg, &miss_force_generic); | 4416 __ JumpIfNotSmi(key_reg, &miss_force_generic); |
4417 | 4417 |
4418 __ ldr(elements_reg, | 4418 __ ldr(elements_reg, |
4419 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); | 4419 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
4420 | 4420 |
4421 // Check that the key is within bounds. | 4421 // Check that the key is within bounds. |
4422 if (is_js_array) { | 4422 if (is_js_array) { |
4423 __ ldr(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); | 4423 __ ldr(scratch1, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
4424 } else { | 4424 } else { |
4425 __ ldr(scratch, | 4425 __ ldr(scratch1, |
4426 FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); | 4426 FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); |
4427 } | 4427 } |
4428 // Compare smis, unsigned compare catches both negative and out-of-bound | 4428 // Compare smis, unsigned compare catches both negative and out-of-bound |
4429 // indexes. | 4429 // indexes. |
4430 __ cmp(key_reg, scratch); | 4430 __ cmp(key_reg, scratch1); |
4431 __ b(hs, &miss_force_generic); | 4431 __ b(hs, &miss_force_generic); |
4432 | 4432 |
4433 // Handle smi values specially. | 4433 __ StoreNumberToDoubleElements(value_reg, key_reg, receiver_reg, elements_reg, |
Rico
2011/10/05 08:39:19
all arguments on one line or each on separate line
| |
4434 __ JumpIfSmi(value_reg, &smi_value); | 4434 scratch1, scratch2, scratch3, scratch4, |
4435 | 4435 &miss_force_generic); |
4436 // Ensure that the object is a heap number | |
4437 __ CheckMap(value_reg, | |
4438 scratch, | |
4439 masm->isolate()->factory()->heap_number_map(), | |
4440 &miss_force_generic, | |
4441 DONT_DO_SMI_CHECK); | |
4442 | |
4443 // Check for nan: all NaN values have a value greater (signed) than 0x7ff00000 | |
4444 // in the exponent. | |
4445 __ mov(scratch, Operand(kNaNOrInfinityLowerBoundUpper32)); | |
4446 __ ldr(exponent_reg, FieldMemOperand(value_reg, HeapNumber::kExponentOffset)); | |
4447 __ cmp(exponent_reg, scratch); | |
4448 __ b(ge, &maybe_nan); | |
4449 | |
4450 __ ldr(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); | |
4451 | |
4452 __ bind(&have_double_value); | |
4453 __ add(scratch, elements_reg, | |
4454 Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize)); | |
4455 __ str(mantissa_reg, FieldMemOperand(scratch, FixedDoubleArray::kHeaderSize)); | |
4456 uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); | |
4457 __ str(exponent_reg, FieldMemOperand(scratch, offset)); | |
4458 __ Ret(); | |
4459 | |
4460 __ bind(&maybe_nan); | |
4461 // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise | |
4462 // it's an Infinity, and the non-NaN code path applies. | |
4463 __ b(gt, &is_nan); | |
4464 __ ldr(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); | |
4465 __ cmp(mantissa_reg, Operand(0)); | |
4466 __ b(eq, &have_double_value); | |
4467 __ bind(&is_nan); | |
4468 // Load canonical NaN for storing into the double array. | |
4469 uint64_t nan_int64 = BitCast<uint64_t>( | |
4470 FixedDoubleArray::canonical_not_the_hole_nan_as_double()); | |
4471 __ mov(mantissa_reg, Operand(static_cast<uint32_t>(nan_int64))); | |
4472 __ mov(exponent_reg, Operand(static_cast<uint32_t>(nan_int64 >> 32))); | |
4473 __ jmp(&have_double_value); | |
4474 | |
4475 __ bind(&smi_value); | |
4476 __ add(scratch, elements_reg, | |
4477 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | |
4478 __ add(scratch, scratch, | |
4479 Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize)); | |
4480 // scratch is now effective address of the double element | |
4481 | |
4482 FloatingPointHelper::Destination destination; | |
4483 if (CpuFeatures::IsSupported(VFP3)) { | |
4484 destination = FloatingPointHelper::kVFPRegisters; | |
4485 } else { | |
4486 destination = FloatingPointHelper::kCoreRegisters; | |
4487 } | |
4488 | |
4489 Register untagged_value = receiver_reg; | |
4490 __ SmiUntag(untagged_value, value_reg); | |
4491 FloatingPointHelper::ConvertIntToDouble( | |
4492 masm, | |
4493 untagged_value, | |
4494 destination, | |
4495 d0, | |
4496 mantissa_reg, | |
4497 exponent_reg, | |
4498 scratch4, | |
4499 s2); | |
4500 if (destination == FloatingPointHelper::kVFPRegisters) { | |
4501 CpuFeatures::Scope scope(VFP3); | |
4502 __ vstr(d0, scratch, 0); | |
4503 } else { | |
4504 __ str(mantissa_reg, MemOperand(scratch, 0)); | |
4505 __ str(exponent_reg, MemOperand(scratch, Register::kSizeInBytes)); | |
4506 } | |
4507 __ Ret(); | 4436 __ Ret(); |
4508 | 4437 |
4509 // Handle store cache miss, replacing the ic with the generic stub. | 4438 // Handle store cache miss, replacing the ic with the generic stub. |
4510 __ bind(&miss_force_generic); | 4439 __ bind(&miss_force_generic); |
4511 Handle<Code> ic = | 4440 Handle<Code> ic = |
4512 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 4441 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
4513 __ Jump(ic, RelocInfo::CODE_TARGET); | 4442 __ Jump(ic, RelocInfo::CODE_TARGET); |
4514 } | 4443 } |
4515 | 4444 |
4516 | 4445 |
4517 #undef __ | 4446 #undef __ |
4518 | 4447 |
4519 } } // namespace v8::internal | 4448 } } // namespace v8::internal |
4520 | 4449 |
4521 #endif // V8_TARGET_ARCH_ARM | 4450 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |