|
|
@ -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) |
|
|
|
{ |
|
|
|
{ |
|
|
|