Chromium Code Reviews| Index: src/compiler/x87/instruction-selector-x87.cc |
| diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/x87/instruction-selector-x87.cc |
| similarity index 78% |
| copy from src/compiler/ia32/instruction-selector-ia32.cc |
| copy to src/compiler/x87/instruction-selector-x87.cc |
| index e7ddc1ad18287b909eb05a3fbb8ced724459e865..ace5467adb5dc670edf940daa3ab1f3878dc9d57 100644 |
| --- a/src/compiler/ia32/instruction-selector-ia32.cc |
| +++ b/src/compiler/x87/instruction-selector-x87.cc |
| @@ -11,10 +11,10 @@ namespace v8 { |
| namespace internal { |
| namespace compiler { |
| -// Adds IA32-specific methods for generating operands. |
| -class IA32OperandGenerator final : public OperandGenerator { |
| +// Adds X87-specific methods for generating operands. |
| +class X87OperandGenerator final : public OperandGenerator { |
| public: |
| - explicit IA32OperandGenerator(InstructionSelector* selector) |
| + explicit X87OperandGenerator(InstructionSelector* selector) |
| : OperandGenerator(selector) {} |
| InstructionOperand UseByteRegister(Node* node) { |
| @@ -27,6 +27,10 @@ class IA32OperandGenerator final : public OperandGenerator { |
| return DefineAsRegister(node); |
| } |
| + InstructionOperand CreateImmediate(int imm) { |
| + return sequence()->AddImmediate(Constant(imm)); |
| + } |
| + |
| bool CanBeImmediate(Node* node) { |
| switch (node->opcode()) { |
| case IrOpcode::kInt32Constant: |
| @@ -125,50 +129,6 @@ class IA32OperandGenerator final : public OperandGenerator { |
| }; |
| -namespace { |
| - |
| -void VisitROFloat(InstructionSelector* selector, Node* node, |
| - ArchOpcode opcode) { |
| - IA32OperandGenerator g(selector); |
| - selector->Emit(opcode, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| -} |
| - |
| - |
| -void VisitRRFloat(InstructionSelector* selector, Node* node, |
| - InstructionCode opcode) { |
| - IA32OperandGenerator g(selector); |
| - selector->Emit(opcode, g.DefineAsRegister(node), |
| - g.UseRegister(node->InputAt(0))); |
| -} |
| - |
| - |
| -void VisitRROFloat(InstructionSelector* selector, Node* node, |
| - ArchOpcode avx_opcode, ArchOpcode sse_opcode) { |
| - IA32OperandGenerator g(selector); |
| - InstructionOperand operand0 = g.UseRegister(node->InputAt(0)); |
| - InstructionOperand operand1 = g.Use(node->InputAt(1)); |
| - if (selector->IsSupported(AVX)) { |
| - selector->Emit(avx_opcode, g.DefineAsRegister(node), operand0, operand1); |
| - } else { |
| - selector->Emit(sse_opcode, g.DefineSameAsFirst(node), operand0, operand1); |
| - } |
| -} |
| - |
| - |
| -void VisitFloatUnop(InstructionSelector* selector, Node* node, Node* input, |
| - ArchOpcode avx_opcode, ArchOpcode sse_opcode) { |
| - IA32OperandGenerator g(selector); |
| - if (selector->IsSupported(AVX)) { |
| - selector->Emit(avx_opcode, g.DefineAsRegister(node), g.Use(input)); |
| - } else { |
| - selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input)); |
| - } |
| -} |
| - |
| - |
| -} // namespace |
| - |
| - |
| void InstructionSelector::VisitLoad(Node* node) { |
| MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); |
| MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); |
| @@ -176,28 +136,28 @@ void InstructionSelector::VisitLoad(Node* node) { |
| ArchOpcode opcode; |
| switch (rep) { |
| case kRepFloat32: |
| - opcode = kIA32Movss; |
| + opcode = kX87Movss; |
| break; |
| case kRepFloat64: |
| - opcode = kIA32Movsd; |
| + opcode = kX87Movsd; |
| break; |
| case kRepBit: // Fall through. |
| case kRepWord8: |
| - opcode = typ == kTypeInt32 ? kIA32Movsxbl : kIA32Movzxbl; |
| + opcode = typ == kTypeInt32 ? kX87Movsxbl : kX87Movzxbl; |
| break; |
| case kRepWord16: |
| - opcode = typ == kTypeInt32 ? kIA32Movsxwl : kIA32Movzxwl; |
| + opcode = typ == kTypeInt32 ? kX87Movsxwl : kX87Movzxwl; |
| break; |
| case kRepTagged: // Fall through. |
| case kRepWord32: |
| - opcode = kIA32Movl; |
| + opcode = kX87Movl; |
| break; |
| default: |
| UNREACHABLE(); |
| return; |
| } |
| - IA32OperandGenerator g(this); |
| + X87OperandGenerator g(this); |
| InstructionOperand outputs[1]; |
| outputs[0] = g.DefineAsRegister(node); |
| InstructionOperand inputs[3]; |
| @@ -210,7 +170,7 @@ void InstructionSelector::VisitLoad(Node* node) { |
| void InstructionSelector::VisitStore(Node* node) { |
| - IA32OperandGenerator g(this); |
| + X87OperandGenerator g(this); |
| Node* base = node->InputAt(0); |
| Node* index = node->InputAt(1); |
| Node* value = node->InputAt(2); |
| @@ -223,12 +183,12 @@ void InstructionSelector::VisitStore(Node* node) { |
| // and pass them here instead of using fixed regs |
| if (g.CanBeImmediate(index)) { |
| InstructionOperand temps[] = {g.TempRegister(ecx), g.TempRegister()}; |
| - Emit(kIA32StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx), |
| + Emit(kX87StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx), |
| g.UseImmediate(index), g.UseFixed(value, ecx), arraysize(temps), |
| temps); |
| } else { |
| InstructionOperand temps[] = {g.TempRegister(ecx), g.TempRegister(edx)}; |
| - Emit(kIA32StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx), |
| + Emit(kX87StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx), |
| g.UseFixed(index, ecx), g.UseFixed(value, edx), arraysize(temps), |
| temps); |
| } |
| @@ -239,21 +199,21 @@ void InstructionSelector::VisitStore(Node* node) { |
| ArchOpcode opcode; |
| switch (rep) { |
| case kRepFloat32: |
| - opcode = kIA32Movss; |
| + opcode = kX87Movss; |
| break; |
| case kRepFloat64: |
| - opcode = kIA32Movsd; |
| + opcode = kX87Movsd; |
| break; |
| case kRepBit: // Fall through. |
| case kRepWord8: |
| - opcode = kIA32Movb; |
| + opcode = kX87Movb; |
| break; |
| case kRepWord16: |
| - opcode = kIA32Movw; |
| + opcode = kX87Movw; |
| break; |
| case kRepTagged: // Fall through. |
| case kRepWord32: |
| - opcode = kIA32Movl; |
| + opcode = kX87Movl; |
| break; |
| default: |
| UNREACHABLE(); |
| @@ -282,7 +242,7 @@ void InstructionSelector::VisitStore(Node* node) { |
| void InstructionSelector::VisitCheckedLoad(Node* node) { |
| MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); |
| MachineType typ = TypeOf(OpParameter<MachineType>(node)); |
| - IA32OperandGenerator g(this); |
| + X87OperandGenerator g(this); |
| Node* const buffer = node->InputAt(0); |
| Node* const offset = node->InputAt(1); |
| Node* const length = node->InputAt(2); |
| @@ -324,7 +284,7 @@ void InstructionSelector::VisitCheckedLoad(Node* node) { |
| void InstructionSelector::VisitCheckedStore(Node* node) { |
| MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); |
| - IA32OperandGenerator g(this); |
| + X87OperandGenerator g(this); |
| Node* const buffer = node->InputAt(0); |
| Node* const offset = node->InputAt(1); |
| Node* const length = node->InputAt(2); |
| @@ -373,7 +333,7 @@ void InstructionSelector::VisitCheckedStore(Node* node) { |
| // Shared routine for multiple binary operations. |
| static void VisitBinop(InstructionSelector* selector, Node* node, |
| InstructionCode opcode, FlagsContinuation* cont) { |
| - IA32OperandGenerator g(selector); |
| + X87OperandGenerator g(selector); |
| Int32BinopMatcher m(node); |
| Node* left = m.left().node(); |
| Node* right = m.right().node(); |
| @@ -413,7 +373,7 @@ static void VisitBinop(InstructionSelector* selector, Node* node, |
| outputs[output_count++] = g.DefineSameAsFirst(node); |
| if (cont->IsSet()) { |
| - outputs[output_count++] = g.DefineAsByteRegister(cont->result()); |
| + outputs[output_count++] = g.DefineAsRegister(cont->result()); |
| } |
| DCHECK_NE(0u, input_count); |
| @@ -435,22 +395,22 @@ static void VisitBinop(InstructionSelector* selector, Node* node, |
| void InstructionSelector::VisitWord32And(Node* node) { |
| - VisitBinop(this, node, kIA32And); |
| + VisitBinop(this, node, kX87And); |
| } |
| void InstructionSelector::VisitWord32Or(Node* node) { |
| - VisitBinop(this, node, kIA32Or); |
| + VisitBinop(this, node, kX87Or); |
| } |
| void InstructionSelector::VisitWord32Xor(Node* node) { |
| - IA32OperandGenerator g(this); |
| + X87OperandGenerator g(this); |
| Int32BinopMatcher m(node); |
| if (m.right().Is(-1)) { |
| - Emit(kIA32Not, g.DefineSameAsFirst(node), g.UseRegister(m.left().node())); |
| + Emit(kX87Not, g.DefineSameAsFirst(node), g.UseRegister(m.left().node())); |
| } else { |
| - VisitBinop(this, node, kIA32Xor); |
| + VisitBinop(this, node, kX87Xor); |
| } |
| } |
| @@ -458,7 +418,7 @@ void InstructionSelector::VisitWord32Xor(Node* node) { |
| // Shared routine for multiple shift operations. |
| static inline void VisitShift(InstructionSelector* selector, Node* node, |
| ArchOpcode opcode) { |
| - IA32OperandGenerator g(selector); |
| + X87OperandGenerator g(selector); |
| Node* left = node->InputAt(0); |
| Node* right = node->InputAt(1); |
| @@ -476,7 +436,7 @@ namespace { |
| void VisitMulHigh(InstructionSelector* selector, Node* node, |
| ArchOpcode opcode) { |
| - IA32OperandGenerator g(selector); |
| + X87OperandGenerator g(selector); |
| selector->Emit(opcode, g.DefineAsFixed(node, edx), |
| g.UseFixed(node->InputAt(0), eax), |
| g.UseUniqueRegister(node->InputAt(1))); |
| @@ -484,7 +444,7 @@ void VisitMulHigh(InstructionSelector* selector, Node* node, |
| void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) { |
| - IA32OperandGenerator g(selector); |
| + X87OperandGenerator g(selector); |
| InstructionOperand temps[] = {g.TempRegister(edx)}; |
| selector->Emit(opcode, g.DefineAsFixed(node, eax), |
| g.UseFixed(node->InputAt(0), eax), |
| @@ -493,7 +453,7 @@ void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) { |
| void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) { |
| - IA32OperandGenerator g(selector); |
| + X87OperandGenerator g(selector); |
| selector->Emit(opcode, g.DefineAsFixed(node, edx), |
| g.UseFixed(node->InputAt(0), eax), |
| g.UseUnique(node->InputAt(1))); |
| @@ -501,7 +461,7 @@ void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) { |
| void EmitLea(InstructionSelector* selector, Node* result, Node* index, |
| int scale, Node* base, Node* displacement) { |
| - IA32OperandGenerator g(selector); |
| + X87OperandGenerator g(selector); |
| InstructionOperand inputs[4]; |
| size_t input_count = 0; |
| AddressingMode mode = g.GenerateMemoryOperandInputs( |
| @@ -513,7 +473,7 @@ void EmitLea(InstructionSelector* selector, Node* result, Node* index, |
| InstructionOperand outputs[1]; |
| outputs[0] = g.DefineAsRegister(result); |
| - InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea; |
| + InstructionCode opcode = AddressingModeField::encode(mode) | kX87Lea; |
| selector->Emit(opcode, 1, outputs, input_count, inputs); |
| } |
| @@ -529,33 +489,33 @@ void InstructionSelector::VisitWord32Shl(Node* node) { |
| EmitLea(this, node, index, m.scale(), base, NULL); |
| return; |
| } |
| - VisitShift(this, node, kIA32Shl); |
| + VisitShift(this, node, kX87Shl); |
| } |
| void InstructionSelector::VisitWord32Shr(Node* node) { |
| - VisitShift(this, node, kIA32Shr); |
| + VisitShift(this, node, kX87Shr); |
| } |
| void InstructionSelector::VisitWord32Sar(Node* node) { |
| - VisitShift(this, node, kIA32Sar); |
| + VisitShift(this, node, kX87Sar); |
| } |
| void InstructionSelector::VisitWord32Ror(Node* node) { |
| - VisitShift(this, node, kIA32Ror); |
| + VisitShift(this, node, kX87Ror); |
| } |
| void InstructionSelector::VisitWord32Clz(Node* node) { |
| - IA32OperandGenerator g(this); |
| - Emit(kIA32Lzcnt, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| + X87OperandGenerator g(this); |
| + Emit(kX87Lzcnt, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| } |
| void InstructionSelector::VisitInt32Add(Node* node) { |
| - IA32OperandGenerator g(this); |
| + X87OperandGenerator g(this); |
| // Try to match the Add to a lea pattern |
| BaseWithIndexAndDisplacement32Matcher m(node); |
| @@ -572,23 +532,23 @@ void InstructionSelector::VisitInt32Add(Node* node) { |
| InstructionOperand outputs[1]; |
| outputs[0] = g.DefineAsRegister(node); |
| - InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea; |
| + InstructionCode opcode = AddressingModeField::encode(mode) | kX87Lea; |
| Emit(opcode, 1, outputs, input_count, inputs); |
| return; |
| } |
| // No lea pattern match, use add |
| - VisitBinop(this, node, kIA32Add); |
| + VisitBinop(this, node, kX87Add); |
| } |
| void InstructionSelector::VisitInt32Sub(Node* node) { |
| - IA32OperandGenerator g(this); |
| + X87OperandGenerator g(this); |
| Int32BinopMatcher m(node); |
| if (m.left().Is(0)) { |
| - Emit(kIA32Neg, g.DefineSameAsFirst(node), g.Use(m.right().node())); |
| + Emit(kX87Neg, g.DefineSameAsFirst(node), g.Use(m.right().node())); |
| } else { |
| - VisitBinop(this, node, kIA32Sub); |
| + VisitBinop(this, node, kX87Sub); |
| } |
| } |
| @@ -601,212 +561,238 @@ void InstructionSelector::VisitInt32Mul(Node* node) { |
| EmitLea(this, node, index, m.scale(), base, NULL); |
| return; |
| } |
| - IA32OperandGenerator g(this); |
| + X87OperandGenerator g(this); |
| Node* left = node->InputAt(0); |
| Node* right = node->InputAt(1); |
| if (g.CanBeImmediate(right)) { |
| - Emit(kIA32Imul, g.DefineAsRegister(node), g.Use(left), |
| + Emit(kX87Imul, g.DefineAsRegister(node), g.Use(left), |
| g.UseImmediate(right)); |
| } else { |
| if (g.CanBeBetterLeftOperand(right)) { |
| std::swap(left, right); |
| } |
| - Emit(kIA32Imul, g.DefineSameAsFirst(node), g.UseRegister(left), |
| + Emit(kX87Imul, g.DefineSameAsFirst(node), g.UseRegister(left), |
| g.Use(right)); |
| } |
| } |
| void InstructionSelector::VisitInt32MulHigh(Node* node) { |
| - VisitMulHigh(this, node, kIA32ImulHigh); |
| + VisitMulHigh(this, node, kX87ImulHigh); |
| } |
| void InstructionSelector::VisitUint32MulHigh(Node* node) { |
| - VisitMulHigh(this, node, kIA32UmulHigh); |
| + VisitMulHigh(this, node, kX87UmulHigh); |
| } |
| void InstructionSelector::VisitInt32Div(Node* node) { |
| - VisitDiv(this, node, kIA32Idiv); |
| + VisitDiv(this, node, kX87Idiv); |
| } |
| void InstructionSelector::VisitUint32Div(Node* node) { |
| - VisitDiv(this, node, kIA32Udiv); |
| + VisitDiv(this, node, kX87Udiv); |
| } |
| void InstructionSelector::VisitInt32Mod(Node* node) { |
| - VisitMod(this, node, kIA32Idiv); |
| + VisitMod(this, node, kX87Idiv); |
| } |
| void InstructionSelector::VisitUint32Mod(Node* node) { |
| - VisitMod(this, node, kIA32Udiv); |
| + VisitMod(this, node, kX87Udiv); |
| } |
| void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { |
| - IA32OperandGenerator g(this); |
| - Emit(kSSEFloat32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| + X87OperandGenerator g(this); |
| + Emit(kX87Float32ToFloat64, g.DefineAsFixed(node, stX_0), |
| + g.Use(node->InputAt(0))); |
| } |
| void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { |
| - IA32OperandGenerator g(this); |
| - Emit(kSSEInt32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| + X87OperandGenerator g(this); |
| + Emit(kX87Int32ToFloat64, g.DefineAsFixed(node, stX_0), |
| + g.Use(node->InputAt(0))); |
| } |
| void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { |
| - IA32OperandGenerator g(this); |
| - Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| + X87OperandGenerator g(this); |
| + Emit(kX87Uint32ToFloat64, g.DefineAsFixed(node, stX_0), |
| + g.UseRegister(node->InputAt(0))); |
| } |
| void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { |
| - IA32OperandGenerator g(this); |
| - Emit(kSSEFloat64ToInt32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| + X87OperandGenerator g(this); |
| + Emit(kX87Float64ToInt32, g.DefineAsRegister(node), |
| + g.Use(node->InputAt(0))); |
| } |
| void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { |
| - IA32OperandGenerator g(this); |
| - Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| + X87OperandGenerator g(this); |
| + Emit(kX87Float64ToUint32, g.DefineAsRegister(node), |
| + g.Use(node->InputAt(0))); |
| } |
| void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { |
| - IA32OperandGenerator g(this); |
| - Emit(kSSEFloat64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| + X87OperandGenerator g(this); |
| + Emit(kX87Float64ToFloat32, g.DefineAsFixed(node, stX_0), |
| + g.Use(node->InputAt(0))); |
| } |
| void InstructionSelector::VisitFloat32Add(Node* node) { |
| - VisitRROFloat(this, node, kAVXFloat32Add, kSSEFloat32Add); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1))); |
| + Emit(kX87Float32Add, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat64Add(Node* node) { |
| - VisitRROFloat(this, node, kAVXFloat64Add, kSSEFloat64Add); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1))); |
| + Emit(kX87Float64Add, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat32Sub(Node* node) { |
| - IA32OperandGenerator g(this); |
| - Float32BinopMatcher m(node); |
| - if (m.left().IsMinusZero()) { |
| - VisitFloatUnop(this, node, m.right().node(), kAVXFloat32Neg, |
| - kSSEFloat32Neg); |
| - return; |
| - } |
| - VisitRROFloat(this, node, kAVXFloat32Sub, kSSEFloat32Sub); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1))); |
| + Emit(kX87Float32Sub, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat64Sub(Node* node) { |
| - IA32OperandGenerator g(this); |
| - Float64BinopMatcher m(node); |
| - if (m.left().IsMinusZero()) { |
| - if (m.right().IsFloat64RoundDown() && |
| - CanCover(m.node(), m.right().node())) { |
| - if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub && |
| - CanCover(m.right().node(), m.right().InputAt(0))) { |
| - Float64BinopMatcher mright0(m.right().InputAt(0)); |
| - if (mright0.left().IsMinusZero()) { |
| - Emit(kSSEFloat64Round | MiscField::encode(kRoundUp), |
| - g.DefineAsRegister(node), g.UseRegister(mright0.right().node())); |
| - return; |
| - } |
| - } |
| - } |
| - VisitFloatUnop(this, node, m.right().node(), kAVXFloat64Neg, |
| - kSSEFloat64Neg); |
| - return; |
| - } |
| - VisitRROFloat(this, node, kAVXFloat64Sub, kSSEFloat64Sub); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1))); |
| + Emit(kX87Float64Sub, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat32Mul(Node* node) { |
| - VisitRROFloat(this, node, kAVXFloat32Mul, kSSEFloat32Mul); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1))); |
| + Emit(kX87Float32Mul, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat64Mul(Node* node) { |
| - VisitRROFloat(this, node, kAVXFloat64Mul, kSSEFloat64Mul); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1))); |
| + Emit(kX87Float64Mul, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat32Div(Node* node) { |
| - VisitRROFloat(this, node, kAVXFloat32Div, kSSEFloat32Div); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1))); |
| + Emit(kX87Float32Div, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat64Div(Node* node) { |
| - VisitRROFloat(this, node, kAVXFloat64Div, kSSEFloat64Div); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1))); |
| + Emit(kX87Float64Div, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat64Mod(Node* node) { |
| - IA32OperandGenerator g(this); |
| + X87OperandGenerator g(this); |
| InstructionOperand temps[] = {g.TempRegister(eax)}; |
| - Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node), |
| - g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1, |
| - temps); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1))); |
| + Emit(kX87Float64Mod, g.DefineAsFixed(node, stX_0), 1, temps)->MarkAsCall(); |
| } |
| void InstructionSelector::VisitFloat32Max(Node* node) { |
| - VisitRROFloat(this, node, kAVXFloat32Max, kSSEFloat32Max); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1))); |
| + Emit(kX87Float32Max, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat64Max(Node* node) { |
| - VisitRROFloat(this, node, kAVXFloat64Max, kSSEFloat64Max); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1))); |
| + Emit(kX87Float64Max, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat32Min(Node* node) { |
| - VisitRROFloat(this, node, kAVXFloat32Min, kSSEFloat32Min); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1))); |
| + Emit(kX87Float32Min, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat64Min(Node* node) { |
| - VisitRROFloat(this, node, kAVXFloat64Min, kSSEFloat64Min); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1))); |
| + Emit(kX87Float64Min, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat32Abs(Node* node) { |
| - IA32OperandGenerator g(this); |
| - VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Abs, kSSEFloat32Abs); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87Float32Abs, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat64Abs(Node* node) { |
| - IA32OperandGenerator g(this); |
| - VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Abs, kSSEFloat64Abs); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87Float64Abs, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat32Sqrt(Node* node) { |
| - VisitROFloat(this, node, kSSEFloat32Sqrt); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87Float32Sqrt, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat64Sqrt(Node* node) { |
| - VisitROFloat(this, node, kSSEFloat64Sqrt); |
| + X87OperandGenerator g(this); |
| + Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0))); |
| + Emit(kX87Float64Sqrt, g.DefineAsFixed(node, stX_0), 0, NULL); |
| } |
| void InstructionSelector::VisitFloat64RoundDown(Node* node) { |
| - VisitRRFloat(this, node, kSSEFloat64Round | MiscField::encode(kRoundDown)); |
| + X87OperandGenerator g(this); |
| + Emit(kX87Float64Round | MiscField::encode(kRoundDown), |
| + g.UseFixed(node, stX_0), g.Use(node->InputAt(0))); |
| } |
| void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
| - VisitRRFloat(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero)); |
| + X87OperandGenerator g(this); |
| + Emit(kX87Float64Round | MiscField::encode(kRoundToZero), |
| + g.UseFixed(node, stX_0), g.Use(node->InputAt(0))); |
| } |
| @@ -816,7 +802,7 @@ void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
| void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { |
| - IA32OperandGenerator g(this); |
| + X87OperandGenerator g(this); |
| const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); |
| FrameStateDescriptor* frame_state_descriptor = nullptr; |
| @@ -837,7 +823,7 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { |
| g.CanBeImmediate(node) |
| ? g.UseImmediate(node) |
| : IsSupported(ATOM) ? g.UseRegister(node) : g.Use(node); |
| - Emit(kIA32Push, g.NoOutput(), value); |
| + Emit(kX87Push, g.NoOutput(), value); |
| } |
| // Pass label of exception handler block. |
| @@ -877,7 +863,7 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { |
| void InstructionSelector::VisitTailCall(Node* node) { |
| - IA32OperandGenerator g(this); |
| + X87OperandGenerator g(this); |
| CallDescriptor const* descriptor = OpParameter<CallDescriptor const*>(node); |
| DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls); |
| DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kPatchableCallSite); |
| @@ -931,7 +917,7 @@ void InstructionSelector::VisitTailCall(Node* node) { |
| g.CanBeImmediate(node) |
| ? g.UseImmediate(node) |
| : IsSupported(ATOM) ? g.UseRegister(node) : g.Use(node); |
| - Emit(kIA32Push, g.NoOutput(), value); |
| + Emit(kX87Push, g.NoOutput(), value); |
| } |
| // Select the appropriate opcode based on the call type. |
| @@ -965,7 +951,7 @@ namespace { |
| void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| InstructionOperand left, InstructionOperand right, |
| FlagsContinuation* cont) { |
| - IA32OperandGenerator g(selector); |
| + X87OperandGenerator g(selector); |
| if (cont->IsBranch()) { |
| selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right, |
| g.Label(cont->true_block()), g.Label(cont->false_block())); |
| @@ -981,7 +967,7 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| Node* left, Node* right, FlagsContinuation* cont, |
| bool commutative) { |
| - IA32OperandGenerator g(selector); |
| + X87OperandGenerator g(selector); |
| if (commutative && g.CanBeBetterLeftOperand(right)) { |
| std::swap(left, right); |
| } |
| @@ -992,25 +978,41 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| // Shared routine for multiple float32 compare operations (inputs commuted). |
| void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
| FlagsContinuation* cont) { |
| - Node* const left = node->InputAt(0); |
| - Node* const right = node->InputAt(1); |
| - VisitCompare(selector, kSSEFloat32Cmp, right, left, cont, false); |
| + X87OperandGenerator g(selector); |
| + selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); |
| + selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1))); |
| + if (cont->IsBranch()) { |
| + selector->Emit(cont->Encode(kX87Float32Cmp), g.NoOutput(), |
| + g.Label(cont->true_block()), g.Label(cont->false_block())); |
| + } else { |
| + DCHECK(cont->IsSet()); |
| + selector->Emit(cont->Encode(kX87Float32Cmp), |
| + g.DefineAsByteRegister(cont->result())); |
| + } |
| } |
| // Shared routine for multiple float64 compare operations (inputs commuted). |
| void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
| FlagsContinuation* cont) { |
| - Node* const left = node->InputAt(0); |
| - Node* const right = node->InputAt(1); |
| - VisitCompare(selector, kSSEFloat64Cmp, right, left, cont, false); |
| + X87OperandGenerator g(selector); |
| + selector->Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0))); |
| + selector->Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1))); |
| + if (cont->IsBranch()) { |
| + selector->Emit(cont->Encode(kX87Float64Cmp), g.NoOutput(), |
| + g.Label(cont->true_block()), g.Label(cont->false_block())); |
| + } else { |
| + DCHECK(cont->IsSet()); |
| + selector->Emit(cont->Encode(kX87Float64Cmp), |
| + g.DefineAsByteRegister(cont->result())); |
| + } |
| } |
| // Shared routine for multiple word compare operations. |
| void VisitWordCompare(InstructionSelector* selector, Node* node, |
| InstructionCode opcode, FlagsContinuation* cont) { |
| - IA32OperandGenerator g(selector); |
| + X87OperandGenerator g(selector); |
| Node* const left = node->InputAt(0); |
| Node* const right = node->InputAt(1); |
| @@ -1029,7 +1031,7 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, |
| void VisitWordCompare(InstructionSelector* selector, Node* node, |
| FlagsContinuation* cont) { |
| - IA32OperandGenerator g(selector); |
| + X87OperandGenerator g(selector); |
| Int32BinopMatcher m(node); |
| if (m.left().IsLoad() && m.right().IsLoadStackPointer()) { |
| LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node()); |
| @@ -1038,7 +1040,7 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, |
| if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) { |
| // Compare(Load(js_stack_limit), LoadStackPointer) |
| if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); |
| - InstructionCode opcode = cont->Encode(kIA32StackCheck); |
| + InstructionCode opcode = cont->Encode(kX87StackCheck); |
| if (cont->IsBranch()) { |
| selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()), |
| g.Label(cont->false_block())); |
| @@ -1049,7 +1051,7 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, |
| return; |
| } |
| } |
| - VisitWordCompare(selector, node, kIA32Cmp, cont); |
| + VisitWordCompare(selector, node, kX87Cmp, cont); |
| } |
| @@ -1117,10 +1119,10 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, |
| switch (node->opcode()) { |
| case IrOpcode::kInt32AddWithOverflow: |
| cont->OverwriteAndNegateIfEqual(kOverflow); |
| - return VisitBinop(selector, node, kIA32Add, cont); |
| + return VisitBinop(selector, node, kX87Add, cont); |
| case IrOpcode::kInt32SubWithOverflow: |
| cont->OverwriteAndNegateIfEqual(kOverflow); |
| - return VisitBinop(selector, node, kIA32Sub, cont); |
| + return VisitBinop(selector, node, kX87Sub, cont); |
| default: |
| break; |
| } |
| @@ -1130,7 +1132,7 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, |
| case IrOpcode::kInt32Sub: |
| return VisitWordCompare(selector, value, cont); |
| case IrOpcode::kWord32And: |
| - return VisitWordCompare(selector, value, kIA32Test, cont); |
| + return VisitWordCompare(selector, value, kX87Test, cont); |
| default: |
| break; |
| } |
| @@ -1138,8 +1140,8 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, |
| } |
| // Continuation could not be combined with a compare, emit compare against 0. |
| - IA32OperandGenerator g(selector); |
| - VisitCompare(selector, kIA32Cmp, g.Use(value), g.TempImmediate(0), cont); |
| + X87OperandGenerator g(selector); |
| + VisitCompare(selector, kX87Cmp, g.Use(value), g.TempImmediate(0), cont); |
| } |
| } // namespace |
| @@ -1153,7 +1155,7 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
| void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { |
| - IA32OperandGenerator g(this); |
| + X87OperandGenerator g(this); |
| InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); |
| // Emit either ArchTableSwitch or ArchLookupSwitch. |
| @@ -1168,7 +1170,7 @@ void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { |
| InstructionOperand index_operand = value_operand; |
| if (sw.min_value) { |
| index_operand = g.TempRegister(); |
| - Emit(kIA32Lea | AddressingModeField::encode(kMode_MRI), index_operand, |
| + Emit(kX87Lea | AddressingModeField::encode(kMode_MRI), index_operand, |
| value_operand, g.TempImmediate(-sw.min_value)); |
| } |
| // Generate a table lookup. |
| @@ -1217,20 +1219,20 @@ void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { |
| void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { |
| if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
| FlagsContinuation cont(kOverflow, ovf); |
| - return VisitBinop(this, node, kIA32Add, &cont); |
| + return VisitBinop(this, node, kX87Add, &cont); |
| } |
| FlagsContinuation cont; |
| - VisitBinop(this, node, kIA32Add, &cont); |
| + VisitBinop(this, node, kX87Add, &cont); |
| } |
| void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { |
| if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
| FlagsContinuation cont(kOverflow, ovf); |
| - return VisitBinop(this, node, kIA32Sub, &cont); |
| + return VisitBinop(this, node, kX87Sub, &cont); |
| } |
| FlagsContinuation cont; |
| - VisitBinop(this, node, kIA32Sub, &cont); |
| + VisitBinop(this, node, kX87Sub, &cont); |
| } |
| @@ -1271,39 +1273,40 @@ void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { |
| void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { |
| - IA32OperandGenerator g(this); |
| - Emit(kSSEFloat64ExtractLowWord32, g.DefineAsRegister(node), |
| + X87OperandGenerator g(this); |
| + Emit(kX87Float64ExtractLowWord32, g.DefineAsRegister(node), |
| g.Use(node->InputAt(0))); |
| } |
| void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { |
| - IA32OperandGenerator g(this); |
| - Emit(kSSEFloat64ExtractHighWord32, g.DefineAsRegister(node), |
| + X87OperandGenerator g(this); |
| + Emit(kX87Float64ExtractHighWord32, g.DefineAsRegister(node), |
| g.Use(node->InputAt(0))); |
| } |
| void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) { |
| - IA32OperandGenerator g(this); |
| + X87OperandGenerator g(this); |
| Node* left = node->InputAt(0); |
| Node* right = node->InputAt(1); |
| - Float64Matcher mleft(left); |
| + /* Float64Matcher mleft(left); |
|
Weiliang
2015/06/15 06:14:30
remove the comments code
|
| if (mleft.HasValue() && (bit_cast<uint64_t>(mleft.Value()) >> 32) == 0u) { |
| - Emit(kSSEFloat64LoadLowWord32, g.DefineAsRegister(node), g.Use(right)); |
| + Emit(kX87Float64LoadLowWord32, g.DefineAsRegister(node), g.Use(right)); |
| return; |
| } |
| - Emit(kSSEFloat64InsertLowWord32, g.DefineSameAsFirst(node), |
| - g.UseRegister(left), g.Use(right)); |
| + */ |
| + Emit(kX87Float64InsertLowWord32, g.UseFixed(node, stX_0), |
| + g.UseRegister(left), g.UseRegister(right)); |
| } |
| void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { |
| - IA32OperandGenerator g(this); |
| + X87OperandGenerator g(this); |
| Node* left = node->InputAt(0); |
| Node* right = node->InputAt(1); |
| - Emit(kSSEFloat64InsertHighWord32, g.DefineSameAsFirst(node), |
| - g.UseRegister(left), g.Use(right)); |
| + Emit(kX87Float64InsertHighWord32, g.UseFixed(node, stX_0), |
| + g.UseRegister(left), g.UseRegister(right)); |
| } |
| @@ -1316,10 +1319,6 @@ InstructionSelector::SupportedMachineOperatorFlags() { |
| MachineOperatorBuilder::kFloat64Max | |
| MachineOperatorBuilder::kFloat64Min | |
| MachineOperatorBuilder::kWord32ShiftIsSafe; |
| - if (CpuFeatures::IsSupported(SSE4_1)) { |
| - flags |= MachineOperatorBuilder::kFloat64RoundDown | |
| - MachineOperatorBuilder::kFloat64RoundTruncate; |
| - } |
| return flags; |
| } |