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
 | 
								// 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)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user