def test_sw(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("sw $s0, 4($s1)") p.reg[16] = 0xdeadbeef p.reg[17] = 0x2f8 - 4 p.do_instr(the_cmd) self.assertListEqual(list(p.mem[0x2f8:0x2f8 + 4]), [0xef, 0xbe, 0xad, 0xde]) the_cmd = CMDParse.parse_cmd("sw $s0, 0($s1)") p.reg[16] = 0xdeadbeef p.reg[17] = 1 try: p.do_instr(the_cmd) self.assertTrue( False, "Cannot store to not naturally aligned memory addresses.") except AddressError: pass
def test_bltzal(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("bltzal $s0, 0xa") p.pc = 10 p.reg[16] = np.uint32(-5) p.reg[31] = 0 p.do_instr(the_cmd) self.assertEqual(p.pc, 54) self.assertEqual(p.reg[31], 18) p.pc = 10 p.reg[16] = 0 p.reg[31] = 0 p.do_instr(the_cmd) self.assertEqual(p.pc, 14) self.assertEqual(p.reg[31], 0) p.pc = 10 p.reg[16] = 22 p.reg[31] = 0 p.do_instr(the_cmd) self.assertEqual(p.pc, 14) self.assertEqual(p.reg[31], 0)
def test_sub(self): p = MIPSProcessor() p.reg[10] = 11 p.reg[11] = 22 p.reg[12] = 3 p._sub(10, 11, 12) self.assertEqual(p.reg[10], 19) try: p.reg[11] = 2**31 - 1 # INT_MAX - -2 = overflow p.reg[12] = -1 p._sub(10, 11, 12) except IntegerOverflow: pass try: p.reg[11] = -2**31 # INT_MIN - 2 = overflow p.reg[12] = 1 p._sub(10, 11, 12) except IntegerOverflow: pass inst = CMDParse.parse_cmd("sub $s3, $s4, $s5") p.reg[19] = 2 p.reg[20] = 22 p.reg[21] = 11 p.do_instr(inst) self.assertEqual(p.reg[19], 11)
def test_addi(self): p = MIPSProcessor() p.reg[10] = 5 p._addi(11, 10, 0x5) self.assertEqual(p.reg[11], 10) try: p.reg[10] = 2**31 - 1 p._addi(11, 10, 2) self.assertTrue(False) except IntegerOverflow: pass try: p.reg[10] = -2**31 p._addi(11, 10, -2) self.assertTrue(False) except IntegerOverflow: pass inst = CMDParse.parse_cmd("addi $s3, $s4, 0xa") p.reg[19] = 2 p.reg[20] = 11 p.do_instr(inst) self.assertEqual(p.reg[19], 21)
def test_encode_complete(self): for s in well_formed: iform = CMDParse.parse_cmd(s) try: bform = iform.encode() except NotImplementedError: self.assertTrue( False, "encode {} is not implemented.".format(iform.op)) except Exception as e: self.assertTrue( False, "Unexpected exception encountered encoding `{}`\n{}". format(s, e)) self.assertEqual(iform.bin, bform) try: iform2 = Instr.decode(bform) except NotImplementedError: self.assertTrue( False, "decode {} is not implemented.".format(iform.op)) except Exception as e: self.assertTrue( False, "Unexpected exception encountered decoding `{}`\n{}". format(s, e)) self.assertEqual(iform2.bin, bform) self.assertEqual(iform, iform2, "error encoding and decoding {}.".format(s))
def test_bltz(self): p = MIPSProcessor() bgez_cmd = CMDParse.parse_cmd("bltz $s0, 0xa") p.pc = 10 p.reg[16] = np.uint32(-5) p.do_instr(bgez_cmd) self.assertEqual(p.pc, 54) p.pc = 10 p.reg[16] = 0 p.do_instr(bgez_cmd) self.assertEqual(p.pc, 14) p.pc = 10 p.reg[16] = 22 p.do_instr(bgez_cmd) self.assertEqual(p.pc, 14)
def test_lui(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("lui $s0, 0xabba") p.reg[16] = 0x0 p.do_instr(the_cmd) self.assertEqual(p.reg[16], 0xabba0000) the_cmd = CMDParse.parse_cmd("lui $s0, 0xdead") p.reg[16] = 0xbeef p.do_instr(the_cmd) self.assertEqual(p.reg[16], 0xdead0000)
def test_noop(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("noop") p.pc = 12 p.do_instr(the_cmd) self.assertEqual(p.pc, 16)
def test_srl(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("srl $s0, $s1, 2") p.reg[16] = 0x0 p.reg[17] = np.uint32(-200) p.do_instr(the_cmd) self.assertEqual(p.reg[16], 1073741774)
def test_sltiu(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("sltiu $s0, $s1, 0x5") p.reg[16] = 0x0 p.reg[17] = np.uint32(-10) p.do_instr(the_cmd) self.assertEqual(p.reg[16], 0)
def test_syscall(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("syscall") try: p.do_instr(the_cmd) self.assertTrue(False, "Software interrupt not thrown on syscall.") except SoftwareInterrupt: pass
def test_sll(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("sll $s0, $s1, 10") p.reg[16] = 0x0 p.reg[17] = 0xa p.do_instr(the_cmd) self.assertEqual(p.reg[16], np.left_shift(0xa, 10))
def test_sra(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("sra $s0, $s1, 2") p.reg[16] = 0x0 p.reg[17] = np.uint32(-200) p.do_instr(the_cmd) self.assertEqual(np.int32(p.reg[16]), -50)
def test_sb(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("sb $s0, 4($s1)") p.reg[16] = 0xabba p.reg[17] = 0x2f8 - 4 p.do_instr(the_cmd) self.assertEqual(p.mem[0x2f8], 0xba)
def test_srlv(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("srlv $s0, $s1, $s2") p.reg[16] = 0x0 p.reg[17] = 0xabbaabba p.reg[18] = 0xa p.do_instr(the_cmd) self.assertEqual(p.reg[16], np.right_shift(0xabbaabba, 0xa))
def test_lw(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("lw $s0, 4($s1)") p.mem[0x2f8:0x2f8 + 4] = np.uint32([0xdeadbeef]).view('uint8') p.reg[16] = 0x0 p.reg[17] = 0x2f8 - 4 p.do_instr(the_cmd) self.assertEqual(p.reg[16], 0xdeadbeef)
def test_encode_addi_heximm(self): o = CMDParse.parse_cmd("addi $s0, $t0, 0xa") o_bin = o.encode() op = Instr.extr_op(o_bin) rs = Instr.extr_rs(o_bin) rt = Instr.extr_rt(o_bin) imm = Instr.extr_imm(o_bin) self.assertEqual(op, IanMIPS.op_dict["addi"]) self.assertEqual(rt, IanMIPS.reg_dict["s0"]) self.assertEqual(rs, IanMIPS.reg_dict["t0"]) self.assertEqual(imm, 10)
def test_encode_bgez(self): o = CMDParse.parse_cmd("bgez $s0, 1000") o_bin = o.encode() op = Instr.extr_op(o_bin) rs = Instr.extr_rs(o_bin) rt = Instr.extr_rt(o_bin) imm = Instr.extr_imm(o_bin) self.assertEqual(op, 1) self.assertEqual(imm, 1000) self.assertEqual(rs, IanMIPS.reg_dict["s0"]) self.assertEqual(rt, IanMIPS.b_instr[o.op])
def test_beq(self): p = MIPSProcessor() beq_cmd = CMDParse.parse_cmd("beq $t0, $s0, 0x3") p.pc = 10 p.reg[8] = 10 p.reg[16] = 10 p.do_instr(beq_cmd) self.assertEqual(p.pc, 26)
def test_mult(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("mult $s0, $s1") p.reg[16] = 0xabbaabba p.reg[17] = 0x9ba461595 p.do_instr(the_cmd) res = np.int64(np.uint32([p.lo, p.hi]).view('int64')[0]) self.assertEqual( res, np.int64(np.int32(0xabbaabba)) * np.int64(np.int32(0x9ba461595)))
def test_mflo(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("mflo $s0") p.lo = 55 p.do_instr(the_cmd) self.assertEqual(p.reg[16], 55) p.lo = -55 p.do_instr(the_cmd) self.assertEqual(np.int32(p.reg[16]), -55)
def test_j(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("j 0xf") p.pc = np.uint32(0xa) p.do_instr(the_cmd) self.assertEqual(p.pc, 0xf * 4) p.pc = np.uint32(0xa00000ba) p.do_instr(the_cmd) self.assertEqual(p.pc, np.bitwise_or(0xa0000000, 0xf * 4))
def test_encode_add(self): o = CMDParse.parse_cmd("add $s0, $s1, $s2") o_bin = o.encode() op = Instr.extr_op(o_bin) rs = Instr.extr_rs(o_bin) rt = Instr.extr_rt(o_bin) rd = Instr.extr_rd(o_bin) funct = Instr.extr_funct(o_bin) self.assertEqual(op, 0) self.assertEqual(funct, IanMIPS.funct_dict["add"]) self.assertEqual(rd, IanMIPS.reg_dict["s0"]) self.assertEqual(rs, IanMIPS.reg_dict["s1"]) self.assertEqual(rt, IanMIPS.reg_dict["s2"])
def attempt_assemble(filename): with open(filename) as ifile: in_file = ifile.readlines() # 1st pass in_file = remove_comments(in_file) out_file_name = os.path.splitext(filename)[0] + ".bin" with open(out_file_name, 'wb') as ofile: print(in_file) label = re.compile('(.+):$') label_dict = {} label_less_prog = [] prog = [] # 2nd pass for l in in_file: m = label.match(l) if m: print("Found label: {}".format(m.group(1))) label_dict[m.group(1)] = len(label_less_prog) continue label_less_prog.append(l) # 3rd pass for i in range(len(label_less_prog)): l = label_less_prog[i] for k, v in label_dict.items(): if k in l.split(): rel_jmp = int(v) - i - 1 l = l.replace(k, "{}".format(rel_jmp)) prog.append(l) for p in prog: ofile.write(CMDParse.parse_cmd(p).bin) pass pass
def test_encode_jr(self): o = CMDParse.parse_cmd("jr $s0") o_bin = o.encode() op = Instr.extr_op(o_bin) rs = Instr.extr_rs(o_bin) rt = Instr.extr_rt(o_bin) rd = Instr.extr_rd(o_bin) shamt = Instr.extr_shamt(o_bin) funct = Instr.extr_funct(o_bin) self.assertEqual(op, 0) self.assertEqual(rs, IanMIPS.reg_dict["s0"]) self.assertEqual(rt, 0) self.assertEqual(rd, 0) self.assertEqual(shamt, 0) self.assertEqual(funct, IanMIPS.funct_dict["jr"])
def test_lb(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("lb $s0, 4($s1)") p.mem[0x2f8] = 77 p.reg[16] = 0x0 p.reg[17] = 0x2f8 - 4 p.do_instr(the_cmd) self.assertEqual(p.reg[16], 77) p.mem[0x2f8] = np.uint8(-96) p.reg[16] = 0x0 p.reg[17] = 0x2f8 - 4 p.do_instr(the_cmd) self.assertEqual(np.int32(p.reg[16]), -96)
def test_jr(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("jr $s0") p.pc = np.uint32(0xa) p.reg[16] = 0xf * 4 p.do_instr(the_cmd) self.assertEqual(p.pc, 0xf * 4) p.pc = np.uint32(0xa) p.reg[16] = 0xf try: p.do_instr(the_cmd) self.assertTrue( False, "Branching to a non 4-byte aligned address isn't allowed.") except AddressError: pass
def test_divu(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("divu $s0, $s1") p.reg[16] = 14 p.reg[17] = 4 p.do_instr(the_cmd) self.assertEqual(p.hi, 2) self.assertEqual(p.lo, 3) p.reg[16] = np.uint32(-14) p.reg[17] = 4 p.do_instr(the_cmd) self.assertEqual(p.hi, 2) self.assertEqual(p.lo, 1073741820)
def test_bne(self): p = MIPSProcessor() the_cmd = CMDParse.parse_cmd("bne $t0, $s0, 0xa") p.pc = 10 p.reg[8] = 10 p.reg[16] = 10 p.do_instr(the_cmd) self.assertEqual(p.pc, 14) p.pc = 10 p.reg[8] = 10 p.reg[16] = 9 p.do_instr(the_cmd) self.assertEqual(p.pc, 54)
def test_add(self): p = MIPSProcessor() p.reg[10] = 11 p.reg[11] = 22 p.reg[12] = 3 p._add(10, 11, 12) self.assertEqual(p.reg[10], 25) try: p.reg[11] = 2**31 - 1 # INT_MAX + 1 = overflow p.reg[12] = 1 p._add(10, 11, 12) self.assertTrue(False) except IntegerOverflow: pass try: p.reg[11] = -2**31 # INT_MIN - 2 = overflow p.reg[12] = -2 p._add(10, 11, 12) self.assertTrue(False) except IntegerOverflow: pass inst = CMDParse.parse_cmd("add $s3, $s4, $s5") p.reg[19] = 2 p.reg[20] = 11 p.reg[21] = 22 p.do_instr(inst) self.assertEqual(p.reg[19], 33)