MIPS: port Implement ICs for FastDoubleArray loads and stores
Ported r8637 (72bd791) BUG= TEST= Review URL: http://codereview.chromium.org/7386003 Patch from Paul Lind <plind44@gmail.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8686 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
f9845f851d
commit
5df0886925
@ -3700,6 +3700,8 @@ void MacroAssembler::AssertFastElements(Register elements) {
|
|||||||
lw(elements, FieldMemOperand(elements, HeapObject::kMapOffset));
|
lw(elements, FieldMemOperand(elements, HeapObject::kMapOffset));
|
||||||
LoadRoot(at, Heap::kFixedArrayMapRootIndex);
|
LoadRoot(at, Heap::kFixedArrayMapRootIndex);
|
||||||
Branch(&ok, eq, elements, Operand(at));
|
Branch(&ok, eq, elements, Operand(at));
|
||||||
|
LoadRoot(at, Heap::kFixedDoubleArrayMapRootIndex);
|
||||||
|
Branch(&ok, eq, elements, Operand(at));
|
||||||
LoadRoot(at, Heap::kFixedCOWArrayMapRootIndex);
|
LoadRoot(at, Heap::kFixedCOWArrayMapRootIndex);
|
||||||
Branch(&ok, eq, elements, Operand(at));
|
Branch(&ok, eq, elements, Operand(at));
|
||||||
Abort("JSObject with fast elements map has slow elements");
|
Abort("JSObject with fast elements map has slow elements");
|
||||||
|
@ -4231,7 +4231,70 @@ void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) {
|
|||||||
|
|
||||||
void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
|
void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
UNIMPLEMENTED();
|
// ----------- S t a t e -------------
|
||||||
|
// -- ra : return address
|
||||||
|
// -- a0 : key
|
||||||
|
// -- a1 : receiver
|
||||||
|
// -----------------------------------
|
||||||
|
Label miss_force_generic, slow_allocate_heapnumber;
|
||||||
|
|
||||||
|
Register key_reg = a0;
|
||||||
|
Register receiver_reg = a1;
|
||||||
|
Register elements_reg = a2;
|
||||||
|
Register heap_number_reg = a2;
|
||||||
|
Register indexed_double_offset = a3;
|
||||||
|
Register scratch = t0;
|
||||||
|
Register scratch2 = t1;
|
||||||
|
Register scratch3 = t2;
|
||||||
|
Register heap_number_map = t3;
|
||||||
|
|
||||||
|
// This stub is meant to be tail-jumped to, the receiver must already
|
||||||
|
// have been verified by the caller to not be a smi.
|
||||||
|
|
||||||
|
// Check that the key is a smi.
|
||||||
|
__ JumpIfNotSmi(key_reg, &miss_force_generic);
|
||||||
|
|
||||||
|
// Get the elements array.
|
||||||
|
__ lw(elements_reg,
|
||||||
|
FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
|
||||||
|
|
||||||
|
// Check that the key is within bounds.
|
||||||
|
__ lw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
|
||||||
|
__ Branch(&miss_force_generic, hs, key_reg, Operand(scratch));
|
||||||
|
|
||||||
|
// Load the upper word of the double in the fixed array and test for NaN.
|
||||||
|
__ sll(scratch2, key_reg, kDoubleSizeLog2 - kSmiTagSize);
|
||||||
|
__ Addu(indexed_double_offset, elements_reg, Operand(scratch2));
|
||||||
|
uint32_t upper_32_offset = FixedArray::kHeaderSize + sizeof(kHoleNanLower32);
|
||||||
|
__ lw(scratch, FieldMemOperand(indexed_double_offset, upper_32_offset));
|
||||||
|
__ Branch(&miss_force_generic, eq, scratch, Operand(kHoleNanUpper32));
|
||||||
|
|
||||||
|
// Non-NaN. Allocate a new heap number and copy the double value into it.
|
||||||
|
__ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
|
||||||
|
__ AllocateHeapNumber(heap_number_reg, scratch2, scratch3,
|
||||||
|
heap_number_map, &slow_allocate_heapnumber);
|
||||||
|
|
||||||
|
// Don't need to reload the upper 32 bits of the double, it's already in
|
||||||
|
// scratch.
|
||||||
|
__ sw(scratch, FieldMemOperand(heap_number_reg,
|
||||||
|
HeapNumber::kExponentOffset));
|
||||||
|
__ lw(scratch, FieldMemOperand(indexed_double_offset,
|
||||||
|
FixedArray::kHeaderSize));
|
||||||
|
__ sw(scratch, FieldMemOperand(heap_number_reg,
|
||||||
|
HeapNumber::kMantissaOffset));
|
||||||
|
|
||||||
|
__ mov(v0, heap_number_reg);
|
||||||
|
__ Ret();
|
||||||
|
|
||||||
|
__ bind(&slow_allocate_heapnumber);
|
||||||
|
Handle<Code> slow_ic =
|
||||||
|
masm->isolate()->builtins()->KeyedLoadIC_Slow();
|
||||||
|
__ Jump(slow_ic, RelocInfo::CODE_TARGET);
|
||||||
|
|
||||||
|
__ bind(&miss_force_generic);
|
||||||
|
Handle<Code> miss_ic =
|
||||||
|
masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
|
||||||
|
__ Jump(miss_ic, RelocInfo::CODE_TARGET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4301,7 +4364,120 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm,
|
|||||||
void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
|
void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
|
||||||
MacroAssembler* masm,
|
MacroAssembler* masm,
|
||||||
bool is_js_array) {
|
bool is_js_array) {
|
||||||
UNIMPLEMENTED();
|
// ----------- S t a t e -------------
|
||||||
|
// -- a0 : value
|
||||||
|
// -- a1 : key
|
||||||
|
// -- a2 : receiver
|
||||||
|
// -- ra : return address
|
||||||
|
// -- a3 : scratch
|
||||||
|
// -- t0 : scratch (elements_reg)
|
||||||
|
// -- t1 : scratch (mantissa_reg)
|
||||||
|
// -- t2 : scratch (exponent_reg)
|
||||||
|
// -- t3 : scratch4
|
||||||
|
// -----------------------------------
|
||||||
|
Label miss_force_generic, smi_value, is_nan, maybe_nan, have_double_value;
|
||||||
|
|
||||||
|
Register value_reg = a0;
|
||||||
|
Register key_reg = a1;
|
||||||
|
Register receiver_reg = a2;
|
||||||
|
Register scratch = a3;
|
||||||
|
Register elements_reg = t0;
|
||||||
|
Register mantissa_reg = t1;
|
||||||
|
Register exponent_reg = t2;
|
||||||
|
Register scratch4 = t3;
|
||||||
|
|
||||||
|
// This stub is meant to be tail-jumped to, the receiver must already
|
||||||
|
// have been verified by the caller to not be a smi.
|
||||||
|
__ JumpIfNotSmi(key_reg, &miss_force_generic);
|
||||||
|
|
||||||
|
__ lw(elements_reg,
|
||||||
|
FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
|
||||||
|
|
||||||
|
// Check that the key is within bounds.
|
||||||
|
if (is_js_array) {
|
||||||
|
__ lw(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
|
||||||
|
} else {
|
||||||
|
__ lw(scratch,
|
||||||
|
FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
|
||||||
|
}
|
||||||
|
// Compare smis, unsigned compare catches both negative and out-of-bound
|
||||||
|
// indexes.
|
||||||
|
__ Branch(&miss_force_generic, hs, key_reg, Operand(scratch));
|
||||||
|
|
||||||
|
// Handle smi values specially.
|
||||||
|
__ JumpIfSmi(value_reg, &smi_value);
|
||||||
|
|
||||||
|
// Ensure that the object is a heap number
|
||||||
|
__ CheckMap(value_reg,
|
||||||
|
scratch,
|
||||||
|
masm->isolate()->factory()->heap_number_map(),
|
||||||
|
&miss_force_generic,
|
||||||
|
DONT_DO_SMI_CHECK);
|
||||||
|
|
||||||
|
// Check for nan: all NaN values have a value greater (signed) than 0x7ff00000
|
||||||
|
// in the exponent.
|
||||||
|
__ li(scratch, Operand(kNaNOrInfinityLowerBoundUpper32));
|
||||||
|
__ lw(exponent_reg, FieldMemOperand(value_reg, HeapNumber::kExponentOffset));
|
||||||
|
__ Branch(&maybe_nan, ge, exponent_reg, Operand(scratch));
|
||||||
|
|
||||||
|
__ lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset));
|
||||||
|
|
||||||
|
__ bind(&have_double_value);
|
||||||
|
__ sll(scratch4, key_reg, kDoubleSizeLog2 - kSmiTagSize);
|
||||||
|
__ Addu(scratch, elements_reg, Operand(scratch4));
|
||||||
|
__ sw(mantissa_reg, FieldMemOperand(scratch, FixedDoubleArray::kHeaderSize));
|
||||||
|
uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32);
|
||||||
|
__ sw(exponent_reg, FieldMemOperand(scratch, offset));
|
||||||
|
__ Ret();
|
||||||
|
|
||||||
|
__ bind(&maybe_nan);
|
||||||
|
// Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise
|
||||||
|
// it's an Infinity, and the non-NaN code path applies.
|
||||||
|
__ li(scratch, Operand(kNaNOrInfinityLowerBoundUpper32));
|
||||||
|
__ Branch(&is_nan, gt, exponent_reg, Operand(scratch));
|
||||||
|
__ lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset));
|
||||||
|
__ Branch(&have_double_value, eq, mantissa_reg, Operand(zero_reg));
|
||||||
|
|
||||||
|
__ bind(&is_nan);
|
||||||
|
// Load canonical NaN for storing into the double array.
|
||||||
|
uint64_t nan_int64 = BitCast<uint64_t>(
|
||||||
|
FixedDoubleArray::canonical_not_the_hole_nan_as_double());
|
||||||
|
__ li(mantissa_reg, Operand(static_cast<uint32_t>(nan_int64)));
|
||||||
|
__ li(exponent_reg, Operand(static_cast<uint32_t>(nan_int64 >> 32)));
|
||||||
|
__ jmp(&have_double_value);
|
||||||
|
|
||||||
|
__ bind(&smi_value);
|
||||||
|
__ Addu(scratch, elements_reg,
|
||||||
|
Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
|
||||||
|
__ sll(scratch4, key_reg, kDoubleSizeLog2 - kSmiTagSize);
|
||||||
|
__ Addu(scratch, scratch, scratch4);
|
||||||
|
// scratch is now effective address of the double element
|
||||||
|
|
||||||
|
FloatingPointHelper::Destination destination;
|
||||||
|
if (CpuFeatures::IsSupported(FPU)) {
|
||||||
|
destination = FloatingPointHelper::kFPURegisters;
|
||||||
|
} else {
|
||||||
|
destination = FloatingPointHelper::kCoreRegisters;
|
||||||
|
}
|
||||||
|
__ SmiUntag(value_reg, value_reg);
|
||||||
|
FloatingPointHelper::ConvertIntToDouble(
|
||||||
|
masm, value_reg, destination,
|
||||||
|
f0, mantissa_reg, exponent_reg, // These are: double_dst, dst1, dst2.
|
||||||
|
scratch4, f2); // These are: scratch2, single_scratch.
|
||||||
|
if (destination == FloatingPointHelper::kFPURegisters) {
|
||||||
|
CpuFeatures::Scope scope(FPU);
|
||||||
|
__ sdc1(f0, MemOperand(scratch, 0));
|
||||||
|
} else {
|
||||||
|
__ sw(mantissa_reg, MemOperand(scratch, 0));
|
||||||
|
__ sw(exponent_reg, MemOperand(scratch, Register::kSizeInBytes));
|
||||||
|
}
|
||||||
|
__ Ret();
|
||||||
|
|
||||||
|
// Handle store cache miss, replacing the ic with the generic stub.
|
||||||
|
__ bind(&miss_force_generic);
|
||||||
|
Handle<Code> ic =
|
||||||
|
masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
|
||||||
|
__ Jump(ic, RelocInfo::CODE_TARGET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user