summaryrefslogtreecommitdiff
path: root/deps/v8/src/ppc/macro-assembler-ppc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ppc/macro-assembler-ppc.cc')
-rw-r--r--deps/v8/src/ppc/macro-assembler-ppc.cc383
1 files changed, 59 insertions, 324 deletions
diff --git a/deps/v8/src/ppc/macro-assembler-ppc.cc b/deps/v8/src/ppc/macro-assembler-ppc.cc
index 676cb2c60e..e973471572 100644
--- a/deps/v8/src/ppc/macro-assembler-ppc.cc
+++ b/deps/v8/src/ppc/macro-assembler-ppc.cc
@@ -11,8 +11,8 @@
#include "src/base/division-by-constant.h"
#include "src/bootstrapper.h"
#include "src/codegen.h"
-#include "src/cpu-profiler.h"
#include "src/debug/debug.h"
+#include "src/ppc/macro-assembler-ppc.h"
#include "src/runtime/runtime.h"
namespace v8 {
@@ -753,6 +753,14 @@ void MacroAssembler::Prologue(bool code_pre_aging, int prologue_offset) {
}
+void MacroAssembler::EmitLoadTypeFeedbackVector(Register vector) {
+ LoadP(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+ LoadP(vector, FieldMemOperand(vector, JSFunction::kSharedFunctionInfoOffset));
+ LoadP(vector,
+ FieldMemOperand(vector, SharedFunctionInfo::kFeedbackVectorOffset));
+}
+
+
void MacroAssembler::EnterFrame(StackFrame::Type type,
bool load_constant_pool_pointer_reg) {
if (FLAG_enable_embedded_constant_pool && load_constant_pool_pointer_reg) {
@@ -987,10 +995,10 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
if (expected.is_immediate()) {
DCHECK(actual.is_immediate());
+ mov(r3, Operand(actual.immediate()));
if (expected.immediate() == actual.immediate()) {
definitely_matches = true;
} else {
- mov(r3, Operand(actual.immediate()));
const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel;
if (expected.immediate() == sentinel) {
// Don't worry about adapting arguments for builtins that
@@ -1005,9 +1013,9 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
}
} else {
if (actual.is_immediate()) {
+ mov(r3, Operand(actual.immediate()));
cmpi(expected.reg(), Operand(actual.immediate()));
beq(&regular_invoke);
- mov(r3, Operand(actual.immediate()));
} else {
cmp(expected.reg(), actual.reg());
beq(&regular_invoke);
@@ -1122,23 +1130,6 @@ void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
}
-void MacroAssembler::IsObjectJSObjectType(Register heap_object, Register map,
- Register scratch, Label* fail) {
- LoadP(map, FieldMemOperand(heap_object, HeapObject::kMapOffset));
- IsInstanceJSObjectType(map, scratch, fail);
-}
-
-
-void MacroAssembler::IsInstanceJSObjectType(Register map, Register scratch,
- Label* fail) {
- lbz(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
- cmpi(scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
- blt(fail);
- cmpi(scratch, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
- bgt(fail);
-}
-
-
void MacroAssembler::IsObjectJSStringType(Register object, Register scratch,
Label* fail) {
DCHECK(kNotStringTag != 0);
@@ -1701,20 +1692,6 @@ void MacroAssembler::CompareObjectType(Register object, Register map,
}
-void MacroAssembler::CheckObjectTypeRange(Register object, Register map,
- InstanceType min_type,
- InstanceType max_type,
- Label* false_label) {
- STATIC_ASSERT(Map::kInstanceTypeOffset < 4096);
- STATIC_ASSERT(LAST_TYPE < 256);
- LoadP(map, FieldMemOperand(object, HeapObject::kMapOffset));
- lbz(ip, FieldMemOperand(map, Map::kInstanceTypeOffset));
- subi(ip, ip, Operand(min_type));
- cmpli(ip, Operand(max_type - min_type));
- bgt(false_label);
-}
-
-
void MacroAssembler::CompareInstanceType(Register map, Register type_reg,
InstanceType type) {
STATIC_ASSERT(Map::kInstanceTypeOffset < 4096);
@@ -1979,36 +1956,7 @@ void MacroAssembler::GetMapConstructor(Register result, Register map,
void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
- Register scratch, Label* miss,
- bool miss_on_bound_function) {
- Label non_instance;
- if (miss_on_bound_function) {
- // Check that the receiver isn't a smi.
- JumpIfSmi(function, miss);
-
- // Check that the function really is a function. Load map into result reg.
- CompareObjectType(function, result, scratch, JS_FUNCTION_TYPE);
- bne(miss);
-
- LoadP(scratch,
- FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
- lwz(scratch,
- FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset));
- TestBit(scratch,
-#if V8_TARGET_ARCH_PPC64
- SharedFunctionInfo::kBoundFunction,
-#else
- SharedFunctionInfo::kBoundFunction + kSmiTagSize,
-#endif
- r0);
- bne(miss, cr0);
-
- // Make sure that the function has an instance prototype.
- lbz(scratch, FieldMemOperand(result, Map::kBitFieldOffset));
- andi(r0, scratch, Operand(1 << Map::kHasNonInstancePrototype));
- bne(&non_instance, cr0);
- }
-
+ Register scratch, Label* miss) {
// Get the prototype or initial map from the function.
LoadP(result,
FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
@@ -2028,15 +1976,6 @@ void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
// Get the prototype from the initial map.
LoadP(result, FieldMemOperand(result, Map::kPrototypeOffset));
- if (miss_on_bound_function) {
- b(&done);
-
- // Non-instance prototype: Fetch prototype from constructor field
- // in initial map.
- bind(&non_instance);
- GetMapConstructor(result, result, scratch, ip);
- }
-
// All done.
bind(&done);
}
@@ -2312,12 +2251,12 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) {
}
-void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag,
+void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag,
const CallWrapper& call_wrapper) {
// You can't call a builtin without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame());
- GetBuiltinEntry(ip, id);
+ GetBuiltinEntry(ip, native_context_index);
if (flag == CALL_FUNCTION) {
call_wrapper.BeforeCall(CallSize(ip));
CallJSEntry(ip);
@@ -2330,21 +2269,20 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag,
void MacroAssembler::GetBuiltinFunction(Register target,
- Builtins::JavaScript id) {
+ int native_context_index) {
// Load the builtins object into target register.
LoadP(target,
MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
- LoadP(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset));
+ LoadP(target, FieldMemOperand(target, GlobalObject::kNativeContextOffset));
// Load the JavaScript builtin function from the builtins object.
- LoadP(target,
- FieldMemOperand(target, JSBuiltinsObject::OffsetOfFunctionWithId(id)),
- r0);
+ LoadP(target, ContextOperand(target, native_context_index), r0);
}
-void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
+void MacroAssembler::GetBuiltinEntry(Register target,
+ int native_context_index) {
DCHECK(!target.is(r4));
- GetBuiltinFunction(r4, id);
+ GetBuiltinFunction(r4, native_context_index);
// Load the code entry point from the builtins object.
LoadP(target, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
}
@@ -2468,6 +2406,12 @@ void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
}
+void MacroAssembler::LoadGlobalProxy(Register dst) {
+ LoadP(dst, GlobalObjectOperand());
+ LoadP(dst, FieldMemOperand(dst, GlobalObject::kGlobalProxyOffset));
+}
+
+
void MacroAssembler::LoadTransitionedArrayMapConditional(
ElementsKind expected_kind, ElementsKind transitioned_kind,
Register map_in_out, Register scratch, Label* no_map_match) {
@@ -2644,6 +2588,19 @@ void MacroAssembler::AssertName(Register object) {
}
+void MacroAssembler::AssertFunction(Register object) {
+ if (emit_debug_code()) {
+ STATIC_ASSERT(kSmiTag == 0);
+ TestIfSmi(object, r0);
+ Check(ne, kOperandIsASmiAndNotAFunction, cr0);
+ push(object);
+ CompareObjectType(object, object, object, JS_FUNCTION_TYPE);
+ pop(object);
+ Check(eq, kOperandIsNotAFunction);
+ }
+}
+
+
void MacroAssembler::AssertUndefinedOrAllocationSite(Register object,
Register scratch) {
if (emit_debug_code()) {
@@ -2678,78 +2635,6 @@ void MacroAssembler::JumpIfNotHeapNumber(Register object,
}
-void MacroAssembler::LookupNumberStringCache(Register object, Register result,
- Register scratch1,
- Register scratch2,
- Register scratch3,
- Label* not_found) {
- // Use of registers. Register result is used as a temporary.
- Register number_string_cache = result;
- Register mask = scratch3;
-
- // Load the number string cache.
- LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex);
-
- // Make the hash mask from the length of the number string cache. It
- // contains two elements (number and string) for each cache entry.
- LoadP(mask, FieldMemOperand(number_string_cache, FixedArray::kLengthOffset));
- // Divide length by two (length is a smi).
- ShiftRightArithImm(mask, mask, kSmiTagSize + kSmiShiftSize + 1);
- subi(mask, mask, Operand(1)); // Make mask.
-
- // Calculate the entry in the number string cache. The hash value in the
- // number string cache for smis is just the smi value, and the hash for
- // doubles is the xor of the upper and lower words. See
- // Heap::GetNumberStringCache.
- Label is_smi;
- Label load_result_from_cache;
- JumpIfSmi(object, &is_smi);
- CheckMap(object, scratch1, Heap::kHeapNumberMapRootIndex, not_found,
- DONT_DO_SMI_CHECK);
-
- STATIC_ASSERT(8 == kDoubleSize);
- lwz(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset));
- lwz(scratch2, FieldMemOperand(object, HeapNumber::kMantissaOffset));
- xor_(scratch1, scratch1, scratch2);
- and_(scratch1, scratch1, mask);
-
- // Calculate address of entry in string cache: each entry consists
- // of two pointer sized fields.
- ShiftLeftImm(scratch1, scratch1, Operand(kPointerSizeLog2 + 1));
- add(scratch1, number_string_cache, scratch1);
-
- Register probe = mask;
- LoadP(probe, FieldMemOperand(scratch1, FixedArray::kHeaderSize));
- JumpIfSmi(probe, not_found);
- lfd(d0, FieldMemOperand(object, HeapNumber::kValueOffset));
- lfd(d1, FieldMemOperand(probe, HeapNumber::kValueOffset));
- fcmpu(d0, d1);
- bne(not_found); // The cache did not contain this value.
- b(&load_result_from_cache);
-
- bind(&is_smi);
- Register scratch = scratch1;
- SmiUntag(scratch, object);
- and_(scratch, mask, scratch);
- // Calculate address of entry in string cache: each entry consists
- // of two pointer sized fields.
- ShiftLeftImm(scratch, scratch, Operand(kPointerSizeLog2 + 1));
- add(scratch, number_string_cache, scratch);
-
- // Check if the entry is the smi we are looking for.
- LoadP(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize));
- cmp(object, probe);
- bne(not_found);
-
- // Get the result from the cache.
- bind(&load_result_from_cache);
- LoadP(result,
- FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize));
- IncrementCounter(isolate()->counters()->number_to_string_native(), 1,
- scratch1, scratch2);
-}
-
-
void MacroAssembler::JumpIfNonSmisNotBothSequentialOneByteStrings(
Register first, Register second, Register scratch1, Register scratch2,
Label* failure) {
@@ -3244,175 +3129,6 @@ void MacroAssembler::DecodeConstantPoolOffset(Register result,
}
-void MacroAssembler::SetRelocatedValue(Register location, Register scratch,
- Register new_value) {
- lwz(scratch, MemOperand(location));
-
- if (FLAG_enable_embedded_constant_pool) {
- if (emit_debug_code()) {
- // Check that the instruction sequence is a load from the constant pool
- ExtractBitMask(scratch, scratch, 0x1f * B16);
- cmpi(scratch, Operand(kConstantPoolRegister.code()));
- Check(eq, kTheInstructionToPatchShouldBeALoadFromConstantPool);
- // Scratch was clobbered. Restore it.
- lwz(scratch, MemOperand(location));
- }
- DecodeConstantPoolOffset(scratch, location);
- StorePX(new_value, MemOperand(kConstantPoolRegister, scratch));
- return;
- }
-
- // This code assumes a FIXED_SEQUENCE for lis/ori
-
- // At this point scratch is a lis instruction.
- if (emit_debug_code()) {
- And(scratch, scratch, Operand(kOpcodeMask | (0x1f * B16)));
- Cmpi(scratch, Operand(ADDIS), r0);
- Check(eq, kTheInstructionToPatchShouldBeALis);
- lwz(scratch, MemOperand(location));
- }
-
-// insert new high word into lis instruction
-#if V8_TARGET_ARCH_PPC64
- srdi(ip, new_value, Operand(32));
- rlwimi(scratch, ip, 16, 16, 31);
-#else
- rlwimi(scratch, new_value, 16, 16, 31);
-#endif
-
- stw(scratch, MemOperand(location));
-
- lwz(scratch, MemOperand(location, kInstrSize));
- // scratch is now ori.
- if (emit_debug_code()) {
- And(scratch, scratch, Operand(kOpcodeMask));
- Cmpi(scratch, Operand(ORI), r0);
- Check(eq, kTheInstructionShouldBeAnOri);
- lwz(scratch, MemOperand(location, kInstrSize));
- }
-
-// insert new low word into ori instruction
-#if V8_TARGET_ARCH_PPC64
- rlwimi(scratch, ip, 0, 16, 31);
-#else
- rlwimi(scratch, new_value, 0, 16, 31);
-#endif
- stw(scratch, MemOperand(location, kInstrSize));
-
-#if V8_TARGET_ARCH_PPC64
- if (emit_debug_code()) {
- lwz(scratch, MemOperand(location, 2 * kInstrSize));
- // scratch is now sldi.
- And(scratch, scratch, Operand(kOpcodeMask | kExt5OpcodeMask));
- Cmpi(scratch, Operand(EXT5 | RLDICR), r0);
- Check(eq, kTheInstructionShouldBeASldi);
- }
-
- lwz(scratch, MemOperand(location, 3 * kInstrSize));
- // scratch is now ori.
- if (emit_debug_code()) {
- And(scratch, scratch, Operand(kOpcodeMask));
- Cmpi(scratch, Operand(ORIS), r0);
- Check(eq, kTheInstructionShouldBeAnOris);
- lwz(scratch, MemOperand(location, 3 * kInstrSize));
- }
-
- rlwimi(scratch, new_value, 16, 16, 31);
- stw(scratch, MemOperand(location, 3 * kInstrSize));
-
- lwz(scratch, MemOperand(location, 4 * kInstrSize));
- // scratch is now ori.
- if (emit_debug_code()) {
- And(scratch, scratch, Operand(kOpcodeMask));
- Cmpi(scratch, Operand(ORI), r0);
- Check(eq, kTheInstructionShouldBeAnOri);
- lwz(scratch, MemOperand(location, 4 * kInstrSize));
- }
- rlwimi(scratch, new_value, 0, 16, 31);
- stw(scratch, MemOperand(location, 4 * kInstrSize));
-#endif
-
-// Update the I-cache so the new lis and addic can be executed.
-#if V8_TARGET_ARCH_PPC64
- FlushICache(location, 5 * kInstrSize, scratch);
-#else
- FlushICache(location, 2 * kInstrSize, scratch);
-#endif
-}
-
-
-void MacroAssembler::GetRelocatedValue(Register location, Register result,
- Register scratch) {
- lwz(result, MemOperand(location));
-
- if (FLAG_enable_embedded_constant_pool) {
- if (emit_debug_code()) {
- // Check that the instruction sequence is a load from the constant pool
- ExtractBitMask(result, result, 0x1f * B16);
- cmpi(result, Operand(kConstantPoolRegister.code()));
- Check(eq, kTheInstructionToPatchShouldBeALoadFromConstantPool);
- lwz(result, MemOperand(location));
- }
- DecodeConstantPoolOffset(result, location);
- LoadPX(result, MemOperand(kConstantPoolRegister, result));
- return;
- }
-
- // This code assumes a FIXED_SEQUENCE for lis/ori
- if (emit_debug_code()) {
- And(result, result, Operand(kOpcodeMask | (0x1f * B16)));
- Cmpi(result, Operand(ADDIS), r0);
- Check(eq, kTheInstructionShouldBeALis);
- lwz(result, MemOperand(location));
- }
-
- // result now holds a lis instruction. Extract the immediate.
- slwi(result, result, Operand(16));
-
- lwz(scratch, MemOperand(location, kInstrSize));
- if (emit_debug_code()) {
- And(scratch, scratch, Operand(kOpcodeMask));
- Cmpi(scratch, Operand(ORI), r0);
- Check(eq, kTheInstructionShouldBeAnOri);
- lwz(scratch, MemOperand(location, kInstrSize));
- }
- // Copy the low 16bits from ori instruction into result
- rlwimi(result, scratch, 0, 16, 31);
-
-#if V8_TARGET_ARCH_PPC64
- if (emit_debug_code()) {
- lwz(scratch, MemOperand(location, 2 * kInstrSize));
- // scratch is now sldi.
- And(scratch, scratch, Operand(kOpcodeMask | kExt5OpcodeMask));
- Cmpi(scratch, Operand(EXT5 | RLDICR), r0);
- Check(eq, kTheInstructionShouldBeASldi);
- }
-
- lwz(scratch, MemOperand(location, 3 * kInstrSize));
- // scratch is now ori.
- if (emit_debug_code()) {
- And(scratch, scratch, Operand(kOpcodeMask));
- Cmpi(scratch, Operand(ORIS), r0);
- Check(eq, kTheInstructionShouldBeAnOris);
- lwz(scratch, MemOperand(location, 3 * kInstrSize));
- }
- sldi(result, result, Operand(16));
- rldimi(result, scratch, 0, 48);
-
- lwz(scratch, MemOperand(location, 4 * kInstrSize));
- // scratch is now ori.
- if (emit_debug_code()) {
- And(scratch, scratch, Operand(kOpcodeMask));
- Cmpi(scratch, Operand(ORI), r0);
- Check(eq, kTheInstructionShouldBeAnOri);
- lwz(scratch, MemOperand(location, 4 * kInstrSize));
- }
- sldi(result, result, Operand(16));
- rldimi(result, scratch, 0, 48);
-#endif
-}
-
-
void MacroAssembler::CheckPageFlag(
Register object,
Register scratch, // scratch may be same register as object
@@ -4040,6 +3756,25 @@ void MacroAssembler::MovDoubleToInt64(
}
+void MacroAssembler::MovIntToFloat(DoubleRegister dst, Register src) {
+ subi(sp, sp, Operand(kFloatSize));
+ stw(src, MemOperand(sp, 0));
+ nop(GROUP_ENDING_NOP); // LHS/RAW optimization
+ lfs(dst, MemOperand(sp, 0));
+ addi(sp, sp, Operand(kFloatSize));
+}
+
+
+void MacroAssembler::MovFloatToInt(Register dst, DoubleRegister src) {
+ subi(sp, sp, Operand(kFloatSize));
+ frsp(src, src);
+ stfs(src, MemOperand(sp, 0));
+ nop(GROUP_ENDING_NOP); // LHS/RAW optimization
+ lwz(dst, MemOperand(sp, 0));
+ addi(sp, sp, Operand(kFloatSize));
+}
+
+
void MacroAssembler::Add(Register dst, Register src, intptr_t value,
Register scratch) {
if (is_int16(value)) {
@@ -4601,7 +4336,7 @@ CodePatcher::CodePatcher(byte* address, int instructions,
CodePatcher::~CodePatcher() {
// Indicate that code has changed.
if (flush_cache_ == FLUSH) {
- CpuFeatures::FlushICache(address_, size_);
+ Assembler::FlushICacheWithoutIsolate(address_, size_);
}
// Check that the code was patched as expected.