Fix branch signextend + offset

master
vhaudiquet 1 year ago
parent 24ca9532d4
commit 57dfd9cb76
  1. 17
      src/cpu/rv32cpu.c

@ -150,7 +150,7 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
{
// Branches ; to know which one, we must analyse func3
// Sign extend immediate from 13 bits to 32 bits
uint32_t immediate = (instruction->immediate & 0xFFF) | (instruction->immediate & 0x1000 ? 0xFFFFE000 : 0);
uint32_t immediate = (instruction->immediate & 0x1FFF) | (instruction->immediate & 0x1000 ? 0xFFFFE000 : 0);
immediate -= 4;
switch(instruction->func3)
@ -158,32 +158,32 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
case FUNC3_BEQ:
// Branch EQual
if(cpu->regs.x[instruction->rs1] == cpu->regs.x[instruction->rs2])
cpu->pc = immediate;
cpu->pc += immediate;
break;
case FUNC3_BNE:
// Branch Not Equal
if(cpu->regs.x[instruction->rs1] != cpu->regs.x[instruction->rs2])
cpu->pc = immediate;
cpu->pc += immediate;
break;
case FUNC3_BLT:
// Branch Less Than
if(((int32_t) cpu->regs.x[instruction->rs1]) < ((int32_t) cpu->regs.x[instruction->rs2]))
cpu->pc = immediate;
cpu->pc += immediate;
break;
case FUNC3_BLTU:
// Branch Less Than Unsigned
if(cpu->regs.x[instruction->rs1] < cpu->regs.x[instruction->rs2])
cpu->pc = immediate;
cpu->pc += immediate;
break;
case FUNC3_BGE:
// Branch Greater Equal
if(((int32_t) cpu->regs.x[instruction->rs1]) >= ((int32_t) cpu->regs.x[instruction->rs2]))
cpu->pc = immediate;
cpu->pc += immediate;
break;
case FUNC3_BGEU:
// Branch Greater Equal Unsigned
if(cpu->regs.x[instruction->rs1] >= cpu->regs.x[instruction->rs2])
cpu->pc = immediate;
cpu->pc += immediate;
break;
default:
fprintf(stderr, "FATAL: Unknown func3 0x%x for branch instruction, could not execute\n", instruction->func3);
@ -621,8 +621,7 @@ static void cpu_print_instruction(instruction_t* instruction)
{
// Branches ; to know which one, we must analyse func3
// Sign extend immediate from 13 bits to 32 bits
uint32_t immediate = (instruction->immediate & 0xFFF) | (instruction->immediate & 0x1000 ? 0xFFFFE000 : 0);
immediate -= 4;
uint32_t immediate = (instruction->immediate & 0x1FFF) | (instruction->immediate & 0x1000 ? 0xFFFFE000 : 0);
switch(instruction->func3)
{

Loading…
Cancel
Save