diff options
Diffstat (limited to 'deps/v8/src/compiler/mips64/instruction-selector-mips64.cc')
-rw-r--r-- | deps/v8/src/compiler/mips64/instruction-selector-mips64.cc | 324 |
1 files changed, 238 insertions, 86 deletions
diff --git a/deps/v8/src/compiler/mips64/instruction-selector-mips64.cc b/deps/v8/src/compiler/mips64/instruction-selector-mips64.cc index 9f9aebc145..f27ad218fd 100644 --- a/deps/v8/src/compiler/mips64/instruction-selector-mips64.cc +++ b/deps/v8/src/compiler/mips64/instruction-selector-mips64.cc @@ -1160,6 +1160,9 @@ void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { VisitRR(this, kMips64CvtDW, node); } +void InstructionSelector::VisitChangeInt64ToFloat64(Node* node) { + VisitRR(this, kMips64CvtDL, node); +} void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { VisitRR(this, kMips64CvtDUw, node); @@ -1239,6 +1242,9 @@ void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { VisitRR(this, kMips64TruncWD, node); } +void InstructionSelector::VisitChangeFloat64ToInt64(Node* node) { + VisitRR(this, kMips64TruncLD, node); +} void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { VisitRR(this, kMips64TruncUwD, node); @@ -2022,6 +2028,119 @@ void EmitWordCompareZero(InstructionSelector* selector, Node* value, g.TempImmediate(0), cont); } +void VisitAtomicLoad(InstructionSelector* selector, Node* node, + ArchOpcode opcode) { + Mips64OperandGenerator g(selector); + Node* base = node->InputAt(0); + Node* index = node->InputAt(1); + if (g.CanBeImmediate(index, opcode)) { + selector->Emit(opcode | AddressingModeField::encode(kMode_MRI), + g.DefineAsRegister(node), g.UseRegister(base), + g.UseImmediate(index)); + } else { + InstructionOperand addr_reg = g.TempRegister(); + selector->Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), + addr_reg, g.UseRegister(index), g.UseRegister(base)); + // Emit desired load opcode, using temp addr_reg. + selector->Emit(opcode | AddressingModeField::encode(kMode_MRI), + g.DefineAsRegister(node), addr_reg, g.TempImmediate(0)); + } +} + +void VisitAtomicStore(InstructionSelector* selector, Node* node, + ArchOpcode opcode) { + Mips64OperandGenerator g(selector); + Node* base = node->InputAt(0); + Node* index = node->InputAt(1); + Node* value = node->InputAt(2); + + if (g.CanBeImmediate(index, opcode)) { + selector->Emit(opcode | AddressingModeField::encode(kMode_MRI), + g.NoOutput(), g.UseRegister(base), g.UseImmediate(index), + g.UseRegisterOrImmediateZero(value)); + } else { + InstructionOperand addr_reg = g.TempRegister(); + selector->Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), + addr_reg, g.UseRegister(index), g.UseRegister(base)); + // Emit desired store opcode, using temp addr_reg. + selector->Emit(opcode | AddressingModeField::encode(kMode_MRI), + g.NoOutput(), addr_reg, g.TempImmediate(0), + g.UseRegisterOrImmediateZero(value)); + } +} + +void VisitAtomicExchange(InstructionSelector* selector, Node* node, + ArchOpcode opcode) { + Mips64OperandGenerator g(selector); + Node* base = node->InputAt(0); + Node* index = node->InputAt(1); + Node* value = node->InputAt(2); + + AddressingMode addressing_mode = kMode_MRI; + InstructionOperand inputs[3]; + size_t input_count = 0; + inputs[input_count++] = g.UseUniqueRegister(base); + inputs[input_count++] = g.UseUniqueRegister(index); + inputs[input_count++] = g.UseUniqueRegister(value); + InstructionOperand outputs[1]; + outputs[0] = g.UseUniqueRegister(node); + InstructionOperand temp[3]; + temp[0] = g.TempRegister(); + temp[1] = g.TempRegister(); + temp[2] = g.TempRegister(); + InstructionCode code = opcode | AddressingModeField::encode(addressing_mode); + selector->Emit(code, 1, outputs, input_count, inputs, 3, temp); +} + +void VisitAtomicCompareExchange(InstructionSelector* selector, Node* node, + ArchOpcode opcode) { + Mips64OperandGenerator g(selector); + 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 = kMode_MRI; + InstructionOperand inputs[4]; + size_t input_count = 0; + inputs[input_count++] = g.UseUniqueRegister(base); + inputs[input_count++] = g.UseUniqueRegister(index); + inputs[input_count++] = g.UseUniqueRegister(old_value); + inputs[input_count++] = g.UseUniqueRegister(new_value); + InstructionOperand outputs[1]; + outputs[0] = g.UseUniqueRegister(node); + InstructionOperand temp[3]; + temp[0] = g.TempRegister(); + temp[1] = g.TempRegister(); + temp[2] = g.TempRegister(); + InstructionCode code = opcode | AddressingModeField::encode(addressing_mode); + selector->Emit(code, 1, outputs, input_count, inputs, 3, temp); +} + +void VisitAtomicBinop(InstructionSelector* selector, Node* node, + ArchOpcode opcode) { + Mips64OperandGenerator g(selector); + Node* base = node->InputAt(0); + Node* index = node->InputAt(1); + Node* value = node->InputAt(2); + + AddressingMode addressing_mode = kMode_MRI; + InstructionOperand inputs[3]; + size_t input_count = 0; + inputs[input_count++] = g.UseUniqueRegister(base); + inputs[input_count++] = g.UseUniqueRegister(index); + inputs[input_count++] = g.UseUniqueRegister(value); + InstructionOperand outputs[1]; + outputs[0] = g.UseUniqueRegister(node); + InstructionOperand temps[4]; + temps[0] = g.TempRegister(); + temps[1] = g.TempRegister(); + temps[2] = g.TempRegister(); + temps[3] = g.TempRegister(); + InstructionCode code = opcode | AddressingModeField::encode(addressing_mode); + selector->Emit(code, 1, outputs, input_count, inputs, 4, temps); +} + } // namespace // Shared routine for word comparisons against zero. @@ -2366,9 +2485,6 @@ void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { void InstructionSelector::VisitWord32AtomicLoad(Node* node) { LoadRepresentation load_rep = LoadRepresentationOf(node->op()); - Mips64OperandGenerator g(this); - Node* base = node->InputAt(0); - Node* index = node->InputAt(1); ArchOpcode opcode = kArchNop; switch (load_rep.representation()) { case MachineRepresentation::kWord8: @@ -2386,25 +2502,11 @@ void InstructionSelector::VisitWord32AtomicLoad(Node* node) { UNREACHABLE(); return; } - if (g.CanBeImmediate(index, opcode)) { - Emit(opcode | AddressingModeField::encode(kMode_MRI), - g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); - } else { - InstructionOperand addr_reg = g.TempRegister(); - Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, - g.UseRegister(index), g.UseRegister(base)); - // Emit desired load opcode, using temp addr_reg. - Emit(opcode | AddressingModeField::encode(kMode_MRI), - g.DefineAsRegister(node), addr_reg, g.TempImmediate(0)); - } + VisitAtomicLoad(this, node, opcode); } void InstructionSelector::VisitWord32AtomicStore(Node* node) { MachineRepresentation rep = AtomicStoreRepresentationOf(node->op()); - Mips64OperandGenerator g(this); - Node* base = node->InputAt(0); - Node* index = node->InputAt(1); - Node* value = node->InputAt(2); ArchOpcode opcode = kArchNop; switch (rep) { case MachineRepresentation::kWord8: @@ -2421,25 +2523,57 @@ void InstructionSelector::VisitWord32AtomicStore(Node* node) { return; } - if (g.CanBeImmediate(index, opcode)) { - Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), - g.UseRegister(base), g.UseImmediate(index), - g.UseRegisterOrImmediateZero(value)); - } else { - InstructionOperand addr_reg = g.TempRegister(); - Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, - g.UseRegister(index), g.UseRegister(base)); - // Emit desired store opcode, using temp addr_reg. - Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), - addr_reg, g.TempImmediate(0), g.UseRegisterOrImmediateZero(value)); + VisitAtomicStore(this, node, opcode); +} + +void InstructionSelector::VisitWord64AtomicLoad(Node* node) { + LoadRepresentation load_rep = LoadRepresentationOf(node->op()); + ArchOpcode opcode = kArchNop; + switch (load_rep.representation()) { + case MachineRepresentation::kWord8: + opcode = kMips64Word64AtomicLoadUint8; + break; + case MachineRepresentation::kWord16: + opcode = kMips64Word64AtomicLoadUint16; + break; + case MachineRepresentation::kWord32: + opcode = kMips64Word64AtomicLoadUint32; + break; + case MachineRepresentation::kWord64: + opcode = kMips64Word64AtomicLoadUint64; + break; + default: + UNREACHABLE(); + return; + } + VisitAtomicLoad(this, node, opcode); +} + +void InstructionSelector::VisitWord64AtomicStore(Node* node) { + MachineRepresentation rep = AtomicStoreRepresentationOf(node->op()); + ArchOpcode opcode = kArchNop; + switch (rep) { + case MachineRepresentation::kWord8: + opcode = kMips64Word64AtomicStoreWord8; + break; + case MachineRepresentation::kWord16: + opcode = kMips64Word64AtomicStoreWord16; + break; + case MachineRepresentation::kWord32: + opcode = kMips64Word64AtomicStoreWord32; + break; + case MachineRepresentation::kWord64: + opcode = kMips64Word64AtomicStoreWord64; + break; + default: + UNREACHABLE(); + return; } + + VisitAtomicStore(this, node, opcode); } void InstructionSelector::VisitWord32AtomicExchange(Node* node) { - Mips64OperandGenerator g(this); - Node* base = node->InputAt(0); - Node* index = node->InputAt(1); - Node* value = node->InputAt(2); ArchOpcode opcode = kArchNop; MachineType type = AtomicOpType(node->op()); if (type == MachineType::Int8()) { @@ -2457,28 +2591,28 @@ void InstructionSelector::VisitWord32AtomicExchange(Node* node) { return; } - AddressingMode addressing_mode = kMode_MRI; - InstructionOperand inputs[3]; - size_t input_count = 0; - inputs[input_count++] = g.UseUniqueRegister(base); - inputs[input_count++] = g.UseUniqueRegister(index); - inputs[input_count++] = g.UseUniqueRegister(value); - InstructionOperand outputs[1]; - outputs[0] = g.UseUniqueRegister(node); - InstructionOperand temp[3]; - temp[0] = g.TempRegister(); - temp[1] = g.TempRegister(); - temp[2] = g.TempRegister(); - InstructionCode code = opcode | AddressingModeField::encode(addressing_mode); - Emit(code, 1, outputs, input_count, inputs, 3, temp); + VisitAtomicExchange(this, node, opcode); +} + +void InstructionSelector::VisitWord64AtomicExchange(Node* node) { + ArchOpcode opcode = kArchNop; + MachineType type = AtomicOpType(node->op()); + if (type == MachineType::Uint8()) { + opcode = kMips64Word64AtomicExchangeUint8; + } else if (type == MachineType::Uint16()) { + opcode = kMips64Word64AtomicExchangeUint16; + } else if (type == MachineType::Uint32()) { + opcode = kMips64Word64AtomicExchangeUint32; + } else if (type == MachineType::Uint64()) { + opcode = kMips64Word64AtomicExchangeUint64; + } else { + UNREACHABLE(); + return; + } + VisitAtomicExchange(this, node, opcode); } void InstructionSelector::VisitWord32AtomicCompareExchange(Node* node) { - Mips64OperandGenerator g(this); - Node* base = node->InputAt(0); - Node* index = node->InputAt(1); - Node* old_value = node->InputAt(2); - Node* new_value = node->InputAt(3); ArchOpcode opcode = kArchNop; MachineType type = AtomicOpType(node->op()); if (type == MachineType::Int8()) { @@ -2496,30 +2630,29 @@ void InstructionSelector::VisitWord32AtomicCompareExchange(Node* node) { return; } - AddressingMode addressing_mode = kMode_MRI; - InstructionOperand inputs[4]; - size_t input_count = 0; - inputs[input_count++] = g.UseUniqueRegister(base); - inputs[input_count++] = g.UseUniqueRegister(index); - inputs[input_count++] = g.UseUniqueRegister(old_value); - inputs[input_count++] = g.UseUniqueRegister(new_value); - InstructionOperand outputs[1]; - outputs[0] = g.UseUniqueRegister(node); - InstructionOperand temp[3]; - temp[0] = g.TempRegister(); - temp[1] = g.TempRegister(); - temp[2] = g.TempRegister(); - InstructionCode code = opcode | AddressingModeField::encode(addressing_mode); - Emit(code, 1, outputs, input_count, inputs, 3, temp); + VisitAtomicCompareExchange(this, node, opcode); } +void InstructionSelector::VisitWord64AtomicCompareExchange(Node* node) { + ArchOpcode opcode = kArchNop; + MachineType type = AtomicOpType(node->op()); + if (type == MachineType::Uint8()) { + opcode = kMips64Word64AtomicCompareExchangeUint8; + } else if (type == MachineType::Uint16()) { + opcode = kMips64Word64AtomicCompareExchangeUint16; + } else if (type == MachineType::Uint32()) { + opcode = kMips64Word64AtomicCompareExchangeUint32; + } else if (type == MachineType::Uint64()) { + opcode = kMips64Word64AtomicCompareExchangeUint64; + } else { + UNREACHABLE(); + return; + } + VisitAtomicCompareExchange(this, node, opcode); +} void InstructionSelector::VisitWord32AtomicBinaryOperation( Node* node, ArchOpcode int8_op, ArchOpcode uint8_op, ArchOpcode int16_op, ArchOpcode uint16_op, ArchOpcode word32_op) { - Mips64OperandGenerator g(this); - Node* base = node->InputAt(0); - Node* index = node->InputAt(1); - Node* value = node->InputAt(2); ArchOpcode opcode = kArchNop; MachineType type = AtomicOpType(node->op()); if (type == MachineType::Int8()) { @@ -2537,21 +2670,7 @@ void InstructionSelector::VisitWord32AtomicBinaryOperation( return; } - AddressingMode addressing_mode = kMode_MRI; - InstructionOperand inputs[3]; - size_t input_count = 0; - inputs[input_count++] = g.UseUniqueRegister(base); - inputs[input_count++] = g.UseUniqueRegister(index); - inputs[input_count++] = g.UseUniqueRegister(value); - InstructionOperand outputs[1]; - outputs[0] = g.UseUniqueRegister(node); - InstructionOperand temps[4]; - temps[0] = g.TempRegister(); - temps[1] = g.TempRegister(); - temps[2] = g.TempRegister(); - temps[3] = g.TempRegister(); - InstructionCode code = opcode | AddressingModeField::encode(addressing_mode); - Emit(code, 1, outputs, input_count, inputs, 4, temps); + VisitAtomicBinop(this, node, opcode); } #define VISIT_ATOMIC_BINOP(op) \ @@ -2568,6 +2687,39 @@ VISIT_ATOMIC_BINOP(Or) VISIT_ATOMIC_BINOP(Xor) #undef VISIT_ATOMIC_BINOP +void InstructionSelector::VisitWord64AtomicBinaryOperation( + Node* node, ArchOpcode uint8_op, ArchOpcode uint16_op, ArchOpcode uint32_op, + ArchOpcode uint64_op) { + ArchOpcode opcode = kArchNop; + MachineType type = AtomicOpType(node->op()); + if (type == MachineType::Uint8()) { + opcode = uint8_op; + } else if (type == MachineType::Uint16()) { + opcode = uint16_op; + } else if (type == MachineType::Uint32()) { + opcode = uint32_op; + } else if (type == MachineType::Uint64()) { + opcode = uint64_op; + } else { + UNREACHABLE(); + return; + } + VisitAtomicBinop(this, node, opcode); +} + +#define VISIT_ATOMIC_BINOP(op) \ + void InstructionSelector::VisitWord64Atomic##op(Node* node) { \ + VisitWord64AtomicBinaryOperation( \ + node, kMips64Word64Atomic##op##Uint8, kMips64Word64Atomic##op##Uint16, \ + kMips64Word64Atomic##op##Uint32, kMips64Word64Atomic##op##Uint64); \ + } +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::VisitInt32AbsWithOverflow(Node* node) { UNREACHABLE(); } |