Commit edf8c035 authored by marija.antic's avatar marija.antic Committed by Commit bot

MIPS64: Implement Mips64And32, Mips64Or32, Mips64Nor32 and Mips64Xor32 operators.

If operands are loaded as unsigned 32-bit integer, they need to be sign extended to 64 bits.

TEST=cctest/test-run-machops/RunWord32AndAndWord32ShrP, cctest/test-run-machops/RunWord32OrP,
cctest/test-run-machops/RunWord32ShrP, cctest/test-run-machops/RunWord32XorP

BUG=

Review-Url: https://codereview.chromium.org/2147883002
Cr-Commit-Position: refs/heads/master@{#37705}
parent 04062e92
......@@ -920,9 +920,29 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kMips64And:
__ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
break;
case kMips64And32:
if (instr->InputAt(1)->IsRegister()) {
__ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
__ sll(i.InputRegister(1), i.InputRegister(1), 0x0);
__ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
} else {
__ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
__ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
}
break;
case kMips64Or:
__ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
break;
case kMips64Or32:
if (instr->InputAt(1)->IsRegister()) {
__ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
__ sll(i.InputRegister(1), i.InputRegister(1), 0x0);
__ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
} else {
__ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
__ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
}
break;
case kMips64Nor:
if (instr->InputAt(1)->IsRegister()) {
__ Nor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
......@@ -931,9 +951,30 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ Nor(i.OutputRegister(), i.InputRegister(0), zero_reg);
}
break;
case kMips64Nor32:
if (instr->InputAt(1)->IsRegister()) {
__ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
__ sll(i.InputRegister(1), i.InputRegister(1), 0x0);
__ Nor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
} else {
DCHECK(i.InputOperand(1).immediate() == 0);
__ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
__ Nor(i.OutputRegister(), i.InputRegister(0), zero_reg);
}
break;
case kMips64Xor:
__ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
break;
case kMips64Xor32:
if (instr->InputAt(1)->IsRegister()) {
__ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
__ sll(i.InputRegister(1), i.InputRegister(1), 0x0);
__ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
} else {
__ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
__ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
}
break;
case kMips64Clz:
__ Clz(i.OutputRegister(), i.InputRegister(0));
break;
......
......@@ -32,9 +32,13 @@ namespace compiler {
V(Mips64ModU) \
V(Mips64DmodU) \
V(Mips64And) \
V(Mips64And32) \
V(Mips64Or) \
V(Mips64Or32) \
V(Mips64Nor) \
V(Mips64Nor32) \
V(Mips64Xor) \
V(Mips64Xor32) \
V(Mips64Clz) \
V(Mips64Lsa) \
V(Mips64Dlsa) \
......
......@@ -319,7 +319,7 @@ void InstructionSelector::VisitWord32And(Node* node) {
return;
}
}
VisitBinop(this, node, kMips64And);
VisitBinop(this, node, kMips64And32);
}
......@@ -375,7 +375,7 @@ void InstructionSelector::VisitWord64And(Node* node) {
void InstructionSelector::VisitWord32Or(Node* node) {
VisitBinop(this, node, kMips64Or);
VisitBinop(this, node, kMips64Or32);
}
......@@ -391,7 +391,7 @@ void InstructionSelector::VisitWord32Xor(Node* node) {
Int32BinopMatcher mleft(m.left().node());
if (!mleft.right().HasValue()) {
Mips64OperandGenerator g(this);
Emit(kMips64Nor, g.DefineAsRegister(node),
Emit(kMips64Nor32, g.DefineAsRegister(node),
g.UseRegister(mleft.left().node()),
g.UseRegister(mleft.right().node()));
return;
......@@ -400,11 +400,11 @@ void InstructionSelector::VisitWord32Xor(Node* node) {
if (m.right().Is(-1)) {
// Use Nor for bit negation and eliminate constant loading for xori.
Mips64OperandGenerator g(this);
Emit(kMips64Nor, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
Emit(kMips64Nor32, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
g.TempImmediate(0));
return;
}
VisitBinop(this, node, kMips64Xor);
VisitBinop(this, node, kMips64Xor32);
}
......
......@@ -67,22 +67,20 @@ struct Conversion {
// Logical instructions.
// ----------------------------------------------------------------------------
const MachInst2 kLogicalInstructions[] = {
{&RawMachineAssembler::Word32And, "Word32And", kMips64And,
{&RawMachineAssembler::Word32And, "Word32And", kMips64And32,
MachineType::Int32()},
{&RawMachineAssembler::Word64And, "Word64And", kMips64And,
MachineType::Int64()},
{&RawMachineAssembler::Word32Or, "Word32Or", kMips64Or,
{&RawMachineAssembler::Word32Or, "Word32Or", kMips64Or32,
MachineType::Int32()},
{&RawMachineAssembler::Word64Or, "Word64Or", kMips64Or,
MachineType::Int64()},
{&RawMachineAssembler::Word32Xor, "Word32Xor", kMips64Xor,
{&RawMachineAssembler::Word32Xor, "Word32Xor", kMips64Xor32,
MachineType::Int32()},
{&RawMachineAssembler::Word64Xor, "Word64Xor", kMips64Xor,
MachineType::Int64()}};
// ----------------------------------------------------------------------------
// Shift instructions.
// ----------------------------------------------------------------------------
......@@ -542,7 +540,7 @@ TEST_F(InstructionSelectorTest, Word32XorMinusOneWithParameter) {
m.Return(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kMips64Nor, s[0]->arch_opcode());
EXPECT_EQ(kMips64Nor32, s[0]->arch_opcode());
EXPECT_EQ(2U, s[0]->InputCount());
EXPECT_EQ(1U, s[0]->OutputCount());
}
......@@ -551,7 +549,7 @@ TEST_F(InstructionSelectorTest, Word32XorMinusOneWithParameter) {
m.Return(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0)));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kMips64Nor, s[0]->arch_opcode());
EXPECT_EQ(kMips64Nor32, s[0]->arch_opcode());
EXPECT_EQ(2U, s[0]->InputCount());
EXPECT_EQ(1U, s[0]->OutputCount());
}
......@@ -589,7 +587,7 @@ TEST_F(InstructionSelectorTest, Word32XorMinusOneWithWord32Or) {
m.Int32Constant(-1)));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kMips64Nor, s[0]->arch_opcode());
EXPECT_EQ(kMips64Nor32, s[0]->arch_opcode());
EXPECT_EQ(2U, s[0]->InputCount());
EXPECT_EQ(1U, s[0]->OutputCount());
}
......@@ -599,7 +597,7 @@ TEST_F(InstructionSelectorTest, Word32XorMinusOneWithWord32Or) {
m.Word32Or(m.Parameter(0), m.Parameter(0))));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kMips64Nor, s[0]->arch_opcode());
EXPECT_EQ(kMips64Nor32, s[0]->arch_opcode());
EXPECT_EQ(2U, s[0]->InputCount());
EXPECT_EQ(1U, s[0]->OutputCount());
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment