aboutsummaryrefslogtreecommitdiff
path: root/src/ppc/assembler-ppc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/ppc/assembler-ppc.cc')
-rw-r--r--src/ppc/assembler-ppc.cc73
1 files changed, 62 insertions, 11 deletions
diff --git a/src/ppc/assembler-ppc.cc b/src/ppc/assembler-ppc.cc
index 08a8005e..645561db 100644
--- a/src/ppc/assembler-ppc.cc
+++ b/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);
}
@@ -344,7 +355,7 @@ bool Assembler::Is32BitLoadIntoR12(Instr instr1, Instr instr2) {
bool Assembler::IsCmpRegister(Instr instr) {
return (((instr & kOpcodeMask) == EXT2) &&
- ((instr & kExt2OpcodeMask) == CMP));
+ ((EXT2 | (instr & kExt2OpcodeMask)) == CMP));
}
@@ -359,7 +370,7 @@ bool Assembler::IsAndi(Instr instr) { return ((instr & kOpcodeMask) == ANDIx); }
#if V8_TARGET_ARCH_PPC64
bool Assembler::IsRldicl(Instr instr) {
return (((instr & kOpcodeMask) == EXT5) &&
- ((instr & kExt5OpcodeMask) == RLDICL));
+ ((EXT5 | (instr & kExt5OpcodeMask)) == RLDICL));
}
#endif
@@ -371,7 +382,7 @@ bool Assembler::IsCmpImmediate(Instr instr) {
bool Assembler::IsCrSet(Instr instr) {
return (((instr & kOpcodeMask) == EXT1) &&
- ((instr & kExt1OpcodeMask) == CREQV));
+ ((EXT1 | (instr & kExt1OpcodeMask)) == CREQV));
}
@@ -414,7 +425,7 @@ enum {
int Assembler::target_at(int pos) {
Instr instr = instr_at(pos);
// check which type of branch this is 16 or 26 bit offset
- int opcode = instr & kOpcodeMask;
+ uint32_t opcode = instr & kOpcodeMask;
int link;
switch (opcode) {
case BX:
@@ -444,7 +455,7 @@ int Assembler::target_at(int pos) {
void Assembler::target_at_put(int pos, int target_pos, bool* is_branch) {
Instr instr = instr_at(pos);
- int opcode = instr & kOpcodeMask;
+ uint32_t opcode = instr & kOpcodeMask;
if (is_branch != nullptr) {
*is_branch = (opcode == BX || opcode == BCX);
@@ -524,7 +535,7 @@ void Assembler::target_at_put(int pos, int target_pos, bool* is_branch) {
int Assembler::max_reach_from(int pos) {
Instr instr = instr_at(pos);
- int opcode = instr & kOpcodeMask;
+ uint32_t opcode = instr & kOpcodeMask;
// check which type of branch this is 16 or 26 bit offset
switch (opcode) {
@@ -635,12 +646,19 @@ void Assembler::x_form(Instr instr, Register ra, Register rs, Register rb,
emit(instr | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 | r);
}
-
void Assembler::xo_form(Instr instr, Register rt, Register ra, Register rb,
OEBit o, RCBit r) {
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 +954,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 +1565,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
@@ -2217,13 +2250,13 @@ void Assembler::fcfidu(const DoubleRegister frt, const DoubleRegister frb,
void Assembler::fcfidus(const DoubleRegister frt, const DoubleRegister frb,
RCBit rc) {
- emit(EXT3 | FCFIDU | frt.code() * B21 | frb.code() * B11 | rc);
+ emit(EXT3 | FCFIDUS | frt.code() * B21 | frb.code() * B11 | rc);
}
void Assembler::fcfids(const DoubleRegister frt, const DoubleRegister frb,
RCBit rc) {
- emit(EXT3 | FCFID | frt.code() * B21 | frb.code() * B11 | rc);
+ emit(EXT3 | FCFIDS | frt.code() * B21 | frb.code() * B11 | rc);
}
@@ -2322,6 +2355,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) {