Commit 0548cf49 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: [wasm] Int64Lowering of Int64Add.

Port 1b230799

Original commit message:
    Int64Add is lowered to a new turbofan operator, Int32AddPair. The new
    operator takes 4 inputs an generates 2 outputs. The inputs are the low
    word of the left input, high word of the left input, the low word of the
    right input, and high word of the right input. The ouputs are the low
    and high word of the result of the addition.

R=ahaas@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1803113002

Cr-Commit-Position: refs/heads/master@{#34797}
parent c423e985
......@@ -969,6 +969,15 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break;
#endif
#if !V8_TARGET_ARCH_PPC64
case kPPC_AddPair:
// i.InputRegister(0) ... left low word.
// i.InputRegister(1) ... left high word.
// i.InputRegister(2) ... right low word.
// i.InputRegister(3) ... right high word.
__ addc(i.OutputRegister(0), i.InputRegister(0), i.InputRegister(2));
__ adde(i.OutputRegister(1), i.InputRegister(1), i.InputRegister(3));
DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
case kPPC_ShiftLeftPair:
if (instr->InputAt(2)->IsImmediate()) {
__ ShiftLeftPair(i.OutputRegister(0), i.OutputRegister(1),
......
......@@ -35,6 +35,7 @@ namespace compiler {
V(PPC_RotLeftAndClearRight64) \
V(PPC_Add) \
V(PPC_AddWithOverflow32) \
V(PPC_AddPair) \
V(PPC_AddDouble) \
V(PPC_Sub) \
V(PPC_SubWithOverflow32) \
......
......@@ -37,6 +37,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kPPC_RotLeftAndClearRight64:
case kPPC_Add:
case kPPC_AddWithOverflow32:
case kPPC_AddPair:
case kPPC_AddDouble:
case kPPC_Sub:
case kPPC_SubWithOverflow32:
......
......@@ -785,6 +785,22 @@ void InstructionSelector::VisitWord32Sar(Node* node) {
}
#if !V8_TARGET_ARCH_PPC64
void InstructionSelector::VisitInt32PairAdd(Node* node) {
PPCOperandGenerator g(this);
// We use UseUniqueRegister here to avoid register sharing with the output
// registers.
InstructionOperand inputs[] = {
g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)),
g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))};
InstructionOperand outputs[] = {
g.DefineAsRegister(node),
g.DefineAsRegister(NodeProperties::FindProjection(node, 1))};
Emit(kPPC_AddPair, 2, outputs, 4, inputs);
}
void VisitPairShift(InstructionSelector* selector, ArchOpcode opcode,
Node* node) {
PPCOperandGenerator g(selector);
......@@ -898,10 +914,6 @@ void InstructionSelector::VisitInt64Add(Node* node) {
}
#endif
#if !V8_TARGET_ARCH_PPC64
void InstructionSelector::VisitInt32PairAdd(Node* node) { UNIMPLEMENTED(); }
#endif
void InstructionSelector::VisitInt32Sub(Node* node) {
PPCOperandGenerator g(this);
Int32BinopMatcher m(node);
......
......@@ -849,6 +849,10 @@ void Assembler::addc(Register dst, Register src1, Register src2, OEBit o,
xo_form(EXT2 | ADDCX, dst, src1, src2, o, r);
}
void Assembler::adde(Register dst, Register src1, Register src2, OEBit o,
RCBit r) {
xo_form(EXT2 | ADDEX, dst, src1, src2, o, r);
}
void Assembler::addze(Register dst, Register src1, OEBit o, RCBit r) {
// a special xo_form
......
......@@ -818,8 +818,9 @@ class Assembler : public AssemblerBase {
void addc(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
RCBit r = LeaveRC);
void addze(Register dst, Register src1, OEBit o, RCBit r);
void adde(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
RCBit r = LeaveRC);
void addze(Register dst, Register src1, OEBit o = LeaveOE, RCBit r = LeaveRC);
void mullw(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
RCBit r = LeaveRC);
......
......@@ -661,6 +661,10 @@ void Decoder::DecodeExt2(Instruction* instr) {
Format(instr, "addc'. 'rt, 'ra, 'rb");
return;
}
case ADDEX: {
Format(instr, "adde'. 'rt, 'ra, 'rb");
return;
}
case CNTLZWX: {
Format(instr, "cntlzw'. 'ra, 'rs");
return;
......
......@@ -2046,7 +2046,7 @@ bool Simulator::ExecuteExt2_9bit_part1(Instruction* instr) {
uintptr_t ra_val = get_register(ra);
uintptr_t rb_val = get_register(rb);
uintptr_t alu_out = ra_val + rb_val;
// Check overflow
// Set carry
if (~ra_val < rb_val) {
special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000;
} else {
......@@ -2059,6 +2059,24 @@ bool Simulator::ExecuteExt2_9bit_part1(Instruction* instr) {
// todo - handle OE bit
break;
}
case ADDEX: {
int rt = instr->RTValue();
int ra = instr->RAValue();
int rb = instr->RBValue();
// int oe = instr->Bit(10);
uintptr_t ra_val = get_register(ra);
uintptr_t rb_val = get_register(rb);
uintptr_t alu_out = ra_val + rb_val;
if (special_reg_xer_ & 0x20000000) {
alu_out += 1;
}
set_register(rt, alu_out);
if (instr->Bit(0)) { // RC bit set
SetCR0(static_cast<intptr_t>(alu_out));
}
// todo - handle OE bit
break;
}
case MULHWX: {
int rt = instr->RTValue();
int ra = instr->RAValue();
......
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