MIPS: [turbofan] Combine ChangeFloat64ToInt32 with Float64Round ops.
TEST=unittests/InstructionSlectorTest.CombineChangeFloat64ToInt32WithRoundFloat64 BUG= Review URL: https://codereview.chromium.org/1510493002 Cr-Commit-Position: refs/heads/master@{#32668}
This commit is contained in:
parent
425983190a
commit
0d4f8a913d
@ -924,6 +924,24 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
|||||||
__ Cvt_d_uw(i.OutputDoubleRegister(), i.InputRegister(0), scratch);
|
__ Cvt_d_uw(i.OutputDoubleRegister(), i.InputRegister(0), scratch);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case kMipsFloorWD: {
|
||||||
|
FPURegister scratch = kScratchDoubleReg;
|
||||||
|
__ floor_w_d(scratch, i.InputDoubleRegister(0));
|
||||||
|
__ mfc1(i.OutputRegister(), scratch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kMipsCeilWD: {
|
||||||
|
FPURegister scratch = kScratchDoubleReg;
|
||||||
|
__ ceil_w_d(scratch, i.InputDoubleRegister(0));
|
||||||
|
__ mfc1(i.OutputRegister(), scratch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kMipsRoundWD: {
|
||||||
|
FPURegister scratch = kScratchDoubleReg;
|
||||||
|
__ round_w_d(scratch, i.InputDoubleRegister(0));
|
||||||
|
__ mfc1(i.OutputRegister(), scratch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case kMipsTruncWD: {
|
case kMipsTruncWD: {
|
||||||
FPURegister scratch = kScratchDoubleReg;
|
FPURegister scratch = kScratchDoubleReg;
|
||||||
// Other arches use round to zero here, so we follow.
|
// Other arches use round to zero here, so we follow.
|
||||||
|
@ -68,6 +68,9 @@ namespace compiler {
|
|||||||
V(MipsCvtSD) \
|
V(MipsCvtSD) \
|
||||||
V(MipsCvtDS) \
|
V(MipsCvtDS) \
|
||||||
V(MipsTruncWD) \
|
V(MipsTruncWD) \
|
||||||
|
V(MipsRoundWD) \
|
||||||
|
V(MipsFloorWD) \
|
||||||
|
V(MipsCeilWD) \
|
||||||
V(MipsTruncUwD) \
|
V(MipsTruncUwD) \
|
||||||
V(MipsCvtDW) \
|
V(MipsCvtDW) \
|
||||||
V(MipsCvtDUw) \
|
V(MipsCvtDUw) \
|
||||||
|
@ -513,6 +513,33 @@ void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
|
|||||||
|
|
||||||
|
|
||||||
void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
|
void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
|
||||||
|
MipsOperandGenerator g(this);
|
||||||
|
Node* value = node->InputAt(0);
|
||||||
|
// Match ChangeFloat64ToInt32(Float64Round##OP) to corresponding instruction
|
||||||
|
// which does rounding and conversion to integer format.
|
||||||
|
if (CanCover(node, value)) {
|
||||||
|
switch (value->opcode()) {
|
||||||
|
case IrOpcode::kFloat64RoundDown:
|
||||||
|
Emit(kMipsFloorWD, g.DefineAsRegister(node),
|
||||||
|
g.UseRegister(value->InputAt(0)));
|
||||||
|
return;
|
||||||
|
case IrOpcode::kFloat64RoundUp:
|
||||||
|
Emit(kMipsCeilWD, g.DefineAsRegister(node),
|
||||||
|
g.UseRegister(value->InputAt(0)));
|
||||||
|
return;
|
||||||
|
case IrOpcode::kFloat64RoundTiesEven:
|
||||||
|
Emit(kMipsRoundWD, g.DefineAsRegister(node),
|
||||||
|
g.UseRegister(value->InputAt(0)));
|
||||||
|
return;
|
||||||
|
case IrOpcode::kFloat64RoundTruncate:
|
||||||
|
Emit(kMipsTruncWD, g.DefineAsRegister(node),
|
||||||
|
g.UseRegister(value->InputAt(0)));
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
VisitRR(this, kMipsTruncWD, node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
VisitRR(this, kMipsTruncWD, node);
|
VisitRR(this, kMipsTruncWD, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1030,6 +1030,24 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
|||||||
__ Cvt_s_ul(i.OutputDoubleRegister(), i.InputRegister(0));
|
__ Cvt_s_ul(i.OutputDoubleRegister(), i.InputRegister(0));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case kMips64FloorWD: {
|
||||||
|
FPURegister scratch = kScratchDoubleReg;
|
||||||
|
__ floor_w_d(scratch, i.InputDoubleRegister(0));
|
||||||
|
__ mfc1(i.OutputRegister(), scratch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kMips64CeilWD: {
|
||||||
|
FPURegister scratch = kScratchDoubleReg;
|
||||||
|
__ ceil_w_d(scratch, i.InputDoubleRegister(0));
|
||||||
|
__ mfc1(i.OutputRegister(), scratch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kMips64RoundWD: {
|
||||||
|
FPURegister scratch = kScratchDoubleReg;
|
||||||
|
__ round_w_d(scratch, i.InputDoubleRegister(0));
|
||||||
|
__ mfc1(i.OutputRegister(), scratch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case kMips64TruncWD: {
|
case kMips64TruncWD: {
|
||||||
FPURegister scratch = kScratchDoubleReg;
|
FPURegister scratch = kScratchDoubleReg;
|
||||||
// Other arches use round to zero here, so we follow.
|
// Other arches use round to zero here, so we follow.
|
||||||
|
@ -81,6 +81,9 @@ namespace compiler {
|
|||||||
V(Mips64CvtSD) \
|
V(Mips64CvtSD) \
|
||||||
V(Mips64CvtDS) \
|
V(Mips64CvtDS) \
|
||||||
V(Mips64TruncWD) \
|
V(Mips64TruncWD) \
|
||||||
|
V(Mips64RoundWD) \
|
||||||
|
V(Mips64FloorWD) \
|
||||||
|
V(Mips64CeilWD) \
|
||||||
V(Mips64TruncLS) \
|
V(Mips64TruncLS) \
|
||||||
V(Mips64TruncLD) \
|
V(Mips64TruncLD) \
|
||||||
V(Mips64TruncUwD) \
|
V(Mips64TruncUwD) \
|
||||||
|
@ -814,6 +814,33 @@ void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
|
|||||||
|
|
||||||
|
|
||||||
void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
|
void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
|
||||||
|
Mips64OperandGenerator g(this);
|
||||||
|
Node* value = node->InputAt(0);
|
||||||
|
// Match ChangeFloat64ToInt32(Float64Round##OP) to corresponding instruction
|
||||||
|
// which does rounding and conversion to integer format.
|
||||||
|
if (CanCover(node, value)) {
|
||||||
|
switch (value->opcode()) {
|
||||||
|
case IrOpcode::kFloat64RoundDown:
|
||||||
|
Emit(kMips64FloorWD, g.DefineAsRegister(node),
|
||||||
|
g.UseRegister(value->InputAt(0)));
|
||||||
|
return;
|
||||||
|
case IrOpcode::kFloat64RoundUp:
|
||||||
|
Emit(kMips64CeilWD, g.DefineAsRegister(node),
|
||||||
|
g.UseRegister(value->InputAt(0)));
|
||||||
|
return;
|
||||||
|
case IrOpcode::kFloat64RoundTiesEven:
|
||||||
|
Emit(kMips64RoundWD, g.DefineAsRegister(node),
|
||||||
|
g.UseRegister(value->InputAt(0)));
|
||||||
|
return;
|
||||||
|
case IrOpcode::kFloat64RoundTruncate:
|
||||||
|
Emit(kMips64TruncWD, g.DefineAsRegister(node),
|
||||||
|
g.UseRegister(value->InputAt(0)));
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
VisitRR(this, kMips64TruncWD, node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
VisitRR(this, kMips64TruncWD, node);
|
VisitRR(this, kMips64TruncWD, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,6 +218,20 @@ const Conversion kConversionInstructions[] = {
|
|||||||
kMipsTruncUwD, kMachFloat64},
|
kMipsTruncUwD, kMachFloat64},
|
||||||
kMachInt32}};
|
kMachInt32}};
|
||||||
|
|
||||||
|
const Conversion kFloat64RoundInstructions[] = {
|
||||||
|
{{&RawMachineAssembler::Float64RoundUp, "Float64RoundUp", kMipsCeilWD,
|
||||||
|
kMachFloat64},
|
||||||
|
kMachInt32},
|
||||||
|
{{&RawMachineAssembler::Float64RoundDown, "Float64RoundDown", kMipsFloorWD,
|
||||||
|
kMachFloat64},
|
||||||
|
kMachInt32},
|
||||||
|
{{&RawMachineAssembler::Float64RoundTiesEven, "Float64RoundTiesEven",
|
||||||
|
kMipsRoundWD, kMachFloat64},
|
||||||
|
kMachInt32},
|
||||||
|
{{&RawMachineAssembler::Float64RoundTruncate, "Float64RoundTruncate",
|
||||||
|
kMipsTruncWD, kMachFloat64},
|
||||||
|
kMachInt32}};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
@ -648,6 +662,28 @@ INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
|
|||||||
::testing::ValuesIn(kConversionInstructions));
|
::testing::ValuesIn(kConversionInstructions));
|
||||||
|
|
||||||
|
|
||||||
|
typedef InstructionSelectorTestWithParam<Conversion>
|
||||||
|
CombineChangeFloat64ToInt32WithRoundFloat64;
|
||||||
|
|
||||||
|
TEST_P(CombineChangeFloat64ToInt32WithRoundFloat64, Parameter) {
|
||||||
|
{
|
||||||
|
const Conversion conv = GetParam();
|
||||||
|
StreamBuilder m(this, conv.mi.machine_type, conv.src_machine_type);
|
||||||
|
m.Return(m.ChangeFloat64ToInt32((m.*conv.mi.constructor)(m.Parameter(0))));
|
||||||
|
Stream s = m.Build();
|
||||||
|
ASSERT_EQ(1U, s.size());
|
||||||
|
EXPECT_EQ(conv.mi.arch_opcode, s[0]->arch_opcode());
|
||||||
|
EXPECT_EQ(kMode_None, s[0]->addressing_mode());
|
||||||
|
ASSERT_EQ(1U, s[0]->InputCount());
|
||||||
|
EXPECT_EQ(1U, s[0]->OutputCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
|
||||||
|
CombineChangeFloat64ToInt32WithRoundFloat64,
|
||||||
|
::testing::ValuesIn(kFloat64RoundInstructions));
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Loads and stores.
|
// Loads and stores.
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -228,6 +228,20 @@ const Conversion kConversionInstructions[] = {
|
|||||||
kMips64TruncUwD, kMachFloat64},
|
kMips64TruncUwD, kMachFloat64},
|
||||||
kMachInt32}};
|
kMachInt32}};
|
||||||
|
|
||||||
|
const Conversion kFloat64RoundInstructions[] = {
|
||||||
|
{{&RawMachineAssembler::Float64RoundUp, "Float64RoundUp", kMips64CeilWD,
|
||||||
|
kMachFloat64},
|
||||||
|
kMachInt32},
|
||||||
|
{{&RawMachineAssembler::Float64RoundDown, "Float64RoundDown",
|
||||||
|
kMips64FloorWD, kMachFloat64},
|
||||||
|
kMachInt32},
|
||||||
|
{{&RawMachineAssembler::Float64RoundTiesEven, "Float64RoundTiesEven",
|
||||||
|
kMips64RoundWD, kMachFloat64},
|
||||||
|
kMachInt32},
|
||||||
|
{{&RawMachineAssembler::Float64RoundTruncate, "Float64RoundTruncate",
|
||||||
|
kMips64TruncWD, kMachFloat64},
|
||||||
|
kMachInt32}};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
@ -812,6 +826,28 @@ TEST_F(InstructionSelectorTest, ChangesFromToSmi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef InstructionSelectorTestWithParam<Conversion>
|
||||||
|
CombineChangeFloat64ToInt32WithRoundFloat64;
|
||||||
|
|
||||||
|
TEST_P(CombineChangeFloat64ToInt32WithRoundFloat64, Parameter) {
|
||||||
|
{
|
||||||
|
const Conversion conv = GetParam();
|
||||||
|
StreamBuilder m(this, conv.mi.machine_type, conv.src_machine_type);
|
||||||
|
m.Return(m.ChangeFloat64ToInt32((m.*conv.mi.constructor)(m.Parameter(0))));
|
||||||
|
Stream s = m.Build();
|
||||||
|
ASSERT_EQ(1U, s.size());
|
||||||
|
EXPECT_EQ(conv.mi.arch_opcode, s[0]->arch_opcode());
|
||||||
|
EXPECT_EQ(kMode_None, s[0]->addressing_mode());
|
||||||
|
ASSERT_EQ(1U, s[0]->InputCount());
|
||||||
|
EXPECT_EQ(1U, s[0]->OutputCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
|
||||||
|
CombineChangeFloat64ToInt32WithRoundFloat64,
|
||||||
|
::testing::ValuesIn(kFloat64RoundInstructions));
|
||||||
|
|
||||||
|
|
||||||
TEST_F(InstructionSelectorTest, CombineShiftsWithMul) {
|
TEST_F(InstructionSelectorTest, CombineShiftsWithMul) {
|
||||||
{
|
{
|
||||||
StreamBuilder m(this, kMachInt32, kMachInt32);
|
StreamBuilder m(this, kMachInt32, kMachInt32);
|
||||||
|
Loading…
Reference in New Issue
Block a user