Fix bugs in all base instructions and make RISCOF tests pass
This commit is contained in:
parent
40179ed237
commit
3888a0d65a
3 changed files with 21 additions and 14 deletions
|
@ -58,7 +58,7 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signature_filename.size() > 0) {
|
if (signature_filename.size() > 0) {
|
||||||
uint32_t signature_begin = std::get<0>(signature) + 4;
|
uint32_t signature_begin = std::get<0>(signature);
|
||||||
uint32_t signature_end = std::get<1>(signature);
|
uint32_t signature_end = std::get<1>(signature);
|
||||||
|
|
||||||
std::vector<uint8_t> mem =
|
std::vector<uint8_t> mem =
|
||||||
|
|
32
src/vm.cpp
32
src/vm.cpp
|
@ -199,8 +199,8 @@ void VM::step() {
|
||||||
} else if (funct3 == 0x02) { // SLT
|
} else if (funct3 == 0x02) { // SLT
|
||||||
setreg(rd, (static_cast<int32_t>(registers[rs1]) <
|
setreg(rd, (static_cast<int32_t>(registers[rs1]) <
|
||||||
static_cast<int32_t>(registers[rs2]))
|
static_cast<int32_t>(registers[rs2]))
|
||||||
? 0
|
? 1
|
||||||
: 1);
|
: 0);
|
||||||
} else if (funct3 == 0x03) { // SLTU
|
} else if (funct3 == 0x03) { // SLTU
|
||||||
setreg(rd, (registers[rs1] < registers[rs2]) ? 1 : 0);
|
setreg(rd, (registers[rs1] < registers[rs2]) ? 1 : 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -294,7 +294,7 @@ void VM::step() {
|
||||||
}
|
}
|
||||||
} else if (funct3 == 0x05) {
|
} else if (funct3 == 0x05) {
|
||||||
if (((imm >> 5) & 0x7f) == 0x20) { // SRAI
|
if (((imm >> 5) & 0x7f) == 0x20) { // SRAI
|
||||||
int32_t value = static_cast<int32_t>(imm & 0x1f);
|
int32_t value = registers[rs1];
|
||||||
int32_t shift_amount = imm & 0x1F;
|
int32_t shift_amount = imm & 0x1F;
|
||||||
setreg(rd, value >> shift_amount);
|
setreg(rd, value >> shift_amount);
|
||||||
} else if (((imm >> 5) & 0x7f) == 0x0) { // SRLI
|
} else if (((imm >> 5) & 0x7f) == 0x0) { // SRLI
|
||||||
|
@ -307,8 +307,8 @@ void VM::step() {
|
||||||
} else if (funct3 == 0x02) { // SLTI
|
} else if (funct3 == 0x02) { // SLTI
|
||||||
setreg(rd, (static_cast<int32_t>(registers[rs1]) <
|
setreg(rd, (static_cast<int32_t>(registers[rs1]) <
|
||||||
static_cast<int32_t>(imm))
|
static_cast<int32_t>(imm))
|
||||||
? 0
|
? 1
|
||||||
: 1);
|
: 0);
|
||||||
} else if (funct3 == 0x03) { // SLTIU
|
} else if (funct3 == 0x03) { // SLTIU
|
||||||
setreg(rd, (registers[rs1] < static_cast<uint32_t>(imm)) ? 1 : 0);
|
setreg(rd, (registers[rs1] < static_cast<uint32_t>(imm)) ? 1 : 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -353,10 +353,10 @@ void VM::step() {
|
||||||
imm = sign_extend(instr >> 20, 12); // Extract 12-bit immediate
|
imm = sign_extend(instr >> 20, 12); // Extract 12-bit immediate
|
||||||
if (funct3 == 0x00) { // LB
|
if (funct3 == 0x00) { // LB
|
||||||
uint32_t addr = registers[rs1] + imm;
|
uint32_t addr = registers[rs1] + imm;
|
||||||
setreg(rd, read_memory_byte(addr));
|
setreg(rd, sign_extend(read_memory_byte(addr), 8));
|
||||||
} else if (funct3 == 0x01) { // LH
|
} else if (funct3 == 0x01) { // LH
|
||||||
uint32_t addr = registers[rs1] + imm;
|
uint32_t addr = registers[rs1] + imm;
|
||||||
setreg(rd, read_memory_half_word(addr));
|
setreg(rd, sign_extend(read_memory_half_word(addr), 16));
|
||||||
} else if (funct3 == 0x2) { // LW
|
} else if (funct3 == 0x2) { // LW
|
||||||
uint32_t addr = registers[rs1] + imm;
|
uint32_t addr = registers[rs1] + imm;
|
||||||
setreg(rd, read_memory_word(addr));
|
setreg(rd, read_memory_word(addr));
|
||||||
|
@ -400,8 +400,9 @@ void VM::step() {
|
||||||
pc += offset - 4;
|
pc += offset - 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x67: { // JALR
|
case 0x67: { // JALR
|
||||||
int32_t offset = (instr >> 20); // Sign-extended 12-bit immediate
|
int32_t offset =
|
||||||
|
sign_extend(instr >> 20, 12); // Sign-extended 12-bit immediate
|
||||||
uint32_t target =
|
uint32_t target =
|
||||||
(registers[rs1] + offset) & ~1; // Target address (LSB cleared)
|
(registers[rs1] + offset) & ~1; // Target address (LSB cleared)
|
||||||
|
|
||||||
|
@ -423,10 +424,15 @@ void VM::step() {
|
||||||
// the current PC
|
// the current PC
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x73: { // EBREAK
|
case 0x73: {
|
||||||
pc -= 4;
|
imm = sign_extend(instr >> 20, 12); // Extract 12-bit immediate
|
||||||
throw EbreakException();
|
if (funct3 == 0x0 && imm == 0x1) { // EBREAK
|
||||||
break;
|
pc -= 4;
|
||||||
|
throw EbreakException();
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("Unknown opcode");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Unknown opcode");
|
throw std::runtime_error("Unknown opcode");
|
||||||
|
|
|
@ -4,6 +4,7 @@ hart0:
|
||||||
physical_addr_sz: 32
|
physical_addr_sz: 32
|
||||||
User_Spec_Version: '2.3'
|
User_Spec_Version: '2.3'
|
||||||
supported_xlen: [32]
|
supported_xlen: [32]
|
||||||
|
hw_data_misaligned_support: false
|
||||||
misa:
|
misa:
|
||||||
# reset-val encodes the CPU capabilities in a special register,
|
# reset-val encodes the CPU capabilities in a special register,
|
||||||
# as specified in https://five-embeddev.com/riscv-priv-isa-manual/Priv-v1.12/machine.html
|
# as specified in https://five-embeddev.com/riscv-priv-isa-manual/Priv-v1.12/machine.html
|
||||||
|
|
Loading…
Reference in a new issue