Index: src/ppc/assembler-ppc.cc |
diff --git a/src/ppc/assembler-ppc.cc b/src/ppc/assembler-ppc.cc |
index d91052873fd5b06e01bb6f59ef91105adf453605..4607ff9dc5fb271f4c7bd141e8c719c1a6c73b00 100644 |
--- a/src/ppc/assembler-ppc.cc |
+++ b/src/ppc/assembler-ppc.cc |
@@ -77,6 +77,10 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { |
cpu.part() == base::CPU::PPC_POWER8) { |
supported_ |= (1u << LWSYNC); |
} |
+ if (cpu.part() == base::CPU::PPC_POWER7 || |
+ cpu.part() == base::CPU::PPC_POWER8) { |
+ supported_ |= (1u << ISELECT); |
+ } |
#if V8_OS_LINUX |
if (!(cpu.part() == base::CPU::PPC_G5 || cpu.part() == base::CPU::PPC_G4)) { |
// Assume support |
@@ -89,6 +93,7 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { |
#else // Simulator |
supported_ |= (1u << FPU); |
supported_ |= (1u << LWSYNC); |
+ supported_ |= (1u << ISELECT); |
#if V8_TARGET_ARCH_PPC64 |
supported_ |= (1u << FPR_GPR_MOV); |
#endif |
@@ -217,9 +222,6 @@ MemOperand::MemOperand(Register ra, Register rb) { |
// ----------------------------------------------------------------------------- |
// Specific instructions, constants, and masks. |
-// Spare buffer. |
-static const int kMinimalBufferSize = 4 * KB; |
- |
Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) |
: AssemblerBase(isolate, buffer, buffer_size), |
@@ -422,7 +424,6 @@ int Assembler::target_at(int pos) { |
} |
} |
- PPCPORT_UNIMPLEMENTED(); |
DCHECK(false); |
return -1; |
} |
@@ -435,17 +436,27 @@ void Assembler::target_at_put(int pos, int target_pos) { |
// check which type of branch this is 16 or 26 bit offset |
if (BX == opcode) { |
int imm26 = target_pos - pos; |
- DCHECK((imm26 & (kAAMask | kLKMask)) == 0); |
- instr &= ((~kImm26Mask) | kAAMask | kLKMask); |
- DCHECK(is_int26(imm26)); |
- instr_at_put(pos, instr | (imm26 & kImm26Mask)); |
+ DCHECK(is_int26(imm26) && (imm26 & (kAAMask | kLKMask)) == 0); |
+ if (imm26 == kInstrSize && !(instr & kLKMask)) { |
+ // Branch to next instr without link. |
+ instr = ORI; // nop: ori, 0,0,0 |
+ } else { |
+ instr &= ((~kImm26Mask) | kAAMask | kLKMask); |
+ instr |= (imm26 & kImm26Mask); |
+ } |
+ instr_at_put(pos, instr); |
return; |
} else if (BCX == opcode) { |
int imm16 = target_pos - pos; |
- DCHECK((imm16 & (kAAMask | kLKMask)) == 0); |
- instr &= ((~kImm16Mask) | kAAMask | kLKMask); |
- DCHECK(is_int16(imm16)); |
- instr_at_put(pos, instr | (imm16 & kImm16Mask)); |
+ DCHECK(is_int16(imm16) && (imm16 & (kAAMask | kLKMask)) == 0); |
+ if (imm16 == kInstrSize && !(instr & kLKMask)) { |
+ // Branch to next instr without link. |
+ instr = ORI; // nop: ori, 0,0,0 |
+ } else { |
+ instr &= ((~kImm16Mask) | kAAMask | kLKMask); |
+ instr |= (imm16 & kImm16Mask); |
+ } |
+ instr_at_put(pos, instr); |
return; |
} else if ((instr & ~kImm26Mask) == 0) { |
DCHECK(target_pos == kEndOfChain || target_pos >= 0); |
@@ -858,9 +869,14 @@ void Assembler::mullw(Register dst, Register src1, Register src2, OEBit o, |
// Multiply hi word |
-void Assembler::mulhw(Register dst, Register src1, Register src2, OEBit o, |
- RCBit r) { |
- xo_form(EXT2 | MULHWX, dst, src1, src2, o, r); |
+void Assembler::mulhw(Register dst, Register src1, Register src2, RCBit r) { |
+ xo_form(EXT2 | MULHWX, dst, src1, src2, LeaveOE, r); |
+} |
+ |
+ |
+// Multiply hi word unsigned |
+void Assembler::mulhwu(Register dst, Register src1, Register src2, RCBit r) { |
+ xo_form(EXT2 | MULHWUX, dst, src1, src2, LeaveOE, r); |
} |
@@ -871,6 +887,13 @@ void Assembler::divw(Register dst, Register src1, Register src2, OEBit o, |
} |
+// Divide word unsigned |
+void Assembler::divwu(Register dst, Register src1, Register src2, OEBit o, |
+ RCBit r) { |
+ xo_form(EXT2 | DIVWU, dst, src1, src2, o, r); |
+} |
+ |
+ |
void Assembler::addi(Register dst, Register src, const Operand& imm) { |
DCHECK(!src.is(r0)); // use li instead to show intent |
d_form(ADDI, dst, src, imm.imm_, true); |
@@ -923,6 +946,11 @@ void Assembler::orx(Register dst, Register src1, Register src2, RCBit rc) { |
} |
+void Assembler::orc(Register dst, Register src1, Register src2, RCBit rc) { |
+ x_form(EXT2 | ORC, dst, src1, src2, rc); |
+} |
+ |
+ |
void Assembler::cmpi(Register src1, const Operand& src2, CRegister cr) { |
intptr_t imm16 = src2.imm_; |
#if V8_TARGET_ARCH_PPC64 |
@@ -1011,6 +1039,12 @@ void Assembler::cmplw(Register src1, Register src2, CRegister cr) { |
} |
+void Assembler::isel(Register rt, Register ra, Register rb, int cb) { |
+ emit(EXT2 | ISEL | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 | |
+ cb * B6); |
+} |
+ |
+ |
// Pseudo op - load immediate |
void Assembler::li(Register dst, const Operand& imm) { |
d_form(ADDI, dst, r0, imm.imm_, true); |
@@ -1077,6 +1111,14 @@ void Assembler::lhzux(Register rt, const MemOperand& src) { |
} |
+void Assembler::lhax(Register rt, const MemOperand& src) { |
+ Register ra = src.ra(); |
+ Register rb = src.rb(); |
+ DCHECK(!ra.is(r0)); |
+ emit(EXT2 | LHAX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11); |
+} |
+ |
+ |
void Assembler::lwz(Register dst, const MemOperand& src) { |
DCHECK(!src.ra_.is(r0)); |
d_form(LWZ, dst, src.ra(), src.offset(), true); |
@@ -1107,6 +1149,12 @@ void Assembler::lwzux(Register rt, const MemOperand& src) { |
} |
+void Assembler::lha(Register dst, const MemOperand& src) { |
+ DCHECK(!src.ra_.is(r0)); |
+ d_form(LHA, dst, src.ra(), src.offset(), true); |
+} |
+ |
+ |
void Assembler::lwa(Register dst, const MemOperand& src) { |
#if V8_TARGET_ARCH_PPC64 |
int offset = src.offset(); |
@@ -1120,6 +1168,18 @@ void Assembler::lwa(Register dst, const MemOperand& src) { |
} |
+void Assembler::lwax(Register rt, const MemOperand& src) { |
+#if V8_TARGET_ARCH_PPC64 |
+ Register ra = src.ra(); |
+ Register rb = src.rb(); |
+ DCHECK(!ra.is(r0)); |
+ emit(EXT2 | LWAX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11); |
+#else |
+ lwzx(rt, src); |
+#endif |
+} |
+ |
+ |
void Assembler::stb(Register dst, const MemOperand& src) { |
DCHECK(!src.ra_.is(r0)); |
d_form(STB, dst, src.ra(), src.offset(), true); |
@@ -1208,6 +1268,16 @@ void Assembler::extsh(Register rs, Register ra, RCBit rc) { |
} |
+void Assembler::extsw(Register rs, Register ra, RCBit rc) { |
+#if V8_TARGET_ARCH_PPC64 |
+ emit(EXT2 | EXTSW | ra.code() * B21 | rs.code() * B16 | rc); |
+#else |
+ // nop on 32-bit |
+ DCHECK(rs.is(ra) && rc == LeaveRC); |
+#endif |
+} |
+ |
+ |
void Assembler::neg(Register rt, Register ra, OEBit o, RCBit r) { |
emit(EXT2 | NEGX | rt.code() * B21 | ra.code() * B16 | o | r); |
} |
@@ -1383,11 +1453,6 @@ void Assembler::cntlzd_(Register ra, Register rs, RCBit rc) { |
} |
-void Assembler::extsw(Register rs, Register ra, RCBit rc) { |
- emit(EXT2 | EXTSW | ra.code() * B21 | rs.code() * B16 | rc); |
-} |
- |
- |
void Assembler::mulld(Register dst, Register src1, Register src2, OEBit o, |
RCBit r) { |
xo_form(EXT2 | MULLD, dst, src1, src2, o, r); |
@@ -1398,21 +1463,13 @@ void Assembler::divd(Register dst, Register src1, Register src2, OEBit o, |
RCBit r) { |
xo_form(EXT2 | DIVD, dst, src1, src2, o, r); |
} |
-#endif |
-void Assembler::fake_asm(enum FAKE_OPCODE_T fopcode) { |
- DCHECK(fopcode < fLastFaker); |
- emit(FAKE_OPCODE | FAKER_SUBOPCODE | fopcode); |
-} |
- |
- |
-void Assembler::marker_asm(int mcode) { |
- if (::v8::internal::FLAG_trace_sim_stubs) { |
- DCHECK(mcode < F_NEXT_AVAILABLE_STUB_MARKER); |
- emit(FAKE_OPCODE | MARKER_SUBOPCODE | mcode); |
- } |
+void Assembler::divdu(Register dst, Register src1, Register src2, OEBit o, |
+ RCBit r) { |
+ xo_form(EXT2 | DIVDU, dst, src1, src2, o, r); |
} |
+#endif |
// Function descriptor for AIX. |
@@ -1544,8 +1601,8 @@ void Assembler::mov(Register dst, const Operand& src) { |
RecordRelocInfo(rinfo); |
} |
- canOptimize = |
- !(src.must_output_reloc_info(this) || is_trampoline_pool_blocked()); |
+ canOptimize = !(src.must_output_reloc_info(this) || |
+ (is_trampoline_pool_blocked() && !is_int16(value))); |
#if V8_OOL_CONSTANT_POOL |
if (use_constant_pool_for_mov(src, canOptimize)) { |
@@ -1741,21 +1798,6 @@ void Assembler::stop(const char* msg, Condition cond, int32_t code, |
void Assembler::bkpt(uint32_t imm16) { emit(0x7d821008); } |
-void Assembler::info(const char* msg, Condition cond, int32_t code, |
- CRegister cr) { |
- if (::v8::internal::FLAG_trace_sim_stubs) { |
- emit(0x7d9ff808); |
-#if V8_TARGET_ARCH_PPC64 |
- uint64_t value = reinterpret_cast<uint64_t>(msg); |
- emit(static_cast<uint32_t>(value >> 32)); |
- emit(static_cast<uint32_t>(value & 0xFFFFFFFF)); |
-#else |
- emit(reinterpret_cast<Instr>(msg)); |
-#endif |
- } |
-} |
- |
- |
void Assembler::dcbf(Register ra, Register rb) { |
emit(EXT2 | DCBF | ra.code() * B16 | rb.code() * B11); |
} |
@@ -1983,8 +2025,27 @@ void Assembler::fctiw(const DoubleRegister frt, const DoubleRegister frb) { |
} |
-void Assembler::frim(const DoubleRegister frt, const DoubleRegister frb) { |
- emit(EXT4 | FRIM | frt.code() * B21 | frb.code() * B11); |
+void Assembler::frin(const DoubleRegister frt, const DoubleRegister frb, |
+ RCBit rc) { |
+ emit(EXT4 | FRIN | frt.code() * B21 | frb.code() * B11 | rc); |
+} |
+ |
+ |
+void Assembler::friz(const DoubleRegister frt, const DoubleRegister frb, |
+ RCBit rc) { |
+ emit(EXT4 | FRIZ | frt.code() * B21 | frb.code() * B11 | rc); |
+} |
+ |
+ |
+void Assembler::frip(const DoubleRegister frt, const DoubleRegister frb, |
+ RCBit rc) { |
+ emit(EXT4 | FRIP | frt.code() * B21 | frb.code() * B11 | rc); |
+} |
+ |
+ |
+void Assembler::frim(const DoubleRegister frt, const DoubleRegister frb, |
+ RCBit rc) { |
+ emit(EXT4 | FRIM | frt.code() * B21 | frb.code() * B11 | rc); |
} |
@@ -2133,6 +2194,15 @@ void Assembler::RecordComment(const char* msg) { |
} |
+void Assembler::RecordDeoptReason(const int reason, const int raw_position) { |
+ if (FLAG_trace_deopt) { |
+ EnsureSpace ensure_space(this); |
+ RecordRelocInfo(RelocInfo::POSITION, raw_position); |
+ RecordRelocInfo(RelocInfo::DEOPT_REASON, reason); |
+ } |
+} |
+ |
+ |
void Assembler::GrowBuffer() { |
if (!own_buffer_) FATAL("external code buffer is too small"); |