S390: [wasm] Int64Lowering of Int64Add

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/1807013002

Cr-Commit-Position: refs/heads/master@{#34840}
This commit is contained in:
jyan 2016-03-16 13:36:39 -07:00 committed by Commit bot
parent 14188ea07f
commit 06bceeb753
9 changed files with 74 additions and 4 deletions

View File

@ -862,6 +862,16 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break;
#endif
#if !V8_TARGET_ARCH_S390X
case kS390_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.
__ AddLogical32(i.OutputRegister(0), i.InputRegister(0),
i.InputRegister(2));
__ AddLogicalWithCarry32(i.OutputRegister(1), i.InputRegister(1),
i.InputRegister(3));
break;
case kS390_ShiftLeftPair:
if (instr->InputAt(2)->IsImmediate()) {
__ ShiftLeftPair(i.OutputRegister(0), i.OutputRegister(1),

View File

@ -35,6 +35,7 @@ namespace compiler {
V(S390_RotLeftAndClearRight64) \
V(S390_Add) \
V(S390_AddWithOverflow32) \
V(S390_AddPair) \
V(S390_AddFloat) \
V(S390_AddDouble) \
V(S390_Sub) \

View File

@ -36,6 +36,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kS390_RotLeftAndClearRight64:
case kS390_Add:
case kS390_AddWithOverflow32:
case kS390_AddPair:
case kS390_AddFloat:
case kS390_AddDouble:
case kS390_Sub:

View File

@ -754,6 +754,22 @@ void InstructionSelector::VisitWord32Sar(Node* node) {
}
#if !V8_TARGET_ARCH_S390X
void InstructionSelector::VisitInt32PairAdd(Node* node) {
S390OperandGenerator 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(kS390_AddPair, 2, outputs, 4, inputs);
}
void VisitPairShift(InstructionSelector* selector, ArchOpcode opcode,
Node* node) {
S390OperandGenerator g(selector);
@ -855,10 +871,6 @@ void InstructionSelector::VisitInt64Add(Node* node) {
}
#endif
#if !V8_TARGET_ARCH_S390X
void InstructionSelector::VisitInt32PairAdd(Node* node) { UNIMPLEMENTED(); }
#endif
void InstructionSelector::VisitInt32Sub(Node* node) {
S390OperandGenerator g(this);
Int32BinopMatcher m(node);

View File

@ -1905,6 +1905,9 @@ void Assembler::alfi(Register r1, const Operand& opnd) {
// Add Logical Register-Register (32)
void Assembler::alr(Register r1, Register r2) { rr_form(ALR, r1, r2); }
// Add Logical With Carry Register-Register (32)
void Assembler::alcr(Register r1, Register r2) { rre_form(ALCR, r1, r2); }
// Add Logical Register-Register-Register (32)
void Assembler::alrk(Register r1, Register r2, Register r3) {
rrf1_form(ALRK, r1, r2, r3);

View File

@ -1003,6 +1003,7 @@ class Assembler : public AssemblerBase {
void aly(Register r1, const MemOperand& opnd);
void alfi(Register r1, const Operand& opnd);
void alr(Register r1, Register r2);
void alcr(Register r1, Register r2);
void alrk(Register r1, Register r2, Register r3);
// 64-bit Add Logical Instructions

View File

@ -766,6 +766,9 @@ bool Decoder::DecodeFourByte(Instruction* instr) {
case MLGR:
Format(instr, "mlgr\t'r5,'r6");
break;
case ALCR:
Format(instr, "alcr\t'r5,'r6");
break;
case ALGR:
Format(instr, "algr\t'r5,'r6");
break;

View File

@ -4006,6 +4006,39 @@ void MacroAssembler::AddP(const MemOperand& opnd, const Operand& imm) {
// Add Logical Instructions
//----------------------------------------------------------------------------
// Add Logical With Carry 32-bit (Register dst = Register src1 + Register src2)
void MacroAssembler::AddLogicalWithCarry32(Register dst, Register src1,
Register src2) {
if (!dst.is(src2) && !dst.is(src1)) {
lr(dst, src1);
alcr(dst, src2);
} else if (!dst.is(src2)) {
// dst == src1
DCHECK(dst.is(src1));
alcr(dst, src2);
} else {
// dst == src2
DCHECK(dst.is(src2));
alcr(dst, src1);
}
}
// Add Logical 32-bit (Register dst = Register src1 + Register src2)
void MacroAssembler::AddLogical32(Register dst, Register src1, Register src2) {
if (!dst.is(src2) && !dst.is(src1)) {
lr(dst, src1);
alr(dst, src2);
} else if (!dst.is(src2)) {
// dst == src1
DCHECK(dst.is(src1));
alr(dst, src2);
} else {
// dst == src2
DCHECK(dst.is(src2));
alr(dst, src1);
}
}
// Add Logical 32-bit (Register dst = Register dst + Immediate opnd)
void MacroAssembler::AddLogical(Register dst, const Operand& imm) {
alfi(dst, imm);

View File

@ -259,6 +259,12 @@ class MacroAssembler : public Assembler {
void Add32(const MemOperand& opnd, const Operand& imm);
void AddP(const MemOperand& opnd, const Operand& imm);
// Add Logical (Register - Register)
void AddLogical32(Register dst, Register src1, Register src2);
// Add Logical With Carry (Register - Register)
void AddLogicalWithCarry32(Register dst, Register src1, Register src2);
// Add Logical (Register - Immediate)
void AddLogical(Register dst, const Operand& imm);
void AddLogicalP(Register dst, const Operand& imm);