Commit 46c6fd92 authored by Lu Yahan's avatar Lu Yahan Committed by V8 LUCI CQ

[riscv64] Optimize instr with imm or constant 0

Change-Id: Icfef3e722d8d01f023677090dca6b899c51a46e8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2931580Reviewed-by: 's avatarBrice Dobry <brice.dobry@futurewei.com>
Commit-Queue: Brice Dobry <brice.dobry@futurewei.com>
Cr-Commit-Position: refs/heads/master@{#74950}
parent dc3f7f81
......@@ -52,7 +52,21 @@ class RiscvOperandConverter final : public InstructionOperandConverter {
Register InputOrZeroRegister(size_t index) {
if (instr_->InputAt(index)->IsImmediate()) {
DCHECK_EQ(0, InputInt32(index));
Constant constant = ToConstant(instr_->InputAt(index));
switch (constant.type()) {
case Constant::kInt32:
case Constant::kInt64:
DCHECK_EQ(0, InputInt32(index));
break;
case Constant::kFloat32:
DCHECK_EQ(0, bit_cast<int32_t>(InputFloat32(index)));
break;
case Constant::kFloat64:
DCHECK_EQ(0, bit_cast<int64_t>(InputDouble(index)));
break;
default:
UNREACHABLE();
}
return zero_reg;
}
return InputRegister(index);
......@@ -322,7 +336,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
#define ASSEMBLE_ATOMIC_BINOP(load_linked, store_conditional, bin_instr) \
do { \
Label binop; \
__ Add64(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
__ Add64(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
__ sync(); \
__ bind(&binop); \
__ load_linked(i.OutputRegister(0), MemOperand(i.TempRegister(0), 0)); \
......@@ -337,7 +351,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
size, bin_instr, representation) \
do { \
Label binop; \
__ Add64(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
__ Add64(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
if (representation == 32) { \
__ And(i.TempRegister(3), i.TempRegister(0), 0x3); \
} else { \
......@@ -366,7 +380,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
Label exchange; \
__ sync(); \
__ bind(&exchange); \
__ Add64(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
__ Add64(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
__ load_linked(i.OutputRegister(0), MemOperand(i.TempRegister(0), 0)); \
__ Move(i.TempRegister(1), i.InputRegister(2)); \
__ store_conditional(i.TempRegister(1), MemOperand(i.TempRegister(0), 0)); \
......@@ -378,7 +392,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
load_linked, store_conditional, sign_extend, size, representation) \
do { \
Label exchange; \
__ Add64(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
__ Add64(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
if (representation == 32) { \
__ And(i.TempRegister(1), i.TempRegister(0), 0x3); \
} else { \
......@@ -405,7 +419,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
do { \
Label compareExchange; \
Label exit; \
__ Add64(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
__ Add64(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
__ sync(); \
__ bind(&compareExchange); \
__ load_linked(i.OutputRegister(0), MemOperand(i.TempRegister(0), 0)); \
......@@ -424,7 +438,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
do { \
Label compareExchange; \
Label exit; \
__ Add64(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
__ Add64(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
if (representation == 32) { \
__ And(i.TempRegister(1), i.TempRegister(0), 0x3); \
} else { \
......@@ -592,7 +606,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
if (instr->InputAt(0)->IsImmediate()) {
__ Call(i.InputCode(0), RelocInfo::CODE_TARGET);
} else {
Register reg = i.InputRegister(0);
Register reg = i.InputOrZeroRegister(0);
DCHECK_IMPLIES(
instr->HasCallDescriptorFlag(CallDescriptor::kFixedTargetRegister),
reg == kJavaScriptCallCodeStartRegister);
......@@ -604,7 +618,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
case kArchCallBuiltinPointer: {
DCHECK(!instr->InputAt(0)->IsImmediate());
Register builtin_index = i.InputRegister(0);
Register builtin_index = i.InputOrZeroRegister(0);
__ CallBuiltinByIndex(builtin_index);
RecordCallPosition(instr);
frame_access_state()->ClearSPDelta();
......@@ -616,7 +630,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Address wasm_code = static_cast<Address>(constant.ToInt64());
__ Call(wasm_code, constant.rmode());
} else {
__ Add64(t6, i.InputRegister(0), 0);
__ Add64(t6, i.InputOrZeroRegister(0), 0);
__ Call(t6);
}
RecordCallPosition(instr);
......@@ -627,7 +641,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
if (instr->InputAt(0)->IsImmediate()) {
__ Jump(i.InputCode(0), RelocInfo::CODE_TARGET);
} else {
Register reg = i.InputRegister(0);
Register reg = i.InputOrZeroRegister(0);
DCHECK_IMPLIES(
instr->HasCallDescriptorFlag(CallDescriptor::kFixedTargetRegister),
reg == kJavaScriptCallCodeStartRegister);
......@@ -643,7 +657,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Address wasm_code = static_cast<Address>(constant.ToInt64());
__ Jump(wasm_code, constant.rmode());
} else {
__ Add64(kScratchReg, i.InputRegister(0), 0);
__ Add64(kScratchReg, i.InputOrZeroRegister(0), 0);
__ Jump(kScratchReg);
}
frame_access_state()->ClearSPDelta();
......@@ -652,7 +666,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
case kArchTailCallAddress: {
CHECK(!instr->InputAt(0)->IsImmediate());
Register reg = i.InputRegister(0);
Register reg = i.InputOrZeroRegister(0);
DCHECK_IMPLIES(
instr->HasCallDescriptorFlag(CallDescriptor::kFixedTargetRegister),
reg == kJavaScriptCallCodeStartRegister);
......@@ -662,7 +676,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
}
case kArchCallJSFunction: {
Register func = i.InputRegister(0);
Register func = i.InputOrZeroRegister(0);
if (FLAG_debug_code) {
// Check the function's context matches the context argument.
__ LoadTaggedPointerField(
......@@ -730,7 +744,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
ExternalReference ref = i.InputExternalReference(0);
__ CallCFunction(ref, num_parameters);
} else {
Register func = i.InputRegister(0);
Register func = i.InputOrZeroRegister(0);
__ CallCFunction(func, num_parameters);
}
__ bind(&after_call);
......@@ -942,125 +956,131 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
ASSEMBLE_IEEE754_UNOP(tanh);
break;
case kRiscvAdd32:
__ Add32(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Add32(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
break;
case kRiscvAdd64:
__ Add64(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Add64(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
break;
case kRiscvAddOvf64:
__ AddOverflow64(i.OutputRegister(), i.InputRegister(0),
__ AddOverflow64(i.OutputRegister(), i.InputOrZeroRegister(0),
i.InputOperand(1), kScratchReg);
break;
case kRiscvSub32:
__ Sub32(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Sub32(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
break;
case kRiscvSub64:
__ Sub64(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Sub64(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
break;
case kRiscvSubOvf64:
__ SubOverflow64(i.OutputRegister(), i.InputRegister(0),
__ SubOverflow64(i.OutputRegister(), i.InputOrZeroRegister(0),
i.InputOperand(1), kScratchReg);
break;
case kRiscvMul32:
__ Mul32(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Mul32(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
break;
case kRiscvMulOvf32:
__ MulOverflow32(i.OutputRegister(), i.InputRegister(0),
__ MulOverflow32(i.OutputRegister(), i.InputOrZeroRegister(0),
i.InputOperand(1), kScratchReg);
break;
case kRiscvMulHigh32:
__ Mulh32(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Mulh32(i.OutputRegister(), i.InputOrZeroRegister(0),
i.InputOperand(1));
break;
case kRiscvMulHighU32:
__ Mulhu32(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1),
kScratchReg, kScratchReg2);
__ Mulhu32(i.OutputRegister(), i.InputOrZeroRegister(0),
i.InputOperand(1), kScratchReg, kScratchReg2);
break;
case kRiscvMulHigh64:
__ Mulh64(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Mulh64(i.OutputRegister(), i.InputOrZeroRegister(0),
i.InputOperand(1));
break;
case kRiscvDiv32: {
__ Div32(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Div32(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
// Set ouput to zero if divisor == 0
__ LoadZeroIfConditionZero(i.OutputRegister(), i.InputRegister(1));
break;
}
case kRiscvDivU32: {
__ Divu32(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Divu32(i.OutputRegister(), i.InputOrZeroRegister(0),
i.InputOperand(1));
// Set ouput to zero if divisor == 0
__ LoadZeroIfConditionZero(i.OutputRegister(), i.InputRegister(1));
break;
}
case kRiscvMod32:
__ Mod32(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Mod32(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
break;
case kRiscvModU32:
__ Modu32(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Modu32(i.OutputRegister(), i.InputOrZeroRegister(0),
i.InputOperand(1));
break;
case kRiscvMul64:
__ Mul64(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Mul64(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
break;
case kRiscvDiv64: {
__ Div64(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Div64(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
// Set ouput to zero if divisor == 0
__ LoadZeroIfConditionZero(i.OutputRegister(), i.InputRegister(1));
break;
}
case kRiscvDivU64: {
__ Divu64(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Divu64(i.OutputRegister(), i.InputOrZeroRegister(0),
i.InputOperand(1));
// Set ouput to zero if divisor == 0
__ LoadZeroIfConditionZero(i.OutputRegister(), i.InputRegister(1));
break;
}
case kRiscvMod64:
__ Mod64(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Mod64(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
break;
case kRiscvModU64:
__ Modu64(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Modu64(i.OutputRegister(), i.InputOrZeroRegister(0),
i.InputOperand(1));
break;
case kRiscvAnd:
__ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ And(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
break;
case kRiscvAnd32:
__ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ And(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
__ Sll32(i.OutputRegister(), i.OutputRegister(), 0x0);
break;
case kRiscvOr:
__ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Or(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
break;
case kRiscvOr32:
__ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Or(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
__ Sll32(i.OutputRegister(), i.OutputRegister(), 0x0);
break;
case kRiscvNor:
if (instr->InputAt(1)->IsRegister()) {
__ Nor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Nor(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
} else {
DCHECK_EQ(0, i.InputOperand(1).immediate());
__ Nor(i.OutputRegister(), i.InputRegister(0), zero_reg);
__ Nor(i.OutputRegister(), i.InputOrZeroRegister(0), zero_reg);
}
break;
case kRiscvNor32:
if (instr->InputAt(1)->IsRegister()) {
__ Nor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Nor(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
__ Sll32(i.OutputRegister(), i.OutputRegister(), 0x0);
} else {
DCHECK_EQ(0, i.InputOperand(1).immediate());
__ Nor(i.OutputRegister(), i.InputRegister(0), zero_reg);
__ Nor(i.OutputRegister(), i.InputOrZeroRegister(0), zero_reg);
__ Sll32(i.OutputRegister(), i.OutputRegister(), 0x0);
}
break;
case kRiscvXor:
__ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Xor(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
break;
case kRiscvXor32:
__ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
__ Xor(i.OutputRegister(), i.InputOrZeroRegister(0), i.InputOperand(1));
__ Sll32(i.OutputRegister(), i.OutputRegister(), 0x0);
break;
case kRiscvClz32:
__ Clz32(i.OutputRegister(), i.InputRegister(0));
__ Clz32(i.OutputRegister(), i.InputOrZeroRegister(0));
break;
case kRiscvClz64:
__ Clz64(i.OutputRegister(), i.InputRegister(0));
__ Clz64(i.OutputRegister(), i.InputOrZeroRegister(0));
break;
case kRiscvCtz32: {
Register src = i.InputRegister(0);
......@@ -1084,7 +1104,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
} break;
case kRiscvShl32:
if (instr->InputAt(1)->IsRegister()) {
__ Sll32(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
__ Sll32(i.OutputRegister(), i.InputRegister(0),
i.InputRegister(1));
} else {
int64_t imm = i.InputOperand(1).immediate();
__ Sll32(i.OutputRegister(), i.InputRegister(0),
......@@ -1093,7 +1114,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
case kRiscvShr32:
if (instr->InputAt(1)->IsRegister()) {
__ Srl32(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
__ Srl32(i.OutputRegister(), i.InputRegister(0),
i.InputRegister(1));
} else {
int64_t imm = i.InputOperand(1).immediate();
__ Srl32(i.OutputRegister(), i.InputRegister(0),
......@@ -1102,7 +1124,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
case kRiscvSar32:
if (instr->InputAt(1)->IsRegister()) {
__ Sra32(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
__ Sra32(i.OutputRegister(), i.InputRegister(0),
i.InputRegister(1));
} else {
int64_t imm = i.InputOperand(1).immediate();
__ Sra32(i.OutputRegister(), i.InputRegister(0),
......@@ -1658,7 +1681,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ Sub32(sp, sp, Operand(kDoubleSize));
frame_access_state()->IncreaseSPDelta(kDoubleSize / kSystemPointerSize);
} else {
__ Push(i.InputRegister(0));
__ Push(i.InputOrZeroRegister(0));
frame_access_state()->IncreaseSPDelta(1);
}
break;
......@@ -1696,7 +1719,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
MemOperand(sp, i.InputInt32(1)));
}
} else {
__ Sd(i.InputRegister(0), MemOperand(sp, i.InputInt32(1)));
__ Sd(i.InputOrZeroRegister(0), MemOperand(sp, i.InputInt32(1)));
}
break;
}
......@@ -1859,7 +1882,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kRiscvStoreCompressTagged: {
size_t index = 0;
MemOperand operand = i.MemoryOperand(&index);
__ StoreTaggedField(i.InputOrZeroRegister(index), operand);
__ StoreTaggedField(i.InputRegister(index), operand);
break;
}
case kRiscvLoadDecompressTaggedSigned: {
......@@ -2199,7 +2222,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
switch (cc) {
case eq:
case ne: {
Register left = i.InputRegister(0);
Register left = i.InputOrZeroRegister(0);
Operand right = i.InputOperand(1);
if (instr->InputAt(1)->IsImmediate()) {
if (is_int12(-right.immediate())) {
......@@ -2241,7 +2264,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
} break;
case lt:
case ge: {
Register left = i.InputRegister(0);
Register left = i.InputOrZeroRegister(0);
Operand right = i.InputOperand(1);
__ Slt(result, left, right);
if (cc == ge) {
......@@ -2250,7 +2273,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
} break;
case gt:
case le: {
Register left = i.InputRegister(1);
Register left = i.InputOrZeroRegister(1);
Operand right = i.InputOperand(0);
__ Slt(result, left, right);
if (cc == le) {
......@@ -2259,7 +2282,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
} break;
case Uless:
case Ugreater_equal: {
Register left = i.InputRegister(0);
Register left = i.InputOrZeroRegister(0);
Operand right = i.InputOperand(1);
__ Sltu(result, left, right);
if (cc == Ugreater_equal) {
......@@ -2283,18 +2306,18 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
cc = FlagsConditionToConditionCmp(condition);
switch (cc) {
case eq: {
Register left = i.InputRegister(0);
Register left = i.InputOrZeroRegister(0);
__ Sltu(result, left, 1);
break;
}
case ne: {
Register left = i.InputRegister(0);
Register left = i.InputOrZeroRegister(0);
__ Sltu(result, zero_reg, left);
break;
}
case lt:
case ge: {
Register left = i.InputRegister(0);
Register left = i.InputOrZeroRegister(0);
Operand right = Operand(zero_reg);
__ Slt(result, left, right);
if (cc == ge) {
......@@ -2311,7 +2334,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
} break;
case Uless:
case Ugreater_equal: {
Register left = i.InputRegister(0);
Register left = i.InputOrZeroRegister(0);
Operand right = Operand(zero_reg);
__ Sltu(result, left, right);
if (cc == Ugreater_equal) {
......@@ -2664,7 +2687,11 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
destination->IsRegister() ? g.ToRegister(destination) : kScratchReg;
switch (src.type()) {
case Constant::kInt32:
__ li(dst, Operand(src.ToInt32()));
if (src.ToInt32() == 0 && destination->IsStackSlot()) {
dst = zero_reg;
} else {
__ li(dst, Operand(src.ToInt32()));
}
break;
case Constant::kFloat32:
__ li(dst, Operand::EmbeddedNumber(src.ToFloat32()));
......@@ -2673,7 +2700,11 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
if (RelocInfo::IsWasmReference(src.rmode())) {
__ li(dst, Operand(src.ToInt64(), src.rmode()));
} else {
__ li(dst, Operand(src.ToInt64()));
if (src.ToInt64() == 0 && destination->IsStackSlot()) {
dst = zero_reg;
} else {
__ li(dst, Operand(src.ToInt64()));
}
}
break;
case Constant::kFloat64:
......
......@@ -41,6 +41,10 @@ class RiscvOperandGenerator final : public OperandGenerator {
}
bool IsIntegerConstant(Node* node) {
if (node->opcode() == IrOpcode::kNumberConstant) {
const double value = OpParameter<double>(node->op());
return bit_cast<int64_t>(value) == 0;
}
return (node->opcode() == IrOpcode::kInt32Constant) ||
(node->opcode() == IrOpcode::kInt64Constant);
}
......@@ -48,9 +52,13 @@ class RiscvOperandGenerator final : public OperandGenerator {
int64_t GetIntegerConstantValue(Node* node) {
if (node->opcode() == IrOpcode::kInt32Constant) {
return OpParameter<int32_t>(node->op());
} else if (node->opcode() == IrOpcode::kInt64Constant) {
return OpParameter<int64_t>(node->op());
}
DCHECK_EQ(IrOpcode::kInt64Constant, node->opcode());
return OpParameter<int64_t>(node->op());
DCHECK_EQ(node->opcode(), IrOpcode::kNumberConstant);
const double value = OpParameter<double>(node->op());
DCHECK_EQ(bit_cast<int64_t>(value), 0);
return bit_cast<int64_t>(value);
}
bool IsFloatConstant(Node* node) {
......@@ -296,12 +304,12 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
if (TryMatchImmediate(selector, &opcode, m.right().node(), &input_count,
&inputs[1])) {
inputs[0] = g.UseRegister(m.left().node());
inputs[0] = g.UseRegisterOrImmediateZero(m.left().node());
input_count++;
} else if (has_reverse_opcode &&
TryMatchImmediate(selector, &reverse_opcode, m.left().node(),
&input_count, &inputs[1])) {
inputs[0] = g.UseRegister(m.right().node());
inputs[0] = g.UseRegisterOrImmediateZero(m.right().node());
opcode = reverse_opcode;
input_count++;
} else {
......@@ -1718,6 +1726,13 @@ static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
selector->EmitWithContinuation(opcode, left, right, cont);
}
// Shared routine for multiple compare operations.
static void VisitWordCompareZero(InstructionSelector* selector,
InstructionOperand value,
FlagsContinuation* cont) {
selector->EmitWithContinuation(kRiscvCmpZero, value, cont);
}
// Shared routine for multiple float32 compare operations.
void VisitFloat32Compare(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
......@@ -1753,8 +1768,12 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
RiscvOperandGenerator g(selector);
Node* left = node->InputAt(0);
Node* right = node->InputAt(1);
// Match immediates on left or right side of comparison.
// If one of the two inputs is an immediate, make sure it's on the right.
if (!g.CanBeImmediate(right, opcode) && g.CanBeImmediate(left, opcode)) {
cont->Commute();
std::swap(left, right);
}
// Match immediates on right side of comparison.
if (g.CanBeImmediate(right, opcode)) {
if (opcode == kRiscvTst) {
VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
......@@ -1767,49 +1786,36 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseImmediate(right), cont);
} else {
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseRegister(right), cont);
Int32BinopMatcher m(node, true);
NumberBinopMatcher n(node, true);
if (m.right().Is(0) || n.right().IsZero()) {
VisitWordCompareZero(selector, g.UseRegister(left), cont);
} else {
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseRegister(right), cont);
}
}
break;
case kSignedLessThan:
case kSignedGreaterThanOrEqual:
case kUnsignedLessThan:
case kUnsignedGreaterThanOrEqual:
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseImmediate(right), cont);
break;
default:
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseRegister(right), cont);
}
}
} else if (g.CanBeImmediate(left, opcode)) {
if (!commutative) cont->Commute();
if (opcode == kRiscvTst) {
VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left),
cont);
} else {
switch (cont->condition()) {
case kEqual:
case kNotEqual:
if (cont->IsSet()) {
VisitCompare(selector, opcode, g.UseRegister(right),
g.UseImmediate(left), cont);
case kUnsignedGreaterThanOrEqual: {
Int32BinopMatcher m(node, true);
if (m.right().Is(0)) {
VisitWordCompareZero(selector, g.UseRegister(left), cont);
} else {
VisitCompare(selector, opcode, g.UseRegister(right),
g.UseRegister(left), cont);
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseImmediate(right), cont);
}
break;
case kSignedLessThan:
case kSignedGreaterThanOrEqual:
case kUnsignedLessThan:
case kUnsignedGreaterThanOrEqual:
VisitCompare(selector, opcode, g.UseRegister(right),
g.UseImmediate(left), cont);
break;
} break;
default:
VisitCompare(selector, opcode, g.UseRegister(right),
g.UseRegister(left), cont);
Int32BinopMatcher m(node, true);
if (m.right().Is(0)) {
VisitWordCompareZero(selector, g.UseRegister(left), cont);
} else {
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseRegister(right), cont);
}
}
}
} else {
......
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