Fix branch signextend + offset
This commit is contained in:
parent
24ca9532d4
commit
57dfd9cb76
@ -150,7 +150,7 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
|
|||||||
{
|
{
|
||||||
// Branches ; to know which one, we must analyse func3
|
// Branches ; to know which one, we must analyse func3
|
||||||
// Sign extend immediate from 13 bits to 32 bits
|
// 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;
|
immediate -= 4;
|
||||||
|
|
||||||
switch(instruction->func3)
|
switch(instruction->func3)
|
||||||
@ -158,32 +158,32 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
|
|||||||
case FUNC3_BEQ:
|
case FUNC3_BEQ:
|
||||||
// Branch EQual
|
// Branch EQual
|
||||||
if(cpu->regs.x[instruction->rs1] == cpu->regs.x[instruction->rs2])
|
if(cpu->regs.x[instruction->rs1] == cpu->regs.x[instruction->rs2])
|
||||||
cpu->pc = immediate;
|
cpu->pc += immediate;
|
||||||
break;
|
break;
|
||||||
case FUNC3_BNE:
|
case FUNC3_BNE:
|
||||||
// Branch Not Equal
|
// Branch Not Equal
|
||||||
if(cpu->regs.x[instruction->rs1] != cpu->regs.x[instruction->rs2])
|
if(cpu->regs.x[instruction->rs1] != cpu->regs.x[instruction->rs2])
|
||||||
cpu->pc = immediate;
|
cpu->pc += immediate;
|
||||||
break;
|
break;
|
||||||
case FUNC3_BLT:
|
case FUNC3_BLT:
|
||||||
// Branch Less Than
|
// Branch Less Than
|
||||||
if(((int32_t) cpu->regs.x[instruction->rs1]) < ((int32_t) cpu->regs.x[instruction->rs2]))
|
if(((int32_t) cpu->regs.x[instruction->rs1]) < ((int32_t) cpu->regs.x[instruction->rs2]))
|
||||||
cpu->pc = immediate;
|
cpu->pc += immediate;
|
||||||
break;
|
break;
|
||||||
case FUNC3_BLTU:
|
case FUNC3_BLTU:
|
||||||
// Branch Less Than Unsigned
|
// Branch Less Than Unsigned
|
||||||
if(cpu->regs.x[instruction->rs1] < cpu->regs.x[instruction->rs2])
|
if(cpu->regs.x[instruction->rs1] < cpu->regs.x[instruction->rs2])
|
||||||
cpu->pc = immediate;
|
cpu->pc += immediate;
|
||||||
break;
|
break;
|
||||||
case FUNC3_BGE:
|
case FUNC3_BGE:
|
||||||
// Branch Greater Equal
|
// Branch Greater Equal
|
||||||
if(((int32_t) cpu->regs.x[instruction->rs1]) >= ((int32_t) cpu->regs.x[instruction->rs2]))
|
if(((int32_t) cpu->regs.x[instruction->rs1]) >= ((int32_t) cpu->regs.x[instruction->rs2]))
|
||||||
cpu->pc = immediate;
|
cpu->pc += immediate;
|
||||||
break;
|
break;
|
||||||
case FUNC3_BGEU:
|
case FUNC3_BGEU:
|
||||||
// Branch Greater Equal Unsigned
|
// Branch Greater Equal Unsigned
|
||||||
if(cpu->regs.x[instruction->rs1] >= cpu->regs.x[instruction->rs2])
|
if(cpu->regs.x[instruction->rs1] >= cpu->regs.x[instruction->rs2])
|
||||||
cpu->pc = immediate;
|
cpu->pc += immediate;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "FATAL: Unknown func3 0x%x for branch instruction, could not execute\n", instruction->func3);
|
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
|
// Branches ; to know which one, we must analyse func3
|
||||||
// Sign extend immediate from 13 bits to 32 bits
|
// 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)
|
switch(instruction->func3)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user