Fix branch signextend + offset
This commit is contained in:
		@@ -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)
 | 
			
		||||
			{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user