Make (preliminary) symbols available to pseudo instruction expanders
MODIFY
src/assembler/assembler.h
src/assembler/assembler.h
@@ -600,7 +600,7 @@ protected:
// Not a pseudo instruction
return PseudoExpandRes(std::nullopt);
}
- auto res = m_pseudoInstructionMap.at(opcode)->expand(line);
+ auto res = m_pseudoInstructionMap.at(opcode)->expand(line, m_symbolMap);
if (auto* error = std::get_if<Error>(&res)) {
if (m_instructionMap.count(opcode) != 0) {
// If this pseudo-instruction aliases with an instruction but threw an error (could arise if ie.

MODIFY
src/assembler/pseudoinstruction.h
src/assembler/pseudoinstruction.h
namespace Ripes {
namespace Assembler {
+class PseudoInstruction;
+
+using PseudoExpandFunc = std::function<PseudoExpandRes(const PseudoInstruction& /*this*/,
+ const Assembler::TokenizedSrcLine&, const SymbolMap&)>;
+
class PseudoInstruction {
public:
- PseudoInstruction(
- const QString& opcode, const std::vector<std::shared_ptr<Field>>& fields,
- const std::function<PseudoExpandRes(const PseudoInstruction&, const Assembler::TokenizedSrcLine&)>& expander)
+ PseudoInstruction(const QString& opcode, const std::vector<std::shared_ptr<Field>>& fields,
+ const PseudoExpandFunc& expander)
: m_opcode(opcode), m_expectedTokens(1 /*opcode*/ + fields.size()), m_fields(fields), m_expander(expander) {}
- PseudoExpandRes expand(const Assembler::TokenizedSrcLine& line) {
+ PseudoExpandRes expand(const Assembler::TokenizedSrcLine& line, const SymbolMap& symbols) {
if (line.tokens.length() != m_expectedTokens) {
- return Assembler::Error(
- line.sourceLine, "Instruction '" + m_opcode + "' expects " + QString::number(m_expectedTokens - 1) +
+ return Assembler::Error(line.sourceLine,
+ "Instruction '" + m_opcode + "' expects " + QString::number(m_expectedTokens - 1) +
" arguments, but got " + QString::number(line.tokens.length() - 1));
}
- return m_expander(*this, line);
+ return m_expander(*this, line, symbols);
}
const QString& name() const { return m_opcode; }
@@ -34,13 +38,16 @@ public:
static std::shared_ptr<Imm> imm() { return std::make_shared<Imm>(0, 0, Imm::Repr::Hex, std::vector<ImmPart>{}); }
private:
- std::function<PseudoExpandRes(const PseudoInstruction& /*this*/, const Assembler::TokenizedSrcLine&)> m_expander;
+ PseudoExpandFunc m_expander;
const QString m_opcode;
const int m_expectedTokens;
const std::vector<std::shared_ptr<Field>> m_fields;
};
+#define PseudoExpandFunc(line, symbols) \
+ [](const PseudoInstruction&, const TokenizedSrcLine& line, const SymbolMap& symbols)
+
using PseudoInstrVec = std::vector<std::shared_ptr<PseudoInstruction>>;
using PseudoInstrMap = std::map<QString, std::shared_ptr<PseudoInstruction>>;

MODIFY
src/assembler/rv32i_assembler.cpp
src/assembler/rv32i_assembler.cpp
@@ -102,11 +102,12 @@ RV32I_Assembler::initInstructions(const ISAInfo<ISA::RV32I>* isa) const {
#define RegTok PseudoInstruction::reg()
#define ImmTok PseudoInstruction::imm()
#define CreatePseudoInstruction
-#define PseudoExpandFunc(line) [](const PseudoInstruction&, const TokenizedSrcLine& line)
+#define PseudoExpandFunc(line, symbols) \
+ [](const PseudoInstruction&, const TokenizedSrcLine& line, const SymbolMap& symbols)
#define PseudoLoad(name) \
std::shared_ptr<PseudoInstruction>(new PseudoInstruction( \
- name, {RegTok, ImmTok}, PseudoExpandFunc(line) { \
+ name, {RegTok, ImmTok}, PseudoExpandFunc(line, symbols) { \
LineTokensVec v; \
v.push_back(QStringList() << "auipc" << line.tokens.at(1) << line.tokens.at(2)); \
v.push_back(QStringList() << name << line.tokens.at(1) \
@@ -119,7 +120,7 @@ RV32I_Assembler::initInstructions(const ISAInfo<ISA::RV32I>* isa) const {
// a number has been provided, then abort the pseudo-op handling.
#define PseudoStore(name) \
std::shared_ptr<PseudoInstruction>(new PseudoInstruction( \
- name, {RegTok, ImmTok, RegTok}, PseudoExpandFunc(line) { \
+ name, {RegTok, ImmTok, RegTok}, PseudoExpandFunc(line, symbols) { \
bool canConvert; \
getImmediate(line.tokens.at(2), canConvert); \
if (canConvert) { \
@@ -145,51 +146,51 @@ void RV32I_Assembler::enableExtI(const ISAInfo<ISA::RV32I>* isa, InstrVec& instr
// clang-format off
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(new PseudoInstruction(
- "la", {RegTok, ImmTok}, PseudoExpandFunc(line) {
+ "la", {RegTok, ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList() << "auipc" << line.tokens.at(1) << line.tokens.at(2),
QStringList() << "addi" << line.tokens.at(1) << line.tokens.at(1) << QString("((%1&0xfff)-(__address__-4))").arg(line.tokens.at(2))};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(new PseudoInstruction(
- "call", {RegTok, ImmTok}, PseudoExpandFunc(line) {
+ "call", {RegTok, ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{LineTokens() << "auipc" << "x6" << line.tokens.at(1),
LineTokens() << "jalr" << "x1" << "x6" << line.tokens.at(1)};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(new PseudoInstruction(
- "tail", {RegTok, ImmTok}, PseudoExpandFunc(line) {
+ "tail", {RegTok, ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList() << "auipc" << "x6" << line.tokens.at(1),
QStringList() << "jalr" << "x0" << "x6" << line.tokens.at(1)};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(new PseudoInstruction(
- "j", {ImmTok}, PseudoExpandFunc(line) {
+ "j", {ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList() << "jal" << "x0" << line.tokens.at(1)};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(new PseudoInstruction(
- "jr", {RegTok}, PseudoExpandFunc(line) {
+ "jr", {RegTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList() << "jalr" << "x0" << line.tokens.at(1) << "0"};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(new PseudoInstruction(
- "jalr", {RegTok}, PseudoExpandFunc(line) {
+ "jalr", {RegTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList() << "jalr" << "x1" << line.tokens.at(1) << "0"};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(new PseudoInstruction(
- "ret", {}, [](const PseudoInstruction&, const TokenizedSrcLine&) {
+ "ret", {}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList() << "jalr" << "x0" << "x1" << "0"};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(new PseudoInstruction(
- "jal", {ImmTok}, PseudoExpandFunc(line) {
+ "jal", {ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList() << "jal" << "x1" << line.tokens.at(1)};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(new PseudoInstruction(
"li", {RegTok, ImmTok},
- PseudoExpandFunc(line) {
+ PseudoExpandFunc(line, symbols) {
LineTokensVec v;
// Determine whether an ADDI or LUI instruction is sufficient, or if both LUI and ADDI is needed, by
// analysing the immediate size
@@ -218,92 +219,92 @@ void RV32I_Assembler::enableExtI(const ISAInfo<ISA::RV32I>* isa, InstrVec& instr
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("nop", {}, [](const PseudoInstruction&, const TokenizedSrcLine&) {
+ new PseudoInstruction("nop", {}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QString("addi x0 x0 0").split(' ')};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(new PseudoInstruction(
- "mv", {RegTok, RegTok}, PseudoExpandFunc(line) {
+ "mv", {RegTok, RegTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"addi", line.tokens.at(1), line.tokens.at(2), "0"}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("not", {RegTok, RegTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("not", {RegTok, RegTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"xori", line.tokens.at(1), line.tokens.at(2), "-1"}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("neg", {RegTok, RegTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("neg", {RegTok, RegTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"sub", line.tokens.at(1), "x0", line.tokens.at(2)}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("seqz", {RegTok, RegTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("seqz", {RegTok, RegTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"sltiu", line.tokens.at(1), line.tokens.at(2), "1"}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("snez", {RegTok, RegTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("snez", {RegTok, RegTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{ QStringList{"sltu", line.tokens.at(1), "x0", line.tokens.at(2)}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("sltz", {RegTok, RegTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("sltz", {RegTok, RegTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"slt", line.tokens.at(1), line.tokens.at(2), "x0"}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("sgtz", {RegTok, RegTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("sgtz", {RegTok, RegTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"slt", line.tokens.at(1), "x0", line.tokens.at(2)}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("beqz", {RegTok, ImmTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("beqz", {RegTok, ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"beq", line.tokens.at(1), "x0", line.tokens.at(2)}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("bnez", {RegTok, ImmTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("bnez", {RegTok, ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"bne", line.tokens.at(1), "x0", line.tokens.at(2)}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("blez", {RegTok, ImmTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("blez", {RegTok, ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"bge", "x0", line.tokens.at(1), line.tokens.at(2)}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("bgez", {RegTok, ImmTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("bgez", {RegTok, ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"bge", line.tokens.at(1), "x0", line.tokens.at(2)}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("bltz", {RegTok, ImmTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("bltz", {RegTok, ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"blt", line.tokens.at(1), "x0", line.tokens.at(2)}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("bgtz", {RegTok, ImmTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("bgtz", {RegTok, ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"blt", "x0", line.tokens.at(1), line.tokens.at(2)}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("bgt", {RegTok, RegTok, ImmTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("bgt", {RegTok, RegTok, ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"blt", line.tokens.at(2), line.tokens.at(1), line.tokens.at(3)}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("ble", {RegTok, RegTok, ImmTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("ble", {RegTok, RegTok, ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"bge", line.tokens.at(2), line.tokens.at(1), line.tokens.at(3)}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("bgtu", {RegTok, RegTok, ImmTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("bgtu", {RegTok, RegTok, ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"bltu", line.tokens.at(2), line.tokens.at(2), line.tokens.at(3)}};
})));
pseudoInstructions.push_back(std::shared_ptr<PseudoInstruction>(
- new PseudoInstruction("bleu", {RegTok, RegTok, ImmTok}, PseudoExpandFunc(line) {
+ new PseudoInstruction("bleu", {RegTok, RegTok, ImmTok}, PseudoExpandFunc(line, symbols) {
return LineTokensVec{QStringList{"bgeu", line.tokens.at(2), line.tokens.at(2), line.tokens.at(3)}};
})));
// clang-format on

Make (preliminary) symbols available to pseudo instruction expanders