Index: src/ppc/macro-assembler-ppc.cc |
diff --git a/src/ppc/macro-assembler-ppc.cc b/src/ppc/macro-assembler-ppc.cc |
index 9ccd3c12ef73425381f35e2dc95657a252da0b44..2c9f7aa7a975b0fbffd59985ec97a8945e53603e 100644 |
--- a/src/ppc/macro-assembler-ppc.cc |
+++ b/src/ppc/macro-assembler-ppc.cc |
@@ -613,26 +613,8 @@ MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) { |
void MacroAssembler::CanonicalizeNaN(const DoubleRegister dst, |
const DoubleRegister src) { |
- Label done; |
- |
- // Test for NaN |
- fcmpu(src, src); |
- |
- if (dst.is(src)) { |
- bordered(&done); |
- } else { |
- Label is_nan; |
- bunordered(&is_nan); |
- fmr(dst, src); |
- b(&done); |
- bind(&is_nan); |
- } |
- |
- // Replace with canonical NaN. |
- double nan_value = FixedDoubleArray::canonical_not_the_hole_nan_as_double(); |
- LoadDoubleLiteral(dst, nan_value, r0); |
- |
- bind(&done); |
+ // Turn potential sNaN into qNaN. |
+ fadd(dst, src, kDoubleRegZero); |
} |
@@ -915,7 +897,8 @@ int MacroAssembler::ActivationFrameAlignment() { |
void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, |
- bool restore_context) { |
+ bool restore_context, |
+ bool argument_count_is_length) { |
#if V8_OOL_CONSTANT_POOL |
ConstantPoolUnavailableScope constant_pool_unavailable(this); |
#endif |
@@ -948,7 +931,9 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, |
LeaveFrame(StackFrame::EXIT); |
if (argument_count.is_valid()) { |
- ShiftLeftImm(argument_count, argument_count, Operand(kPointerSizeLog2)); |
+ if (!argument_count_is_length) { |
+ ShiftLeftImm(argument_count, argument_count, Operand(kPointerSizeLog2)); |
+ } |
add(sp, sp, argument_count); |
} |
} |
@@ -1742,9 +1727,7 @@ void MacroAssembler::UndoAllocationInNewSpace(Register object, |
ExternalReference::new_space_allocation_top_address(isolate()); |
// Make sure the object has no tag before resetting top. |
- mov(r0, Operand(~kHeapObjectTagMask)); |
- and_(object, object, r0); |
-// was.. and_(object, object, Operand(~kHeapObjectTagMask)); |
+ ClearRightImm(object, object, Operand(kHeapObjectTagSize)); |
#ifdef DEBUG |
// Check that the object un-allocated is below the current top. |
mov(scratch, Operand(new_space_allocation_top)); |
@@ -1942,7 +1925,7 @@ void MacroAssembler::StoreNumberToDoubleElements( |
DONT_DO_SMI_CHECK); |
lfd(double_scratch, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); |
- // Force a canonical NaN. |
+ // Double value, turn potential sNaN into qNaN. |
CanonicalizeNaN(double_scratch); |
b(&store); |
@@ -1967,23 +1950,26 @@ void MacroAssembler::AddAndCheckForOverflow(Register dst, Register left, |
DCHECK(!overflow_dst.is(left)); |
DCHECK(!overflow_dst.is(right)); |
+ bool left_is_right = left.is(right); |
+ RCBit xorRC = left_is_right ? SetRC : LeaveRC; |
+ |
// C = A+B; C overflows if A/B have same sign and C has diff sign than A |
if (dst.is(left)) { |
mr(scratch, left); // Preserve left. |
add(dst, left, right); // Left is overwritten. |
- xor_(scratch, dst, scratch); // Original left. |
- xor_(overflow_dst, dst, right); |
+ xor_(overflow_dst, dst, scratch, xorRC); // Original left. |
+ if (!left_is_right) xor_(scratch, dst, right); |
} else if (dst.is(right)) { |
mr(scratch, right); // Preserve right. |
add(dst, left, right); // Right is overwritten. |
- xor_(scratch, dst, scratch); // Original right. |
- xor_(overflow_dst, dst, left); |
+ xor_(overflow_dst, dst, left, xorRC); |
+ if (!left_is_right) xor_(scratch, dst, scratch); // Original right. |
} else { |
add(dst, left, right); |
- xor_(overflow_dst, dst, left); |
- xor_(scratch, dst, right); |
+ xor_(overflow_dst, dst, left, xorRC); |
+ if (!left_is_right) xor_(scratch, dst, right); |
} |
- and_(overflow_dst, scratch, overflow_dst, SetRC); |
+ if (!left_is_right) and_(overflow_dst, scratch, overflow_dst, SetRC); |
} |
@@ -2085,22 +2071,42 @@ void MacroAssembler::CheckMap(Register obj, Register scratch, |
} |
-void MacroAssembler::DispatchMap(Register obj, Register scratch, |
- Handle<Map> map, Handle<Code> success, |
- SmiCheckType smi_check_type) { |
+void MacroAssembler::DispatchWeakMap(Register obj, Register scratch1, |
+ Register scratch2, Handle<WeakCell> cell, |
+ Handle<Code> success, |
+ SmiCheckType smi_check_type) { |
Label fail; |
if (smi_check_type == DO_SMI_CHECK) { |
JumpIfSmi(obj, &fail); |
} |
- LoadP(scratch, FieldMemOperand(obj, HeapObject::kMapOffset)); |
- mov(r0, Operand(map)); |
- cmp(scratch, r0); |
- bne(&fail); |
- Jump(success, RelocInfo::CODE_TARGET, al); |
+ LoadP(scratch1, FieldMemOperand(obj, HeapObject::kMapOffset)); |
+ CmpWeakValue(scratch1, cell, scratch2); |
+ Jump(success, RelocInfo::CODE_TARGET, eq); |
bind(&fail); |
} |
+void MacroAssembler::CmpWeakValue(Register value, Handle<WeakCell> cell, |
+ Register scratch, CRegister cr) { |
+ mov(scratch, Operand(cell)); |
+ LoadP(scratch, FieldMemOperand(scratch, WeakCell::kValueOffset)); |
+ cmp(value, scratch, cr); |
+} |
+ |
+ |
+void MacroAssembler::GetWeakValue(Register value, Handle<WeakCell> cell) { |
+ mov(value, Operand(cell)); |
+ LoadP(value, FieldMemOperand(value, WeakCell::kValueOffset)); |
+} |
+ |
+ |
+void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell, |
+ Label* miss) { |
+ GetWeakValue(value, cell); |
+ JumpIfSmi(value, miss); |
+} |
+ |
+ |
void MacroAssembler::TryGetFunctionPrototype(Register function, Register result, |
Register scratch, Label* miss, |
bool miss_on_bound_function) { |
@@ -2177,138 +2183,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) { |
} |
-static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { |
- return ref0.address() - ref1.address(); |
-} |
- |
- |
-void MacroAssembler::CallApiFunctionAndReturn( |
- Register function_address, ExternalReference thunk_ref, int stack_space, |
- MemOperand return_value_operand, MemOperand* context_restore_operand) { |
- ExternalReference next_address = |
- ExternalReference::handle_scope_next_address(isolate()); |
- const int kNextOffset = 0; |
- const int kLimitOffset = AddressOffset( |
- ExternalReference::handle_scope_limit_address(isolate()), next_address); |
- const int kLevelOffset = AddressOffset( |
- ExternalReference::handle_scope_level_address(isolate()), next_address); |
- |
- DCHECK(function_address.is(r4) || function_address.is(r5)); |
- Register scratch = r6; |
- |
- Label profiler_disabled; |
- Label end_profiler_check; |
- mov(scratch, Operand(ExternalReference::is_profiling_address(isolate()))); |
- lbz(scratch, MemOperand(scratch, 0)); |
- cmpi(scratch, Operand::Zero()); |
- beq(&profiler_disabled); |
- |
- // Additional parameter is the address of the actual callback. |
- mov(scratch, Operand(thunk_ref)); |
- jmp(&end_profiler_check); |
- |
- bind(&profiler_disabled); |
- mr(scratch, function_address); |
- bind(&end_profiler_check); |
- |
- // Allocate HandleScope in callee-save registers. |
- // r17 - next_address |
- // r14 - next_address->kNextOffset |
- // r15 - next_address->kLimitOffset |
- // r16 - next_address->kLevelOffset |
- mov(r17, Operand(next_address)); |
- LoadP(r14, MemOperand(r17, kNextOffset)); |
- LoadP(r15, MemOperand(r17, kLimitOffset)); |
- lwz(r16, MemOperand(r17, kLevelOffset)); |
- addi(r16, r16, Operand(1)); |
- stw(r16, MemOperand(r17, kLevelOffset)); |
- |
- if (FLAG_log_timer_events) { |
- FrameScope frame(this, StackFrame::MANUAL); |
- PushSafepointRegisters(); |
- PrepareCallCFunction(1, r3); |
- mov(r3, Operand(ExternalReference::isolate_address(isolate()))); |
- CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1); |
- PopSafepointRegisters(); |
- } |
- |
- // Native call returns to the DirectCEntry stub which redirects to the |
- // return address pushed on stack (could have moved after GC). |
- // DirectCEntry stub itself is generated early and never moves. |
- DirectCEntryStub stub(isolate()); |
- stub.GenerateCall(this, scratch); |
- |
- if (FLAG_log_timer_events) { |
- FrameScope frame(this, StackFrame::MANUAL); |
- PushSafepointRegisters(); |
- PrepareCallCFunction(1, r3); |
- mov(r3, Operand(ExternalReference::isolate_address(isolate()))); |
- CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); |
- PopSafepointRegisters(); |
- } |
- |
- Label promote_scheduled_exception; |
- Label exception_handled; |
- Label delete_allocated_handles; |
- Label leave_exit_frame; |
- Label return_value_loaded; |
- |
- // load value from ReturnValue |
- LoadP(r3, return_value_operand); |
- bind(&return_value_loaded); |
- // No more valid handles (the result handle was the last one). Restore |
- // previous handle scope. |
- StoreP(r14, MemOperand(r17, kNextOffset)); |
- if (emit_debug_code()) { |
- lwz(r4, MemOperand(r17, kLevelOffset)); |
- cmp(r4, r16); |
- Check(eq, kUnexpectedLevelAfterReturnFromApiCall); |
- } |
- subi(r16, r16, Operand(1)); |
- stw(r16, MemOperand(r17, kLevelOffset)); |
- LoadP(r0, MemOperand(r17, kLimitOffset)); |
- cmp(r15, r0); |
- bne(&delete_allocated_handles); |
- |
- // Check if the function scheduled an exception. |
- bind(&leave_exit_frame); |
- LoadRoot(r14, Heap::kTheHoleValueRootIndex); |
- mov(r15, Operand(ExternalReference::scheduled_exception_address(isolate()))); |
- LoadP(r15, MemOperand(r15)); |
- cmp(r14, r15); |
- bne(&promote_scheduled_exception); |
- bind(&exception_handled); |
- |
- bool restore_context = context_restore_operand != NULL; |
- if (restore_context) { |
- LoadP(cp, *context_restore_operand); |
- } |
- // LeaveExitFrame expects unwind space to be in a register. |
- mov(r14, Operand(stack_space)); |
- LeaveExitFrame(false, r14, !restore_context); |
- blr(); |
- |
- bind(&promote_scheduled_exception); |
- { |
- FrameScope frame(this, StackFrame::INTERNAL); |
- CallExternalReference( |
- ExternalReference(Runtime::kPromoteScheduledException, isolate()), 0); |
- } |
- jmp(&exception_handled); |
- |
- // HandleScope limit has changed. Delete allocated extensions. |
- bind(&delete_allocated_handles); |
- StoreP(r15, MemOperand(r17, kLimitOffset)); |
- mr(r14, r3); |
- PrepareCallCFunction(1, r15); |
- mov(r3, Operand(ExternalReference::isolate_address(isolate()))); |
- CallCFunction(ExternalReference::delete_handle_scope_extensions(isolate()), |
- 1); |
- mr(r3, r14); |
- b(&leave_exit_frame); |
-} |
- |
- |
bool MacroAssembler::AllowThisStubCall(CodeStub* stub) { |
return has_frame_ || !stub->SometimesSetsUpAFrame(); |
} |
@@ -2352,7 +2226,7 @@ void MacroAssembler::TryDoubleToInt32Exact(Register result, |
result, double_scratch); |
#if V8_TARGET_ARCH_PPC64 |
- TestIfInt32(result, scratch, r0); |
+ TestIfInt32(result, r0); |
#else |
TestIfInt32(scratch, result, r0); |
#endif |
@@ -2389,7 +2263,7 @@ void MacroAssembler::TryInt32Floor(Register result, DoubleRegister double_input, |
// Test for overflow |
#if V8_TARGET_ARCH_PPC64 |
- TestIfInt32(result, scratch, r0); |
+ TestIfInt32(result, r0); |
#else |
TestIfInt32(scratch, result, r0); |
#endif |
@@ -2409,7 +2283,9 @@ void MacroAssembler::TryInlineTruncateDoubleToI(Register result, |
DoubleRegister double_input, |
Label* done) { |
DoubleRegister double_scratch = kScratchDoubleReg; |
+#if !V8_TARGET_ARCH_PPC64 |
Register scratch = ip; |
+#endif |
ConvertDoubleToInt64(double_input, |
#if !V8_TARGET_ARCH_PPC64 |
@@ -2419,7 +2295,7 @@ void MacroAssembler::TryInlineTruncateDoubleToI(Register result, |
// Test for overflow |
#if V8_TARGET_ARCH_PPC64 |
- TestIfInt32(result, scratch, r0); |
+ TestIfInt32(result, r0); |
#else |
TestIfInt32(scratch, result, r0); |
#endif |
@@ -2733,8 +2609,8 @@ void MacroAssembler::LoadTransitionedArrayMapConditional( |
LoadP(scratch, |
MemOperand(scratch, Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX))); |
size_t offset = expected_kind * kPointerSize + FixedArrayBase::kHeaderSize; |
- LoadP(scratch, FieldMemOperand(scratch, offset)); |
- cmp(map_in_out, scratch); |
+ LoadP(ip, FieldMemOperand(scratch, offset)); |
+ cmp(map_in_out, ip); |
bne(no_map_match); |
// Use the transitioned cached map. |
@@ -2820,7 +2696,6 @@ void MacroAssembler::SmiTagCheckOverflow(Register dst, Register src, |
void MacroAssembler::JumpIfNotBothSmi(Register reg1, Register reg2, |
Label* on_not_both_smi) { |
STATIC_ASSERT(kSmiTag == 0); |
- DCHECK_EQ(1, static_cast<int>(kSmiTagMask)); |
orx(r0, reg1, reg2, LeaveRC); |
JumpIfNotSmi(r0, on_not_both_smi); |
} |
@@ -2829,8 +2704,7 @@ void MacroAssembler::JumpIfNotBothSmi(Register reg1, Register reg2, |
void MacroAssembler::UntagAndJumpIfSmi(Register dst, Register src, |
Label* smi_case) { |
STATIC_ASSERT(kSmiTag == 0); |
- STATIC_ASSERT(kSmiTagSize == 1); |
- TestBit(src, 0, r0); |
+ TestBitRange(src, kSmiTagSize - 1, 0, r0); |
SmiUntag(dst, src); |
beq(smi_case, cr0); |
} |
@@ -2839,8 +2713,7 @@ void MacroAssembler::UntagAndJumpIfSmi(Register dst, Register src, |
void MacroAssembler::UntagAndJumpIfNotSmi(Register dst, Register src, |
Label* non_smi_case) { |
STATIC_ASSERT(kSmiTag == 0); |
- STATIC_ASSERT(kSmiTagSize == 1); |
- TestBit(src, 0, r0); |
+ TestBitRange(src, kSmiTagSize - 1, 0, r0); |
SmiUntag(dst, src); |
bne(non_smi_case, cr0); |
} |
@@ -3693,17 +3566,6 @@ void MacroAssembler::CheckPageFlag( |
} |
-void MacroAssembler::CheckMapDeprecated(Handle<Map> map, Register scratch, |
- Label* if_deprecated) { |
- if (map->CanBeDeprecated()) { |
- mov(scratch, Operand(map)); |
- lwz(scratch, FieldMemOperand(scratch, Map::kBitField3Offset)); |
- ExtractBitMask(scratch, scratch, Map::Deprecated::kMask, SetRC); |
- bne(if_deprecated, cr0); |
- } |
-} |
- |
- |
void MacroAssembler::JumpIfBlack(Register object, Register scratch0, |
Register scratch1, Label* on_black) { |
HasColor(object, scratch0, scratch1, on_black, 1, 0); // kBlackBitPattern. |
@@ -3896,28 +3758,38 @@ void MacroAssembler::EnsureNotWhite(Register value, Register bitmap_scratch, |
// if input_value > 255, output_value is 255 |
// otherwise output_value is the input_value |
void MacroAssembler::ClampUint8(Register output_reg, Register input_reg) { |
- Label done, negative_label, overflow_label; |
int satval = (1 << 8) - 1; |
- cmpi(input_reg, Operand::Zero()); |
- blt(&negative_label); |
+ if (CpuFeatures::IsSupported(ISELECT)) { |
+ // set to 0 if negative |
+ cmpi(input_reg, Operand::Zero()); |
+ isel(lt, output_reg, r0, input_reg); |
- cmpi(input_reg, Operand(satval)); |
- bgt(&overflow_label); |
- if (!output_reg.is(input_reg)) { |
- mr(output_reg, input_reg); |
- } |
- b(&done); |
- |
- bind(&negative_label); |
- li(output_reg, Operand::Zero()); // set to 0 if negative |
- b(&done); |
+ // set to satval if > satval |
+ li(r0, Operand(satval)); |
+ cmpi(output_reg, Operand(satval)); |
+ isel(lt, output_reg, output_reg, r0); |
+ } else { |
+ Label done, negative_label, overflow_label; |
+ cmpi(input_reg, Operand::Zero()); |
+ blt(&negative_label); |
+ |
+ cmpi(input_reg, Operand(satval)); |
+ bgt(&overflow_label); |
+ if (!output_reg.is(input_reg)) { |
+ mr(output_reg, input_reg); |
+ } |
+ b(&done); |
+ bind(&negative_label); |
+ li(output_reg, Operand::Zero()); // set to 0 if negative |
+ b(&done); |
- bind(&overflow_label); // set to satval if > satval |
- li(output_reg, Operand(satval)); |
+ bind(&overflow_label); // set to satval if > satval |
+ li(output_reg, Operand(satval)); |
- bind(&done); |
+ bind(&done); |
+ } |
} |
@@ -3982,6 +3854,20 @@ void MacroAssembler::EnumLength(Register dst, Register map) { |
} |
+void MacroAssembler::LoadAccessor(Register dst, Register holder, |
+ int accessor_index, |
+ AccessorComponent accessor) { |
+ LoadP(dst, FieldMemOperand(holder, HeapObject::kMapOffset)); |
+ LoadInstanceDescriptors(dst, dst); |
+ LoadP(dst, |
+ FieldMemOperand(dst, DescriptorArray::GetValueOffset(accessor_index))); |
+ const int getterOffset = AccessorPair::kGetterOffset; |
+ const int setterOffset = AccessorPair::kSetterOffset; |
+ int offset = ((accessor == ACCESSOR_GETTER) ? getterOffset : setterOffset); |
+ LoadP(dst, FieldMemOperand(dst, offset)); |
+} |
+ |
+ |
void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) { |
Register empty_fixed_array_value = r9; |
LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); |
@@ -4422,9 +4308,10 @@ void MacroAssembler::LoadP(Register dst, const MemOperand& mem, |
Register scratch) { |
int offset = mem.offset(); |
- if (!scratch.is(no_reg) && !is_int16(offset)) { |
+ if (!is_int16(offset)) { |
/* cannot use d-form */ |
- LoadIntLiteral(scratch, offset); |
+ DCHECK(!scratch.is(no_reg)); |
+ mov(scratch, Operand(offset)); |
#if V8_TARGET_ARCH_PPC64 |
ldx(dst, MemOperand(mem.ra(), scratch)); |
#else |
@@ -4454,9 +4341,10 @@ void MacroAssembler::StoreP(Register src, const MemOperand& mem, |
Register scratch) { |
int offset = mem.offset(); |
- if (!scratch.is(no_reg) && !is_int16(offset)) { |
+ if (!is_int16(offset)) { |
/* cannot use d-form */ |
- LoadIntLiteral(scratch, offset); |
+ DCHECK(!scratch.is(no_reg)); |
+ mov(scratch, Operand(offset)); |
#if V8_TARGET_ARCH_PPC64 |
stdx(src, MemOperand(mem.ra(), scratch)); |
#else |
@@ -4489,15 +4377,10 @@ void MacroAssembler::LoadWordArith(Register dst, const MemOperand& mem, |
Register scratch) { |
int offset = mem.offset(); |
- if (!scratch.is(no_reg) && !is_int16(offset)) { |
- /* cannot use d-form */ |
- LoadIntLiteral(scratch, offset); |
-#if V8_TARGET_ARCH_PPC64 |
- // lwax(dst, MemOperand(mem.ra(), scratch)); |
- DCHECK(0); // lwax not yet implemented |
-#else |
- lwzx(dst, MemOperand(mem.ra(), scratch)); |
-#endif |
+ if (!is_int16(offset)) { |
+ DCHECK(!scratch.is(no_reg)); |
+ mov(scratch, Operand(offset)); |
+ lwax(dst, MemOperand(mem.ra(), scratch)); |
} else { |
#if V8_TARGET_ARCH_PPC64 |
int misaligned = (offset & 3); |
@@ -4549,6 +4432,20 @@ void MacroAssembler::StoreWord(Register src, const MemOperand& mem, |
} |
+void MacroAssembler::LoadHalfWordArith(Register dst, const MemOperand& mem, |
+ Register scratch) { |
+ int offset = mem.offset(); |
+ |
+ if (!is_int16(offset)) { |
+ DCHECK(!scratch.is(no_reg)); |
+ mov(scratch, Operand(offset)); |
+ lhax(dst, MemOperand(mem.ra(), scratch)); |
+ } else { |
+ lha(dst, mem); |
+ } |
+} |
+ |
+ |
// Variable length depending on whether offset fits into immediate field |
// MemOperand currently only supports d-form |
void MacroAssembler::LoadHalfWord(Register dst, const MemOperand& mem, |
@@ -4622,13 +4519,12 @@ void MacroAssembler::LoadRepresentation(Register dst, const MemOperand& mem, |
} else if (r.IsUInteger8()) { |
LoadByte(dst, mem, scratch); |
} else if (r.IsInteger16()) { |
- LoadHalfWord(dst, mem, scratch); |
- extsh(dst, dst); |
+ LoadHalfWordArith(dst, mem, scratch); |
} else if (r.IsUInteger16()) { |
LoadHalfWord(dst, mem, scratch); |
#if V8_TARGET_ARCH_PPC64 |
} else if (r.IsInteger32()) { |
- LoadWord(dst, mem, scratch); |
+ LoadWordArith(dst, mem, scratch); |
#endif |
} else { |
LoadP(dst, mem, scratch); |
@@ -4658,6 +4554,34 @@ void MacroAssembler::StoreRepresentation(Register src, const MemOperand& mem, |
} |
+void MacroAssembler::LoadDouble(DoubleRegister dst, const MemOperand& mem, |
+ Register scratch) { |
+ Register base = mem.ra(); |
+ int offset = mem.offset(); |
+ |
+ if (!is_int16(offset)) { |
+ mov(scratch, Operand(offset)); |
+ lfdx(dst, MemOperand(base, scratch)); |
+ } else { |
+ lfd(dst, mem); |
+ } |
+} |
+ |
+ |
+void MacroAssembler::StoreDouble(DoubleRegister src, const MemOperand& mem, |
+ Register scratch) { |
+ Register base = mem.ra(); |
+ int offset = mem.offset(); |
+ |
+ if (!is_int16(offset)) { |
+ mov(scratch, Operand(offset)); |
+ stfdx(src, MemOperand(base, scratch)); |
+ } else { |
+ stfd(src, mem); |
+ } |
+} |
+ |
+ |
void MacroAssembler::TestJSArrayForAllocationMemento(Register receiver_reg, |
Register scratch_reg, |
Label* no_memento_found) { |