Factor out shared logic between RV32 and RV64 ISA info
MODIFY
src/binutils.h
src/binutils.h
@@ -45,10 +45,22 @@ constexpr inline bool isInt<32>(int64_t x) {
return x2 == x;
}
+/// Checks if an unsigned integer fits into the given bit width.
+///
+/// This is written as two functions rather than as simply
+///
+/// return N >= 64 || X < (UINT64_C(1) << N);
+///
+/// to keep MSVC from (incorrectly) warning on isUInt<64> that we're shifting
+/// left too many places.
template <unsigned N>
-constexpr inline bool isUInt(uint64_t X) {
+constexpr inline std::enable_if_t<(N < 64), bool> isUInt(uint64_t X) {
static_assert(N > 0, "isUInt<0> doesn't make sense");
- return N >= 64 || X < (UINT64_C(1) << N);
+ return X < (UINT64_C(1) << (N));
+}
+template <unsigned N>
+constexpr inline std::enable_if_t<N >= 64, bool> isUInt(uint64_t) {
+ return true;
}
// Template specializations to get better code for common cases.

MODIFY
src/isa/isainfo.h
src/isa/isainfo.h
@@ -29,8 +29,10 @@ public:
virtual QString regAlias(unsigned i) const = 0;
virtual QString regInfo(unsigned i) const = 0;
virtual bool regIsReadOnly(unsigned i) const = 0;
- virtual unsigned bits() const = 0;
- unsigned bytes() const { return bits() / CHAR_BIT; }
+ virtual unsigned bits() const = 0; // Register width, in bits
+ unsigned bytes() const { return bits() / CHAR_BIT; } // Register width, in bytes
+ virtual unsigned instrBits() const = 0; // Instruction width, in bits
+ unsigned instrBytes() const { return instrBits() / CHAR_BIT; } // Instruction width, in bytes
virtual int spReg() const { return -1; } // Stack pointer
virtual int gpReg() const { return -1; } // Global pointer
virtual int syscallReg() const { return -1; } // Syscall function register

MODIFY
src/isa/rv32isainfo.h
src/isa/rv32isainfo.h
namespace Ripes {
template <>
-class ISAInfo<ISA::RV32I> : public ISAInfoBase {
+class ISAInfo<ISA::RV32I> : public RVISAInfoBase {
public:
ISAInfo<ISA::RV32I>(const QStringList extensions) {
// Validate extensions
@@ -22,35 +22,8 @@ public:
QString name() const override { return "RV32I"; }
ISA isaID() const override { return ISA::RV32I; }
- unsigned int regCnt() const override { return 32; }
- QString regName(unsigned i) const override {
- return RVISA::RegNames.size() > static_cast<int>(i) ? RVISA::RegNames.at(static_cast<int>(i)) : QString();
- }
- QString regAlias(unsigned i) const override {
- return RVISA::RegAliases.size() > static_cast<int>(i) ? RVISA::RegAliases.at(static_cast<int>(i)) : QString();
- }
- QString regInfo(unsigned i) const override {
- return RVISA::RegDescs.size() > static_cast<int>(i) ? RVISA::RegDescs.at(static_cast<int>(i)) : QString();
- }
- bool regIsReadOnly(unsigned i) const override { return i == 0; }
unsigned int bits() const override { return 32; }
- int spReg() const override { return 2; }
- int gpReg() const override { return 3; }
- int syscallReg() const override { return 17; }
unsigned elfMachineId() const override { return EM_RISCV; }
- unsigned int regNumber(const QString& reg, bool& success) const override {
- QString regRes = reg;
- success = true;
- if (reg[0] == 'x' && (RVISA::RegNames.count(reg) != 0)) {
- regRes.remove('x');
- return regRes.toInt(&success, 10);
- } else if (RVISA::RegAliases.contains(reg)) {
- return RVISA::RegAliases.indexOf(reg);
- }
- success = false;
- return 0;
- }
-
QString CCmarch() const override {
QString march = "rv32i";
@@ -64,28 +37,6 @@ public:
return march;
}
QString CCmabi() const override { return "ilp32"; }
-
- QString elfSupportsFlags(unsigned flags) const override {
- /** We expect no flags for RV32IM compiled RISC-V executables.
- * Refer to: https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#-elf-object-files
- */
- if (flags == 0)
- return QString();
- QString err;
- for (const auto& flag : RVABI::ELFFlagStrings) {
- if (flags & flag.first) {
- err += "ELF flag '" + RVABI::ELFFlagStrings.at(flag.first) + "' unsupported<br/>";
- }
- }
- return err;
- }
-
- const QStringList& supportedExtensions() const override { return m_supportedExtensions; }
- const QStringList& enabledExtensions() const override { return m_enabledExtensions; }
-
-private:
- QStringList m_enabledExtensions;
- QStringList m_supportedExtensions = {"M"};
};
} // namespace Ripes

MODIFY
src/isa/rv64isainfo.h
src/isa/rv64isainfo.h
namespace Ripes {
template <>
-class ISAInfo<ISA::RV64I> : public ISAInfoBase {
+class ISAInfo<ISA::RV64I> : public RVISAInfoBase {
public:
ISAInfo<ISA::RV64I>(const QStringList extensions) {
// Validate extensions
@@ -22,35 +22,7 @@ public:
QString name() const override { return "RV64I"; }
ISA isaID() const override { return ISA::RV64I; }
- unsigned int regCnt() const override { return 32; }
- QString regName(unsigned i) const override {
- return RVISA::RegNames.size() > static_cast<int>(i) ? RVISA::RegNames.at(static_cast<int>(i)) : QString();
- }
- QString regAlias(unsigned i) const override {
- return RVISA::RegAliases.size() > static_cast<int>(i) ? RVISA::RegAliases.at(static_cast<int>(i)) : QString();
- }
- QString regInfo(unsigned i) const override {
- return RVISA::RegDescs.size() > static_cast<int>(i) ? RVISA::RegDescs.at(static_cast<int>(i)) : QString();
- }
- bool regIsReadOnly(unsigned i) const override { return i == 0; }
unsigned int bits() const override { return 64; }
- int spReg() const override { return 2; }
- int gpReg() const override { return 3; }
- int syscallReg() const override { return 17; }
- unsigned elfMachineId() const override { return EM_RISCV; }
- unsigned int regNumber(const QString& reg, bool& success) const override {
- QString regRes = reg;
- success = true;
- if (reg[0] == 'x' && (RVISA::RegNames.count(reg) != 0)) {
- regRes.remove('x');
- return regRes.toInt(&success, 10);
- } else if (RVISA::RegAliases.contains(reg)) {
- return RVISA::RegAliases.indexOf(reg);
- }
- success = false;
- return 0;
- }
-
QString CCmarch() const override {
QString march = "rv64i";
@@ -64,28 +36,6 @@ public:
return march;
}
QString CCmabi() const override { return "lp64"; }
-
- QString elfSupportsFlags(unsigned flags) const override {
- /** We expect no flags for RV32IM compiled RISC-V executables.
- * Refer to: https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#-elf-object-files
- */
- if (flags == 0)
- return QString();
- QString err;
- for (const auto& flag : RVABI::ELFFlagStrings) {
- if (flags & flag.first) {
- err += "ELF flag '" + RVABI::ELFFlagStrings.at(flag.first) + "' unsupported<br/>";
- }
- }
- return err;
- }
-
- const QStringList& supportedExtensions() const override { return m_supportedExtensions; }
- const QStringList& enabledExtensions() const override { return m_enabledExtensions; }
-
-private:
- QStringList m_enabledExtensions;
- QStringList m_supportedExtensions = {"M"};
};
} // namespace Ripes

MODIFY
src/isa/rvisainfo_common.h
src/isa/rvisainfo_common.h
@@ -57,4 +57,59 @@ enum SysCall {
};
} // namespace RVABI
+
+class RVISAInfoBase : public ISAInfoBase {
+public:
+ unsigned int regCnt() const override { return 32; }
+ QString regName(unsigned i) const override {
+ return RVISA::RegNames.size() > static_cast<int>(i) ? RVISA::RegNames.at(static_cast<int>(i)) : QString();
+ }
+ QString regAlias(unsigned i) const override {
+ return RVISA::RegAliases.size() > static_cast<int>(i) ? RVISA::RegAliases.at(static_cast<int>(i)) : QString();
+ }
+ QString regInfo(unsigned i) const override {
+ return RVISA::RegDescs.size() > static_cast<int>(i) ? RVISA::RegDescs.at(static_cast<int>(i)) : QString();
+ }
+ bool regIsReadOnly(unsigned i) const override { return i == 0; }
+ int spReg() const override { return 2; }
+ int gpReg() const override { return 3; }
+ int syscallReg() const override { return 17; }
+ unsigned instrBits() const override { return 32; }
+ unsigned elfMachineId() const override { return EM_RISCV; }
+ unsigned int regNumber(const QString& reg, bool& success) const override {
+ QString regRes = reg;
+ success = true;
+ if (reg[0] == 'x' && (RVISA::RegNames.count(reg) != 0)) {
+ regRes.remove('x');
+ return regRes.toInt(&success, 10);
+ } else if (RVISA::RegAliases.contains(reg)) {
+ return RVISA::RegAliases.indexOf(reg);
+ }
+ success = false;
+ return 0;
+ }
+
+ QString elfSupportsFlags(unsigned flags) const override {
+ /** We expect no flags for RV32IM compiled RISC-V executables.
+ * Refer to: https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#-elf-object-files
+ */
+ if (flags == 0)
+ return QString();
+ QString err;
+ for (const auto& flag : RVABI::ELFFlagStrings) {
+ if (flags & flag.first) {
+ err += "ELF flag '" + RVABI::ELFFlagStrings.at(flag.first) + "' unsupported<br/>";
+ }
+ }
+ return err;
+ }
+
+ const QStringList& supportedExtensions() const override { return m_supportedExtensions; }
+ const QStringList& enabledExtensions() const override { return m_enabledExtensions; }
+
+protected:
+ QStringList m_enabledExtensions;
+ QStringList m_supportedExtensions = {"M"};
+};
+
} // namespace Ripes

Factor out shared logic between RV32 and RV64 ISA info