aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
Diffstat (limited to 'backend')
-rw-r--r--backend/lib/Target/RISCV/GISel/RISCVCallLowering.cpp21
-rw-r--r--backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp142
-rw-r--r--backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp6
-rw-r--r--backend/lib/Target/RISCV/RISCVFrameLowering.cpp37
-rw-r--r--backend/lib/Target/RISCV/RISCVInstrInfo.cpp98
-rw-r--r--backend/lib/Target/RISCV/RISCVMachineCombiner.cpp10
-rw-r--r--backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp28
-rw-r--r--backend/lib/Target/RISCV/RISCVRegisterAllocation.cpp16
-rw-r--r--backend/unittests/Target/RISCVRegisterAllocationTest.cpp32
-rw-r--r--backend/unittests/Target/RISCVSSAExitTest.cpp23
-rw-r--r--backend/utils/TableGen/InstrInfoEmitter.cpp5
11 files changed, 198 insertions, 220 deletions
diff --git a/backend/lib/Target/RISCV/GISel/RISCVCallLowering.cpp b/backend/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
index 71c7251..b4d513a 100644
--- a/backend/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
+++ b/backend/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
@@ -35,10 +35,6 @@ constexpr std::uint64_t ABIStackAlignmentBytes = 16;
constexpr std::uint32_t AllowedDirectCallFlags =
static_cast<std::uint32_t>(CallTargetFlag::DirectCall);
-[[nodiscard]] Opcode targetOpcode(InstructionOpcode Value) noexcept {
- return Opcode::fromValue(static_cast<std::uint32_t>(Value));
-}
-
[[nodiscard]] std::uint64_t stackObjectFlag(CallStackObjectFlag Flag) noexcept {
return static_cast<std::uint64_t>(Flag);
}
@@ -806,7 +802,7 @@ createMemoryOperand(MachineFunction &Function, MemoryAccessFlags Accesses, std::
Register Source, CallValueTransform Transform) {
const Opcode CopyOpcode = Transform == CallValueTransform::Full
? opcode(GenericOpcode::COPY)
- : targetOpcode(InstructionOpcode::PseudoCC_COPY);
+ : instructionOpcode(InstructionOpcode::PseudoCC_COPY);
auto Instruction = Builder.buildInstr(CopyOpcode);
if (!Instruction)
return std::unexpected(Instruction.error());
@@ -831,7 +827,7 @@ createMemoryOperand(MachineFunction &Function, MemoryAccessFlags Accesses, std::
const CCAssignment &Assignment, FrameIndex Object,
std::uint64_t ObjectOffset,
const MachineMemOperand &Memory) {
- auto Instruction = Builder.buildInstr(targetOpcode(InstructionOpcode::PseudoLOAD_STACK_ARG));
+ auto Instruction = Builder.buildInstr(instructionOpcode(InstructionOpcode::PseudoLOAD_STACK_ARG));
if (!Instruction)
return std::unexpected(Instruction.error());
auto Def = Instruction->addDef(Assignment.OriginalValue);
@@ -860,7 +856,8 @@ createMemoryOperand(MachineFunction &Function, MemoryAccessFlags Accesses, std::
FrameIndex Object, std::uint64_t ObjectOffset,
const MachineMemOperand &Memory,
CallValueTransform Transform) {
- auto Instruction = Builder.buildInstr(targetOpcode(InstructionOpcode::PseudoSTORE_STACK_ARG));
+ auto Instruction =
+ Builder.buildInstr(instructionOpcode(InstructionOpcode::PseudoSTORE_STACK_ARG));
if (!Instruction)
return std::unexpected(Instruction.error());
auto Use = Instruction->addUse(Source);
@@ -978,7 +975,7 @@ createMemoryOperand(MachineFunction &Function, MemoryAccessFlags Accesses, std::
InstructionOpcode::PseudoRET,
};
for (const InstructionOpcode OpcodeValue : Required) {
- if (Builder.target().instructionDescriptor(targetOpcode(OpcodeValue)) == nullptr) {
+ if (Builder.target().instructionDescriptor(instructionOpcode(OpcodeValue)) == nullptr) {
return makeUnexpected(ErrorCode::InternalError,
"RISC-V target description lacks a call-lowering pseudo");
}
@@ -1205,7 +1202,7 @@ createMemoryOperand(MachineFunction &Function, MemoryAccessFlags Accesses, std::
return makeUnexpected(ErrorCode::Unsupported,
"RISC-V call-frame size does not fit a MIR immediate");
}
- auto Instruction = Builder.buildInstr(targetOpcode(OpcodeValue));
+ auto Instruction = Builder.buildInstr(instructionOpcode(OpcodeValue));
if (!Instruction)
return std::unexpected(Instruction.error());
auto Size = Instruction->addImmediate(static_cast<std::int64_t>(Frame.SizeBytes));
@@ -1249,7 +1246,7 @@ emitByValCopies(MachineIRBuilder &Builder, const CallLoweringPlan &Plan) {
if (!DestinationMemory)
return std::unexpected(DestinationMemory.error());
- auto Instruction = Builder.buildInstr(targetOpcode(InstructionOpcode::PseudoBYVAL_COPY));
+ auto Instruction = Builder.buildInstr(instructionOpcode(InstructionOpcode::PseudoBYVAL_COPY));
if (!Instruction)
return std::unexpected(Instruction.error());
auto Def = Instruction->addDef(*Temporary);
@@ -1359,7 +1356,7 @@ emitOutgoingArguments(MachineIRBuilder &Builder, const CallLoweringPlan &Plan,
const CallLoweringPlan &Plan) {
const bool IsTail = Plan.tailDecision() != TailCallKind::NotTail;
auto Instruction = Builder.buildInstr(
- targetOpcode(IsTail ? InstructionOpcode::PseudoTAIL : InstructionOpcode::PseudoCALL));
+ instructionOpcode(IsTail ? InstructionOpcode::PseudoTAIL : InstructionOpcode::PseudoCALL));
if (!Instruction)
return std::unexpected(Instruction.error());
auto Callee = addCallTarget(*Instruction, *Plan.callee());
@@ -1459,7 +1456,7 @@ emitOutgoingArguments(MachineIRBuilder &Builder, const CallLoweringPlan &Plan,
return std::unexpected(Copy.error());
}
- auto Return = Builder.buildInstr(targetOpcode(InstructionOpcode::PseudoRET));
+ auto Return = Builder.buildInstr(instructionOpcode(InstructionOpcode::PseudoRET));
if (!Return)
return std::unexpected(Return.error());
for (const CCAssignment &Assignment : Plan.returnAssignments()) {
diff --git a/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 2090496..3d5ea2a 100644
--- a/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -31,10 +31,6 @@
namespace rcc::riscv {
namespace {
-[[nodiscard]] Opcode targetOpcode(InstructionOpcode Value) noexcept {
- return Opcode::fromValue(static_cast<std::uint32_t>(Value));
-}
-
[[nodiscard]] std::optional<LLT> registerType(const MachineFunction &Function,
const MachineOperand &Operand) {
const Register *Reg = Operand.getIf<Register>();
@@ -149,7 +145,7 @@ public:
[[nodiscard]] Expected<void> canSelect(const MachineInstr &Instruction,
const MachineFunction &Function,
const TargetDescription &Target) const override {
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::G_SLLW)) {
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::G_SLLW)) {
const std::optional<LLT> Type = resultType(Function, Instruction);
const std::optional<LLT> Left = operandType(Function, Instruction, 1);
const std::optional<LLT> Right = operandType(Function, Instruction, 2);
@@ -308,13 +304,13 @@ public:
auto Match = canSelect(Instruction, Function, Target);
if (!Match)
return std::unexpected(Match.error());
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::G_SLLW))
- return Instruction.setOpcode(targetOpcode(InstructionOpcode::SLLW));
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::G_SLLW))
+ return Instruction.setOpcode(instructionOpcode(InstructionOpcode::SLLW));
const GenericOpcode Generic = static_cast<GenericOpcode>(Instruction.opcode().value());
const std::optional<LLT> Type = resultType(Function, Instruction);
const auto SelectDirect = [&Instruction](InstructionOpcode Selected) {
- return Instruction.setOpcode(targetOpcode(Selected));
+ return Instruction.setOpcode(instructionOpcode(Selected));
};
switch (Generic) {
case GenericOpcode::G_ADD:
@@ -559,7 +555,7 @@ private:
auto Point = Builder.setInsertPointAfter(Anchor);
if (!Point)
return std::unexpected(Point.error());
- auto Pending = Builder.buildInstr(targetOpcode(Opcode));
+ auto Pending = Builder.buildInstr(instructionOpcode(Opcode));
if (!Pending)
return std::unexpected(Pending.error());
auto DefResult = Pending->addDef(Def);
@@ -583,7 +579,7 @@ private:
auto Point = Builder.setInsertPointAfter(Anchor);
if (!Point)
return std::unexpected(Point.error());
- auto Pending = Builder.buildInstr(targetOpcode(Opcode));
+ auto Pending = Builder.buildInstr(instructionOpcode(Opcode));
if (!Pending)
return std::unexpected(Pending.error());
auto DefResult = Pending->addDef(Def);
@@ -607,7 +603,7 @@ private:
auto Point = Builder.setInsertPointBefore(Anchor);
if (!Point)
return std::unexpected(Point.error());
- auto Pending = Builder.buildInstr(targetOpcode(Opcode));
+ auto Pending = Builder.buildInstr(instructionOpcode(Opcode));
if (!Pending)
return std::unexpected(Pending.error());
auto DefResult = Pending->addDef(Def);
@@ -676,7 +672,7 @@ private:
auto Point = Builder.setInsertPointAfter(Anchor);
if (!Point)
return std::unexpected(Point.error());
- auto Pending = Builder.buildInstr(targetOpcode(Opcode));
+ auto Pending = Builder.buildInstr(instructionOpcode(Opcode));
if (!Pending)
return std::unexpected(Pending.error());
auto DefResult = Pending->addDef(Def);
@@ -762,7 +758,7 @@ private:
const InstructionOpcode RemainderOpcode =
IsWord ? (Signed ? InstructionOpcode::REMW : InstructionOpcode::REMUW)
: (Signed ? InstructionOpcode::REM : InstructionOpcode::REMU);
- auto SetDivision = Instruction.setOpcode(targetOpcode(Division));
+ auto SetDivision = Instruction.setOpcode(instructionOpcode(Division));
if (!SetDivision)
return std::unexpected(SetDivision.error());
MachineIRBuilder Builder(Function, Target);
@@ -782,7 +778,7 @@ private:
"RISC-V high multiplication has no result type");
if (Type->scalarBitWidth() == 64) {
return Instruction.setOpcode(
- targetOpcode(Signed ? InstructionOpcode::MULH : InstructionOpcode::MULHU));
+ instructionOpcode(Signed ? InstructionOpcode::MULH : InstructionOpcode::MULHU));
}
const MachineOperand *DestinationOperand = Instruction.operandAt(0);
@@ -821,7 +817,7 @@ private:
auto Immediate = appendImmediate(Instruction, 0);
if (!Immediate)
return std::unexpected(Immediate.error());
- auto SetOpcode = Instruction.setOpcode(targetOpcode(InstructionOpcode::ADDIW));
+ auto SetOpcode = Instruction.setOpcode(instructionOpcode(InstructionOpcode::ADDIW));
if (!SetOpcode)
return std::unexpected(SetOpcode.error());
auto ExtendRight = buildImmediateAfter(Builder, *Anchor, InstructionOpcode::ADDIW,
@@ -840,7 +836,7 @@ private:
auto Immediate = appendImmediate(Instruction, 32);
if (!Immediate)
return std::unexpected(Immediate.error());
- auto SetOpcode = Instruction.setOpcode(targetOpcode(InstructionOpcode::SLLI));
+ auto SetOpcode = Instruction.setOpcode(instructionOpcode(InstructionOpcode::SLLI));
if (!SetOpcode)
return std::unexpected(SetOpcode.error());
auto ExtendLeft = buildImmediateAfter(Builder, *Anchor, InstructionOpcode::SRLI,
@@ -910,7 +906,7 @@ private:
if (!SetRight)
return std::unexpected(SetRight.error());
auto SetCompare = Instruction.setOpcode(
- targetOpcode(Unsigned ? InstructionOpcode::SLTU : InstructionOpcode::SLT));
+ instructionOpcode(Unsigned ? InstructionOpcode::SLTU : InstructionOpcode::SLT));
if (!SetCompare)
return std::unexpected(SetCompare.error());
const bool IsMaximum = Generic == GenericOpcode::G_SMAX || Generic == GenericOpcode::G_UMAX;
@@ -964,7 +960,7 @@ private:
auto Mask = appendImmediate(Instruction, 1);
if (!Mask)
return std::unexpected(Mask.error());
- auto SetNormalize = Instruction.setOpcode(targetOpcode(InstructionOpcode::ANDI));
+ auto SetNormalize = Instruction.setOpcode(instructionOpcode(InstructionOpcode::ANDI));
if (!SetNormalize)
return std::unexpected(SetNormalize.error());
@@ -1045,7 +1041,7 @@ private:
return std::unexpected(Shift.error());
const bool IsWord = Type->scalarBitWidth() <= 32;
auto SetShift = Instruction.setOpcode(
- targetOpcode(IsWord ? InstructionOpcode::SRAIW : InstructionOpcode::SRAI));
+ instructionOpcode(IsWord ? InstructionOpcode::SRAIW : InstructionOpcode::SRAI));
if (!SetShift)
return std::unexpected(SetShift.error());
MachineIRBuilder Builder(Function, Target);
@@ -1136,7 +1132,7 @@ private:
IsAdd ? (IsWord ? InstructionOpcode::ADDW : InstructionOpcode::ADD)
: IsSub ? (IsWord ? InstructionOpcode::SUBW : InstructionOpcode::SUB)
: (IsWord ? InstructionOpcode::MULW : InstructionOpcode::MUL);
- auto SetArithmetic = Instruction.setOpcode(targetOpcode(Arithmetic));
+ auto SetArithmetic = Instruction.setOpcode(instructionOpcode(Arithmetic));
if (!SetArithmetic)
return std::unexpected(SetArithmetic.error());
MachineIRBuilder Builder(Function, Target);
@@ -1355,7 +1351,7 @@ private:
auto RemoveCarryIn = Instruction.eraseOperand(3);
if (!RemoveCarryIn)
return std::unexpected(RemoveCarryIn.error());
- auto SetArithmetic = Instruction.setOpcode(targetOpcode(Arithmetic));
+ auto SetArithmetic = Instruction.setOpcode(instructionOpcode(Arithmetic));
if (!SetArithmetic)
return std::unexpected(SetArithmetic.error());
MachineIRBuilder Builder(Function, Target);
@@ -1429,7 +1425,7 @@ private:
if (!Point)
return std::unexpected(Point.error());
auto Pending = Builder.buildInstr(
- targetOpcode(IsWord ? InstructionOpcode::SUBW : InstructionOpcode::SUB));
+ instructionOpcode(IsWord ? InstructionOpcode::SUBW : InstructionOpcode::SUB));
if (!Pending)
return std::unexpected(Pending.error());
auto Def = Pending->addDef(*Negated);
@@ -1481,7 +1477,7 @@ private:
auto SetAddress = Instruction.operandAt(2)->setRegister(*Address);
if (!SetAddress)
return std::unexpected(SetAddress.error());
- return Instruction.setOpcode(targetOpcode(Selected));
+ return Instruction.setOpcode(instructionOpcode(Selected));
}
[[nodiscard]] Expected<void> selectIntegerExtension(MachineInstr &Instruction,
@@ -1508,7 +1504,7 @@ private:
auto ImmediateResult = appendImmediate(Instruction, 0);
if (!ImmediateResult)
return std::unexpected(ImmediateResult.error());
- return Instruction.setOpcode(targetOpcode(InstructionOpcode::ADDIW));
+ return Instruction.setOpcode(instructionOpcode(InstructionOpcode::ADDIW));
}
const std::uint32_t ContainerBits = DestinationBits <= 32 ? 32 : 64;
@@ -1525,7 +1521,7 @@ private:
auto SetDestination = Instruction.operandAt(0)->setRegister(*Temporary);
if (!SetDestination)
return std::unexpected(SetDestination.error());
- auto SetOpcode = Instruction.setOpcode(targetOpcode(ShiftLeft));
+ auto SetOpcode = Instruction.setOpcode(instructionOpcode(ShiftLeft));
if (!SetOpcode)
return std::unexpected(SetOpcode.error());
auto ShiftImmediate = appendImmediate(Instruction, Shift);
@@ -1572,7 +1568,7 @@ private:
auto ImmediateResult = replaceImmediate(Instruction, 2, 0);
if (!ImmediateResult)
return std::unexpected(ImmediateResult.error());
- return Instruction.setOpcode(targetOpcode(InstructionOpcode::ADDIW));
+ return Instruction.setOpcode(instructionOpcode(InstructionOpcode::ADDIW));
}
const std::uint32_t ContainerBits = TypeBits <= 32 ? 32 : 64;
const std::int64_t Shift = static_cast<std::int64_t>(ContainerBits) - *Width;
@@ -1586,7 +1582,7 @@ private:
auto SetDestination = Instruction.operandAt(0)->setRegister(*Temporary);
if (!SetDestination)
return std::unexpected(SetDestination.error());
- auto SetOpcode = Instruction.setOpcode(targetOpcode(ShiftLeft));
+ auto SetOpcode = Instruction.setOpcode(instructionOpcode(ShiftLeft));
if (!SetOpcode)
return std::unexpected(SetOpcode.error());
auto ShiftImmediate = replaceImmediate(Instruction, 2, Shift);
@@ -1707,7 +1703,7 @@ private:
auto Set = SetSources(*LeftRegister, *RightRegister);
if (!Set)
return std::unexpected(Set.error());
- auto SetOpcode = Instruction.setOpcode(targetOpcode(InstructionOpcode::XOR));
+ auto SetOpcode = Instruction.setOpcode(instructionOpcode(InstructionOpcode::XOR));
if (!SetOpcode)
return std::unexpected(SetOpcode.error());
if (Condition == IntegerPredicate::Equal) {
@@ -1749,7 +1745,7 @@ private:
if (!Set)
return std::unexpected(Set.error());
}
- auto SetOpcode = Instruction.setOpcode(targetOpcode(*OpcodeValue));
+ auto SetOpcode = Instruction.setOpcode(instructionOpcode(*OpcodeValue));
if (!SetOpcode)
return std::unexpected(SetOpcode.error());
auto Result = buildImmediateAfter(Builder, Instruction, InstructionOpcode::XORI,
@@ -1767,7 +1763,7 @@ private:
if (!Set)
return std::unexpected(Set.error());
}
- return Instruction.setOpcode(targetOpcode(*OpcodeValue));
+ return Instruction.setOpcode(instructionOpcode(*OpcodeValue));
}
[[nodiscard]] Expected<void> selectFloatingCompare(MachineInstr &Instruction,
@@ -1814,7 +1810,7 @@ private:
auto SetRight = Instruction.operandAt(2)->setRegister(NewRight);
if (!SetRight)
return std::unexpected(SetRight.error());
- return Instruction.setOpcode(targetOpcode(OpcodeValue));
+ return Instruction.setOpcode(instructionOpcode(OpcodeValue));
};
const auto BuildInverted = [&](InstructionOpcode BaseOpcode, Register BaseLeft,
Register BaseRight) -> Expected<void> {
@@ -1915,7 +1911,7 @@ private:
appendImmediate(Instruction, Condition == FloatingPredicate::AlwaysTrue ? 1 : 0);
if (!Immediate)
return std::unexpected(Immediate.error());
- return Instruction.setOpcode(targetOpcode(InstructionOpcode::ADDI));
+ return Instruction.setOpcode(instructionOpcode(InstructionOpcode::ADDI));
}
case FloatingPredicate::OrderedEqual:
return SetBase(EqualOpcode, DestinationRegister, LeftRegister, RightRegister);
@@ -1965,11 +1961,11 @@ private:
return std::unexpected(Rounding.error());
const bool IsWord = Type->scalarBitWidth() <= 32;
if (Source->scalarBitWidth() == 32) {
- return Instruction.setOpcode(targetOpcode(
+ return Instruction.setOpcode(instructionOpcode(
IsWord ? (Unsigned ? InstructionOpcode::FCVT_WU_S : InstructionOpcode::FCVT_W_S)
: (Unsigned ? InstructionOpcode::FCVT_LU_S : InstructionOpcode::FCVT_L_S)));
}
- return Instruction.setOpcode(targetOpcode(
+ return Instruction.setOpcode(instructionOpcode(
IsWord ? (Unsigned ? InstructionOpcode::FCVT_WU_D : InstructionOpcode::FCVT_W_D)
: (Unsigned ? InstructionOpcode::FCVT_LU_D : InstructionOpcode::FCVT_L_D)));
}
@@ -1997,11 +1993,11 @@ private:
return std::unexpected(Rounding.error());
const bool IsWord = Source->scalarBitWidth() <= 32;
if (Type->scalarBitWidth() == 32) {
- return Instruction.setOpcode(targetOpcode(
+ return Instruction.setOpcode(instructionOpcode(
IsWord ? (Unsigned ? InstructionOpcode::FCVT_S_WU : InstructionOpcode::FCVT_S_W)
: (Unsigned ? InstructionOpcode::FCVT_S_LU : InstructionOpcode::FCVT_S_L)));
}
- return Instruction.setOpcode(targetOpcode(
+ return Instruction.setOpcode(instructionOpcode(
IsWord ? (Unsigned ? InstructionOpcode::FCVT_D_WU : InstructionOpcode::FCVT_D_W)
: (Unsigned ? InstructionOpcode::FCVT_D_LU : InstructionOpcode::FCVT_D_L)));
}
@@ -2011,9 +2007,9 @@ private:
InstructionOpcode Single,
InstructionOpcode Double) const {
if (Type && Type->isFloat() && Type->scalarBitWidth() == 32)
- return Instruction.setOpcode(targetOpcode(Single));
+ return Instruction.setOpcode(instructionOpcode(Single));
if (Type && Type->isFloat() && Type->scalarBitWidth() == 64)
- return Instruction.setOpcode(targetOpcode(Double));
+ return Instruction.setOpcode(instructionOpcode(Double));
return makeUnexpected(ErrorCode::Unsupported,
"RISC-V cannot select this floating min/max type");
}
@@ -2047,7 +2043,7 @@ private:
auto SetSucc = replaceImmediate(Instruction, 1, Succ);
if (!SetSucc)
return std::unexpected(SetSucc.error());
- return Instruction.setOpcode(targetOpcode(InstructionOpcode::FENCE));
+ return Instruction.setOpcode(instructionOpcode(InstructionOpcode::FENCE));
}
[[nodiscard]] Expected<void> selectIndirectBranch(MachineInstr &Instruction) const {
@@ -2060,7 +2056,7 @@ private:
auto Immediate = appendImmediate(Instruction, 0);
if (!Immediate)
return std::unexpected(Immediate.error());
- return Instruction.setOpcode(targetOpcode(InstructionOpcode::JALR));
+ return Instruction.setOpcode(instructionOpcode(InstructionOpcode::JALR));
}
[[nodiscard]] Expected<void> selectTrap(MachineInstr &Instruction) const {
@@ -2069,7 +2065,7 @@ private:
if (!Erased)
return std::unexpected(Erased.error());
}
- return Instruction.setOpcode(targetOpcode(InstructionOpcode::EBREAK));
+ return Instruction.setOpcode(instructionOpcode(InstructionOpcode::EBREAK));
}
[[nodiscard]] Expected<void> selectBitcast(MachineInstr &Instruction,
@@ -2080,14 +2076,14 @@ private:
return makeUnexpected(ErrorCode::VerificationError,
"RISC-V bitcast has invalid register types");
if (DestinationType->isInteger() && SourceType->isFloat()) {
- return Instruction.setOpcode(targetOpcode(SourceType->scalarBitWidth() == 32
- ? InstructionOpcode::FMV_X_W
- : InstructionOpcode::FMV_X_D));
+ return Instruction.setOpcode(instructionOpcode(SourceType->scalarBitWidth() == 32
+ ? InstructionOpcode::FMV_X_W
+ : InstructionOpcode::FMV_X_D));
}
if (DestinationType->isFloat() && SourceType->isInteger()) {
- return Instruction.setOpcode(targetOpcode(DestinationType->scalarBitWidth() == 32
- ? InstructionOpcode::FMV_W_X
- : InstructionOpcode::FMV_D_X));
+ return Instruction.setOpcode(instructionOpcode(DestinationType->scalarBitWidth() == 32
+ ? InstructionOpcode::FMV_W_X
+ : InstructionOpcode::FMV_D_X));
}
return makeUnexpected(ErrorCode::Unsupported, "RISC-V bitcast pair is unsupported");
}
@@ -2100,7 +2096,7 @@ private:
return makeUnexpected(ErrorCode::Unsupported,
"RISC-V integer instruction requires a supported scalar integer");
const bool IsWord = Type->isInteger() && Type->scalarBitWidth() <= 32;
- return Instruction.setOpcode(targetOpcode(IsWord ? Word : DoubleWord));
+ return Instruction.setOpcode(instructionOpcode(IsWord ? Word : DoubleWord));
}
[[nodiscard]] Expected<void>
@@ -2135,7 +2131,7 @@ private:
if (!SetRight)
return std::unexpected(SetRight.error());
const bool IsWord = Type->scalarBitWidth() <= 32;
- return Instruction.setOpcode(targetOpcode(IsWord ? Word : DoubleWord));
+ return Instruction.setOpcode(instructionOpcode(IsWord ? Word : DoubleWord));
}
[[nodiscard]] Expected<void> selectLoad(MachineInstr &Instruction,
@@ -2152,7 +2148,7 @@ private:
return makeUnexpected(ErrorCode::Unsupported,
"RISC-V atomic load requires a 32-bit or 64-bit GPR value");
return Instruction.setOpcode(
- targetOpcode(*Bytes == 4 ? InstructionOpcode::LR_W : InstructionOpcode::LR_D));
+ instructionOpcode(*Bytes == 4 ? InstructionOpcode::LR_W : InstructionOpcode::LR_D));
}
auto AppendOffset = appendImmediate(Instruction, 0);
if (!AppendOffset)
@@ -2165,12 +2161,12 @@ private:
: InstructionOpcode::Invalid;
if (Selected == InstructionOpcode::Invalid)
return makeUnexpected(ErrorCode::Unsupported, "RISC-V integer load width is unsupported");
- return Instruction.setOpcode(targetOpcode(Selected));
+ return Instruction.setOpcode(instructionOpcode(Selected));
}
if (Type->isFloat() && Type->scalarBitWidth() == 32)
- return Instruction.setOpcode(targetOpcode(InstructionOpcode::FLW));
+ return Instruction.setOpcode(instructionOpcode(InstructionOpcode::FLW));
if (Type->isFloat() && Type->scalarBitWidth() == 64)
- return Instruction.setOpcode(targetOpcode(InstructionOpcode::FLD));
+ return Instruction.setOpcode(instructionOpcode(InstructionOpcode::FLD));
return makeUnexpected(ErrorCode::Unsupported, "RISC-V cannot select this generic load type");
}
@@ -2192,7 +2188,7 @@ private:
auto Immediate = appendImmediate(Instruction, 0);
if (!Immediate)
return std::unexpected(Immediate.error());
- return Instruction.setOpcode(targetOpcode(Selected));
+ return Instruction.setOpcode(instructionOpcode(Selected));
}
[[nodiscard]] Expected<void> selectFloatExtLoad(MachineInstr &Instruction,
@@ -2217,7 +2213,7 @@ private:
auto Immediate = appendImmediate(Instruction, 0);
if (!Immediate)
return std::unexpected(Immediate.error());
- auto SetOpcode = Instruction.setOpcode(targetOpcode(InstructionOpcode::FLW));
+ auto SetOpcode = Instruction.setOpcode(instructionOpcode(InstructionOpcode::FLW));
if (!SetOpcode)
return std::unexpected(SetOpcode.error());
MachineIRBuilder Builder(Function, Target);
@@ -2247,7 +2243,7 @@ private:
auto Point = Builder.setInsertPointBefore(Instruction);
if (!Point)
return std::unexpected(Point.error());
- auto Conversion = Builder.buildInstr(targetOpcode(InstructionOpcode::FCVT_S_D));
+ auto Conversion = Builder.buildInstr(instructionOpcode(InstructionOpcode::FCVT_S_D));
if (!Conversion)
return std::unexpected(Conversion.error());
auto Def = Conversion->addDef(*Temporary);
@@ -2268,7 +2264,7 @@ private:
auto Immediate = appendImmediate(Instruction, 0);
if (!Immediate)
return std::unexpected(Immediate.error());
- return Instruction.setOpcode(targetOpcode(InstructionOpcode::FSW));
+ return Instruction.setOpcode(instructionOpcode(InstructionOpcode::FSW));
}
[[nodiscard]] Expected<void> selectStore(MachineInstr &Instruction,
@@ -2293,8 +2289,8 @@ private:
auto Destination = insertPhysicalRegister(Instruction, 0, *Zero, RegisterOperandFlag::Define);
if (!Destination)
return std::unexpected(Destination.error());
- return Instruction.setOpcode(
- targetOpcode(*Bytes == 4 ? InstructionOpcode::AMOSWAP_W : InstructionOpcode::AMOSWAP_D));
+ return Instruction.setOpcode(instructionOpcode(*Bytes == 4 ? InstructionOpcode::AMOSWAP_W
+ : InstructionOpcode::AMOSWAP_D));
}
auto AppendOffset = appendImmediate(Instruction, 0);
if (!AppendOffset)
@@ -2307,12 +2303,12 @@ private:
: InstructionOpcode::Invalid;
if (Selected == InstructionOpcode::Invalid)
return makeUnexpected(ErrorCode::Unsupported, "RISC-V integer store width is unsupported");
- return Instruction.setOpcode(targetOpcode(Selected));
+ return Instruction.setOpcode(instructionOpcode(Selected));
}
if (Type->isFloat() && Type->scalarBitWidth() == 32)
- return Instruction.setOpcode(targetOpcode(InstructionOpcode::FSW));
+ return Instruction.setOpcode(instructionOpcode(InstructionOpcode::FSW));
if (Type->isFloat() && Type->scalarBitWidth() == 64)
- return Instruction.setOpcode(targetOpcode(InstructionOpcode::FSD));
+ return Instruction.setOpcode(instructionOpcode(InstructionOpcode::FSD));
return makeUnexpected(ErrorCode::Unsupported, "RISC-V cannot select this generic store type");
}
@@ -2323,7 +2319,7 @@ private:
auto Inserted = insertPhysicalRegister(Instruction, 0, *Zero, RegisterOperandFlag::Define);
if (!Inserted)
return std::unexpected(Inserted.error());
- return Instruction.setOpcode(targetOpcode(InstructionOpcode::JAL));
+ return Instruction.setOpcode(instructionOpcode(InstructionOpcode::JAL));
}
[[nodiscard]] Expected<void> selectConditionalBranch(MachineInstr &Instruction) const {
@@ -2333,7 +2329,7 @@ private:
auto Inserted = insertPhysicalRegister(Instruction, 1, *Zero, RegisterOperandFlag::Use);
if (!Inserted)
return std::unexpected(Inserted.error());
- return Instruction.setOpcode(targetOpcode(InstructionOpcode::BNE));
+ return Instruction.setOpcode(instructionOpcode(InstructionOpcode::BNE));
}
[[nodiscard]] Expected<void> selectIntegerConstant(MachineInstr &Instruction,
@@ -2380,7 +2376,7 @@ private:
Instruction.insertOperand(2, MachineOperand::immediate(Value, ImmediateTargetFlags));
if (!NormalizeImmediate)
return std::unexpected(NormalizeImmediate.error());
- return Instruction.setOpcode(targetOpcode(AddImmediate));
+ return Instruction.setOpcode(instructionOpcode(AddImmediate));
}
// Recursively decompose the value into signed 12-bit chunks. The
@@ -2410,7 +2406,7 @@ private:
if (Parent == nullptr)
return makeUnexpected(ErrorCode::VerificationError,
"RISC-V constant selection received a detached instruction");
- auto SetOpcode = Instruction.setOpcode(targetOpcode(AddImmediate));
+ auto SetOpcode = Instruction.setOpcode(instructionOpcode(AddImmediate));
if (!SetOpcode)
return std::unexpected(SetOpcode.error());
auto SetDestination = Instruction.operandAt(0)->setRegister(*Temporary);
@@ -2440,7 +2436,7 @@ private:
auto ShiftResult = createTemporary(Function, *Type, Target);
if (!ShiftResult)
return std::unexpected(ShiftResult.error());
- auto Shift = Builder.buildInstr(targetOpcode(ShiftLeftImmediate));
+ auto Shift = Builder.buildInstr(instructionOpcode(ShiftLeftImmediate));
if (!Shift)
return std::unexpected(Shift.error());
auto ShiftDef = Shift->addDef(*ShiftResult);
@@ -2469,7 +2465,7 @@ private:
auto Add = Builder.setInsertPointAfter(**BuiltShift);
if (!Add)
return std::unexpected(Add.error());
- auto AddInstruction = Builder.buildInstr(targetOpcode(AddImmediate));
+ auto AddInstruction = Builder.buildInstr(instructionOpcode(AddImmediate));
if (!AddInstruction)
return std::unexpected(AddInstruction.error());
auto AddDef = AddInstruction->addDef(AddDestination);
@@ -2552,7 +2548,7 @@ private:
return std::unexpected(InsertPoint.error());
const InstructionOpcode Move =
BitWidth == 32 ? InstructionOpcode::FMV_W_X : InstructionOpcode::FMV_D_X;
- auto MoveInstruction = Builder.buildInstr(targetOpcode(Move));
+ auto MoveInstruction = Builder.buildInstr(instructionOpcode(Move));
if (!MoveInstruction)
return std::unexpected(MoveInstruction.error());
auto MoveDef = MoveInstruction->addDef(DestinationRegister);
@@ -2575,9 +2571,9 @@ private:
if (!RoundingMode)
return std::unexpected(RoundingMode.error());
if (Type && Type->isFloat() && Type->scalarBitWidth() == 32)
- return Instruction.setOpcode(targetOpcode(Single));
+ return Instruction.setOpcode(instructionOpcode(Single));
if (Type && Type->isFloat() && Type->scalarBitWidth() == 64)
- return Instruction.setOpcode(targetOpcode(Double));
+ return Instruction.setOpcode(instructionOpcode(Double));
return makeUnexpected(ErrorCode::Unsupported, "RISC-V cannot select this floating binary type");
}
@@ -2608,9 +2604,9 @@ private:
if (!Duplicate)
return std::unexpected(Duplicate.error());
if (Type && Type->isFloat() && Type->scalarBitWidth() == 32)
- return Instruction.setOpcode(targetOpcode(Single));
+ return Instruction.setOpcode(instructionOpcode(Single));
if (Type && Type->isFloat() && Type->scalarBitWidth() == 64)
- return Instruction.setOpcode(targetOpcode(Double));
+ return Instruction.setOpcode(instructionOpcode(Double));
return makeUnexpected(ErrorCode::Unsupported, "RISC-V cannot select this floating unary type");
}
const RISCVSubtarget &Subtarget;
diff --git a/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index da8d687..541af2b 100644
--- a/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -31,10 +31,6 @@
namespace rcc::riscv {
namespace {
-[[nodiscard]] Opcode targetOpcode(InstructionOpcode Value) noexcept {
- return Opcode::fromValue(static_cast<std::uint32_t>(Value));
-}
-
[[nodiscard]] std::optional<LLT> registerType(const MachineFunction &Function,
const MachineOperand &Operand) {
const Register *Reg = Operand.getIf<Register>();
@@ -943,7 +939,7 @@ lowerAtomicCompareExchangeWithSuccess(MachineInstr &Instruction, MachineFunction
Amount = *MaskedAmount;
}
auto SetOpcode =
- Extension.setOpcode(Plan->SourceWidth == 32 ? targetOpcode(InstructionOpcode::G_SLLW)
+ Extension.setOpcode(Plan->SourceWidth == 32 ? instructionOpcode(InstructionOpcode::G_SLLW)
: opcode(GenericOpcode::G_SHL));
if (!SetOpcode)
return std::unexpected(SetOpcode.error());
diff --git a/backend/lib/Target/RISCV/RISCVFrameLowering.cpp b/backend/lib/Target/RISCV/RISCVFrameLowering.cpp
index 108f6da..dd59ba9 100644
--- a/backend/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/backend/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -43,10 +43,6 @@ constexpr std::uint8_t DwarfCFAExpression = 0x10U;
constexpr std::uint8_t DwarfOpBaseRegister0 = 0x70U;
constexpr std::uint8_t DwarfOpBaseRegisterExtended = 0x92U;
-[[nodiscard]] constexpr Opcode targetOpcode(InstructionOpcode Value) noexcept {
- return Opcode::fromValue(static_cast<std::uint32_t>(Value));
-}
-
[[nodiscard]] Expected<PhysicalRegister> physical(PhysicalRegisterID ID) {
return physicalRegister(ID);
}
@@ -280,8 +276,9 @@ struct CallFrameRequirement final {
for (const MachineInstr *Instruction = Block->firstInstruction(); Instruction != nullptr;
Instruction = Instruction->next()) {
const bool IsDown =
- Instruction->opcode() == targetOpcode(InstructionOpcode::ADJCALLSTACKDOWN);
- const bool IsUp = Instruction->opcode() == targetOpcode(InstructionOpcode::ADJCALLSTACKUP);
+ Instruction->opcode() == instructionOpcode(InstructionOpcode::ADJCALLSTACKDOWN);
+ const bool IsUp =
+ Instruction->opcode() == instructionOpcode(InstructionOpcode::ADJCALLSTACKUP);
if (!IsDown && !IsUp)
continue;
SawPseudo = true;
@@ -584,7 +581,7 @@ emitSavedRegisterCFI(MachineIRBuilder &Builder, const TargetDescription &Target,
Remaining |= ~std::uint64_t{0} << 52U;
}
- auto Base = Builder.buildInstr(targetOpcode(InstructionOpcode::ADDI));
+ auto Base = Builder.buildInstr(instructionOpcode(InstructionOpcode::ADDI));
if (!Base)
return std::unexpected(Base.error());
if (auto Result = Base->addDef(Register::fromPhysical(Destination)); !Result)
@@ -599,7 +596,7 @@ emitSavedRegisterCFI(MachineIRBuilder &Builder, const TargetDescription &Target,
return std::unexpected(Result.error());
for (std::size_t Reverse = Digits.size(); Reverse != 0; --Reverse) {
- auto Shift = Builder.buildInstr(targetOpcode(InstructionOpcode::SLLI));
+ auto Shift = Builder.buildInstr(instructionOpcode(InstructionOpcode::SLLI));
if (!Shift)
return std::unexpected(Shift.error());
if (auto Result = Shift->addDef(Register::fromPhysical(Destination)); !Result)
@@ -613,7 +610,7 @@ emitSavedRegisterCFI(MachineIRBuilder &Builder, const TargetDescription &Target,
if (auto Result = Shift->build(); !Result)
return std::unexpected(Result.error());
- auto Add = Builder.buildInstr(targetOpcode(InstructionOpcode::ADDI));
+ auto Add = Builder.buildInstr(instructionOpcode(InstructionOpcode::ADDI));
if (!Add)
return std::unexpected(Add.error());
if (auto Result = Add->addDef(Register::fromPhysical(Destination)); !Result)
@@ -634,7 +631,7 @@ emitSavedRegisterCFI(MachineIRBuilder &Builder, const TargetDescription &Target,
PhysicalRegister Destination, PhysicalRegister Left,
PhysicalRegister Right,
std::optional<MachineInstrFlag> Flag) {
- auto Add = Builder.buildInstr(targetOpcode(InstructionOpcode::ADD));
+ auto Add = Builder.buildInstr(instructionOpcode(InstructionOpcode::ADD));
if (!Add)
return std::unexpected(Add.error());
if (auto Result = Add->addDef(Register::fromPhysical(Destination)); !Result)
@@ -655,7 +652,7 @@ emitSavedRegisterCFI(MachineIRBuilder &Builder, const TargetDescription &Target,
PhysicalRegister Destination, PhysicalRegister Source,
std::int64_t Amount,
std::optional<MachineInstrFlag> Flag) {
- auto Add = Builder.buildInstr(targetOpcode(InstructionOpcode::ADDI));
+ auto Add = Builder.buildInstr(instructionOpcode(InstructionOpcode::ADDI));
if (!Add)
return std::unexpected(Add.error());
if (auto Result = Add->addDef(Register::fromPhysical(Destination)); !Result)
@@ -676,7 +673,7 @@ emitSavedRegisterCFI(MachineIRBuilder &Builder, const TargetDescription &Target,
PhysicalRegister Destination, PhysicalRegister Source,
std::int64_t Amount,
std::optional<MachineInstrFlag> Flag) {
- auto And = Builder.buildInstr(targetOpcode(InstructionOpcode::ANDI));
+ auto And = Builder.buildInstr(instructionOpcode(InstructionOpcode::ANDI));
if (!And)
return std::unexpected(And.error());
if (auto Result = And->addDef(Register::fromPhysical(Destination)); !Result)
@@ -697,7 +694,7 @@ emitSavedRegisterCFI(MachineIRBuilder &Builder, const TargetDescription &Target,
PhysicalRegister Destination, PhysicalRegister Left,
PhysicalRegister Right,
std::optional<MachineInstrFlag> Flag) {
- auto And = Builder.buildInstr(targetOpcode(InstructionOpcode::AND));
+ auto And = Builder.buildInstr(instructionOpcode(InstructionOpcode::AND));
if (!And)
return std::unexpected(And.error());
if (auto Result = And->addDef(Register::fromPhysical(Destination)); !Result)
@@ -1001,7 +998,7 @@ emitCalleeSave(MachineIRBuilder &Builder, PhysicalRegister Reg, FrameIndex Index
Restore ? MemoryAccessFlag::Load : MemoryAccessFlag::Store);
if (!Memory)
return std::unexpected(Memory.error());
- auto Pending = Builder.buildInstr(targetOpcode(OpcodeValue));
+ auto Pending = Builder.buildInstr(instructionOpcode(OpcodeValue));
if (!Pending)
return std::unexpected(Pending.error());
const Register Value = Register::fromPhysical(Reg);
@@ -1439,8 +1436,8 @@ public:
}
[[nodiscard]] bool isCallFramePseudo(const MachineInstr &Instruction) const noexcept override {
- return Instruction.opcode() == targetOpcode(InstructionOpcode::ADJCALLSTACKDOWN) ||
- Instruction.opcode() == targetOpcode(InstructionOpcode::ADJCALLSTACKUP);
+ return Instruction.opcode() == instructionOpcode(InstructionOpcode::ADJCALLSTACKDOWN) ||
+ Instruction.opcode() == instructionOpcode(InstructionOpcode::ADJCALLSTACKUP);
}
[[nodiscard]] Expected<void>
@@ -1455,7 +1452,7 @@ public:
if (!Amount)
return std::unexpected(Amount.error());
std::int64_t Adjustment = *Amount;
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::ADJCALLSTACKDOWN))
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::ADJCALLSTACKDOWN))
Adjustment = -Adjustment;
auto Adjusted = emitStackAdjustment(Instruction, Function, Target, Scavenger, Adjustment,
Adjustment < 0 ? MachineInstrFlag::FrameSetup
@@ -1664,7 +1661,7 @@ public:
[[nodiscard]] bool isEpilogueTerminator(const MachineInstr &Instruction,
const TargetDescription &Target) const noexcept override {
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::PseudoTAIL))
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoTAIL))
return true;
const InstructionDescriptor *Descriptor = Target.instructionDescriptor(Instruction.opcode());
return Descriptor != nullptr && Descriptor->Flags.has(InstructionFlag::Return);
@@ -2027,8 +2024,8 @@ private:
Function, Restore ? MemoryAccessFlag::Load : MemoryAccessFlag::Store, Reference.Offset);
if (!Memory)
return std::unexpected(Memory.error());
- auto Pending =
- Builder.buildInstr(targetOpcode(Restore ? InstructionOpcode::LD : InstructionOpcode::SD));
+ auto Pending = Builder.buildInstr(
+ instructionOpcode(Restore ? InstructionOpcode::LD : InstructionOpcode::SD));
if (!Pending)
return std::unexpected(Pending.error());
auto Value = Restore ? Pending->addDef(Register::fromPhysical(Scratch))
diff --git a/backend/lib/Target/RISCV/RISCVInstrInfo.cpp b/backend/lib/Target/RISCV/RISCVInstrInfo.cpp
index 6e26e2c..9d80638 100644
--- a/backend/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/backend/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -30,19 +30,15 @@ namespace {
constexpr std::uint32_t PCRelativeHighFlag = 2;
constexpr std::uint32_t PCRelativeLowFlag = 4;
-[[nodiscard]] constexpr Opcode targetOpcode(InstructionOpcode Value) noexcept {
- return Opcode::fromValue(static_cast<std::uint32_t>(Value));
-}
-
[[nodiscard]] bool isConditionalBranch(Opcode Value) noexcept {
- return Value == targetOpcode(InstructionOpcode::BEQ) ||
- Value == targetOpcode(InstructionOpcode::BNE) ||
- Value == targetOpcode(InstructionOpcode::BLT) ||
- Value == targetOpcode(InstructionOpcode::BGE) ||
- Value == targetOpcode(InstructionOpcode::BLTU) ||
- Value == targetOpcode(InstructionOpcode::BGEU) ||
- Value == targetOpcode(InstructionOpcode::C_BEQZ) ||
- Value == targetOpcode(InstructionOpcode::C_BNEZ);
+ return Value == instructionOpcode(InstructionOpcode::BEQ) ||
+ Value == instructionOpcode(InstructionOpcode::BNE) ||
+ Value == instructionOpcode(InstructionOpcode::BLT) ||
+ Value == instructionOpcode(InstructionOpcode::BGE) ||
+ Value == instructionOpcode(InstructionOpcode::BLTU) ||
+ Value == instructionOpcode(InstructionOpcode::BGEU) ||
+ Value == instructionOpcode(InstructionOpcode::C_BEQZ) ||
+ Value == instructionOpcode(InstructionOpcode::C_BNEZ);
}
[[nodiscard]] std::optional<Opcode> reversedOpcode(Opcode Value) noexcept {
@@ -53,10 +49,10 @@ constexpr std::uint32_t PCRelativeLowFlag = 4;
{InstructionOpcode::C_BEQZ, InstructionOpcode::C_BNEZ},
}};
for (const auto &[Left, Right] : Pairs) {
- if (Value == targetOpcode(Left))
- return targetOpcode(Right);
- if (Value == targetOpcode(Right))
- return targetOpcode(Left);
+ if (Value == instructionOpcode(Left))
+ return instructionOpcode(Right);
+ if (Value == instructionOpcode(Right))
+ return instructionOpcode(Left);
}
return std::nullopt;
}
@@ -76,33 +72,33 @@ constexpr std::uint32_t PCRelativeLowFlag = 4;
}
[[nodiscard]] bool isUnconditionalBranch(const MachineInstr &Instruction) noexcept {
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::C_J) ||
- Instruction.opcode() == targetOpcode(InstructionOpcode::PseudoBR)) {
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::C_J) ||
+ Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoBR)) {
return true;
}
- return Instruction.opcode() == targetOpcode(InstructionOpcode::JAL) &&
+ return Instruction.opcode() == instructionOpcode(InstructionOpcode::JAL) &&
isZeroRegister(Instruction.operandAt(0));
}
[[nodiscard]] std::size_t branchTargetIndex(Opcode Value) noexcept {
- if (Value == targetOpcode(InstructionOpcode::C_J) ||
- Value == targetOpcode(InstructionOpcode::PseudoBR)) {
+ if (Value == instructionOpcode(InstructionOpcode::C_J) ||
+ Value == instructionOpcode(InstructionOpcode::PseudoBR)) {
return 0;
}
- if (Value == targetOpcode(InstructionOpcode::C_BEQZ) ||
- Value == targetOpcode(InstructionOpcode::C_BNEZ)) {
+ if (Value == instructionOpcode(InstructionOpcode::C_BEQZ) ||
+ Value == instructionOpcode(InstructionOpcode::C_BNEZ)) {
return 1;
}
- if (Value == targetOpcode(InstructionOpcode::JAL))
+ if (Value == instructionOpcode(InstructionOpcode::JAL))
return 1;
return 2;
}
[[nodiscard]] Expected<MachineBasicBlock *> directTarget(MachineInstr &Instruction) {
if (!isConditionalBranch(Instruction.opcode()) &&
- Instruction.opcode() != targetOpcode(InstructionOpcode::JAL) &&
- Instruction.opcode() != targetOpcode(InstructionOpcode::C_J) &&
- Instruction.opcode() != targetOpcode(InstructionOpcode::PseudoBR)) {
+ Instruction.opcode() != instructionOpcode(InstructionOpcode::JAL) &&
+ Instruction.opcode() != instructionOpcode(InstructionOpcode::C_J) &&
+ Instruction.opcode() != instructionOpcode(InstructionOpcode::PseudoBR)) {
return static_cast<MachineBasicBlock *>(nullptr);
}
MachineOperand *Operand = Instruction.operandAt(branchTargetIndex(Instruction.opcode()));
@@ -149,7 +145,7 @@ buildJAL(MachineFunction &Function, const TargetDescription &Target, MachineBasi
Before == nullptr ? Builder.setInsertPoint(Block) : Builder.setInsertPointBefore(*Before);
if (!Point)
return std::unexpected(Point.error());
- auto Pending = Builder.buildInstr(targetOpcode(InstructionOpcode::JAL));
+ auto Pending = Builder.buildInstr(instructionOpcode(InstructionOpcode::JAL));
if (!Pending)
return std::unexpected(Pending.error());
auto Def = Pending->addDef(Register::fromPhysical(Destination));
@@ -284,7 +280,7 @@ selectLongBranchScratch(const MachineInstr &Instruction, const MachineBasicBlock
if (!Point)
return std::unexpected(Point.error());
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::C_J)) {
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::C_J)) {
auto Zero = physical(PhysicalRegisterID::X0);
if (!Zero)
return std::unexpected(Zero.error());
@@ -308,10 +304,10 @@ selectLongBranchScratch(const MachineInstr &Instruction, const MachineBasicBlock
auto Zero = physical(PhysicalRegisterID::X0);
if (!Zero)
return std::unexpected(Zero.error());
- const InstructionOpcode Expanded = Instruction.opcode() == targetOpcode(InstructionOpcode::C_BEQZ)
- ? InstructionOpcode::BEQ
- : InstructionOpcode::BNE;
- auto Pending = Builder.buildInstr(targetOpcode(Expanded));
+ const InstructionOpcode Expanded =
+ Instruction.opcode() == instructionOpcode(InstructionOpcode::C_BEQZ) ? InstructionOpcode::BEQ
+ : InstructionOpcode::BNE;
+ auto Pending = Builder.buildInstr(instructionOpcode(Expanded));
if (!Pending)
return std::unexpected(Pending.error());
auto First = Pending->addUse(*Source);
@@ -378,7 +374,7 @@ selectLongBranchScratch(const MachineInstr &Instruction, const MachineBasicBlock
auto Point = Builder.setInsertPointAfter(Instruction);
if (!Point)
return std::unexpected(Point.error());
- auto Pending = Builder.buildInstr(targetOpcode(InstructionOpcode::JAL));
+ auto Pending = Builder.buildInstr(instructionOpcode(InstructionOpcode::JAL));
if (!Pending)
return std::unexpected(Pending.error());
auto Def = Pending->addDef(Register::fromPhysical(*Zero));
@@ -440,7 +436,7 @@ selectLongBranchScratch(const MachineInstr &Instruction, const MachineBasicBlock
auto Point = Builder.setInsertPointBefore(Instruction);
if (!Point)
return std::unexpected(Point.error());
- auto HighPending = Builder.buildInstr(targetOpcode(InstructionOpcode::AUIPC));
+ auto HighPending = Builder.buildInstr(instructionOpcode(InstructionOpcode::AUIPC));
if (!HighPending)
return std::unexpected(HighPending.error());
auto HighDef = HighPending->addDef(Register::fromPhysical(*Scratch));
@@ -459,7 +455,7 @@ selectLongBranchScratch(const MachineInstr &Instruction, const MachineBasicBlock
if (!HighIdentity)
return std::unexpected(HighIdentity.error());
- auto LowPending = Builder.buildInstr(targetOpcode(InstructionOpcode::JALR));
+ auto LowPending = Builder.buildInstr(instructionOpcode(InstructionOpcode::JALR));
if (!LowPending)
return std::unexpected(LowPending.error());
auto LowDef = LowPending->addDef(*Destination);
@@ -742,17 +738,17 @@ public:
const Opcode Value = Instruction.opcode();
if (!isConditionalBranch(Value))
return std::optional<bool>{};
- if (Value == targetOpcode(InstructionOpcode::C_BEQZ) ||
- Value == targetOpcode(InstructionOpcode::C_BNEZ)) {
+ if (Value == instructionOpcode(InstructionOpcode::C_BEQZ) ||
+ Value == instructionOpcode(InstructionOpcode::C_BNEZ)) {
if (!isZeroRegister(Instruction.operandAt(0)))
return std::optional<bool>{};
- return std::optional<bool>{Value == targetOpcode(InstructionOpcode::C_BEQZ)};
+ return std::optional<bool>{Value == instructionOpcode(InstructionOpcode::C_BEQZ)};
}
if (!sameRegister(Instruction.operandAt(0), Instruction.operandAt(1)))
return std::optional<bool>{};
- if (Value == targetOpcode(InstructionOpcode::BEQ) ||
- Value == targetOpcode(InstructionOpcode::BGE) ||
- Value == targetOpcode(InstructionOpcode::BGEU)) {
+ if (Value == instructionOpcode(InstructionOpcode::BEQ) ||
+ Value == instructionOpcode(InstructionOpcode::BGE) ||
+ Value == instructionOpcode(InstructionOpcode::BGEU)) {
return std::optional<bool>{true};
}
return std::optional<bool>{false};
@@ -763,16 +759,16 @@ public:
if ((Offset & 1) != 0)
return false;
const Opcode Value = Instruction.opcode();
- if (Value == targetOpcode(InstructionOpcode::C_BEQZ) ||
- Value == targetOpcode(InstructionOpcode::C_BNEZ)) {
+ if (Value == instructionOpcode(InstructionOpcode::C_BEQZ) ||
+ Value == instructionOpcode(InstructionOpcode::C_BNEZ)) {
return Offset >= -256 && Offset <= 254;
}
- if (Value == targetOpcode(InstructionOpcode::C_J))
+ if (Value == instructionOpcode(InstructionOpcode::C_J))
return Offset >= -2048 && Offset <= 2046;
if (isConditionalBranch(Value))
return Offset >= -4096 && Offset <= 4094;
- if (Value == targetOpcode(InstructionOpcode::JAL) ||
- Value == targetOpcode(InstructionOpcode::PseudoBR)) {
+ if (Value == instructionOpcode(InstructionOpcode::JAL) ||
+ Value == instructionOpcode(InstructionOpcode::PseudoBR)) {
return Offset >= -1048576 && Offset <= 1048574;
}
return true;
@@ -784,14 +780,14 @@ public:
if (&Instruction.function() != &Function)
return makeUnexpected(ErrorCode::InvalidArgument,
"RISC-V branch relaxation references another function");
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::C_J) ||
- Instruction.opcode() == targetOpcode(InstructionOpcode::C_BEQZ) ||
- Instruction.opcode() == targetOpcode(InstructionOpcode::C_BNEZ)) {
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::C_J) ||
+ Instruction.opcode() == instructionOpcode(InstructionOpcode::C_BEQZ) ||
+ Instruction.opcode() == instructionOpcode(InstructionOpcode::C_BNEZ)) {
return expandCompressedBranch(Instruction, Function, Target);
}
if (isConditionalBranch(Instruction.opcode()))
return relaxConditionalBranch(Instruction, Function, Target);
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::JAL))
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::JAL))
return relaxJAL(Instruction, Offset, Function, Target);
return false;
}
diff --git a/backend/lib/Target/RISCV/RISCVMachineCombiner.cpp b/backend/lib/Target/RISCV/RISCVMachineCombiner.cpp
index f41e77a..78c764c 100644
--- a/backend/lib/Target/RISCV/RISCVMachineCombiner.cpp
+++ b/backend/lib/Target/RISCV/RISCVMachineCombiner.cpp
@@ -12,10 +12,6 @@
namespace rcc::riscv {
namespace {
-[[nodiscard]] constexpr Opcode targetOpcode(InstructionOpcode Value) noexcept {
- return Opcode::fromValue(static_cast<std::uint32_t>(Value));
-}
-
[[nodiscard]] constexpr MachineCombinerStageMask allOptimizationStages() noexcept {
return machineCombinerStageMask(MachineCombinerStage::SelectedSSA) |
machineCombinerStageMask(MachineCombinerStage::PreRegisterAllocation) |
@@ -27,7 +23,7 @@ namespace {
std::string Name, std::int64_t Immediate) {
return {
.Name = std::move(Name),
- .RootOpcode = targetOpcode(OpcodeValue),
+ .RootOpcode = instructionOpcode(OpcodeValue),
.Stages = allOptimizationStages(),
.Predicates = {{MachineCombinerPredicateKind::ImmediateEquals, 2, 0, Immediate}},
.Action = {MachineCombinerActionKind::ReplaceDefWithOperandAndErase, 0, 1},
@@ -39,7 +35,7 @@ namespace {
std::size_t SourceOperand) {
return {
.Name = std::move(Name),
- .RootOpcode = targetOpcode(OpcodeValue),
+ .RootOpcode = instructionOpcode(OpcodeValue),
.Stages = allOptimizationStages(),
.Predicates = {{MachineCombinerPredicateKind::PhysicalRegisterEquals, ZeroOperand, 0,
static_cast<std::int64_t>(PhysicalRegisterID::X0)}},
@@ -51,7 +47,7 @@ namespace {
std::string Name) {
return {
.Name = std::move(Name),
- .RootOpcode = targetOpcode(OpcodeValue),
+ .RootOpcode = instructionOpcode(OpcodeValue),
.Stages = allOptimizationStages(),
.Predicates = {{MachineCombinerPredicateKind::RegisterEquals, 1, 2, 0}},
.Action = {MachineCombinerActionKind::ReplaceDefWithOperandAndErase, 0, 1},
diff --git a/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp b/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp
index 1f3564c..df85124 100644
--- a/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp
+++ b/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp
@@ -29,10 +29,6 @@ constexpr std::uint32_t PCRelativeLowFlag = 4;
constexpr std::uint32_t CopyF32Flag = 8;
constexpr std::uint32_t CopyF64Flag = 16;
-[[nodiscard]] constexpr Opcode targetOpcode(InstructionOpcode Value) noexcept {
- return Opcode::fromValue(static_cast<std::uint32_t>(Value));
-}
-
[[nodiscard]] Expected<PhysicalRegister> physical(PhysicalRegisterID ID) {
auto Reg = physicalRegister(ID);
if (!Reg)
@@ -246,7 +242,7 @@ copyRegisters(const MachineInstr &Instruction) {
auto Point = Builder.setInsertPointBefore(Instruction);
if (!Point)
return std::unexpected(Point.error());
- auto Pending = Builder.buildInstr(targetOpcode(Selected));
+ auto Pending = Builder.buildInstr(instructionOpcode(Selected));
if (!Pending)
return std::unexpected(Pending.error());
auto Def = Pending->addDef(Destination);
@@ -352,7 +348,7 @@ copyRegisters(const MachineInstr &Instruction) {
if (!Point)
return std::unexpected(Point.error());
auto Pending = Builder.buildInstr(
- targetOpcode(IsRead ? InstructionOpcode::CSRRS : InstructionOpcode::CSRRW));
+ instructionOpcode(IsRead ? InstructionOpcode::CSRRS : InstructionOpcode::CSRRW));
if (!Pending)
return std::unexpected(Pending.error());
Expected<void> Added = IsRead ? Pending->addOperand(ValueOperand->cloneDetached())
@@ -413,7 +409,7 @@ copyRegisters(const MachineInstr &Instruction) {
: std::optional<std::string>{".Lrcc_call_" +
std::to_string(Function.stableID().value()) + "_" +
std::to_string(Instruction.stableID().value())};
- auto HighPending = Builder.buildInstr(targetOpcode(InstructionOpcode::AUIPC));
+ auto HighPending = Builder.buildInstr(instructionOpcode(InstructionOpcode::AUIPC));
if (!HighPending)
return std::unexpected(HighPending.error());
auto HighDef = HighPending->addDef(Base);
@@ -441,7 +437,7 @@ copyRegisters(const MachineInstr &Instruction) {
const InstructionOpcode LowOpcode =
IsTail ? InstructionOpcode::JALR_TAIL : InstructionOpcode::JALR_CALL;
- auto LowPending = Builder.buildInstr(targetOpcode(LowOpcode));
+ auto LowPending = Builder.buildInstr(instructionOpcode(LowOpcode));
if (!LowPending)
return std::unexpected(LowPending.error());
const PhysicalRegister DestinationRegister = IsTail ? *Zero : *Link;
@@ -489,7 +485,7 @@ copyRegisters(const MachineInstr &Instruction) {
auto Point = Builder.setInsertPointBefore(Instruction);
if (!Point)
return std::unexpected(Point.error());
- auto Pending = Builder.buildInstr(targetOpcode(InstructionOpcode::JALR_RET));
+ auto Pending = Builder.buildInstr(instructionOpcode(InstructionOpcode::JALR_RET));
if (!Pending)
return std::unexpected(Pending.error());
auto Def = Pending->addDef(Register::fromPhysical(*Zero));
@@ -533,7 +529,7 @@ copyRegisters(const MachineInstr &Instruction) {
auto Point = Builder.setInsertPointBefore(Instruction);
if (!Point)
return std::unexpected(Point.error());
- auto Pending = Builder.buildInstr(targetOpcode(InstructionOpcode::JAL));
+ auto Pending = Builder.buildInstr(instructionOpcode(InstructionOpcode::JAL));
if (!Pending)
return std::unexpected(Pending.error());
auto Def = Pending->addDef(Register::fromPhysical(*Zero));
@@ -573,17 +569,17 @@ public:
auto Subregister = expandSubregisterCopy(Instruction, Function, Target);
if (!Subregister || *Subregister)
return Subregister;
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::PseudoCALL))
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoCALL))
return expandCall(Instruction, Function, Target, false);
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::PseudoTAIL))
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoTAIL))
return expandCall(Instruction, Function, Target, true);
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::PseudoRET))
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoRET))
return expandReturn(Instruction, Function, Target);
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::PseudoBR))
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoBR))
return expandBranch(Instruction, Function, Target);
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::ReadFFLAGS))
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::ReadFFLAGS))
return expandFFLAGSAccess(Instruction, Function, Target, true);
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::WriteFFLAGS))
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::WriteFFLAGS))
return expandFFLAGSAccess(Instruction, Function, Target, false);
return false;
}
diff --git a/backend/lib/Target/RISCV/RISCVRegisterAllocation.cpp b/backend/lib/Target/RISCV/RISCVRegisterAllocation.cpp
index de5900d..e24c199 100644
--- a/backend/lib/Target/RISCV/RISCVRegisterAllocation.cpp
+++ b/backend/lib/Target/RISCV/RISCVRegisterAllocation.cpp
@@ -28,10 +28,6 @@ struct SpillForm final {
std::uint64_t SizeInBytes;
};
-[[nodiscard]] constexpr Opcode targetOpcode(InstructionOpcode Value) noexcept {
- return Opcode::fromValue(static_cast<std::uint32_t>(Value));
-}
-
[[nodiscard]] constexpr RegisterClassID registerClassID(RegisterClass Value) noexcept {
return RegisterClassID::fromValue(static_cast<std::uint32_t>(Value));
}
@@ -177,7 +173,7 @@ public:
}
for (const InstructionOpcode OpcodeValue : {Form->Load, Form->Store}) {
const InstructionDescriptor *Instruction =
- Target.instructionDescriptor(targetOpcode(OpcodeValue));
+ Target.instructionDescriptor(instructionOpcode(OpcodeValue));
const InstructionFlag MemoryFlag =
OpcodeValue == Form->Load ? InstructionFlag::MayLoad : InstructionFlag::MayStore;
if (Instruction == nullptr || Instruction->Operands.size() != 3 ||
@@ -212,7 +208,7 @@ public:
Description->SpillAlignmentInBits / 8U);
if (!Memory)
return std::unexpected(Memory.error());
- auto Pending = Builder.buildInstr(targetOpcode(Form.Load));
+ auto Pending = Builder.buildInstr(instructionOpcode(Form.Load));
if (!Pending)
return std::unexpected(Pending.error());
if (auto Result = Pending->addDef(Destination); !Result)
@@ -247,7 +243,7 @@ public:
Description->SpillAlignmentInBits / 8U);
if (!Memory)
return std::unexpected(Memory.error());
- auto Pending = Builder.buildInstr(targetOpcode(Form.Store));
+ auto Pending = Builder.buildInstr(instructionOpcode(Form.Store));
if (!Pending)
return std::unexpected(Pending.error());
if (auto Result = Pending->addUse(Source); !Result)
@@ -269,10 +265,10 @@ public:
if (DefinedReg == nullptr || *DefinedReg != VirtualReg || !Definition->isDef())
return false;
- if (Instruction.opcode() == targetOpcode(InstructionOpcode::LUI))
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::LUI))
return Instruction.operandCount() == 2 && Instruction.operandAt(1) != nullptr;
- if (Instruction.opcode() != targetOpcode(InstructionOpcode::ADDI) &&
- Instruction.opcode() != targetOpcode(InstructionOpcode::ADDIW)) {
+ if (Instruction.opcode() != instructionOpcode(InstructionOpcode::ADDI) &&
+ Instruction.opcode() != instructionOpcode(InstructionOpcode::ADDIW)) {
return false;
}
if (Instruction.operandCount() != 3)
diff --git a/backend/unittests/Target/RISCVRegisterAllocationTest.cpp b/backend/unittests/Target/RISCVRegisterAllocationTest.cpp
index acd4b3a..6daf58a 100644
--- a/backend/unittests/Target/RISCVRegisterAllocationTest.cpp
+++ b/backend/unittests/Target/RISCVRegisterAllocationTest.cpp
@@ -52,10 +52,6 @@ private:
int Failures = 0;
};
-[[nodiscard]] constexpr rcc::Opcode targetOpcode(rcc::riscv::InstructionOpcode Value) noexcept {
- return rcc::Opcode::fromValue(static_cast<std::uint32_t>(Value));
-}
-
[[nodiscard]] constexpr rcc::RegisterClassID
registerClass(rcc::riscv::RegisterClass Value) noexcept {
return rcc::RegisterClassID::fromValue(static_cast<std::uint32_t>(Value));
@@ -108,7 +104,8 @@ buildAddImmediate(rcc::MachineFunction &Function, const rcc::TargetDescription &
rcc::MachineIRBuilder Builder(Function, Target);
if (auto Result = Builder.setInsertPoint(Block); !Result)
return std::unexpected(Result.error());
- auto Pending = Builder.buildInstr(targetOpcode(rcc::riscv::InstructionOpcode::ADDI));
+ auto Pending =
+ Builder.buildInstr(rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::ADDI));
if (!Pending)
return std::unexpected(Pending.error());
if (auto Result = Pending->addDef(Destination); !Result)
@@ -128,7 +125,8 @@ buildAddImmediate(rcc::MachineFunction &Function, const rcc::TargetDescription &
rcc::MachineIRBuilder Builder(Function, Target);
if (auto Result = Builder.setInsertPoint(Block); !Result)
return std::unexpected(Result.error());
- auto Pending = Builder.buildInstr(targetOpcode(rcc::riscv::InstructionOpcode::ADD));
+ auto Pending =
+ Builder.buildInstr(rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::ADD));
if (!Pending)
return std::unexpected(Pending.error());
if (auto Result = Pending->addDef(Destination); !Result)
@@ -198,7 +196,7 @@ enum class AllocatorKind : std::uint8_t {
Block = Block->next()) {
for (const rcc::MachineInstr *Instruction = Block->firstInstruction(); Instruction != nullptr;
Instruction = Instruction->next()) {
- Count += Instruction->opcode() == targetOpcode(Value) ? 1U : 0U;
+ Count += Instruction->opcode() == rcc::riscv::instructionOpcode(Value) ? 1U : 0U;
}
}
return Count;
@@ -277,12 +275,18 @@ void testTargetHooks(TestContext &Context, const rcc::TargetDescription &Target)
Info.emitSpill(Builder, physical(rcc::riscv::PhysicalRegisterID::F11_D),
registerClass(rcc::riscv::RegisterClass::FPR64), *Slot, rcc::LaneMask::all());
Context.expect(GPRReload && GPRSpill && F32Reload && F32Spill && F64Reload && F64Spill &&
- (*GPRReload)->opcode() == targetOpcode(rcc::riscv::InstructionOpcode::LD) &&
- (*GPRSpill)->opcode() == targetOpcode(rcc::riscv::InstructionOpcode::SD) &&
- (*F32Reload)->opcode() == targetOpcode(rcc::riscv::InstructionOpcode::FLW) &&
- (*F32Spill)->opcode() == targetOpcode(rcc::riscv::InstructionOpcode::FSW) &&
- (*F64Reload)->opcode() == targetOpcode(rcc::riscv::InstructionOpcode::FLD) &&
- (*F64Spill)->opcode() == targetOpcode(rcc::riscv::InstructionOpcode::FSD),
+ (*GPRReload)->opcode() ==
+ rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::LD) &&
+ (*GPRSpill)->opcode() ==
+ rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::SD) &&
+ (*F32Reload)->opcode() ==
+ rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::FLW) &&
+ (*F32Spill)->opcode() ==
+ rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::FSW) &&
+ (*F64Reload)->opcode() ==
+ rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::FLD) &&
+ (*F64Spill)->opcode() ==
+ rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::FSD),
"RV64GC hooks must select width- and bank-correct stack instructions");
if (GPRReload && F32Reload && F64Reload) {
Context.expect(
@@ -321,7 +325,7 @@ void testRematerialization(TestContext &Context, const rcc::TargetDescription &T
auto Materialized = Info.rematerialize(Builder, **Definition, *Child, *Original, Target);
Context.expect(Accepted && *Accepted && Materialized &&
(*Materialized)->opcode() ==
- targetOpcode(rcc::riscv::InstructionOpcode::ADDI) &&
+ rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::ADDI) &&
(*Materialized)->operandAt(0)->registerValue() == *Child &&
(*Materialized)->operandAt(1)->registerValue() ==
physical(rcc::riscv::PhysicalRegisterID::X0),
diff --git a/backend/unittests/Target/RISCVSSAExitTest.cpp b/backend/unittests/Target/RISCVSSAExitTest.cpp
index ec98bd1..54a5911 100644
--- a/backend/unittests/Target/RISCVSSAExitTest.cpp
+++ b/backend/unittests/Target/RISCVSSAExitTest.cpp
@@ -46,10 +46,6 @@ private:
int Failures = 0;
};
-[[nodiscard]] rcc::Opcode targetOpcode(rcc::riscv::InstructionOpcode Opcode) {
- return rcc::Opcode::fromValue(static_cast<std::uint32_t>(Opcode));
-}
-
[[nodiscard]] rcc::RegisterBankID bank(rcc::riscv::RegisterBank Bank) {
return rcc::RegisterBankID::fromValue(static_cast<std::uint32_t>(Bank));
}
@@ -91,7 +87,8 @@ buildAddImmediate(rcc::MachineFunction &Function, const rcc::TargetDescription &
auto Point = Builder.setInsertPoint(Block);
if (!Point)
return std::unexpected(Point.error());
- auto Pending = Builder.buildInstr(targetOpcode(rcc::riscv::InstructionOpcode::ADDI));
+ auto Pending =
+ Builder.buildInstr(rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::ADDI));
if (!Pending)
return std::unexpected(Pending.error());
auto Def = Pending->addDef(Destination);
@@ -114,7 +111,8 @@ buildBranchEqual(rcc::MachineFunction &Function, const rcc::TargetDescription &T
auto Point = Builder.setInsertPoint(Block);
if (!Point)
return std::unexpected(Point.error());
- auto Pending = Builder.buildInstr(targetOpcode(rcc::riscv::InstructionOpcode::BEQ));
+ auto Pending =
+ Builder.buildInstr(rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::BEQ));
if (!Pending)
return std::unexpected(Pending.error());
auto LeftUse = Pending->addUse(Left);
@@ -208,7 +206,8 @@ void testBehaviorAndCopyLegality(TestContext &Context, const rcc::TargetDescript
rcc::MachineInstr *Jump = (*First)->lastInstruction();
const auto X0 = rcc::riscv::physicalRegister(rcc::riscv::PhysicalRegisterID::X0);
Context.expect(Jump != nullptr &&
- Jump->opcode() == targetOpcode(rcc::riscv::InstructionOpcode::JAL) &&
+ Jump->opcode() ==
+ rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::JAL) &&
Jump->operandAt(0)->registerValue() == rcc::Register::fromPhysical(*X0) &&
blockOperand(*Jump, 1) != nullptr && blockOperand(*Jump, 1)->Block == *Second,
"RV64GC unconditional branches must use JAL with x0 as the link destination");
@@ -280,7 +279,8 @@ void testCompressedConditionalBranchBehavior(TestContext &Context,
Context.expect(false, "compressed conditional branch insertion point must be established");
return;
}
- auto Pending = Builder.buildInstr(targetOpcode(rcc::riscv::InstructionOpcode::C_BEQZ));
+ auto Pending =
+ Builder.buildInstr(rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::C_BEQZ));
if (!X8 || !Pending || !Pending->addUse(rcc::Register::fromPhysical(*X8)) ||
!Pending->addBasicBlock(**BranchTarget)) {
Context.expect(false, "compressed conditional branch construction must succeed");
@@ -370,7 +370,8 @@ void testRV64GCCriticalEdge(TestContext &Context, const rcc::TargetDescription &
return;
rcc::MachineInstr *Conditional = (*From)->lastInstruction();
Context.expect(Conditional != nullptr &&
- Conditional->opcode() == targetOpcode(rcc::riscv::InstructionOpcode::BEQ) &&
+ Conditional->opcode() ==
+ rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::BEQ) &&
blockOperand(*Conditional, 2) != nullptr &&
blockOperand(*Conditional, 2)->Block == Edge,
"RV64GC BEQ must be redirected to the critical-edge block");
@@ -380,13 +381,13 @@ void testRV64GCCriticalEdge(TestContext &Context, const rcc::TargetDescription &
Context.expect(OtherInstructions.size() == 3 &&
OtherInstructions[1]->opcode() == rcc::opcode(rcc::GenericOpcode::COPY) &&
OtherInstructions[2]->opcode() ==
- targetOpcode(rcc::riscv::InstructionOpcode::JAL) &&
+ rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::JAL) &&
blockOperand(*OtherInstructions[2], 1)->Block == *Merge,
"RV64GC must materialize an unrelated fallthrough before edge-block insertion");
Context.expect(EdgeInstructions.size() == 2 &&
EdgeInstructions[0]->opcode() == rcc::opcode(rcc::GenericOpcode::COPY) &&
EdgeInstructions[1]->opcode() ==
- targetOpcode(rcc::riscv::InstructionOpcode::JAL) &&
+ rcc::riscv::instructionOpcode(rcc::riscv::InstructionOpcode::JAL) &&
EdgeInstructions[1]->operandAt(0)->registerValue() == Zero &&
blockOperand(*EdgeInstructions[1], 1)->Block == *Merge,
"RV64GC edge block must transfer the PHI value and jump to the merge");
diff --git a/backend/utils/TableGen/InstrInfoEmitter.cpp b/backend/utils/TableGen/InstrInfoEmitter.cpp
index 6c6426d..795a718 100644
--- a/backend/utils/TableGen/InstrInfoEmitter.cpp
+++ b/backend/utils/TableGen/InstrInfoEmitter.cpp
@@ -104,13 +104,16 @@ void emitImmediatePredicate(std::ostream &Output, const NormalizedImmediatePredi
appendQuoted(Output, SourceName);
Output << ". Do not edit it manually.\n\n";
Output << "#ifndef " << Guard << "\n#define " << Guard << "\n\n";
- Output << "#include <cstdint>\n\n";
+ Output << "#include \"rcc/CodeGen/MachineIRTypes.h\"\n\n#include <cstdint>\n\n";
Output << "namespace rcc::" << Model.Target.Namespace << " {\n\n";
Output << "enum class InstructionOpcode : std::uint32_t {\n Invalid = 0,\n";
for (const NormalizedInstruction &Instruction : Model.Instructions)
Output << " " << Instruction.Symbol << " = " << Instruction.ID << ",\n";
Output << "};\n\n";
+ Output << "[[nodiscard]] constexpr Opcode instructionOpcode(InstructionOpcode Value) noexcept {\n"
+ " return Opcode::fromValue(static_cast<std::uint32_t>(Value));\n"
+ "}\n\n";
Output << "enum class ImmediatePredicate : std::uint32_t {\n None = 0,\n";
for (const NormalizedImmediatePredicate &Predicate : Model.ImmediatePredicates)