Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Unified Diff: src/compiler/x87/instruction-selector-x87.cc

Issue 1179763004: X87: enable the X87 turbofan support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/x87/instruction-codes-x87.h ('k') | src/compiler/x87/linkage-x87.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 79%
copy from src/compiler/ia32/instruction-selector-ia32.cc
copy to src/compiler/x87/instruction-selector-x87.cc
index e7ddc1ad18287b909eb05a3fbb8ced724459e865..76b339dbc986d92ba693f5d2ddb8f7486ac26f97 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,236 @@ 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 +800,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 +821,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 +861,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 +915,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 +949,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 +965,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 +976,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 +1029,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 +1038,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 +1049,7 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
return;
}
}
- VisitWordCompare(selector, node, kIA32Cmp, cont);
+ VisitWordCompare(selector, node, kX87Cmp, cont);
}
@@ -1117,10 +1117,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 +1130,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 +1138,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 +1153,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 +1168,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 +1217,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 +1271,34 @@ 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);
- if (mleft.HasValue() && (bit_cast<uint64_t>(mleft.Value()) >> 32) == 0u) {
- Emit(kSSEFloat64LoadLowWord32, 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 +1311,6 @@ InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::kFloat64Max |
MachineOperatorBuilder::kFloat64Min |
MachineOperatorBuilder::kWord32ShiftIsSafe;
- if (CpuFeatures::IsSupported(SSE4_1)) {
- flags |= MachineOperatorBuilder::kFloat64RoundDown |
- MachineOperatorBuilder::kFloat64RoundTruncate;
- }
return flags;
}
« no previous file with comments | « src/compiler/x87/instruction-codes-x87.h ('k') | src/compiler/x87/linkage-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698