diff --git a/riscemu/CPU.py b/riscemu/CPU.py index c1a66ad..b0eebf7 100644 --- a/riscemu/CPU.py +++ b/riscemu/CPU.py @@ -178,10 +178,20 @@ class CPU: INS_NOT_IMPLEMENTED(ins) def instruction_beq(self, ins: 'LoadedInstruction'): - INS_NOT_IMPLEMENTED(ins) + ASSERT_LEN(ins.args, 3) + reg1 = ins.get_reg(0) + reg2 = ins.get_reg(1) + dest = ins.get_imm(2) + if self.regs.get(reg1) == self.regs.get(reg2): + self.pc = dest def instruction_bne(self, ins: 'LoadedInstruction'): - INS_NOT_IMPLEMENTED(ins) + ASSERT_LEN(ins.args, 3) + reg1 = ins.get_reg(0) + reg2 = ins.get_reg(1) + dest = ins.get_imm(2) + if self.regs.get(reg1) != self.regs.get(reg2): + self.pc = dest def instruction_blt(self, ins: 'LoadedInstruction'): ASSERT_LEN(ins.args, 3) @@ -192,13 +202,28 @@ class CPU: self.pc = dest def instruction_bge(self, ins: 'LoadedInstruction'): - INS_NOT_IMPLEMENTED(ins) + ASSERT_LEN(ins.args, 3) + reg1 = ins.get_reg(0) + reg2 = ins.get_reg(1) + dest = ins.get_imm(2) + if self.regs.get(reg1) >= self.regs.get(reg2): + self.pc = dest def instruction_bltu(self, ins: 'LoadedInstruction'): - INS_NOT_IMPLEMENTED(ins) + ASSERT_LEN(ins.args, 3) + reg1 = to_unsigned(ins.get_reg(0)) + reg2 = to_unsigned(ins.get_reg(1)) + dest = ins.get_imm(2) + if self.regs.get(reg1) < self.regs.get(reg2): + self.pc = dest def instruction_bgeu(self, ins: 'LoadedInstruction'): - INS_NOT_IMPLEMENTED(ins) + ASSERT_LEN(ins.args, 3) + reg1 = to_unsigned(ins.get_reg(0)) + reg2 = to_unsigned(ins.get_reg(1)) + dest = ins.get_imm(2) + if self.regs.get(reg1) >= self.regs.get(reg2): + self.pc = dest def instruction_j(self, ins: 'LoadedInstruction'): INS_NOT_IMPLEMENTED(ins) diff --git a/riscemu/helpers.py b/riscemu/helpers.py index 0441bfc..14226ec 100644 --- a/riscemu/helpers.py +++ b/riscemu/helpers.py @@ -35,10 +35,21 @@ def int_from_bytes(bytes, unsigned=False): for b in bytes: num = num << 8 num += b - sign = num >> (len(bytes) * 8 - 1) - if sign and not unsigned: - return num - 2 ** (8 * len(bytes)) - return num + + if unsigned: + return num + + return to_signed(num) + + +def to_unsigned(num: int, bytes=4): + if num < 0: + return 2**(bytes * 8) - num + + +def to_signed(num: int, bytes=4): + if num >> (bytes * 8 - 1): + return num - 2 ** (8 * bytes) # Colors