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) {
|
||||
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);
|
||||
|
||||
std::vector<uint8_t> mem =
|
||||
|
|
24
src/vm.cpp
24
src/vm.cpp
|
@ -199,8 +199,8 @@ void VM::step() {
|
|||
} else if (funct3 == 0x02) { // SLT
|
||||
setreg(rd, (static_cast<int32_t>(registers[rs1]) <
|
||||
static_cast<int32_t>(registers[rs2]))
|
||||
? 0
|
||||
: 1);
|
||||
? 1
|
||||
: 0);
|
||||
} else if (funct3 == 0x03) { // SLTU
|
||||
setreg(rd, (registers[rs1] < registers[rs2]) ? 1 : 0);
|
||||
} else {
|
||||
|
@ -294,7 +294,7 @@ void VM::step() {
|
|||
}
|
||||
} else if (funct3 == 0x05) {
|
||||
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;
|
||||
setreg(rd, value >> shift_amount);
|
||||
} else if (((imm >> 5) & 0x7f) == 0x0) { // SRLI
|
||||
|
@ -307,8 +307,8 @@ void VM::step() {
|
|||
} else if (funct3 == 0x02) { // SLTI
|
||||
setreg(rd, (static_cast<int32_t>(registers[rs1]) <
|
||||
static_cast<int32_t>(imm))
|
||||
? 0
|
||||
: 1);
|
||||
? 1
|
||||
: 0);
|
||||
} else if (funct3 == 0x03) { // SLTIU
|
||||
setreg(rd, (registers[rs1] < static_cast<uint32_t>(imm)) ? 1 : 0);
|
||||
} else {
|
||||
|
@ -353,10 +353,10 @@ void VM::step() {
|
|||
imm = sign_extend(instr >> 20, 12); // Extract 12-bit immediate
|
||||
if (funct3 == 0x00) { // LB
|
||||
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
|
||||
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
|
||||
uint32_t addr = registers[rs1] + imm;
|
||||
setreg(rd, read_memory_word(addr));
|
||||
|
@ -401,7 +401,8 @@ void VM::step() {
|
|||
break;
|
||||
}
|
||||
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 =
|
||||
(registers[rs1] + offset) & ~1; // Target address (LSB cleared)
|
||||
|
||||
|
@ -423,10 +424,15 @@ void VM::step() {
|
|||
// the current PC
|
||||
break;
|
||||
}
|
||||
case 0x73: { // EBREAK
|
||||
case 0x73: {
|
||||
imm = sign_extend(instr >> 20, 12); // Extract 12-bit immediate
|
||||
if (funct3 == 0x0 && imm == 0x1) { // EBREAK
|
||||
pc -= 4;
|
||||
throw EbreakException();
|
||||
break;
|
||||
} else {
|
||||
throw std::runtime_error("Unknown opcode");
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error("Unknown opcode");
|
||||
|
|
|
@ -4,6 +4,7 @@ hart0:
|
|||
physical_addr_sz: 32
|
||||
User_Spec_Version: '2.3'
|
||||
supported_xlen: [32]
|
||||
hw_data_misaligned_support: false
|
||||
misa:
|
||||
# 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
|
||||
|
|
Loading…
Reference in a new issue