Add support for RV32M expansion
MODIFY
src/pipeline.cpp
src/pipeline.cpp
@@ -288,6 +288,51 @@ void Pipeline::controlGen() {
case 0b0110011: {
// R-type
auto fields = Parser::getParser()->decodeRInstr((uint32_t)r_instr_IFID);
+ if(fields[0] == 0b1){
+ // RV32M Standard extension
+ switch(fields[3]){
+ case 0b000: {
+ // mul
+ s_ALUOP = ALUOps::MUL;
+ break;
+ }
+ case 0b001: {
+ // mulh
+ s_ALUOP = ALUOps::MULH;
+ break;
+ }
+ case 0b010: {
+ // mulhsu
+ s_ALUOP = ALUOps::MULHSU;
+ break;
+ }
+ case 0b011: {
+ // mulhu
+ s_ALUOP = ALUOps::MULHU;
+ break;
+ }
+ case 0b100: {
+ // div
+ s_ALUOP = ALUOps::DIV;
+ break;
+ }
+ case 0b101: {
+ // divu
+ s_ALUOP = ALUOps::DIVU;
+ break;
+ }
+ case 0b110: {
+ // rem
+ s_ALUOP = ALUOps::REM;
+ break;
+ }
+ case 0b111: {
+ // remu
+ s_ALUOP = ALUOps::REMU;
+ break;
+ }
+ }
+ } else {
switch (fields[3]) {
case 0b000: {
switch (fields[0]) {
@@ -350,6 +395,7 @@ void Pipeline::controlGen() {
break;
}
}
+ }
s_RegWrite = 1;
break;
}

MODIFY
src/pipelineobjects.h
src/pipelineobjects.h
@@ -284,7 +284,13 @@ enum OPCODE {
LUI = 10,
LT = 11,
LTU = 12,
- EQ = 13
+ EQ = 13,
+ MULH = 14,
+ MULHU = 15,
+ MULHSU = 16,
+ DIVU = 17,
+ REM = 18,
+ REMU = 19
};
} // namespace ALUOps
@@ -324,7 +330,7 @@ template <int n>
void ALU<n>::update() {
if (!initialized())
throw std::runtime_error("Mux not initialized");
- switch ((ALUOps::OPCODE)(int)*m_control) {
+ switch ((ALUOps::OPCODE)(uint32_t)*m_control) {
case ALUOps::ADD:
m_output = (uint32_t)*m_op1 + (uint32_t)*m_op2;
break;
@@ -332,11 +338,38 @@ void ALU<n>::update() {
m_output = (uint32_t)*m_op1 - (uint32_t)*m_op2;
break;
case ALUOps::MUL:
- m_output = (uint32_t)*m_op1 * (uint32_t)*m_op2;
+ m_output = (int)*m_op1 * (int)*m_op2;
break;
+ case ALUOps::MULH:
+ {
+ int64_t res = (int)*m_op1 * (int)*m_op2;
+ m_output = static_cast<uint32_t>(res >> 32);
+ break;
+ }
+ case ALUOps::MULHU:
+ {
+ int64_t res = (uint32_t)*m_op1 * (uint32_t)*m_op2;
+ m_output = static_cast<uint32_t>(res >> 32);
+ break;
+ }
+ case ALUOps::MULHSU:
+ {
+ int64_t res = (int)*m_op1 * (uint32_t)*m_op2;
+ m_output = static_cast<uint32_t>(res >> 32);
+ break;
+ }
case ALUOps::DIV:
+ m_output = (int)*m_op1 / (int)*m_op2;
+ break;
+ case ALUOps::DIVU:
m_output = (uint32_t)*m_op1 / (uint32_t)*m_op2;
break;
+ case ALUOps::REM:
+ m_output = (int)*m_op1 % (int)*m_op2;
+ break;
+ case ALUOps::REMU:
+ m_output = (uint32_t)*m_op1 % (uint32_t)*m_op2;
+ break;
case ALUOps::AND:
m_output = (uint32_t)*m_op1 & (uint32_t)*m_op2;
break;

MODIFY
src/syntaxhighlighter.cpp
src/syntaxhighlighter.cpp
@@ -180,7 +180,18 @@ SyntaxHighlighter::SyntaxHighlighter(QTextDocument* parent) : QSyntaxHighlighter
<< "\\band\\b"
<< "\\bandi\\b"
<< "\\badd\\b"
- << "\\becall\\b";
+ << "\\becall\\b"
+
+ << "\\bmul\\b"
+ << "\\bmulh\\b"
+ << "\\bmulhu\\b"
+ << "\\bmulhsu\\b"
+
+ << "\\bdiv\\b"
+ << "\\bdivu\\b"
+ << "\\brem\\b"
+ << "\\bremu\\b";
+
instrFormat.setForeground(QColor(Colors::BerkeleyBlue));
for (const auto& pattern : instructionPatterns) {
rule.pattern = QRegularExpression(pattern);
@@ -466,7 +477,15 @@ void SyntaxHighlighter::createSyntaxRules() {
<< "srl"
<< "sra"
<< "or"
- << "and";
+ << "and"
+ << "mul"
+ << "mulh"
+ << "mulhu"
+ << "mulhsu"
+ << "rem"
+ << "remu"
+ << "div"
+ << "divu";
for (const auto& name : names) {
rule.instr = name;
rule.fields = 4;

Add support for RV32M expansion