Commit 3124e59d authored by QiuJi's avatar QiuJi Committed by Commit Bot

[riscv64] Implementation of RiscvCmpZero ARCH OPCODE

Change-Id: I3828c6a854d09629784f481c76781003b4030993
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2814562Reviewed-by: 's avatarBrice Dobry <brice.dobry@futurewei.com>
Commit-Queue: Brice Dobry <brice.dobry@futurewei.com>
Cr-Commit-Position: refs/heads/master@{#73952}
parent 867cd038
......@@ -1127,6 +1127,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kRiscvCmp:
// Pseudo-instruction used for cmp/branch. No opcode emitted here.
break;
case kRiscvCmpZero:
// Pseudo-instruction used for cmpzero/branch. No opcode emitted here.
break;
case kRiscvMov:
// TODO(plind): Should we combine mov/li like this, or use separate instr?
// - Also see x64 ASSEMBLE_BINOP & RegisterOrOperandType
......@@ -1907,6 +1910,9 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm,
} else if (instr->arch_opcode() == kRiscvCmp) {
cc = FlagsConditionToConditionCmp(condition);
__ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
} else if (instr->arch_opcode() == kRiscvCmpZero) {
cc = FlagsConditionToConditionCmp(condition);
__ Branch(tlabel, cc, i.InputRegister(0), Operand(zero_reg));
} else if (instr->arch_opcode() == kArchStackPointerGreaterThan) {
cc = FlagsConditionToConditionCmp(condition);
Register lhs_register = sp;
......@@ -1962,6 +1968,12 @@ void CodeGenerator::AssembleBranchPoisoning(FlagsCondition condition,
__ LoadZeroIfConditionNotZero(kSpeculationPoisonRegister, kScratchReg);
}
return;
case kRiscvCmpZero: {
__ CompareI(kScratchReg, i.InputRegister(0), Operand(zero_reg),
FlagsConditionToConditionCmp(condition));
__ LoadZeroIfConditionNotZero(kSpeculationPoisonRegister, kScratchReg);
}
return;
case kRiscvTst: {
switch (condition) {
case kEqual:
......@@ -2229,6 +2241,58 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
UNREACHABLE();
}
return;
} else if (instr->arch_opcode() == kRiscvCmpZero) {
cc = FlagsConditionToConditionCmp(condition);
switch (cc) {
case eq: {
Register left = i.InputRegister(0);
__ Sltu(result, left, 1);
break;
}
case ne: {
Register left = i.InputRegister(0);
__ Sltu(result, zero_reg, left);
break;
}
case lt:
case ge: {
Register left = i.InputRegister(0);
Operand right = Operand(zero_reg);
__ Slt(result, left, right);
if (cc == ge) {
__ Xor(result, result, 1);
}
} break;
case gt:
case le: {
Operand left = i.InputOperand(0);
__ Slt(result, zero_reg, left);
if (cc == le) {
__ Xor(result, result, 1);
}
} break;
case Uless:
case Ugreater_equal: {
Register left = i.InputRegister(0);
Operand right = Operand(zero_reg);
__ Sltu(result, left, right);
if (cc == Ugreater_equal) {
__ Xor(result, result, 1);
}
} break;
case Ugreater:
case Uless_equal: {
Register left = zero_reg;
Operand right = i.InputOperand(0);
__ Sltu(result, left, right);
if (cc == Uless_equal) {
__ Xor(result, result, 1);
}
} break;
default:
UNREACHABLE();
}
return;
} else if (instr->arch_opcode() == kRiscvCmpD ||
instr->arch_opcode() == kRiscvCmpS) {
FPURegister left = i.InputOrZeroDoubleRegister(0);
......
......@@ -59,6 +59,7 @@ namespace compiler {
V(RiscvMov) \
V(RiscvTst) \
V(RiscvCmp) \
V(RiscvCmpZero) \
V(RiscvCmpS) \
V(RiscvAddS) \
V(RiscvSubS) \
......
......@@ -32,6 +32,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kRiscvCeilWS:
case kRiscvClz32:
case kRiscvCmp:
case kRiscvCmpZero:
case kRiscvCmpD:
case kRiscvCmpS:
case kRiscvCtz32:
......
......@@ -459,6 +459,7 @@ void InstructionSelector::VisitLoad(Node* node) {
break;
case MachineRepresentation::kCompressedPointer: // Fall through.
case MachineRepresentation::kCompressed: // Fall through.
case MachineRepresentation::kMapWord: // Fall through.
case MachineRepresentation::kNone:
UNREACHABLE();
}
......@@ -533,6 +534,7 @@ void InstructionSelector::VisitStore(Node* node) {
break;
case MachineRepresentation::kCompressedPointer: // Fall through.
case MachineRepresentation::kCompressed: // Fall through.
case MachineRepresentation::kMapWord: // Fall through.
case MachineRepresentation::kNone:
UNREACHABLE();
}
......@@ -1598,6 +1600,7 @@ void InstructionSelector::VisitUnalignedLoad(Node* node) {
case MachineRepresentation::kBit: // Fall through.
case MachineRepresentation::kCompressedPointer: // Fall through.
case MachineRepresentation::kCompressed: // Fall through.
case MachineRepresentation::kMapWord: // Fall through.
case MachineRepresentation::kNone:
UNREACHABLE();
}
......@@ -1651,6 +1654,7 @@ void InstructionSelector::VisitUnalignedStore(Node* node) {
case MachineRepresentation::kBit: // Fall through.
case MachineRepresentation::kCompressedPointer: // Fall through.
case MachineRepresentation::kCompressed: // Fall through.
case MachineRepresentation::kMapWord: // Fall through.
case MachineRepresentation::kNone:
UNREACHABLE();
}
......@@ -1878,8 +1882,7 @@ void VisitWord64Compare(InstructionSelector* selector, Node* node,
void EmitWordCompareZero(InstructionSelector* selector, Node* value,
FlagsContinuation* cont) {
RiscvOperandGenerator g(selector);
selector->EmitWithContinuation(kRiscvCmp, g.UseRegister(value),
g.TempImmediate(0), cont);
selector->EmitWithContinuation(kRiscvCmpZero, g.UseRegister(value), cont);
}
void VisitAtomicLoad(InstructionSelector* selector, Node* node,
......
......@@ -1396,9 +1396,9 @@ TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kRiscvCmp, s[0]->arch_opcode());
EXPECT_EQ(kRiscvCmpZero, s[0]->arch_opcode());
EXPECT_EQ(kMode_None, s[0]->addressing_mode());
ASSERT_EQ(2U, s[0]->InputCount());
ASSERT_EQ(1U, s[0]->InputCount());
EXPECT_EQ(1U, s[0]->OutputCount());
EXPECT_EQ(kFlags_set, s[0]->flags_mode());
EXPECT_EQ(kEqual, s[0]->flags_condition());
......@@ -1408,9 +1408,9 @@ TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kRiscvCmp, s[0]->arch_opcode());
EXPECT_EQ(kRiscvCmpZero, s[0]->arch_opcode());
EXPECT_EQ(kMode_None, s[0]->addressing_mode());
ASSERT_EQ(2U, s[0]->InputCount());
ASSERT_EQ(1U, s[0]->InputCount());
EXPECT_EQ(1U, s[0]->OutputCount());
EXPECT_EQ(kFlags_set, s[0]->flags_mode());
EXPECT_EQ(kEqual, s[0]->flags_condition());
......@@ -1423,9 +1423,9 @@ TEST_F(InstructionSelectorTest, Word64EqualWithZero) {
m.Return(m.Word64Equal(m.Parameter(0), m.Int64Constant(0)));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kRiscvCmp, s[0]->arch_opcode());
EXPECT_EQ(kRiscvCmpZero, s[0]->arch_opcode());
EXPECT_EQ(kMode_None, s[0]->addressing_mode());
ASSERT_EQ(2U, s[0]->InputCount());
ASSERT_EQ(1U, s[0]->InputCount());
EXPECT_EQ(1U, s[0]->OutputCount());
EXPECT_EQ(kFlags_set, s[0]->flags_mode());
EXPECT_EQ(kEqual, s[0]->flags_condition());
......@@ -1435,9 +1435,9 @@ TEST_F(InstructionSelectorTest, Word64EqualWithZero) {
m.Return(m.Word64Equal(m.Int32Constant(0), m.Parameter(0)));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kRiscvCmp, s[0]->arch_opcode());
EXPECT_EQ(kRiscvCmpZero, s[0]->arch_opcode());
EXPECT_EQ(kMode_None, s[0]->addressing_mode());
ASSERT_EQ(2U, s[0]->InputCount());
ASSERT_EQ(1U, s[0]->InputCount());
EXPECT_EQ(1U, s[0]->OutputCount());
EXPECT_EQ(kFlags_set, s[0]->flags_mode());
EXPECT_EQ(kEqual, s[0]->flags_condition());
......
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