From 7e66b57acb8f319611fb7b59fbe8d01f417894c4 Mon Sep 17 00:00:00 2001 From: "zhengxing.li" Date: Tue, 15 Mar 2016 20:12:44 -0700 Subject: [PATCH] X87: [wasm] Int64Lowering of Int64Add on ia32 and arm. port 1b230799364b7a6fbff3b0ffaee38bc06e19504b (r34747) 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. BUG= Review URL: https://codereview.chromium.org/1806833002 Cr-Commit-Position: refs/heads/master@{#34803} --- src/compiler/x87/code-generator-x87.cc | 25 ++++++++++++++ src/compiler/x87/instruction-codes-x87.h | 1 + src/compiler/x87/instruction-selector-x87.cc | 18 +++++++++- src/x87/disasm-x87.cc | 35 +++++++------------- test/cctest/test-disasm-x87.cc | 1 + 5 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/compiler/x87/code-generator-x87.cc b/src/compiler/x87/code-generator-x87.cc index 37dbbca5fb..a59a6ad978 100644 --- a/src/compiler/x87/code-generator-x87.cc +++ b/src/compiler/x87/code-generator-x87.cc @@ -762,6 +762,31 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ sar_cl(i.OutputOperand()); } break; + case kX87AddPair: { + // i.OutputRegister(0) == i.InputRegister(0) ... left low word. + // i.InputRegister(1) ... left high word. + // i.InputRegister(2) ... right low word. + // i.InputRegister(3) ... right high word. + bool use_temp = false; + if (i.OutputRegister(0).code() == i.InputRegister(1).code() || + i.OutputRegister(0).code() == i.InputRegister(3).code()) { + // We cannot write to the output register directly, because it would + // overwrite an input for adc. We have to use the temp register. + use_temp = true; + __ Move(i.TempRegister(0), i.InputRegister(0)); + __ add(i.TempRegister(0), i.InputRegister(2)); + } else { + __ add(i.OutputRegister(0), i.InputRegister(2)); + } + __ adc(i.InputRegister(1), Operand(i.InputRegister(3))); + if (i.OutputRegister(1).code() != i.InputRegister(1).code()) { + __ Move(i.OutputRegister(1), i.InputRegister(1)); + } + if (use_temp) { + __ Move(i.OutputRegister(0), i.TempRegister(0)); + } + break; + } case kX87ShlPair: if (HasImmediateInput(instr, 2)) { __ ShlPair(i.InputRegister(1), i.InputRegister(0), i.InputInt6(2)); diff --git a/src/compiler/x87/instruction-codes-x87.h b/src/compiler/x87/instruction-codes-x87.h index 6680582517..81ccc2ad1f 100644 --- a/src/compiler/x87/instruction-codes-x87.h +++ b/src/compiler/x87/instruction-codes-x87.h @@ -31,6 +31,7 @@ namespace compiler { V(X87Shl) \ V(X87Shr) \ V(X87Sar) \ + V(X87AddPair) \ V(X87ShlPair) \ V(X87ShrPair) \ V(X87SarPair) \ diff --git a/src/compiler/x87/instruction-selector-x87.cc b/src/compiler/x87/instruction-selector-x87.cc index 7d6f762f1c..b43db54668 100644 --- a/src/compiler/x87/instruction-selector-x87.cc +++ b/src/compiler/x87/instruction-selector-x87.cc @@ -544,7 +544,23 @@ void InstructionSelector::VisitWord32Sar(Node* node) { VisitShift(this, node, kX87Sar); } -void InstructionSelector::VisitInt32PairAdd(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitInt32PairAdd(Node* node) { + X87OperandGenerator g(this); + + // We use UseUniqueRegister here to avoid register sharing with the temp + // register. + 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.DefineSameAsFirst(node), + g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; + + InstructionOperand temps[] = {g.TempRegister()}; + + Emit(kX87AddPair, 2, outputs, 4, inputs, 1, temps); +} void InstructionSelector::VisitWord32PairShl(Node* node) { X87OperandGenerator g(this); diff --git a/src/x87/disasm-x87.cc b/src/x87/disasm-x87.cc index 26e1b9b187..ba102e25da 100644 --- a/src/x87/disasm-x87.cc +++ b/src/x87/disasm-x87.cc @@ -29,29 +29,18 @@ struct ByteMnemonic { }; static const ByteMnemonic two_operands_instr[] = { - {0x01, "add", OPER_REG_OP_ORDER}, - {0x03, "add", REG_OPER_OP_ORDER}, - {0x09, "or", OPER_REG_OP_ORDER}, - {0x0B, "or", REG_OPER_OP_ORDER}, - {0x1B, "sbb", REG_OPER_OP_ORDER}, - {0x21, "and", OPER_REG_OP_ORDER}, - {0x23, "and", REG_OPER_OP_ORDER}, - {0x29, "sub", OPER_REG_OP_ORDER}, - {0x2A, "subb", REG_OPER_OP_ORDER}, - {0x2B, "sub", REG_OPER_OP_ORDER}, - {0x31, "xor", OPER_REG_OP_ORDER}, - {0x33, "xor", REG_OPER_OP_ORDER}, - {0x38, "cmpb", OPER_REG_OP_ORDER}, - {0x39, "cmp", OPER_REG_OP_ORDER}, - {0x3A, "cmpb", REG_OPER_OP_ORDER}, - {0x3B, "cmp", REG_OPER_OP_ORDER}, - {0x84, "test_b", REG_OPER_OP_ORDER}, - {0x85, "test", REG_OPER_OP_ORDER}, - {0x87, "xchg", REG_OPER_OP_ORDER}, - {0x8A, "mov_b", REG_OPER_OP_ORDER}, - {0x8B, "mov", REG_OPER_OP_ORDER}, - {0x8D, "lea", REG_OPER_OP_ORDER}, - {-1, "", UNSET_OP_ORDER}}; + {0x01, "add", OPER_REG_OP_ORDER}, {0x03, "add", REG_OPER_OP_ORDER}, + {0x09, "or", OPER_REG_OP_ORDER}, {0x0B, "or", REG_OPER_OP_ORDER}, + {0x13, "adc", REG_OPER_OP_ORDER}, {0x1B, "sbb", REG_OPER_OP_ORDER}, + {0x21, "and", OPER_REG_OP_ORDER}, {0x23, "and", REG_OPER_OP_ORDER}, + {0x29, "sub", OPER_REG_OP_ORDER}, {0x2A, "subb", REG_OPER_OP_ORDER}, + {0x2B, "sub", REG_OPER_OP_ORDER}, {0x31, "xor", OPER_REG_OP_ORDER}, + {0x33, "xor", REG_OPER_OP_ORDER}, {0x38, "cmpb", OPER_REG_OP_ORDER}, + {0x39, "cmp", OPER_REG_OP_ORDER}, {0x3A, "cmpb", REG_OPER_OP_ORDER}, + {0x3B, "cmp", REG_OPER_OP_ORDER}, {0x84, "test_b", REG_OPER_OP_ORDER}, + {0x85, "test", REG_OPER_OP_ORDER}, {0x87, "xchg", REG_OPER_OP_ORDER}, + {0x8A, "mov_b", REG_OPER_OP_ORDER}, {0x8B, "mov", REG_OPER_OP_ORDER}, + {0x8D, "lea", REG_OPER_OP_ORDER}, {-1, "", UNSET_OP_ORDER}}; static const ByteMnemonic zero_operands_instr[] = { {0xC3, "ret", UNSET_OP_ORDER}, diff --git a/test/cctest/test-disasm-x87.cc b/test/cctest/test-disasm-x87.cc index 96325be816..959be6626a 100644 --- a/test/cctest/test-disasm-x87.cc +++ b/test/cctest/test-disasm-x87.cc @@ -96,6 +96,7 @@ TEST(DisasmIa320) { __ nop(); __ add(ebx, Immediate(12)); __ nop(); + __ adc(edx, Operand(ebx)); __ adc(ecx, 12); __ adc(ecx, 1000); __ nop();