Commit eb0a2324 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: [wasm] Int64Lowering of Int64Sub.

Port 33c08596

Original commit message:
    Int64Sub is lowered to a new turbofan operator, Int32SubPair. 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 subtraction.

    The implementation is very similar to the implementation of Int64Add.

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

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

Cr-Commit-Position: refs/heads/master@{#34821}
parent 4513e077
......@@ -978,6 +978,15 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ adde(i.OutputRegister(1), i.InputRegister(1), i.InputRegister(3));
DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
case kPPC_SubPair:
// i.InputRegister(0) ... left low word.
// i.InputRegister(1) ... left high word.
// i.InputRegister(2) ... right low word.
// i.InputRegister(3) ... right high word.
__ subc(i.OutputRegister(0), i.InputRegister(0), i.InputRegister(2));
__ sube(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),
......
......@@ -39,6 +39,7 @@ namespace compiler {
V(PPC_AddDouble) \
V(PPC_Sub) \
V(PPC_SubWithOverflow32) \
V(PPC_SubPair) \
V(PPC_SubDouble) \
V(PPC_Mul32) \
V(PPC_Mul64) \
......
......@@ -41,6 +41,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kPPC_AddDouble:
case kPPC_Sub:
case kPPC_SubWithOverflow32:
case kPPC_SubPair:
case kPPC_SubDouble:
case kPPC_Mul32:
case kPPC_Mul64:
......
......@@ -785,8 +785,9 @@ void InstructionSelector::VisitWord32Sar(Node* node) {
}
#if !V8_TARGET_ARCH_PPC64
void InstructionSelector::VisitInt32PairAdd(Node* node) {
PPCOperandGenerator g(this);
void VisitPairBinop(InstructionSelector* selector, ArchOpcode opcode,
Node* node) {
PPCOperandGenerator g(selector);
// We use UseUniqueRegister here to avoid register sharing with the output
// registers.
......@@ -798,10 +799,16 @@ void InstructionSelector::VisitInt32PairAdd(Node* node) {
g.DefineAsRegister(node),
g.DefineAsRegister(NodeProperties::FindProjection(node, 1))};
Emit(kPPC_AddPair, 2, outputs, 4, inputs);
selector->Emit(opcode, 2, outputs, 4, inputs);
}
void InstructionSelector::VisitInt32PairSub(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitInt32PairAdd(Node* node) {
VisitPairBinop(this, kPPC_AddPair, node);
}
void InstructionSelector::VisitInt32PairSub(Node* node) {
VisitPairBinop(this, kPPC_SubPair, node);
}
void VisitPairShift(InstructionSelector* selector, ArchOpcode opcode,
Node* node) {
......
......@@ -862,12 +862,15 @@ void Assembler::sub(Register dst, Register src1, Register src2, OEBit o,
xo_form(EXT2 | SUBFX, dst, src2, src1, o, r);
}
void Assembler::subfc(Register dst, Register src1, Register src2, OEBit o,
RCBit r) {
void Assembler::subc(Register dst, Register src1, Register src2, OEBit o,
RCBit r) {
xo_form(EXT2 | SUBFCX, dst, src2, src1, o, r);
}
void Assembler::sube(Register dst, Register src1, Register src2, OEBit o,
RCBit r) {
xo_form(EXT2 | SUBFEX, dst, src2, src1, o, r);
}
void Assembler::subfic(Register dst, Register src, const Operand& imm) {
d_form(SUBFIC, dst, src, imm.imm_, true);
......
......@@ -808,10 +808,12 @@ class Assembler : public AssemblerBase {
void sub(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
RCBit r = LeaveRC);
void subfic(Register dst, Register src, const Operand& imm);
void subc(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
RCBit r = LeaveRC);
void sube(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
RCBit r = LeaveRC);
void subfc(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
RCBit r = LeaveRC);
void subfic(Register dst, Register src, const Operand& imm);
void add(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
RCBit r = LeaveRC);
......
......@@ -657,6 +657,10 @@ void Decoder::DecodeExt2(Instruction* instr) {
Format(instr, "subfc'. 'rt, 'ra, 'rb");
return;
}
case SUBFEX: {
Format(instr, "subfe'. 'rt, 'ra, 'rb");
return;
}
case ADDCX: {
Format(instr, "addc'. 'rt, 'ra, 'rb");
return;
......
......@@ -2025,19 +2025,37 @@ 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 + 1;
set_register(rt, alu_out);
// If the sign of rb and alu_out don't match, carry = 0
if ((alu_out ^ rb_val) & 0x80000000) {
special_reg_xer_ &= ~0xF0000000;
} else {
// Set carry
if (ra_val <= rb_val) {
special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000;
} else {
special_reg_xer_ &= ~0xF0000000;
}
set_register(rt, alu_out);
if (instr->Bit(0)) { // RC bit set
SetCR0(alu_out);
}
// todo - handle OE bit
break;
}
case SUBFEX: {
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 ADDCX: {
int rt = instr->RTValue();
int ra = instr->RAValue();
......
......@@ -4201,8 +4201,7 @@ uint64_t ToInt64(uint32_t low, uint32_t high) {
return (static_cast<uint64_t>(high) << 32) | static_cast<uint64_t>(low);
}
#if V8_TARGET_ARCH_32_BIT && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_PPC && \
!V8_TARGET_ARCH_X87
#if V8_TARGET_ARCH_32_BIT && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_X87
TEST(RunInt32PairAdd) {
BufferedRawMachineAssemblerTester<int32_t> m(
MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32(),
......
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