diff options
Diffstat (limited to 'deps/v8/src/compiler/ia32/instruction-selector-ia32.cc')
-rw-r--r-- | deps/v8/src/compiler/ia32/instruction-selector-ia32.cc | 235 |
1 files changed, 87 insertions, 148 deletions
diff --git a/deps/v8/src/compiler/ia32/instruction-selector-ia32.cc b/deps/v8/src/compiler/ia32/instruction-selector-ia32.cc index ce2f14e97f..43b572170f 100644 --- a/deps/v8/src/compiler/ia32/instruction-selector-ia32.cc +++ b/deps/v8/src/compiler/ia32/instruction-selector-ia32.cc @@ -935,10 +935,10 @@ void InstructionSelector::VisitRoundUint32ToFloat32(Node* node) { void InstructionSelector::VisitFloat64Mod(Node* node) { IA32OperandGenerator g(this); - InstructionOperand temps[] = {g.TempRegister(eax)}; + InstructionOperand temps[] = {g.TempRegister(eax), g.TempRegister()}; Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node), - g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1, - temps); + g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), + arraysize(temps), temps); } void InstructionSelector::VisitFloat32Max(Node* node) { @@ -1343,43 +1343,42 @@ void VisitPairAtomicBinOp(InstructionSelector* selector, Node* node, // For Word64 operations, the value input is split into the a high node, // and a low node in the int64-lowering phase. Node* value_high = node->InputAt(3); +#if defined(V8_EMBEDDED_BUILTINS) + bool block_root_register = !selector->CanUseRootsRegister(); +#else + bool block_root_register = true; +#endif // Wasm lives in 32-bit address space, so we do not need to worry about // base/index lowering. This will need to be fixed for Wasm64. AddressingMode addressing_mode; InstructionOperand inputs[] = { - g.UseFixed(value, ebx), g.UseFixed(value_high, ecx), + g.UseUniqueRegisterOrSlotOrConstant(value), g.UseFixed(value_high, ecx), g.UseUniqueRegister(base), g.GetEffectiveIndexOperand(index, &addressing_mode)}; - InstructionOperand outputs[] = { - g.DefineAsFixed(NodeProperties::FindProjection(node, 0), eax), - g.DefineAsFixed(NodeProperties::FindProjection(node, 1), edx)}; - InstructionCode code = opcode | AddressingModeField::encode(addressing_mode); - selector->Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs); -} - -void VisitNarrowAtomicBinOp(InstructionSelector* selector, Node* node, - ArchOpcode opcode, MachineType type) { - IA32OperandGenerator g(selector); - Node* base = node->InputAt(0); - Node* index = node->InputAt(1); - Node* value = node->InputAt(2); - - // Wasm lives in 32-bit address space, so we do not need to worry about - // base/index lowering. This will need to be fixed for Wasm64. - AddressingMode addressing_mode; - InstructionOperand inputs[] = { - g.UseUniqueRegister(value), g.UseUniqueRegister(base), - g.GetEffectiveIndexOperand(index, &addressing_mode)}; - InstructionOperand outputs[] = { - g.DefineAsFixed(NodeProperties::FindProjection(node, 0), eax), - g.DefineAsFixed(NodeProperties::FindProjection(node, 1), edx)}; - InstructionOperand temp[] = {(type == MachineType::Uint8()) - ? g.UseByteRegister(node) - : g.TempRegister()}; InstructionCode code = opcode | AddressingModeField::encode(addressing_mode); - selector->Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs, - arraysize(temp), temp); + Node* projection0 = NodeProperties::FindProjection(node, 0); + Node* projection1 = NodeProperties::FindProjection(node, 1); + if (projection1) { + InstructionOperand temps[] = {g.TempRegister(ebx)}; + InstructionOperand outputs[] = {g.DefineAsFixed(projection0, eax), + g.DefineAsFixed(projection1, edx)}; + const int num_temps = arraysize(temps) - (block_root_register ? 0 : 1); + selector->Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs, + num_temps, temps); + } else if (projection0) { + InstructionOperand outputs[] = {g.DefineAsFixed(projection0, eax)}; + InstructionOperand temps[] = {g.TempRegister(edx), g.TempRegister(ebx)}; + const int num_temps = arraysize(temps) - (block_root_register ? 0 : 1); + selector->Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs, + num_temps, temps); + } else { + InstructionOperand temps[] = {g.TempRegister(eax), g.TempRegister(edx), + g.TempRegister(ebx)}; + const int num_temps = arraysize(temps) - (block_root_register ? 0 : 1); + selector->Emit(code, 0, nullptr, arraysize(inputs), inputs, num_temps, + temps); + } } } // namespace @@ -1769,14 +1768,27 @@ void InstructionSelector::VisitWord32AtomicPairLoad(Node* node) { Node* index = node->InputAt(1); InstructionOperand inputs[] = {g.UseUniqueRegister(base), g.GetEffectiveIndexOperand(index, &mode)}; - InstructionOperand temps[] = {g.TempDoubleRegister()}; - InstructionOperand outputs[] = { - g.DefineAsRegister(NodeProperties::FindProjection(node, 0)), - g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; + Node* projection0 = NodeProperties::FindProjection(node, 0); + Node* projection1 = NodeProperties::FindProjection(node, 1); InstructionCode code = kIA32Word32AtomicPairLoad | AddressingModeField::encode(mode); - Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs, - arraysize(temps), temps); + + if (projection1) { + InstructionOperand temps[] = {g.TempDoubleRegister()}; + InstructionOperand outputs[] = {g.DefineAsRegister(projection0), + g.DefineAsRegister(projection1)}; + Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs, + arraysize(temps), temps); + } else if (projection0) { + InstructionOperand temps[] = {g.TempDoubleRegister(), g.TempRegister()}; + InstructionOperand outputs[] = {g.DefineAsRegister(projection0)}; + Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs, + arraysize(temps), temps); + } else { + InstructionOperand temps[] = {g.TempDoubleRegister(), g.TempRegister(), + g.TempRegister()}; + Emit(code, 0, nullptr, arraysize(inputs), inputs, arraysize(temps), temps); + } } void InstructionSelector::VisitWord32AtomicPairStore(Node* node) { @@ -1785,19 +1797,26 @@ void InstructionSelector::VisitWord32AtomicPairStore(Node* node) { Node* index = node->InputAt(1); Node* value = node->InputAt(2); Node* value_high = node->InputAt(3); +#if defined(V8_EMBEDDED_BUILTINS) + bool block_root_register = !CanUseRootsRegister(); +#else + bool block_root_register = true; +#endif AddressingMode addressing_mode; InstructionOperand inputs[] = { - g.UseFixed(value, ebx), g.UseFixed(value_high, ecx), + g.UseUniqueRegisterOrSlotOrConstant(value), g.UseFixed(value_high, ecx), g.UseUniqueRegister(base), g.GetEffectiveIndexOperand(index, &addressing_mode)}; // Allocating temp registers here as stores are performed using an atomic // exchange, the output of which is stored in edx:eax, which should be saved // and restored at the end of the instruction. - InstructionOperand temps[] = {g.TempRegister(eax), g.TempRegister(edx)}; + InstructionOperand temps[] = {g.TempRegister(eax), g.TempRegister(edx), + g.TempRegister(ebx)}; + const int num_temps = arraysize(temps) - (block_root_register ? 0 : 1); InstructionCode code = kIA32Word32AtomicPairStore | AddressingModeField::encode(addressing_mode); - Emit(code, 0, nullptr, arraysize(inputs), inputs, arraysize(temps), temps); + Emit(code, 0, nullptr, arraysize(inputs), inputs, num_temps, temps); } void InstructionSelector::VisitWord32AtomicPairAdd(Node* node) { @@ -1828,125 +1847,45 @@ void InstructionSelector::VisitWord32AtomicPairCompareExchange(Node* node) { IA32OperandGenerator g(this); Node* index = node->InputAt(1); AddressingMode addressing_mode; +#if defined(V8_EMBEDDED_BUILTINS) + bool block_root_register = !CanUseRootsRegister(); +#else + bool block_root_register = true; +#endif + InstructionOperand inputs[] = { // High, Low values of old value g.UseFixed(node->InputAt(2), eax), g.UseFixed(node->InputAt(3), edx), // High, Low values of new value - g.UseFixed(node->InputAt(4), ebx), g.UseFixed(node->InputAt(5), ecx), + g.UseUniqueRegisterOrSlotOrConstant(node->InputAt(4)), + g.UseFixed(node->InputAt(5), ecx), // InputAt(0) => base g.UseUniqueRegister(node->InputAt(0)), g.GetEffectiveIndexOperand(index, &addressing_mode)}; - InstructionOperand outputs[] = { - g.DefineAsFixed(NodeProperties::FindProjection(node, 0), eax), - g.DefineAsFixed(NodeProperties::FindProjection(node, 1), edx)}; + Node* projection0 = NodeProperties::FindProjection(node, 0); + Node* projection1 = NodeProperties::FindProjection(node, 1); InstructionCode code = kIA32Word32AtomicPairCompareExchange | AddressingModeField::encode(addressing_mode); - Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs); -} -void InstructionSelector::VisitWord64AtomicNarrowBinop(Node* node, - ArchOpcode uint8_op, - ArchOpcode uint16_op, - ArchOpcode uint32_op) { - MachineType type = AtomicOpType(node->op()); - DCHECK(type != MachineType::Uint64()); - ArchOpcode opcode = kArchNop; - if (type == MachineType::Uint32()) { - opcode = uint32_op; - } else if (type == MachineType::Uint16()) { - opcode = uint16_op; - } else if (type == MachineType::Uint8()) { - opcode = uint8_op; - } else { - UNREACHABLE(); - return; - } - VisitNarrowAtomicBinOp(this, node, opcode, type); -} - -#define VISIT_ATOMIC_BINOP(op) \ - void InstructionSelector::VisitWord64AtomicNarrow##op(Node* node) { \ - VisitWord64AtomicNarrowBinop(node, kIA32Word64AtomicNarrow##op##Uint8, \ - kIA32Word64AtomicNarrow##op##Uint16, \ - kIA32Word64AtomicNarrow##op##Uint32); \ - } -VISIT_ATOMIC_BINOP(Add) -VISIT_ATOMIC_BINOP(Sub) -VISIT_ATOMIC_BINOP(And) -VISIT_ATOMIC_BINOP(Or) -VISIT_ATOMIC_BINOP(Xor) -#undef VISIT_ATOMIC_BINOP - -void InstructionSelector::VisitWord64AtomicNarrowExchange(Node* node) { - MachineType type = AtomicOpType(node->op()); - DCHECK(type != MachineType::Uint64()); - ArchOpcode opcode = kArchNop; - if (type == MachineType::Uint32()) { - opcode = kIA32Word64AtomicNarrowExchangeUint32; - } else if (type == MachineType::Uint16()) { - opcode = kIA32Word64AtomicNarrowExchangeUint16; - } else if (type == MachineType::Uint8()) { - opcode = kIA32Word64AtomicNarrowExchangeUint8; - } else { - UNREACHABLE(); - return; - } - IA32OperandGenerator g(this); - Node* base = node->InputAt(0); - Node* index = node->InputAt(1); - Node* value = node->InputAt(2); - AddressingMode addressing_mode; - InstructionOperand value_operand = - (type.representation() == MachineRepresentation::kWord8) - ? g.UseFixed(value, edx) - : g.UseUniqueRegister(value); - InstructionOperand inputs[] = { - value_operand, g.UseUniqueRegister(base), - g.GetEffectiveIndexOperand(index, &addressing_mode)}; - InstructionOperand outputs[2]; - if (type.representation() == MachineRepresentation::kWord8) { - // Using DefineSameAsFirst requires the register to be unallocated. - outputs[0] = g.DefineAsFixed(NodeProperties::FindProjection(node, 0), edx); - } else { - outputs[0] = g.DefineSameAsFirst(NodeProperties::FindProjection(node, 0)); - } - outputs[1] = g.DefineAsRegister(NodeProperties::FindProjection(node, 1)); - InstructionCode code = opcode | AddressingModeField::encode(addressing_mode); - Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs); -} - -void InstructionSelector::VisitWord64AtomicNarrowCompareExchange(Node* node) { - MachineType type = AtomicOpType(node->op()); - DCHECK(type != MachineType::Uint64()); - ArchOpcode opcode = kArchNop; - if (type == MachineType::Uint32()) { - opcode = kIA32Word64AtomicNarrowCompareExchangeUint32; - } else if (type == MachineType::Uint16()) { - opcode = kIA32Word64AtomicNarrowCompareExchangeUint16; - } else if (type == MachineType::Uint8()) { - opcode = kIA32Word64AtomicNarrowCompareExchangeUint8; + if (projection1) { + InstructionOperand temps[] = {g.TempRegister(ebx)}; + InstructionOperand outputs[] = {g.DefineAsFixed(projection0, eax), + g.DefineAsFixed(projection1, edx)}; + const int num_temps = arraysize(temps) - (block_root_register ? 0 : 1); + Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs, + num_temps, temps); + } else if (projection0) { + InstructionOperand outputs[] = {g.DefineAsFixed(projection0, eax)}; + InstructionOperand temps[] = {g.TempRegister(edx), g.TempRegister(ebx)}; + const int num_temps = arraysize(temps) - (block_root_register ? 0 : 1); + Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs, + num_temps, temps); } else { - UNREACHABLE(); - return; + InstructionOperand temps[] = {g.TempRegister(eax), g.TempRegister(edx), + g.TempRegister(ebx)}; + const int num_temps = arraysize(temps) - (block_root_register ? 0 : 1); + Emit(code, 0, nullptr, arraysize(inputs), inputs, num_temps, temps); } - IA32OperandGenerator g(this); - Node* base = node->InputAt(0); - Node* index = node->InputAt(1); - Node* old_value = node->InputAt(2); - Node* new_value = node->InputAt(3); - AddressingMode addressing_mode; - InstructionOperand new_value_operand = - (type.representation() == MachineRepresentation::kWord8) - ? g.UseByteRegister(new_value) - : g.UseUniqueRegister(new_value); - InstructionOperand inputs[] = { - g.UseFixed(old_value, eax), new_value_operand, g.UseUniqueRegister(base), - g.GetEffectiveIndexOperand(index, &addressing_mode)}; - InstructionOperand outputs[] = { - g.DefineAsFixed(NodeProperties::FindProjection(node, 0), eax), - g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; - InstructionCode code = opcode | AddressingModeField::encode(addressing_mode); - Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs); } #define SIMD_INT_TYPES(V) \ |