diff options
Diffstat (limited to 'deps/v8/src/ppc')
-rw-r--r-- | deps/v8/src/ppc/assembler-ppc.cc | 56 | ||||
-rw-r--r-- | deps/v8/src/ppc/assembler-ppc.h | 20 | ||||
-rw-r--r-- | deps/v8/src/ppc/code-stubs-ppc.cc | 492 | ||||
-rw-r--r-- | deps/v8/src/ppc/code-stubs-ppc.h | 13 | ||||
-rw-r--r-- | deps/v8/src/ppc/codegen-ppc.cc | 324 | ||||
-rw-r--r-- | deps/v8/src/ppc/constants-ppc.h | 53 | ||||
-rw-r--r-- | deps/v8/src/ppc/disasm-ppc.cc | 45 | ||||
-rw-r--r-- | deps/v8/src/ppc/interface-descriptors-ppc.cc | 8 | ||||
-rw-r--r-- | deps/v8/src/ppc/macro-assembler-ppc.cc | 260 | ||||
-rw-r--r-- | deps/v8/src/ppc/macro-assembler-ppc.h | 76 | ||||
-rw-r--r-- | deps/v8/src/ppc/simulator-ppc.cc | 128 | ||||
-rw-r--r-- | deps/v8/src/ppc/simulator-ppc.h | 1 |
12 files changed, 319 insertions, 1157 deletions
diff --git a/deps/v8/src/ppc/assembler-ppc.cc b/deps/v8/src/ppc/assembler-ppc.cc index 08a8005ee1..32408f3079 100644 --- a/deps/v8/src/ppc/assembler-ppc.cc +++ b/deps/v8/src/ppc/assembler-ppc.cc @@ -66,6 +66,9 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { #ifndef USE_SIMULATOR // Probe for additional features at runtime. base::CPU cpu; + if (cpu.part() == base::CPU::PPC_POWER9) { + supported_ |= (1u << MODULO); + } #if V8_TARGET_ARCH_PPC64 if (cpu.part() == base::CPU::PPC_POWER8) { supported_ |= (1u << FPR_GPR_MOV); @@ -79,6 +82,7 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { if (cpu.part() == base::CPU::PPC_POWER7 || cpu.part() == base::CPU::PPC_POWER8) { supported_ |= (1u << ISELECT); + supported_ |= (1u << VSX); } #if V8_OS_LINUX if (!(cpu.part() == base::CPU::PPC_G5 || cpu.part() == base::CPU::PPC_G4)) { @@ -96,6 +100,8 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { supported_ |= (1u << FPU); supported_ |= (1u << LWSYNC); supported_ |= (1u << ISELECT); + supported_ |= (1u << VSX); + supported_ |= (1u << MODULO); #if V8_TARGET_ARCH_PPC64 supported_ |= (1u << FPR_GPR_MOV); #endif @@ -171,14 +177,19 @@ Address RelocInfo::wasm_global_reference() { return Assembler::target_address_at(pc_, host_); } +uint32_t RelocInfo::wasm_function_table_size_reference() { + DCHECK(IsWasmFunctionTableSizeReference(rmode_)); + return static_cast<uint32_t>( + reinterpret_cast<intptr_t>(Assembler::target_address_at(pc_, host_))); +} void RelocInfo::unchecked_update_wasm_memory_reference( Address address, ICacheFlushMode flush_mode) { Assembler::set_target_address_at(isolate_, pc_, host_, address, flush_mode); } -void RelocInfo::unchecked_update_wasm_memory_size(uint32_t size, - ICacheFlushMode flush_mode) { +void RelocInfo::unchecked_update_wasm_size(uint32_t size, + ICacheFlushMode flush_mode) { Assembler::set_target_address_at(isolate_, pc_, host_, reinterpret_cast<Address>(size), flush_mode); } @@ -641,6 +652,14 @@ void Assembler::xo_form(Instr instr, Register rt, Register ra, Register rb, emit(instr | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 | o | r); } +void Assembler::xx3_form(Instr instr, DoubleRegister t, DoubleRegister a, + DoubleRegister b) { + int AX = ((a.code() & 0x20) >> 5) & 0x1; + int BX = ((b.code() & 0x20) >> 5) & 0x1; + int TX = ((t.code() & 0x20) >> 5) & 0x1; + emit(instr | (t.code() & 0x1F) * B21 | (a.code() & 0x1F) * B16 | (b.code() + & 0x1F) * B11 | AX * B2 | BX * B1 | TX); +} void Assembler::md_form(Instr instr, Register ra, Register rs, int shift, int maskbit, RCBit r) { @@ -936,6 +955,13 @@ void Assembler::divwu(Register dst, Register src1, Register src2, OEBit o, xo_form(EXT2 | DIVWU, dst, src1, src2, o, r); } +void Assembler::modsw(Register rt, Register ra, Register rb) { + x_form(EXT2 | MODSW, ra, rt, rb, LeaveRC); +} + +void Assembler::moduw(Register rt, Register ra, Register rb) { + x_form(EXT2 | MODUW, ra, rt, rb, LeaveRC); +} void Assembler::addi(Register dst, Register src, const Operand& imm) { DCHECK(!src.is(r0)); // use li instead to show intent @@ -1540,6 +1566,14 @@ void Assembler::divdu(Register dst, Register src1, Register src2, OEBit o, RCBit r) { xo_form(EXT2 | DIVDU, dst, src1, src2, o, r); } + +void Assembler::modsd(Register rt, Register ra, Register rb) { + x_form(EXT2 | MODSD, ra, rt, rb, LeaveRC); +} + +void Assembler::modud(Register rt, Register ra, Register rb) { + x_form(EXT2 | MODUD, ra, rt, rb, LeaveRC); +} #endif @@ -2322,6 +2356,24 @@ void Assembler::fmsub(const DoubleRegister frt, const DoubleRegister fra, frc.code() * B6 | rc); } +// Support for VSX instructions + +void Assembler::xsadddp(const DoubleRegister frt, const DoubleRegister fra, + const DoubleRegister frb) { + xx3_form(EXT6 | XSADDDP, frt, fra, frb); +} +void Assembler::xssubdp(const DoubleRegister frt, const DoubleRegister fra, + const DoubleRegister frb) { + xx3_form(EXT6 | XSSUBDP, frt, fra, frb); +} +void Assembler::xsdivdp(const DoubleRegister frt, const DoubleRegister fra, + const DoubleRegister frb) { + xx3_form(EXT6 | XSDIVDP, frt, fra, frb); +} +void Assembler::xsmuldp(const DoubleRegister frt, const DoubleRegister fra, + const DoubleRegister frb) { + xx3_form(EXT6 | XSMULDP, frt, fra, frb); +} // Pseudo instructions. void Assembler::nop(int type) { diff --git a/deps/v8/src/ppc/assembler-ppc.h b/deps/v8/src/ppc/assembler-ppc.h index f49ac6305e..b385af0321 100644 --- a/deps/v8/src/ppc/assembler-ppc.h +++ b/deps/v8/src/ppc/assembler-ppc.h @@ -837,6 +837,8 @@ class Assembler : public AssemblerBase { RCBit r = LeaveRC); void divwu(Register dst, Register src1, Register src2, OEBit o = LeaveOE, RCBit r = LeaveRC); + void modsw(Register rt, Register ra, Register rb); + void moduw(Register rt, Register ra, Register rb); void addi(Register dst, Register src, const Operand& imm); void addis(Register dst, Register src, const Operand& imm); @@ -932,6 +934,8 @@ class Assembler : public AssemblerBase { RCBit r = LeaveRC); void divdu(Register dst, Register src1, Register src2, OEBit o = LeaveOE, RCBit r = LeaveRC); + void modsd(Register rt, Register ra, Register rb); + void modud(Register rt, Register ra, Register rb); #endif void rlwinm(Register ra, Register rs, int sh, int mb, int me, @@ -1104,6 +1108,17 @@ class Assembler : public AssemblerBase { const DoubleRegister frc, const DoubleRegister frb, RCBit rc = LeaveRC); + // Support for VSX instructions + + void xsadddp(const DoubleRegister frt, const DoubleRegister fra, + const DoubleRegister frb); + void xssubdp(const DoubleRegister frt, const DoubleRegister fra, + const DoubleRegister frb); + void xsdivdp(const DoubleRegister frt, const DoubleRegister fra, + const DoubleRegister frb); + void xsmuldp(const DoubleRegister frt, const DoubleRegister fra, + const DoubleRegister frc); + // Pseudo instructions // Different nop operations are used by the code generator to detect certain @@ -1188,9 +1203,6 @@ class Assembler : public AssemblerBase { // Debugging - // Mark generator continuation. - void RecordGeneratorContinuation(); - // Mark address of a debug break slot. void RecordDebugBreakSlot(RelocInfo::Mode mode); @@ -1409,6 +1421,8 @@ class Assembler : public AssemblerBase { void x_form(Instr instr, Register ra, Register rs, Register rb, RCBit r); void xo_form(Instr instr, Register rt, Register ra, Register rb, OEBit o, RCBit r); + void xx3_form(Instr instr, DoubleRegister t, DoubleRegister a, + DoubleRegister b); void md_form(Instr instr, Register ra, Register rs, int shift, int maskbit, RCBit r); void mds_form(Instr instr, Register ra, Register rs, Register rb, int maskbit, diff --git a/deps/v8/src/ppc/code-stubs-ppc.cc b/deps/v8/src/ppc/code-stubs-ppc.cc index a48fc06116..c2c27d6c99 100644 --- a/deps/v8/src/ppc/code-stubs-ppc.cc +++ b/deps/v8/src/ppc/code-stubs-ppc.cc @@ -32,17 +32,6 @@ void ArrayNArgumentsConstructorStub::Generate(MacroAssembler* masm) { __ TailCallRuntime(Runtime::kNewArray); } -void FastArrayPushStub::InitializeDescriptor(CodeStubDescriptor* descriptor) { - Address deopt_handler = Runtime::FunctionForId(Runtime::kArrayPush)->entry; - descriptor->Initialize(r3, deopt_handler, -1, JS_FUNCTION_STUB_MODE); -} - -void FastFunctionBindStub::InitializeDescriptor( - CodeStubDescriptor* descriptor) { - Address deopt_handler = Runtime::FunctionForId(Runtime::kFunctionBind)->entry; - descriptor->Initialize(r3, deopt_handler, -1, JS_FUNCTION_STUB_MODE); -} - static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow, Condition cond); static void EmitSmiNonsmiComparison(MacroAssembler* masm, Register lhs, @@ -664,8 +653,11 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) { if (cc == eq) { { FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); - __ Push(lhs, rhs); - __ CallRuntime(strict() ? Runtime::kStrictEqual : Runtime::kEqual); + __ Push(cp); + __ Call(strict() ? isolate()->builtins()->StrictEqual() + : isolate()->builtins()->Equal(), + RelocInfo::CODE_TARGET); + __ Pop(cp); } // Turn true into 0 and false into some non-zero value. STATIC_ASSERT(EQUAL == 0); @@ -879,7 +871,6 @@ void CodeStub::GenerateFPStubs(Isolate* isolate) { SaveFPRegsMode mode = kSaveFPRegs; CEntryStub(isolate, 1, mode).GetCode(); StoreBufferOverflowStub(isolate, mode).GetCode(); - isolate->set_fp_stubs_generated(true); } @@ -2170,45 +2161,6 @@ void StringCharFromCodeGenerator::GenerateSlow( __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase); } - -enum CopyCharactersFlags { COPY_ONE_BYTE = 1, DEST_ALWAYS_ALIGNED = 2 }; - - -void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, Register dest, - Register src, Register count, - Register scratch, - String::Encoding encoding) { - if (FLAG_debug_code) { - // Check that destination is word aligned. - __ andi(r0, dest, Operand(kPointerAlignmentMask)); - __ Check(eq, kDestinationOfCopyNotAligned, cr0); - } - - // Nothing to do for zero characters. - Label done; - if (encoding == String::TWO_BYTE_ENCODING) { - // double the length - __ add(count, count, count, LeaveOE, SetRC); - __ beq(&done, cr0); - } else { - __ cmpi(count, Operand::Zero()); - __ beq(&done); - } - - // Copy count bytes from src to dst. - Label byte_loop; - __ mtctr(count); - __ bind(&byte_loop); - __ lbz(scratch, MemOperand(src)); - __ addi(src, src, Operand(1)); - __ stb(scratch, MemOperand(dest)); - __ addi(dest, dest, Operand(1)); - __ bdnz(&byte_loop); - - __ bind(&done); -} - - void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm, Register left, Register right, @@ -2842,84 +2794,6 @@ void NameDictionaryLookupStub::GenerateNegativeLookup( __ bne(miss); } - -// Probe the name dictionary in the |elements| register. Jump to the -// |done| label if a property with the given name is found. Jump to -// the |miss| label otherwise. -// If lookup was successful |scratch2| will be equal to elements + 4 * index. -void NameDictionaryLookupStub::GeneratePositiveLookup( - MacroAssembler* masm, Label* miss, Label* done, Register elements, - Register name, Register scratch1, Register scratch2) { - DCHECK(!elements.is(scratch1)); - DCHECK(!elements.is(scratch2)); - DCHECK(!name.is(scratch1)); - DCHECK(!name.is(scratch2)); - - __ AssertName(name); - - // Compute the capacity mask. - __ LoadP(scratch1, FieldMemOperand(elements, kCapacityOffset)); - __ SmiUntag(scratch1); // convert smi to int - __ subi(scratch1, scratch1, Operand(1)); - - // Generate an unrolled loop that performs a few probes before - // giving up. Measurements done on Gmail indicate that 2 probes - // cover ~93% of loads from dictionaries. - for (int i = 0; i < kInlinedProbes; i++) { - // Compute the masked index: (hash + i + i * i) & mask. - __ lwz(scratch2, FieldMemOperand(name, Name::kHashFieldOffset)); - if (i > 0) { - // Add the probe offset (i + i * i) left shifted to avoid right shifting - // the hash in a separate instruction. The value hash + i + i * i is right - // shifted in the following and instruction. - DCHECK(NameDictionary::GetProbeOffset(i) < - 1 << (32 - Name::kHashFieldOffset)); - __ addi(scratch2, scratch2, - Operand(NameDictionary::GetProbeOffset(i) << Name::kHashShift)); - } - __ srwi(scratch2, scratch2, Operand(Name::kHashShift)); - __ and_(scratch2, scratch1, scratch2); - - // Scale the index by multiplying by the entry size. - STATIC_ASSERT(NameDictionary::kEntrySize == 3); - // scratch2 = scratch2 * 3. - __ ShiftLeftImm(ip, scratch2, Operand(1)); - __ add(scratch2, scratch2, ip); - - // Check if the key is identical to the name. - __ ShiftLeftImm(ip, scratch2, Operand(kPointerSizeLog2)); - __ add(scratch2, elements, ip); - __ LoadP(ip, FieldMemOperand(scratch2, kElementsStartOffset)); - __ cmp(name, ip); - __ beq(done); - } - - const int spill_mask = (r0.bit() | r9.bit() | r8.bit() | r7.bit() | r6.bit() | - r5.bit() | r4.bit() | r3.bit()) & - ~(scratch1.bit() | scratch2.bit()); - - __ mflr(r0); - __ MultiPush(spill_mask); - if (name.is(r3)) { - DCHECK(!elements.is(r4)); - __ mr(r4, name); - __ mr(r3, elements); - } else { - __ mr(r3, elements); - __ mr(r4, name); - } - NameDictionaryLookupStub stub(masm->isolate(), POSITIVE_LOOKUP); - __ CallStub(&stub); - __ cmpi(r3, Operand::Zero()); - __ mr(scratch2, r5); - __ MultiPop(spill_mask); - __ mtlr(r0); - - __ bne(done); - __ beq(miss); -} - - void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { // This stub overrides SometimesSetsUpAFrame() to return false. That means // we cannot call anything that could cause a GC from this stub. @@ -3202,246 +3076,6 @@ void CallICTrampolineStub::Generate(MacroAssembler* masm) { __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); } - -static void HandleArrayCases(MacroAssembler* masm, Register feedback, - Register receiver_map, Register scratch1, - Register scratch2, bool is_polymorphic, - Label* miss) { - // feedback initially contains the feedback array - Label next_loop, prepare_next; - Label start_polymorphic; - - Register cached_map = scratch1; - - __ LoadP(cached_map, - FieldMemOperand(feedback, FixedArray::OffsetOfElementAt(0))); - __ LoadP(cached_map, FieldMemOperand(cached_map, WeakCell::kValueOffset)); - __ cmp(receiver_map, cached_map); - __ bne(&start_polymorphic); - // found, now call handler. - Register handler = feedback; - __ LoadP(handler, - FieldMemOperand(feedback, FixedArray::OffsetOfElementAt(1))); - __ addi(ip, handler, Operand(Code::kHeaderSize - kHeapObjectTag)); - __ Jump(ip); - - - Register length = scratch2; - __ bind(&start_polymorphic); - __ LoadP(length, FieldMemOperand(feedback, FixedArray::kLengthOffset)); - if (!is_polymorphic) { - // If the IC could be monomorphic we have to make sure we don't go past the - // end of the feedback array. - __ CmpSmiLiteral(length, Smi::FromInt(2), r0); - __ beq(miss); - } - - Register too_far = length; - Register pointer_reg = feedback; - - // +-----+------+------+-----+-----+ ... ----+ - // | map | len | wm0 | h0 | wm1 | hN | - // +-----+------+------+-----+-----+ ... ----+ - // 0 1 2 len-1 - // ^ ^ - // | | - // pointer_reg too_far - // aka feedback scratch2 - // also need receiver_map - // use cached_map (scratch1) to look in the weak map values. - __ SmiToPtrArrayOffset(r0, length); - __ add(too_far, feedback, r0); - __ addi(too_far, too_far, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); - __ addi(pointer_reg, feedback, - Operand(FixedArray::OffsetOfElementAt(2) - kHeapObjectTag)); - - __ bind(&next_loop); - __ LoadP(cached_map, MemOperand(pointer_reg)); - __ LoadP(cached_map, FieldMemOperand(cached_map, WeakCell::kValueOffset)); - __ cmp(receiver_map, cached_map); - __ bne(&prepare_next); - __ LoadP(handler, MemOperand(pointer_reg, kPointerSize)); - __ addi(ip, handler, Operand(Code::kHeaderSize - kHeapObjectTag)); - __ Jump(ip); - - __ bind(&prepare_next); - __ addi(pointer_reg, pointer_reg, Operand(kPointerSize * 2)); - __ cmp(pointer_reg, too_far); - __ blt(&next_loop); - - // We exhausted our array of map handler pairs. - __ b(miss); -} - - -static void HandleMonomorphicCase(MacroAssembler* masm, Register receiver, - Register receiver_map, Register feedback, - Register vector, Register slot, - Register scratch, Label* compare_map, - Label* load_smi_map, Label* try_array) { - __ JumpIfSmi(receiver, load_smi_map); - __ LoadP(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset)); - __ bind(compare_map); - Register cached_map = scratch; - // Move the weak map into the weak_cell register. - __ LoadP(cached_map, FieldMemOperand(feedback, WeakCell::kValueOffset)); - __ cmp(cached_map, receiver_map); - __ bne(try_array); - Register handler = feedback; - __ SmiToPtrArrayOffset(r0, slot); - __ add(handler, vector, r0); - __ LoadP(handler, - FieldMemOperand(handler, FixedArray::kHeaderSize + kPointerSize)); - __ addi(ip, handler, Operand(Code::kHeaderSize - kHeapObjectTag)); - __ Jump(ip); -} - -void KeyedStoreICTrampolineStub::Generate(MacroAssembler* masm) { - __ EmitLoadTypeFeedbackVector(StoreWithVectorDescriptor::VectorRegister()); - KeyedStoreICStub stub(isolate(), state()); - stub.GenerateForTrampoline(masm); -} - -void KeyedStoreICStub::Generate(MacroAssembler* masm) { - GenerateImpl(masm, false); -} - -void KeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { - GenerateImpl(masm, true); -} - - -static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register feedback, - Register receiver_map, Register scratch1, - Register scratch2, Label* miss) { - // feedback initially contains the feedback array - Label next_loop, prepare_next; - Label start_polymorphic; - Label transition_call; - - Register cached_map = scratch1; - Register too_far = scratch2; - Register pointer_reg = feedback; - __ LoadP(too_far, FieldMemOperand(feedback, FixedArray::kLengthOffset)); - - // +-----+------+------+-----+-----+-----+ ... ----+ - // | map | len | wm0 | wt0 | h0 | wm1 | hN | - // +-----+------+------+-----+-----+ ----+ ... ----+ - // 0 1 2 len-1 - // ^ ^ - // | | - // pointer_reg too_far - // aka feedback scratch2 - // also need receiver_map - // use cached_map (scratch1) to look in the weak map values. - __ SmiToPtrArrayOffset(r0, too_far); - __ add(too_far, feedback, r0); - __ addi(too_far, too_far, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); - __ addi(pointer_reg, feedback, - Operand(FixedArray::OffsetOfElementAt(0) - kHeapObjectTag)); - - __ bind(&next_loop); - __ LoadP(cached_map, MemOperand(pointer_reg)); - __ LoadP(cached_map, FieldMemOperand(cached_map, WeakCell::kValueOffset)); - __ cmp(receiver_map, cached_map); - __ bne(&prepare_next); - // Is it a transitioning store? - __ LoadP(too_far, MemOperand(pointer_reg, kPointerSize)); - __ CompareRoot(too_far, Heap::kUndefinedValueRootIndex); - __ bne(&transition_call); - __ LoadP(pointer_reg, MemOperand(pointer_reg, kPointerSize * 2)); - __ addi(ip, pointer_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); - __ Jump(ip); - - __ bind(&transition_call); - __ LoadP(too_far, FieldMemOperand(too_far, WeakCell::kValueOffset)); - __ JumpIfSmi(too_far, miss); - - __ LoadP(receiver_map, MemOperand(pointer_reg, kPointerSize * 2)); - - // Load the map into the correct register. - DCHECK(feedback.is(StoreTransitionDescriptor::MapRegister())); - __ mr(feedback, too_far); - - __ addi(ip, receiver_map, Operand(Code::kHeaderSize - kHeapObjectTag)); - __ Jump(ip); - - __ bind(&prepare_next); - __ addi(pointer_reg, pointer_reg, Operand(kPointerSize * 3)); - __ cmpl(pointer_reg, too_far); - __ blt(&next_loop); - - // We exhausted our array of map handler pairs. - __ b(miss); -} - -void KeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { - Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // r4 - Register key = StoreWithVectorDescriptor::NameRegister(); // r5 - Register vector = StoreWithVectorDescriptor::VectorRegister(); // r6 - Register slot = StoreWithVectorDescriptor::SlotRegister(); // r7 - DCHECK(StoreWithVectorDescriptor::ValueRegister().is(r3)); // r3 - Register feedback = r8; - Register receiver_map = r9; - Register scratch1 = r10; - - __ SmiToPtrArrayOffset(r0, slot); - __ add(feedback, vector, r0); - __ LoadP(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize)); - - // Try to quickly handle the monomorphic case without knowing for sure - // if we have a weak cell in feedback. We do know it's safe to look - // at WeakCell::kValueOffset. - Label try_array, load_smi_map, compare_map; - Label not_array, miss; - HandleMonomorphicCase(masm, receiver, receiver_map, feedback, vector, slot, - scratch1, &compare_map, &load_smi_map, &try_array); - - __ bind(&try_array); - // Is it a fixed array? - __ LoadP(scratch1, FieldMemOperand(feedback, HeapObject::kMapOffset)); - __ CompareRoot(scratch1, Heap::kFixedArrayMapRootIndex); - __ bne(¬_array); - - // We have a polymorphic element handler. - Label polymorphic, try_poly_name; - __ bind(&polymorphic); - - Register scratch2 = r11; - - HandlePolymorphicStoreCase(masm, feedback, receiver_map, scratch1, scratch2, - &miss); - - __ bind(¬_array); - // Is it generic? - __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex); - __ bne(&try_poly_name); - Handle<Code> megamorphic_stub = - KeyedStoreIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState()); - __ Jump(megamorphic_stub, RelocInfo::CODE_TARGET); - - __ bind(&try_poly_name); - // We might have a name in feedback, and a fixed array in the next slot. - __ cmp(key, feedback); - __ bne(&miss); - // If the name comparison succeeded, we know we have a fixed array with - // at least one map/handler pair. - __ SmiToPtrArrayOffset(r0, slot); - __ add(feedback, vector, r0); - __ LoadP(feedback, - FieldMemOperand(feedback, FixedArray::kHeaderSize + kPointerSize)); - HandleArrayCases(masm, feedback, receiver_map, scratch1, scratch2, false, - &miss); - - __ bind(&miss); - KeyedStoreIC::GenerateMiss(masm); - - __ bind(&load_smi_map); - __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); - __ b(&compare_map); -} - - void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { if (masm->isolate()->function_entry_hook() != NULL) { PredictableCodeSizeScope predictable(masm, @@ -3812,122 +3446,6 @@ void InternalArrayConstructorStub::Generate(MacroAssembler* masm) { GenerateCase(masm, FAST_ELEMENTS); } -void FastNewObjectStub::Generate(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- r4 : target - // -- r6 : new target - // -- cp : context - // -- lr : return address - // ----------------------------------- - __ AssertFunction(r4); - __ AssertReceiver(r6); - - // Verify that the new target is a JSFunction. - Label new_object; - __ CompareObjectType(r6, r5, r5, JS_FUNCTION_TYPE); - __ bne(&new_object); - - // Load the initial map and verify that it's in fact a map. - __ LoadP(r5, FieldMemOperand(r6, JSFunction::kPrototypeOrInitialMapOffset)); - __ JumpIfSmi(r5, &new_object); - __ CompareObjectType(r5, r3, r3, MAP_TYPE); - __ bne(&new_object); - - // Fall back to runtime if the target differs from the new target's - // initial map constructor. - __ LoadP(r3, FieldMemOperand(r5, Map::kConstructorOrBackPointerOffset)); - __ cmp(r3, r4); - __ bne(&new_object); - - // Allocate the JSObject on the heap. - Label allocate, done_allocate; - __ lbz(r7, FieldMemOperand(r5, Map::kInstanceSizeOffset)); - __ Allocate(r7, r3, r8, r9, &allocate, SIZE_IN_WORDS); - __ bind(&done_allocate); - - // Initialize the JSObject fields. - __ StoreP(r5, FieldMemOperand(r3, JSObject::kMapOffset), r0); - __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex); - __ StoreP(r6, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0); - __ StoreP(r6, FieldMemOperand(r3, JSObject::kElementsOffset), r0); - STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize); - __ addi(r4, r3, Operand(JSObject::kHeaderSize - kHeapObjectTag)); - - // ----------- S t a t e ------------- - // -- r3 : result (tagged) - // -- r4 : result fields (untagged) - // -- r8 : result end (untagged) - // -- r5 : initial map - // -- cp : context - // -- lr : return address - // ----------------------------------- - - // Perform in-object slack tracking if requested. - Label slack_tracking; - STATIC_ASSERT(Map::kNoSlackTracking == 0); - __ LoadRoot(r9, Heap::kUndefinedValueRootIndex); - __ lwz(r6, FieldMemOperand(r5, Map::kBitField3Offset)); - __ DecodeField<Map::ConstructionCounter>(r10, r6, SetRC); - __ bne(&slack_tracking, cr0); - { - // Initialize all in-object fields with undefined. - __ InitializeFieldsWithFiller(r4, r8, r9); - __ Ret(); - } - __ bind(&slack_tracking); - { - // Decrease generous allocation count. - STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); - __ Add(r6, r6, -(1 << Map::ConstructionCounter::kShift), r0); - __ stw(r6, FieldMemOperand(r5, Map::kBitField3Offset)); - - // Initialize the in-object fields with undefined. - __ lbz(r7, FieldMemOperand(r5, Map::kUnusedPropertyFieldsOffset)); - __ ShiftLeftImm(r7, r7, Operand(kPointerSizeLog2)); - __ sub(r7, r8, r7); - __ InitializeFieldsWithFiller(r4, r7, r9); - - // Initialize the remaining (reserved) fields with one pointer filler map. - __ LoadRoot(r9, Heap::kOnePointerFillerMapRootIndex); - __ InitializeFieldsWithFiller(r4, r8, r9); - - // Check if we can finalize the instance size. - __ cmpi(r10, Operand(Map::kSlackTrackingCounterEnd)); - __ Ret(ne); - - // Finalize the instance size. - { - FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); - __ Push(r3, r5); - __ CallRuntime(Runtime::kFinalizeInstanceSize); - __ Pop(r3); - } - __ Ret(); - } - - // Fall back to %AllocateInNewSpace. - __ bind(&allocate); - { - FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); - STATIC_ASSERT(kSmiTag == 0); - __ ShiftLeftImm(r7, r7, - Operand(kPointerSizeLog2 + kSmiTagSize + kSmiShiftSize)); - __ Push(r5, r7); - __ CallRuntime(Runtime::kAllocateInNewSpace); - __ Pop(r5); - } - __ lbz(r8, FieldMemOperand(r5, Map::kInstanceSizeOffset)); - __ ShiftLeftImm(r8, r8, Operand(kPointerSizeLog2)); - __ add(r8, r3, r8); - __ subi(r8, r8, Operand(kHeapObjectTag)); - __ b(&done_allocate); - - // Fall back to %NewObject. - __ bind(&new_object); - __ Push(r4, r6); - __ TailCallRuntime(Runtime::kNewObject); -} - void FastNewRestParameterStub::Generate(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- r4 : function diff --git a/deps/v8/src/ppc/code-stubs-ppc.h b/deps/v8/src/ppc/code-stubs-ppc.h index d394171d89..f873f93679 100644 --- a/deps/v8/src/ppc/code-stubs-ppc.h +++ b/deps/v8/src/ppc/code-stubs-ppc.h @@ -16,15 +16,6 @@ void ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code); class StringHelper : public AllStatic { public: - // Generate code for copying a large number of characters. This function - // is allowed to spend extra time setting up conditions to make copying - // faster. Copying of overlapping regions is not supported. - // Dest register ends at the position after the last character written. - static void GenerateCopyCharacters(MacroAssembler* masm, Register dest, - Register src, Register count, - Register scratch, - String::Encoding encoding); - // Compares two flat one-byte strings and returns result in r0. static void GenerateCompareFlatOneByteStrings(MacroAssembler* masm, Register left, Register right, @@ -297,10 +288,6 @@ class NameDictionaryLookupStub : public PlatformCodeStub { Register properties, Handle<Name> name, Register scratch0); - static void GeneratePositiveLookup(MacroAssembler* masm, Label* miss, - Label* done, Register elements, - Register name, Register r0, Register r1); - bool SometimesSetsUpAFrame() override { return false; } private: diff --git a/deps/v8/src/ppc/codegen-ppc.cc b/deps/v8/src/ppc/codegen-ppc.cc index 07853edc20..bb365b4e63 100644 --- a/deps/v8/src/ppc/codegen-ppc.cc +++ b/deps/v8/src/ppc/codegen-ppc.cc @@ -73,304 +73,6 @@ void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { #define __ ACCESS_MASM(masm) -void ElementsTransitionGenerator::GenerateMapChangeElementsTransition( - MacroAssembler* masm, Register receiver, Register key, Register value, - Register target_map, AllocationSiteMode mode, - Label* allocation_memento_found) { - Register scratch_elements = r7; - DCHECK(!AreAliased(receiver, key, value, target_map, scratch_elements)); - - if (mode == TRACK_ALLOCATION_SITE) { - DCHECK(allocation_memento_found != NULL); - __ JumpIfJSArrayHasAllocationMemento(receiver, scratch_elements, r11, - allocation_memento_found); - } - - // Set transitioned map. - __ StoreP(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset), r0); - __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, r11, - kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET, - OMIT_SMI_CHECK); -} - - -void ElementsTransitionGenerator::GenerateSmiToDouble( - MacroAssembler* masm, Register receiver, Register key, Register value, - Register target_map, AllocationSiteMode mode, Label* fail) { - // lr contains the return address - Label loop, entry, convert_hole, only_change_map, done; - Register elements = r7; - Register length = r8; - Register array = r9; - Register array_end = array; - - // target_map parameter can be clobbered. - Register scratch1 = target_map; - Register scratch2 = r10; - Register scratch3 = r11; - Register scratch4 = r14; - - // Verify input registers don't conflict with locals. - DCHECK(!AreAliased(receiver, key, value, target_map, elements, length, array, - scratch2)); - - if (mode == TRACK_ALLOCATION_SITE) { - __ JumpIfJSArrayHasAllocationMemento(receiver, elements, scratch3, fail); - } - - // Check for empty arrays, which only require a map transition and no changes - // to the backing store. - __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); - __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex); - __ beq(&only_change_map); - - __ LoadP(length, FieldMemOperand(elements, FixedArray::kLengthOffset)); - // length: number of elements (smi-tagged) - - // Allocate new FixedDoubleArray. - __ SmiToDoubleArrayOffset(scratch3, length); - __ addi(scratch3, scratch3, Operand(FixedDoubleArray::kHeaderSize)); - __ Allocate(scratch3, array, scratch4, scratch2, fail, DOUBLE_ALIGNMENT); - __ subi(array, array, Operand(kHeapObjectTag)); - // array: destination FixedDoubleArray, not tagged as heap object. - // elements: source FixedArray. - - // Set destination FixedDoubleArray's length and map. - __ LoadRoot(scratch2, Heap::kFixedDoubleArrayMapRootIndex); - __ StoreP(length, MemOperand(array, FixedDoubleArray::kLengthOffset)); - // Update receiver's map. - __ StoreP(scratch2, MemOperand(array, HeapObject::kMapOffset)); - - __ StoreP(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset), r0); - __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, scratch2, - kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET, - OMIT_SMI_CHECK); - // Replace receiver's backing store with newly created FixedDoubleArray. - __ addi(scratch1, array, Operand(kHeapObjectTag)); - __ StoreP(scratch1, FieldMemOperand(receiver, JSObject::kElementsOffset), r0); - __ RecordWriteField(receiver, JSObject::kElementsOffset, scratch1, scratch2, - kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET, - OMIT_SMI_CHECK); - - // Prepare for conversion loop. - __ addi(scratch1, elements, - Operand(FixedArray::kHeaderSize - kHeapObjectTag)); - __ addi(scratch2, array, Operand(FixedDoubleArray::kHeaderSize)); - __ SmiToDoubleArrayOffset(array_end, length); - __ add(array_end, scratch2, array_end); -// Repurpose registers no longer in use. -#if V8_TARGET_ARCH_PPC64 - Register hole_int64 = elements; - __ mov(hole_int64, Operand(kHoleNanInt64)); -#else - Register hole_lower = elements; - Register hole_upper = length; - __ mov(hole_lower, Operand(kHoleNanLower32)); - __ mov(hole_upper, Operand(kHoleNanUpper32)); -#endif - // scratch1: begin of source FixedArray element fields, not tagged - // hole_lower: kHoleNanLower32 OR hol_int64 - // hole_upper: kHoleNanUpper32 - // array_end: end of destination FixedDoubleArray, not tagged - // scratch2: begin of FixedDoubleArray element fields, not tagged - - __ b(&entry); - - __ bind(&only_change_map); - __ StoreP(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset), r0); - __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, scratch2, - kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET, - OMIT_SMI_CHECK); - __ b(&done); - - // Convert and copy elements. - __ bind(&loop); - __ LoadP(scratch3, MemOperand(scratch1)); - __ addi(scratch1, scratch1, Operand(kPointerSize)); - // scratch3: current element - __ UntagAndJumpIfNotSmi(scratch3, scratch3, &convert_hole); - - // Normal smi, convert to double and store. - __ ConvertIntToDouble(scratch3, d0); - __ stfd(d0, MemOperand(scratch2, 0)); - __ addi(scratch2, scratch2, Operand(8)); - __ b(&entry); - - // Hole found, store the-hole NaN. - __ bind(&convert_hole); - if (FLAG_debug_code) { - __ LoadP(scratch3, MemOperand(scratch1, -kPointerSize)); - __ CompareRoot(scratch3, Heap::kTheHoleValueRootIndex); - __ Assert(eq, kObjectFoundInSmiOnlyArray); - } -#if V8_TARGET_ARCH_PPC64 - __ std(hole_int64, MemOperand(scratch2, 0)); -#else - __ stw(hole_upper, MemOperand(scratch2, Register::kExponentOffset)); - __ stw(hole_lower, MemOperand(scratch2, Register::kMantissaOffset)); -#endif - __ addi(scratch2, scratch2, Operand(8)); - - __ bind(&entry); - __ cmp(scratch2, array_end); - __ blt(&loop); - - __ bind(&done); -} - - -void ElementsTransitionGenerator::GenerateDoubleToObject( - MacroAssembler* masm, Register receiver, Register key, Register value, - Register target_map, AllocationSiteMode mode, Label* fail) { - // Register lr contains the return address. - Label loop, convert_hole, gc_required, only_change_map; - Register elements = r7; - Register array = r9; - Register length = r8; - Register scratch = r10; - Register scratch3 = r11; - Register hole_value = r14; - - // Verify input registers don't conflict with locals. - DCHECK(!AreAliased(receiver, key, value, target_map, elements, array, length, - scratch)); - - if (mode == TRACK_ALLOCATION_SITE) { - __ JumpIfJSArrayHasAllocationMemento(receiver, elements, scratch3, fail); - } - - // Check for empty arrays, which only require a map transition and no changes - // to the backing store. - __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); - __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex); - __ beq(&only_change_map); - - __ Push(target_map, receiver, key, value); - __ LoadP(length, FieldMemOperand(elements, FixedArray::kLengthOffset)); - // elements: source FixedDoubleArray - // length: number of elements (smi-tagged) - - // Allocate new FixedArray. - // Re-use value and target_map registers, as they have been saved on the - // stack. - Register array_size = value; - Register allocate_scratch = target_map; - __ li(array_size, Operand(FixedDoubleArray::kHeaderSize)); - __ SmiToPtrArrayOffset(r0, length); - __ add(array_size, array_size, r0); - __ Allocate(array_size, array, allocate_scratch, scratch, &gc_required, - NO_ALLOCATION_FLAGS); - // array: destination FixedArray, tagged as heap object - // Set destination FixedDoubleArray's length and map. - __ LoadRoot(scratch, Heap::kFixedArrayMapRootIndex); - __ StoreP(length, FieldMemOperand(array, - FixedDoubleArray::kLengthOffset), r0); - __ StoreP(scratch, FieldMemOperand(array, HeapObject::kMapOffset), r0); - - // Prepare for conversion loop. - Register src_elements = elements; - Register dst_elements = target_map; - Register dst_end = length; - Register heap_number_map = scratch; - __ addi(src_elements, elements, - Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); - __ SmiToPtrArrayOffset(length, length); - __ LoadRoot(hole_value, Heap::kTheHoleValueRootIndex); - - Label initialization_loop, loop_done; - __ ShiftRightImm(r0, length, Operand(kPointerSizeLog2), SetRC); - __ beq(&loop_done, cr0); - - // Allocating heap numbers in the loop below can fail and cause a jump to - // gc_required. We can't leave a partly initialized FixedArray behind, - // so pessimistically fill it with holes now. - __ mtctr(r0); - __ addi(dst_elements, array, - Operand(FixedArray::kHeaderSize - kHeapObjectTag - kPointerSize)); - __ bind(&initialization_loop); - __ StorePU(hole_value, MemOperand(dst_elements, kPointerSize)); - __ bdnz(&initialization_loop); - - __ addi(dst_elements, array, - Operand(FixedArray::kHeaderSize - kHeapObjectTag)); - __ add(dst_end, dst_elements, length); - __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); - // Using offsetted addresses in src_elements to fully take advantage of - // post-indexing. - // dst_elements: begin of destination FixedArray element fields, not tagged - // src_elements: begin of source FixedDoubleArray element fields, - // not tagged, +4 - // dst_end: end of destination FixedArray, not tagged - // array: destination FixedArray - // hole_value: the-hole pointer - // heap_number_map: heap number map - __ b(&loop); - - // Call into runtime if GC is required. - __ bind(&gc_required); - __ Pop(target_map, receiver, key, value); - __ b(fail); - - // Replace the-hole NaN with the-hole pointer. - __ bind(&convert_hole); - __ StoreP(hole_value, MemOperand(dst_elements)); - __ addi(dst_elements, dst_elements, Operand(kPointerSize)); - __ cmpl(dst_elements, dst_end); - __ bge(&loop_done); - - __ bind(&loop); - Register upper_bits = key; - __ lwz(upper_bits, MemOperand(src_elements, Register::kExponentOffset)); - __ addi(src_elements, src_elements, Operand(kDoubleSize)); - // upper_bits: current element's upper 32 bit - // src_elements: address of next element's upper 32 bit - __ Cmpi(upper_bits, Operand(kHoleNanUpper32), r0); - __ beq(&convert_hole); - - // Non-hole double, copy value into a heap number. - Register heap_number = receiver; - Register scratch2 = value; - __ AllocateHeapNumber(heap_number, scratch2, scratch3, heap_number_map, - &gc_required); - // heap_number: new heap number -#if V8_TARGET_ARCH_PPC64 - __ ld(scratch2, MemOperand(src_elements, -kDoubleSize)); - // subtract tag for std - __ addi(upper_bits, heap_number, Operand(-kHeapObjectTag)); - __ std(scratch2, MemOperand(upper_bits, HeapNumber::kValueOffset)); -#else - __ lwz(scratch2, - MemOperand(src_elements, Register::kMantissaOffset - kDoubleSize)); - __ lwz(upper_bits, - MemOperand(src_elements, Register::kExponentOffset - kDoubleSize)); - __ stw(scratch2, FieldMemOperand(heap_number, HeapNumber::kMantissaOffset)); - __ stw(upper_bits, FieldMemOperand(heap_number, HeapNumber::kExponentOffset)); -#endif - __ mr(scratch2, dst_elements); - __ StoreP(heap_number, MemOperand(dst_elements)); - __ addi(dst_elements, dst_elements, Operand(kPointerSize)); - __ RecordWrite(array, scratch2, heap_number, kLRHasNotBeenSaved, - kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); - __ cmpl(dst_elements, dst_end); - __ blt(&loop); - __ bind(&loop_done); - - __ Pop(target_map, receiver, key, value); - // Replace receiver's backing store with newly created and filled FixedArray. - __ StoreP(array, FieldMemOperand(receiver, JSObject::kElementsOffset), r0); - __ RecordWriteField(receiver, JSObject::kElementsOffset, array, scratch, - kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET, - OMIT_SMI_CHECK); - - __ bind(&only_change_map); - // Update receiver's map. - __ StoreP(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset), r0); - __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, scratch, - kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET, - OMIT_SMI_CHECK); -} - - // assume ip can be used as a scratch register below void StringCharLoadGenerator::Generate(MacroAssembler* masm, Register string, Register index, Register result, @@ -493,31 +195,25 @@ bool Code::IsYoungSequence(Isolate* isolate, byte* sequence) { return result; } +Code::Age Code::GetCodeAge(Isolate* isolate, byte* sequence) { + if (IsYoungSequence(isolate, sequence)) return kNoAgeCodeAge; -void Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age, - MarkingParity* parity) { - if (IsYoungSequence(isolate, sequence)) { - *age = kNoAgeCodeAge; - *parity = NO_MARKING_PARITY; - } else { - Code* code = NULL; - Address target_address = - Assembler::target_address_at(sequence + kCodeAgingTargetDelta, code); - Code* stub = GetCodeFromTargetAddress(target_address); - GetCodeAgeAndParity(stub, age, parity); - } + Code* code = NULL; + Address target_address = + Assembler::target_address_at(sequence + kCodeAgingTargetDelta, code); + Code* stub = GetCodeFromTargetAddress(target_address); + return GetAgeOfCodeAgeStub(stub); } - -void Code::PatchPlatformCodeAge(Isolate* isolate, byte* sequence, Code::Age age, - MarkingParity parity) { +void Code::PatchPlatformCodeAge(Isolate* isolate, byte* sequence, + Code::Age age) { uint32_t young_length = isolate->code_aging_helper()->young_sequence_length(); if (age == kNoAgeCodeAge) { isolate->code_aging_helper()->CopyYoungSequenceTo(sequence); Assembler::FlushICache(isolate, sequence, young_length); } else { // FIXED_SEQUENCE - Code* stub = GetCodeAgeStub(isolate, age, parity); + Code* stub = GetCodeAgeStub(isolate, age); CodePatcher patcher(isolate, sequence, young_length / Assembler::kInstrSize); Assembler::BlockTrampolinePoolScope block_trampoline_pool(patcher.masm()); diff --git a/deps/v8/src/ppc/constants-ppc.h b/deps/v8/src/ppc/constants-ppc.h index 393f039e27..daa52257d6 100644 --- a/deps/v8/src/ppc/constants-ppc.h +++ b/deps/v8/src/ppc/constants-ppc.h @@ -145,6 +145,7 @@ enum Opcode { STFDU = 55 << 26, // Store Floating-Point Double with Update LD = 58 << 26, // Load Double Word EXT3 = 59 << 26, // Extended code set 3 + EXT6 = 60 << 26, // Extended code set 6 STD = 62 << 26, // Store Double Word (optionally with Update) EXT4 = 63 << 26 // Extended code set 4 }; @@ -203,24 +204,27 @@ enum OpcodeExt2 { STWX = 151 << 1, // store word w/ x-form MTVSRD = 179 << 1, // Move To VSR Doubleword STDUX = 181 << 1, - STWUX = 183 << 1, // store word w/ update x-form - /* - MTCRF - MTMSR - STWCXx - SUBFZEX - */ - ADDZEX = 202 << 1, // Add to Zero Extended - /* - MTSR + STWUX = 183 << 1, // store word w/ update x-form + /* + MTCRF + MTMSR + STWCXx + SUBFZEX */ + ADDZEX = 202 << 1, // Add to Zero Extended + /* + MTSR + */ + MTVSRWA = 211 << 1, // Move To VSR Word Algebraic STBX = 215 << 1, // store byte w/ x-form MULLD = 233 << 1, // Multiply Low Double Word MULLW = 235 << 1, // Multiply Low Word MTVSRWZ = 243 << 1, // Move To VSR Word And Zero STBUX = 247 << 1, // store byte w/ update x-form + MODUD = 265 << 1, // Modulo Unsigned Dword ADDX = 266 << 1, // Add + MODUW = 267 << 1, // Modulo Unsigned Word LHZX = 279 << 1, // load half-word zero w/ x-form LHZUX = 311 << 1, // load half-word zero w/ update x-form LWAX = 341 << 1, // load word algebraic w/ x-form @@ -254,6 +258,8 @@ enum OpcodeExt2 { STFSUX = 695 << 1, // store float-single w/ update x-form STFDX = 727 << 1, // store float-double w/ x-form STFDUX = 759 << 1, // store float-double w/ update x-form + MODSD = 777 << 1, // Modulo Signed Dword + MODSW = 779 << 1, // Modulo Signed Word LHBRX = 790 << 1, // load half word byte reversed w/ x-form SRAW = 792 << 1, // Shift Right Algebraic Word SRAD = 794 << 1, // Shift Right Algebraic Double Word @@ -314,10 +320,37 @@ enum OpcodeExt5 { RLDCR = 9 << 1 // Rotate Left Double Word then Clear Right }; +// Bits 10-3 +#define XX3_OPCODE_LIST(V) \ + V(xsaddsp, XSADDSP, 0 << 3) /* VSX Scalar Add SP */ \ + V(xssubsp, XSSUBSP, 8 << 3) /* VSX Scalar Subtract SP */ \ + V(xsmulsp, XSMULSP, 16 << 3) /* VSX Scalar Multiply SP */ \ + V(xsdivsp, XSDIVSP, 24 << 3) /* VSX Scalar Divide SP */ \ + V(xsadddp, XSADDDP, 32 << 3) /* VSX Scalar Add DP */ \ + V(xssubdp, XSSUBDP, 40 << 3) /* VSX Scalar Subtract DP */ \ + V(xsmuldp, XSMULDP, 48 << 3) /* VSX Scalar Multiply DP */ \ + V(xsdivdp, XSDIVDP, 56 << 3) /* VSX Scalar Divide DP */ \ + V(xsmaxdp, XSMAXDP, 160 << 3) /* VSX Scalar Maximum DP */ \ + V(xsmindp, XSMINDP, 168 << 3) /* VSX Scalar Minimum DP */ + +// Bits 10-2 +#define XX2_OPCODE_LIST(V) \ + V(XSCVDPSP, XSCVDPSP, 265 << 2) /* VSX Scalar Convert DP to SP */ \ + V(XSCVSPDP, XSCVSPDP, 329 << 2) /* VSX Scalar Convert SP to DP */ + +enum OpcodeExt6 { +#define DECLARE_OPCODES(name, opcode_name, opcode_value) \ + opcode_name = opcode_value, + XX3_OPCODE_LIST(DECLARE_OPCODES) XX2_OPCODE_LIST(DECLARE_OPCODES) +#undef DECLARE_OPCODES +}; + // Instruction encoding bits and masks. enum { // Instruction encoding bit B1 = 1 << 1, + B2 = 1 << 2, + B3 = 1 << 3, B4 = 1 << 4, B5 = 1 << 5, B7 = 1 << 7, diff --git a/deps/v8/src/ppc/disasm-ppc.cc b/deps/v8/src/ppc/disasm-ppc.cc index c0a02a8b9c..5da45f27f0 100644 --- a/deps/v8/src/ppc/disasm-ppc.cc +++ b/deps/v8/src/ppc/disasm-ppc.cc @@ -82,6 +82,7 @@ class Decoder { void DecodeExt3(Instruction* instr); void DecodeExt4(Instruction* instr); void DecodeExt5(Instruction* instr); + void DecodeExt6(Instruction* instr); const disasm::NameConverter& converter_; Vector<char> out_buffer_; @@ -561,6 +562,24 @@ void Decoder::DecodeExt2(Instruction* instr) { return; } #endif + case MODSW: { + Format(instr, "modsw 'rt, 'ra, 'rb"); + return; + } + case MODUW: { + Format(instr, "moduw 'rt, 'ra, 'rb"); + return; + } +#if V8_TARGET_ARCH_PPC64 + case MODSD: { + Format(instr, "modsd 'rt, 'ra, 'rb"); + return; + } + case MODUD: { + Format(instr, "modud 'rt, 'ra, 'rb"); + return; + } +#endif case SRAWIX: { Format(instr, "srawi'. 'ra,'rs,'sh"); return; @@ -1073,6 +1092,28 @@ void Decoder::DecodeExt5(Instruction* instr) { Unknown(instr); // not used by V8 } +void Decoder::DecodeExt6(Instruction* instr) { + switch (instr->Bits(10, 3) << 3) { +#define DECODE_XX3_INSTRUCTIONS(name, opcode_name, opcode_value) \ + case opcode_name: { \ + Format(instr, #name" 'Dt, 'Da, 'Db"); \ + return; \ + } + XX3_OPCODE_LIST(DECODE_XX3_INSTRUCTIONS) +#undef DECODE_XX3_INSTRUCTIONS + } + switch (instr->Bits(10, 2) << 2) { +#define DECODE_XX2_INSTRUCTIONS(name, opcode_name, opcode_value) \ + case opcode_name: { \ + Format(instr, #name" 'Dt, 'Db"); \ + return; \ + } + XX2_OPCODE_LIST(DECODE_XX2_INSTRUCTIONS) + } +#undef DECODE_XX3_INSTRUCTIONS + Unknown(instr); // not used by V8 +} + #undef VERIFIY // Disassemble the instruction at *instr_ptr into the output buffer. @@ -1360,6 +1401,10 @@ int Decoder::InstructionDecode(byte* instr_ptr) { DecodeExt5(instr); break; } + case EXT6: { + DecodeExt6(instr); + break; + } #if V8_TARGET_ARCH_PPC64 case LD: { switch (instr->Bits(1, 0)) { diff --git a/deps/v8/src/ppc/interface-descriptors-ppc.cc b/deps/v8/src/ppc/interface-descriptors-ppc.cc index 74ad56405f..4ff59bbaf1 100644 --- a/deps/v8/src/ppc/interface-descriptors-ppc.cc +++ b/deps/v8/src/ppc/interface-descriptors-ppc.cc @@ -63,13 +63,7 @@ const Register GrowArrayElementsDescriptor::KeyRegister() { return r6; } void FastNewClosureDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { - Register registers[] = {r5}; - data->InitializePlatformSpecific(arraysize(registers), registers); -} - -void FastNewObjectDescriptor::InitializePlatformSpecific( - CallInterfaceDescriptorData* data) { - Register registers[] = {r4, r6}; + Register registers[] = {r4, r5, r6}; data->InitializePlatformSpecific(arraysize(registers), registers); } diff --git a/deps/v8/src/ppc/macro-assembler-ppc.cc b/deps/v8/src/ppc/macro-assembler-ppc.cc index 6588540035..172971ea0b 100644 --- a/deps/v8/src/ppc/macro-assembler-ppc.cc +++ b/deps/v8/src/ppc/macro-assembler-ppc.cc @@ -1403,19 +1403,17 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, } } - -void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, - const ParameterCount& expected, - const ParameterCount& actual) { - Label skip_flooding; - ExternalReference last_step_action = - ExternalReference::debug_last_step_action_address(isolate()); - STATIC_ASSERT(StepFrame > StepIn); - mov(r7, Operand(last_step_action)); +void MacroAssembler::CheckDebugHook(Register fun, Register new_target, + const ParameterCount& expected, + const ParameterCount& actual) { + Label skip_hook; + ExternalReference debug_hook_avtive = + ExternalReference::debug_hook_on_function_call_address(isolate()); + mov(r7, Operand(debug_hook_avtive)); LoadByte(r7, MemOperand(r7), r0); extsb(r7, r7); - cmpi(r7, Operand(StepIn)); - blt(&skip_flooding); + CmpSmiLiteral(r7, Smi::kZero, r0); + beq(&skip_hook); { FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); @@ -1431,7 +1429,7 @@ void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, Push(new_target); } Push(fun, fun); - CallRuntime(Runtime::kDebugPrepareStepInIfStepping); + CallRuntime(Runtime::kDebugOnFunctionCall); Pop(fun); if (new_target.is_valid()) { Pop(new_target); @@ -1445,7 +1443,7 @@ void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, SmiUntag(expected.reg()); } } - bind(&skip_flooding); + bind(&skip_hook); } @@ -1459,8 +1457,8 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, DCHECK(function.is(r4)); DCHECK_IMPLIES(new_target.is_valid(), new_target.is(r6)); - if (call_wrapper.NeedsDebugStepCheck()) { - FloodFunctionIfStepping(function, new_target, expected, actual); + if (call_wrapper.NeedsDebugHookCheck()) { + CheckDebugHook(function, new_target, expected, actual); } // Clear the new.target register if not given. @@ -1949,103 +1947,6 @@ void MacroAssembler::FastAllocate(int object_size, Register result, addi(result, result, Operand(kHeapObjectTag)); } - -void MacroAssembler::AllocateTwoByteString(Register result, Register length, - Register scratch1, Register scratch2, - Register scratch3, - Label* gc_required) { - // Calculate the number of bytes needed for the characters in the string while - // observing object alignment. - DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); - slwi(scratch1, length, Operand(1)); // Length in bytes, not chars. - addi(scratch1, scratch1, - Operand(kObjectAlignmentMask + SeqTwoByteString::kHeaderSize)); - mov(r0, Operand(~kObjectAlignmentMask)); - and_(scratch1, scratch1, r0); - - // Allocate two-byte string in new space. - Allocate(scratch1, result, scratch2, scratch3, gc_required, - NO_ALLOCATION_FLAGS); - - // Set the map, length and hash field. - InitializeNewString(result, length, Heap::kStringMapRootIndex, scratch1, - scratch2); -} - - -void MacroAssembler::AllocateOneByteString(Register result, Register length, - Register scratch1, Register scratch2, - Register scratch3, - Label* gc_required) { - // Calculate the number of bytes needed for the characters in the string while - // observing object alignment. - DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); - DCHECK(kCharSize == 1); - addi(scratch1, length, - Operand(kObjectAlignmentMask + SeqOneByteString::kHeaderSize)); - li(r0, Operand(~kObjectAlignmentMask)); - and_(scratch1, scratch1, r0); - - // Allocate one-byte string in new space. - Allocate(scratch1, result, scratch2, scratch3, gc_required, - NO_ALLOCATION_FLAGS); - - // Set the map, length and hash field. - InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex, - scratch1, scratch2); -} - - -void MacroAssembler::AllocateTwoByteConsString(Register result, Register length, - Register scratch1, - Register scratch2, - Label* gc_required) { - Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, - NO_ALLOCATION_FLAGS); - - InitializeNewString(result, length, Heap::kConsStringMapRootIndex, scratch1, - scratch2); -} - - -void MacroAssembler::AllocateOneByteConsString(Register result, Register length, - Register scratch1, - Register scratch2, - Label* gc_required) { - Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, - NO_ALLOCATION_FLAGS); - - InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex, - scratch1, scratch2); -} - - -void MacroAssembler::AllocateTwoByteSlicedString(Register result, - Register length, - Register scratch1, - Register scratch2, - Label* gc_required) { - Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, - NO_ALLOCATION_FLAGS); - - InitializeNewString(result, length, Heap::kSlicedStringMapRootIndex, scratch1, - scratch2); -} - - -void MacroAssembler::AllocateOneByteSlicedString(Register result, - Register length, - Register scratch1, - Register scratch2, - Label* gc_required) { - Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, - NO_ALLOCATION_FLAGS); - - InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex, - scratch1, scratch2); -} - - void MacroAssembler::CompareObjectType(Register object, Register map, Register type_reg, InstanceType type) { const Register temp = type_reg.is(no_reg) ? r0 : type_reg; @@ -2070,60 +1971,6 @@ void MacroAssembler::CompareRoot(Register obj, Heap::RootListIndex index) { cmp(obj, r0); } -void MacroAssembler::CheckFastObjectElements(Register map, Register scratch, - Label* fail) { - STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); - STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); - STATIC_ASSERT(FAST_ELEMENTS == 2); - STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); - lbz(scratch, FieldMemOperand(map, Map::kBitField2Offset)); - cmpli(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); - ble(fail); - cmpli(scratch, Operand(Map::kMaximumBitField2FastHoleyElementValue)); - bgt(fail); -} - - -void MacroAssembler::CheckFastSmiElements(Register map, Register scratch, - Label* fail) { - STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); - STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); - lbz(scratch, FieldMemOperand(map, Map::kBitField2Offset)); - cmpli(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); - bgt(fail); -} - - -void MacroAssembler::StoreNumberToDoubleElements( - Register value_reg, Register key_reg, Register elements_reg, - Register scratch1, DoubleRegister double_scratch, Label* fail, - int elements_offset) { - DCHECK(!AreAliased(value_reg, key_reg, elements_reg, scratch1)); - Label smi_value, store; - - // Handle smi values specially. - JumpIfSmi(value_reg, &smi_value); - - // Ensure that the object is a heap number - CheckMap(value_reg, scratch1, isolate()->factory()->heap_number_map(), fail, - DONT_DO_SMI_CHECK); - - lfd(double_scratch, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); - // Double value, turn potential sNaN into qNaN. - CanonicalizeNaN(double_scratch); - b(&store); - - bind(&smi_value); - SmiToDouble(double_scratch, value_reg); - - bind(&store); - SmiToDoubleArrayOffset(scratch1, key_reg); - add(scratch1, elements_reg, scratch1); - stfd(double_scratch, FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - - elements_offset)); -} - - void MacroAssembler::AddAndCheckForOverflow(Register dst, Register left, Register right, Register overflow_dst, @@ -2737,25 +2584,6 @@ void MacroAssembler::LoadContext(Register dst, int context_chain_length) { } } - -void MacroAssembler::LoadTransitionedArrayMapConditional( - ElementsKind expected_kind, ElementsKind transitioned_kind, - Register map_in_out, Register scratch, Label* no_map_match) { - DCHECK(IsFastElementsKind(expected_kind)); - DCHECK(IsFastElementsKind(transitioned_kind)); - - // Check that the function's map is the same as the expected cached map. - LoadP(scratch, NativeContextMemOperand()); - LoadP(ip, ContextMemOperand(scratch, Context::ArrayMapIndex(expected_kind))); - cmp(map_in_out, ip); - bne(no_map_match); - - // Use the transitioned cached map. - LoadP(map_in_out, - ContextMemOperand(scratch, Context::ArrayMapIndex(transitioned_kind))); -} - - void MacroAssembler::LoadNativeContextSlot(int index, Register dst) { LoadP(dst, NativeContextMemOperand()); LoadP(dst, ContextMemOperand(dst, index)); @@ -2840,16 +2668,6 @@ void MacroAssembler::UntagAndJumpIfSmi(Register dst, Register src, beq(smi_case, cr0); } - -void MacroAssembler::UntagAndJumpIfNotSmi(Register dst, Register src, - Label* non_smi_case) { - STATIC_ASSERT(kSmiTag == 0); - TestBitRange(src, kSmiTagSize - 1, 0, r0); - SmiUntag(dst, src); - bne(non_smi_case, cr0); -} - - void MacroAssembler::JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi) { STATIC_ASSERT(kSmiTag == 0); @@ -3130,19 +2948,6 @@ void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( bne(failure); } - -void MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte(Register type, - Register scratch, - Label* failure) { - const int kFlatOneByteStringMask = - kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; - const int kFlatOneByteStringTag = - kStringTag | kOneByteStringTag | kSeqStringTag; - andi(scratch, type, Operand(kFlatOneByteStringMask)); - cmpi(scratch, Operand(kFlatOneByteStringTag)); - bne(failure); -} - static const int kRegisterPassedArguments = 8; @@ -3867,7 +3672,6 @@ void MacroAssembler::MovIntToFloat(DoubleRegister dst, Register src) { 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)); @@ -4492,44 +4296,6 @@ Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2, Register reg3, return no_reg; } - -void MacroAssembler::JumpIfDictionaryInPrototypeChain(Register object, - Register scratch0, - Register scratch1, - Label* found) { - DCHECK(!scratch1.is(scratch0)); - Register current = scratch0; - Label loop_again, end; - - // scratch contained elements pointer. - mr(current, object); - LoadP(current, FieldMemOperand(current, HeapObject::kMapOffset)); - LoadP(current, FieldMemOperand(current, Map::kPrototypeOffset)); - CompareRoot(current, Heap::kNullValueRootIndex); - beq(&end); - - // Loop based on the map going up the prototype chain. - bind(&loop_again); - LoadP(current, FieldMemOperand(current, HeapObject::kMapOffset)); - - STATIC_ASSERT(JS_PROXY_TYPE < JS_OBJECT_TYPE); - STATIC_ASSERT(JS_VALUE_TYPE < JS_OBJECT_TYPE); - lbz(scratch1, FieldMemOperand(current, Map::kInstanceTypeOffset)); - cmpi(scratch1, Operand(JS_OBJECT_TYPE)); - blt(found); - - lbz(scratch1, FieldMemOperand(current, Map::kBitField2Offset)); - DecodeField<Map::ElementsKindBits>(scratch1); - cmpi(scratch1, Operand(DICTIONARY_ELEMENTS)); - beq(found); - LoadP(current, FieldMemOperand(current, Map::kPrototypeOffset)); - CompareRoot(current, Heap::kNullValueRootIndex); - bne(&loop_again); - - bind(&end); -} - - #ifdef DEBUG bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4, Register reg5, Register reg6, Register reg7, Register reg8, diff --git a/deps/v8/src/ppc/macro-assembler-ppc.h b/deps/v8/src/ppc/macro-assembler-ppc.h index 28eceb18a4..0d16c4b1ed 100644 --- a/deps/v8/src/ppc/macro-assembler-ppc.h +++ b/deps/v8/src/ppc/macro-assembler-ppc.h @@ -470,16 +470,6 @@ class MacroAssembler : public Assembler { LoadNativeContextSlot(Context::GLOBAL_PROXY_INDEX, dst); } - // Conditionally load the cached Array transitioned map of type - // transitioned_kind from the native context if the map in register - // map_in_out is the cached Array map in the native context of - // expected_kind. - void LoadTransitionedArrayMapConditional(ElementsKind expected_kind, - ElementsKind transitioned_kind, - Register map_in_out, - Register scratch, - Label* no_map_match); - void LoadNativeContextSlot(int index, Register dst); // Load the initial map from the global function. The registers @@ -621,9 +611,10 @@ class MacroAssembler : public Assembler { const ParameterCount& actual, InvokeFlag flag, const CallWrapper& call_wrapper); - void FloodFunctionIfStepping(Register fun, Register new_target, - const ParameterCount& expected, - const ParameterCount& actual); + // On function call, call into the debugger if necessary. + void CheckDebugHook(Register fun, Register new_target, + const ParameterCount& expected, + const ParameterCount& actual); // Invoke the JavaScript function in the given register. Changes the // current context to the context in the function before invoking. @@ -722,25 +713,6 @@ class MacroAssembler : public Assembler { void FastAllocate(Register object_size, Register result, Register result_end, Register scratch, AllocationFlags flags); - void AllocateTwoByteString(Register result, Register length, - Register scratch1, Register scratch2, - Register scratch3, Label* gc_required); - void AllocateOneByteString(Register result, Register length, - Register scratch1, Register scratch2, - Register scratch3, Label* gc_required); - void AllocateTwoByteConsString(Register result, Register length, - Register scratch1, Register scratch2, - Label* gc_required); - void AllocateOneByteConsString(Register result, Register length, - Register scratch1, Register scratch2, - Label* gc_required); - void AllocateTwoByteSlicedString(Register result, Register length, - Register scratch1, Register scratch2, - Label* gc_required); - void AllocateOneByteSlicedString(Register result, Register length, - Register scratch1, Register scratch2, - Label* gc_required); - // Allocates a heap number or jumps to the gc_required label if the young // space is full and a scavenge is needed. All registers are clobbered also // when control continues at the gc_required label. @@ -803,22 +775,6 @@ class MacroAssembler : public Assembler { // sets the flags and leaves the object type in the type_reg register. void CompareInstanceType(Register map, Register type_reg, InstanceType type); - // Check if a map for a JSObject indicates that the object can have both smi - // and HeapObject elements. Jump to the specified label if it does not. - void CheckFastObjectElements(Register map, Register scratch, Label* fail); - - // Check if a map for a JSObject indicates that the object has fast smi only - // elements. Jump to the specified label if it does not. - void CheckFastSmiElements(Register map, Register scratch, Label* fail); - - // Check to see if maybe_number can be stored as a double in - // FastDoubleElements. If it can, store it at the index specified by key in - // the FastDoubleElements array elements. Otherwise jump to fail. - void StoreNumberToDoubleElements(Register value_reg, Register key_reg, - Register elements_reg, Register scratch1, - DoubleRegister double_scratch, Label* fail, - int elements_offset = 0); - // Compare an object's map with the specified map and its transitioned // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. Condition flags are // set with result of map compare. If multiple map compares are required, the @@ -1309,10 +1265,6 @@ class MacroAssembler : public Assembler { // Souce and destination can be the same register. void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case); - // Untag the source value into destination and jump if source is not a smi. - // Souce and destination can be the same register. - void UntagAndJumpIfNotSmi(Register dst, Register src, Label* non_smi_case); - inline void TestIfSmi(Register value, Register scratch) { TestBitRange(value, kSmiTagSize - 1, 0, scratch); } @@ -1434,11 +1386,6 @@ class MacroAssembler : public Assembler { Register first_object_instance_type, Register second_object_instance_type, Register scratch1, Register scratch2, Label* failure); - // Check if instance type is sequential one-byte string and jump to label if - // it is not. - void JumpIfInstanceTypeIsNotSequentialOneByte(Register type, Register scratch, - Label* failure); - void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name); void EmitSeqStringSetCharCheck(Register string, Register index, @@ -1528,21 +1475,6 @@ class MacroAssembler : public Assembler { Register scratch2_reg, Label* no_memento_found); - void JumpIfJSArrayHasAllocationMemento(Register receiver_reg, - Register scratch_reg, - Register scratch2_reg, - Label* memento_found) { - Label no_memento_found; - TestJSArrayForAllocationMemento(receiver_reg, scratch_reg, scratch2_reg, - &no_memento_found); - beq(memento_found); - bind(&no_memento_found); - } - - // Jumps to found label if a prototype map has dictionary elements. - void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0, - Register scratch1, Label* found); - // Loads the constant pool pointer (kConstantPoolRegister). void LoadConstantPoolPointerRegisterFromCodeTargetAddress( Register code_target_address); diff --git a/deps/v8/src/ppc/simulator-ppc.cc b/deps/v8/src/ppc/simulator-ppc.cc index 84fbb399b3..e3761579b0 100644 --- a/deps/v8/src/ppc/simulator-ppc.cc +++ b/deps/v8/src/ppc/simulator-ppc.cc @@ -1708,6 +1708,60 @@ bool Simulator::ExecuteExt2_10bit(Instruction* instr) { break; } #endif + case MODUW: { + int rt = instr->RTValue(); + int ra = instr->RAValue(); + int rb = instr->RBValue(); + uint32_t ra_val = get_register(ra); + uint32_t rb_val = get_register(rb); + uint32_t alu_out = (rb_val == 0) ? -1 : ra_val % rb_val; + set_register(rt, alu_out); + break; + } +#if V8_TARGET_ARCH_PPC64 + case MODUD: { + int rt = instr->RTValue(); + int ra = instr->RAValue(); + int rb = instr->RBValue(); + uint64_t ra_val = get_register(ra); + uint64_t rb_val = get_register(rb); + uint64_t alu_out = (rb_val == 0) ? -1 : ra_val % rb_val; + set_register(rt, alu_out); + break; + } +#endif + case MODSW: { + int rt = instr->RTValue(); + int ra = instr->RAValue(); + int rb = instr->RBValue(); + int32_t ra_val = get_register(ra); + int32_t rb_val = get_register(rb); + bool overflow = (ra_val == kMinInt && rb_val == -1); + // result is undefined if divisor is zero or if operation + // is 0x80000000 / -1. + int32_t alu_out = (rb_val == 0 || overflow) ? -1 : ra_val % rb_val; + set_register(rt, alu_out); + break; + } +#if V8_TARGET_ARCH_PPC64 + case MODSD: { + int rt = instr->RTValue(); + int ra = instr->RAValue(); + int rb = instr->RBValue(); + int64_t ra_val = get_register(ra); + int64_t rb_val = get_register(rb); + int64_t one = 1; // work-around gcc + int64_t kMinLongLong = (one << 63); + // result is undefined if divisor is zero or if operation + // is 0x80000000_00000000 / -1. + int64_t alu_out = + (rb_val == 0 || (ra_val == kMinLongLong && rb_val == -1)) + ? -1 + : ra_val % rb_val; + set_register(rt, alu_out); + break; + } +#endif case SRAW: { int rs = instr->RSValue(); int ra = instr->RAValue(); @@ -3295,6 +3349,51 @@ void Simulator::ExecuteExt5(Instruction* instr) { } #endif +void Simulator::ExecuteExt6(Instruction* instr) { + switch (instr->Bits(10, 3) << 3) { + case XSADDDP: { + int frt = instr->RTValue(); + int fra = instr->RAValue(); + int frb = instr->RBValue(); + double fra_val = get_double_from_d_register(fra); + double frb_val = get_double_from_d_register(frb); + double frt_val = fra_val + frb_val; + set_d_register_from_double(frt, frt_val); + return; + } + case XSSUBDP: { + int frt = instr->RTValue(); + int fra = instr->RAValue(); + int frb = instr->RBValue(); + double fra_val = get_double_from_d_register(fra); + double frb_val = get_double_from_d_register(frb); + double frt_val = fra_val - frb_val; + set_d_register_from_double(frt, frt_val); + return; + } + case XSMULDP: { + int frt = instr->RTValue(); + int fra = instr->RAValue(); + int frb = instr->RBValue(); + double fra_val = get_double_from_d_register(fra); + double frb_val = get_double_from_d_register(frb); + double frt_val = fra_val * frb_val; + set_d_register_from_double(frt, frt_val); + return; + } + case XSDIVDP: { + int frt = instr->RTValue(); + int fra = instr->RAValue(); + int frb = instr->RBValue(); + double fra_val = get_double_from_d_register(fra); + double frb_val = get_double_from_d_register(frb); + double frt_val = fra_val / frb_val; + set_d_register_from_double(frt, frt_val); + return; + } + } + UNIMPLEMENTED(); // Not used by V8. +} void Simulator::ExecuteGeneric(Instruction* instr) { int opcode = instr->OpcodeValue() << 26; @@ -3701,7 +3800,16 @@ void Simulator::ExecuteGeneric(Instruction* instr) { intptr_t ra_val = ra == 0 ? 0 : get_register(ra); int32_t val = ReadW(ra_val + offset, instr); float* fptr = reinterpret_cast<float*>(&val); - set_d_register_from_double(frt, static_cast<double>(*fptr)); +// Conversion using double changes sNan to qNan on ia32/x64 +#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 + if (val == 0x7fa00000) { + set_d_register(frt, 0x7ff4000000000000); + } else { +#endif + set_d_register_from_double(frt, static_cast<double>(*fptr)); +#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 + } +#endif if (opcode == LFSU) { DCHECK(ra != 0); set_register(ra, ra_val + offset); @@ -3731,7 +3839,19 @@ void Simulator::ExecuteGeneric(Instruction* instr) { int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); intptr_t ra_val = ra == 0 ? 0 : get_register(ra); float frs_val = static_cast<float>(get_double_from_d_register(frs)); - int32_t* p = reinterpret_cast<int32_t*>(&frs_val); + int32_t* p; +// Conversion using double changes sNan to qNan on ia32/x64 +#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 + int64_t frs_isnan = get_d_register(frs); + int32_t frs_nan_single = 0x7fa00000; + if (frs_isnan == 0x7ff4000000000000) { + p = &frs_nan_single; + } else { +#endif + p = reinterpret_cast<int32_t*>(&frs_val); +#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 + } +#endif WriteW(ra_val + offset, *p, instr); if (opcode == STFSU) { DCHECK(ra != 0); @@ -3810,6 +3930,10 @@ void Simulator::ExecuteGeneric(Instruction* instr) { break; } #endif + case EXT6: { + ExecuteExt6(instr); + break; + } default: { UNIMPLEMENTED(); diff --git a/deps/v8/src/ppc/simulator-ppc.h b/deps/v8/src/ppc/simulator-ppc.h index d061545099..91e7f05ea5 100644 --- a/deps/v8/src/ppc/simulator-ppc.h +++ b/deps/v8/src/ppc/simulator-ppc.h @@ -321,6 +321,7 @@ class Simulator { #if V8_TARGET_ARCH_PPC64 void ExecuteExt5(Instruction* instr); #endif + void ExecuteExt6(Instruction* instr); void ExecuteGeneric(Instruction* instr); void SetFPSCR(int bit) { fp_condition_reg_ |= (1 << (31 - bit)); } |