[llvm] [Exegesis][RISCV] Add RISCV support for llvm-exegesis (PR #89047)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 6 10:33:11 PST 2024
================
@@ -0,0 +1,350 @@
+//===-- Target.cpp ----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "../Target.h"
+
+#include "MCTargetDesc/RISCVBaseInfo.h"
+#include "MCTargetDesc/RISCVMCTargetDesc.h"
+#include "MCTargetDesc/RISCVMatInt.h"
+#include "RISCVInstrInfo.h"
+
+// include computeAvailableFeatures and computeRequiredFeatures.
+#define GET_COMPUTE_FEATURES
+#define GET_AVAILABLE_OPCODE_CHECKER
+#include "RISCVGenInstrInfo.inc"
+#undef GET_COMPUTE_FEATURES
+
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+
+#include <vector>
+
+namespace llvm {
+namespace exegesis {
+
+namespace {
+
+class ExegesisRISCVTarget : public ExegesisTarget {
+public:
+ ExegesisRISCVTarget();
+
+ MCRegister findRegisterByName(const StringRef RegName) const override;
+
+ bool matchesArch(Triple::ArchType Arch) const override;
+
+ std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg,
+ const APInt &Value) const override;
+
+ unsigned getDefaultLoopCounterRegister(const Triple &) const override;
+
+ void decrementLoopCounterAndJump(MachineBasicBlock &MBB,
+ MachineBasicBlock &TargetMBB,
+ const MCInstrInfo &MII,
+ unsigned LoopRegister) const override;
+
+ unsigned getScratchMemoryRegister(const Triple &TT) const override;
+
+ void fillMemoryOperands(InstructionTemplate &IT, unsigned Reg,
+ unsigned Offset) const override;
+
+ ArrayRef<unsigned> getUnavailableRegisters() const override;
+
+ Error randomizeTargetMCOperand(const Instruction &Instr, const Variable &Var,
+ MCOperand &AssignedValue,
+ const BitVector &ForbiddenRegs) const override;
+
+ void processInstructionReservedRegs(InstructionTemplate &IT) const override;
+
+ std::vector<InstructionTemplate>
+ generateInstructionVariants(const Instruction &Instr,
+ unsigned MaxConfigsPerOpcode) const override;
+};
+
+ExegesisRISCVTarget::ExegesisRISCVTarget()
+ : ExegesisTarget(ArrayRef<CpuAndPfmCounters>{},
+ RISCV_MC::isOpcodeAvailable) {}
+
+#define GET_REGISTER_MATCHER
+#include "RISCVGenAsmMatcher.inc"
+
+MCRegister
+ExegesisRISCVTarget::findRegisterByName(const StringRef RegName) const {
+ MCRegister Reg;
+ if ((Reg = MatchRegisterName(RegName)))
+ return Reg;
+ if ((Reg = MatchRegisterAltName(RegName)))
+ return Reg;
+ return RISCV::NoRegister;
+}
+
+bool ExegesisRISCVTarget::matchesArch(Triple::ArchType Arch) const {
+ return Arch == Triple::riscv32 || Arch == Triple::riscv64;
+}
+
+// Stores constant value to a general-purpose (integer) register.
+static std::vector<MCInst> loadIntReg(const MCSubtargetInfo &STI, unsigned Reg,
+ const APInt &Value) {
+ RISCVMatInt::InstSeq InstSeq =
+ RISCVMatInt::generateInstSeq(Value.getSExtValue(), STI);
+ // First instruction has form 'Op DestReg, X0, Imm'
+ MCRegister SrcReg = RISCV::X0;
+ MCRegister DestReg = Reg;
+ std::vector<MCInst> MatIntInstrs;
+ MatIntInstrs.reserve(InstSeq.size());
+ for (const RISCVMatInt::Inst &Inst : InstSeq) {
+ switch (Inst.getOpndKind()) {
+ case RISCVMatInt::Imm:
+ MatIntInstrs.push_back(MCInstBuilder(Inst.getOpcode())
+ .addReg(DestReg)
+ .addImm(Inst.getImm()));
+ break;
+ case RISCVMatInt::RegX0:
+ MatIntInstrs.push_back(MCInstBuilder(Inst.getOpcode())
+ .addReg(DestReg)
+ .addReg(SrcReg)
+ .addReg(RISCV::X0));
+ break;
+ case RISCVMatInt::RegReg:
+ MatIntInstrs.push_back(MCInstBuilder(Inst.getOpcode())
+ .addReg(DestReg)
+ .addReg(SrcReg)
+ .addReg(SrcReg));
+ break;
+ case RISCVMatInt::RegImm:
+ MatIntInstrs.push_back(MCInstBuilder(Inst.getOpcode())
+ .addReg(DestReg)
+ .addReg(SrcReg)
+ .addImm(Inst.getImm()));
+ break;
+ default:
+ llvm_unreachable("Unexpected kind!");
+ }
+ // Further instructions have form 'Op DestReg, DestReg, Imm'
+ SrcReg = DestReg;
+ }
+ return MatIntInstrs;
+}
+
+const unsigned ScratchIntReg = RISCV::X30; // t5
+
+// Stores constant bits to a floating-point register.
+static std::vector<MCInst> loadFPRegBits(const MCSubtargetInfo &STI,
+ unsigned Reg, const APInt &Bits,
+ unsigned FmvOpcode) {
+ std::vector<MCInst> Instrs = loadIntReg(STI, ScratchIntReg, Bits);
+ Instrs.push_back(MCInstBuilder(FmvOpcode).addReg(Reg).addReg(ScratchIntReg));
+ return Instrs;
+}
+
+// main idea is:
+// we support APInt only if (represented as double) it have zero fractional
----------------
topperc wrote:
have -> has?
https://github.com/llvm/llvm-project/pull/89047
More information about the llvm-commits
mailing list