Commit 8af80a0a authored by bjaideep's avatar bjaideep Committed by Commit bot

PPC: Enable P9 and implement mod[s|u][d|w] instr

Enabled support for Power9 hardware and implemented P9 modulo
instruction.

R=joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com, jochen@chromium.org
BUG=
LOG=n

Review-Url: https://codereview.chromium.org/2625013002
Cr-Commit-Position: refs/heads/master@{#42341}
parent f9fbaec3
......@@ -670,7 +670,9 @@ CPU::CPU()
part_ = -1;
if (auxv_cpu_type) {
if (strcmp(auxv_cpu_type, "power8") == 0) {
if (strcmp(auxv_cpu_type, "power9") == 0) {
part_ = PPC_POWER9;
} else if (strcmp(auxv_cpu_type, "power8") == 0) {
part_ = PPC_POWER8;
} else if (strcmp(auxv_cpu_type, "power7") == 0) {
part_ = PPC_POWER7;
......@@ -689,6 +691,9 @@ CPU::CPU()
#elif V8_OS_AIX
switch (_system_configuration.implementation) {
case POWER_9:
part_ = PPC_POWER9;
break;
case POWER_8:
part_ = PPC_POWER8;
break;
......
......@@ -69,6 +69,7 @@ class V8_BASE_EXPORT CPU final {
PPC_POWER6,
PPC_POWER7,
PPC_POWER8,
PPC_POWER9,
PPC_G4,
PPC_G5,
PPC_PA6T
......
......@@ -1447,19 +1447,35 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
ASSEMBLE_FLOAT_BINOP_RC(fdiv, MiscField::decode(instr->opcode()));
break;
case kPPC_Mod32:
ASSEMBLE_MODULO(divw, mullw);
if (CpuFeatures::IsSupported(MODULO)) {
__ modsw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
} else {
ASSEMBLE_MODULO(divw, mullw);
}
break;
#if V8_TARGET_ARCH_PPC64
case kPPC_Mod64:
ASSEMBLE_MODULO(divd, mulld);
if (CpuFeatures::IsSupported(MODULO)) {
__ modsd(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
} else {
ASSEMBLE_MODULO(divd, mulld);
}
break;
#endif
case kPPC_ModU32:
ASSEMBLE_MODULO(divwu, mullw);
if (CpuFeatures::IsSupported(MODULO)) {
__ moduw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
} else {
ASSEMBLE_MODULO(divwu, mullw);
}
break;
#if V8_TARGET_ARCH_PPC64
case kPPC_ModU64:
ASSEMBLE_MODULO(divdu, mulld);
if (CpuFeatures::IsSupported(MODULO)) {
__ modud(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
} else {
ASSEMBLE_MODULO(divdu, mulld);
}
break;
#endif
case kPPC_ModDouble:
......
......@@ -785,6 +785,7 @@ enum CpuFeature {
LWSYNC,
ISELECT,
VSX,
MODULO,
// S390
DISTINCT_OPS,
GENERAL_INSTR_EXT,
......
......@@ -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);
......@@ -98,6 +101,7 @@ void CpuFeatures::ProbeImpl(bool cross_compile) {
supported_ |= (1u << LWSYNC);
supported_ |= (1u << ISELECT);
supported_ |= (1u << VSX);
supported_ |= (1u << MODULO);
#if V8_TARGET_ARCH_PPC64
supported_ |= (1u << FPR_GPR_MOV);
#endif
......@@ -951,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
......@@ -1555,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
......
......@@ -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,
......
......@@ -204,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
......@@ -255,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
......
......@@ -561,6 +561,24 @@ void Decoder::DecodeExt2(Instruction* instr) {
Format(instr, "srad'. 'ra, 'rs, 'rb");
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");
......
......@@ -1707,6 +1707,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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment