def test_srai(self): riscv_machine.registers["X8"] = 10 assemble("40000 SRAI X10, X8, 4", riscv_machine) self.assertEqual(riscv_machine.registers["X10"], 0) riscv_machine.registers["X8"] = -10 assemble("40000 SRAI X10, X8, 4", riscv_machine) self.assertEqual(riscv_machine.registers["X10"], 15)
def test_call(self): """ Tests call. At the time of writing this test blank lines are skipped by the tokenizer. In order to have emu jump to the location of label_addr, we have to make no-op lines to assign the correct locations to the lines we test. """ for i in range(NUM_TESTS): intel_machine.re_init() intel_machine.base = "dec" call_instr_addr = random.randint(FIRST_INST_ADDRESS, MAX_INSTRUCTIONS) label_addr = random.randint(FIRST_INST_ADDRESS, MAX_INSTRUCTIONS) code_to_run = [NO_OP] * (MAX_INSTRUCTIONS + 1) code_to_run[call_instr_addr] = "call " + TEST_LABEL + "\n" prev_label_info = code_to_run[label_addr] code_to_run[label_addr] = TEST_LABEL + ": " + prev_label_info intel_machine.labels[TEST_LABEL] = label_addr intel_machine.set_ip(call_instr_addr) # We step once through the code, executing only `call`. assemble("".join(code_to_run), 'att', intel_machine, step=True) self.assertEqual(intel_machine.get_ip(), label_addr)
def test_lui(self): for _ in range(0, NUM_TESTS): a = random.randint(0, 1048576) hex_string = hex(a).upper() correct = check_overflow(opfunc.lshift(a, 12), riscv_machine) assemble("40000 LUI X10, " + hex_string, riscv_machine) self.assertEqual(riscv_machine.registers["X10"], correct)
def two_op_test(self, operator, instr, low1=MIN_TEST, high1=MAX_TEST, low2=MIN_TEST, high2=MAX_TEST, op_type=INT, first_val=INT, second_val=INT): for i in range(0, NUM_TESTS): a = random.randint(low1, high1) b = random.randint(low2, high2) if op_type == FLOAT: if first_val == FLOAT: a = float(random.uniform(MIN_MUL, MAX_MUL)) if second_val == FLOAT: b = float(random.uniform(MIN_MUL, MAX_MUL)) correct = operator(a, b) intel_machine.registers["FRA"] = a intel_machine.registers["FRB"] = b intel_machine.registers[ "FRT"] = None #since no replacement, destination float register assemble(instr, 'intel', intel_machine) self.assertAlmostEqual(intel_machine.registers["FRT"], correct) #assert abs(intel_machine.registers["FRT"]-correct) < 0.00001, str(intel_machine.registers["FRT"]) + " does not equal " + str(correct) else: correct = operator(a, b) intel_machine.registers["EAX"] = a intel_machine.registers["EBX"] = b intel_machine.base = "dec" assemble(instr + " eax, ebx", 'intel', intel_machine) self.assertEqual(intel_machine.registers["EAX"], correct)
def two_op_test_double_float(self, operator, instr, low1=0, high1=MAX_TEST, low2=0, high2=MAX_TEST): for i in range(0, NUM_TESTS): a = random.uniform(low1, high1) b = random.uniform(low2, high2) correct = operator(a, b) is_a_neg = False is_b_neg = False # pre-processing to deal with negatives # we will be keep track if the value is a negative # or a positive with a flag for a and for b # using this flag to set the sign bit after # we do the conversion of the abs of the number if a < 0: is_a_neg = True a = abs(a) if b < 0: is_b_neg = True b = abs(b) a_binary = f_to_b64(a) # if a was neg overwrite the sign bit to 1 if (is_a_neg): a_binary = "1" + a_binary[1:] mips_machine.registers["F8"] = a_binary[:32] mips_machine.registers["F9"] = a_binary[32:] b_binary = f_to_b64(b) # if b was neg overwrite the sign bit to 1 if (is_b_neg): b_binary = "1" + b_binary[1:] mips_machine.registers["F10"] = b_binary[:32] mips_machine.registers["F11"] = b_binary[32:] mips_machine.base = "hex" assemble("40000 " + instr + " F12, F8, F10", 'mips_asm', mips_machine) # the answer from the assembly call # will be in the F12, F13 registers first_32 = str(mips_machine.registers["F12"]) last_32 = str(mips_machine.registers["F13"]) binary_result = first_32 + last_32 # check if the binary result is negative # if so mark a flag and overwrite the value to positive is_result_neg = False if binary_result[0] == "1": is_result_neg = True binary_result = "0" + binary_result[1:] result = b_to_f64(binary_result) result = result * -1 if is_result_neg else result self.assertEqual(result, correct)
def two_op_test( self, operator, instr, float=False, low1=MIN_TEST, high1=MAX_TEST, low2=MIN_TEST, high2=MAX_TEST, ): for i in range(0, NUM_TESTS): a = random.randint(low1, high1) b = random.randint(low2, high2) if float: a = random.uniform(low1, high1) b = random.uniform(low2, high2) correct = operator(a, b) if float: mips_machine.registers["F8"] = a mips_machine.registers["F10"] = b assemble(f"40000 {instr} F12, F8, F10", mips_machine) self.assertEqual(mips_machine.registers["F12"], correct) else: mips_machine.registers["R8"] = a mips_machine.registers["R9"] = b assemble(f"40000 {instr} R10, R8, R9", mips_machine) self.assertEqual(mips_machine.registers["R10"], correct)
def one_op_test(self, operator, instr, op_type=None, replaces=True): """replace boolean needed because some fp instructions do not replace the contents of the register, but rather place it another register""" for i in range(NUM_TESTS): # changeback to num_tests if op_type == FLOAT: a = float(random.uniform(MIN_MUL, MAX_MUL)) intel_machine.registers["FRB"] = a # source float register correct = operator(a) """ if replaces == False: intel_machine.registers["FRT"] = None #since no replacement, destination float register assemble(instr + ' frb', 'intel', intel_machine) self.assertEqual(intel_machine.registers["FRT"], correct) #since the new value is in the destination register, #compare correct to FRT else:""" # needs to be corrected to not use frb # assemble(instr + ' frb', intel_machine) # self.assertEqual(intel_machine.registers["FRB"], correct) # since the new value has not been replaced # (in source register), compare FRB to correct else: a = random.randint(MIN_TEST, MAX_TEST) intel_machine.registers["EAX"] = a correct = operator(a) assemble(instr + " eax", intel_machine) self.assertEqual(intel_machine.registers["EAX"], correct)
def test_mov(self): for i in range(0, NUM_TESTS): a = random.randint(MIN_TEST, MAX_TEST) correct = a vmachine.registers["EAX"] = a assemble("mov eax, " + str(a), vmachine) self.assertEqual(vmachine.registers["EAX"], correct)
def test_mov(self): for i in range(0, NUM_TESTS): a = random.randint(MIN_TEST, MAX_TEST) correct = a intel_machine.registers["EAX"] = a assemble("mov $" + str(a) + ", %eax", intel_machine) self.assertEqual(intel_machine.registers["EAX"], correct)
def one_op_test(self, operator, instr): for i in range(NUM_TESTS): a = random.randint(MIN_TEST, MAX_TEST) correct = operator(a) vmachine.registers["EAX"] = a assemble(instr + " eax", vmachine) self.assertEqual(vmachine.registers["EAX"], correct)
def test_cmp_eq(self): intel_machine.registers["EAX"] = 1 intel_machine.registers["EBX"] = 1 intel_machine.flags["ZF"] = 0 intel_machine.flags["SF"] = 0 assemble("cmp %ebx, %eax", 'att', intel_machine) self.assertEqual(intel_machine.flags["ZF"], 1) self.assertEqual(intel_machine.flags["SF"], 0)
def test_gt(self): vmachine.re_init() test_code = self.read_test_code("tests/gt.asm") assemble(test_code, vmachine) self.assertEqual(vmachine.registers["EAX"], 17) self.assertEqual(vmachine.registers["EBX"], 16) self.assertEqual(vmachine.registers["ECX"], 16) self.assertEqual(vmachine.registers["EDX"], 19)
def test_mov(self): for i in range(0, NUM_TESTS): a = random.randint(MIN_TEST, MAX_TEST) correct = a intel_machine.registers["EAX"] = a intel_machine.base = "dec" assemble("mov eax, " + str(a), 'intel', intel_machine) self.assertEqual(intel_machine.registers["EAX"], correct)
def one_op_test(self, operator, instr): for i in range(NUM_TESTS): a = random.randint(MIN_TEST, MAX_TEST) correct = operator(a) intel_machine.registers["EAX"] = a intel_machine.base = "dec" assemble(instr + " %eax", 'att', intel_machine) self.assertEqual(intel_machine.registers["EAX"], correct)
def test_cmp_l(self): intel_machine.registers["EAX"] = 0 intel_machine.registers["EBX"] = 1 intel_machine.flags["ZF"] = 0 intel_machine.flags["SF"] = 0 assemble("cmp eax, ebx", intel_machine) self.assertEqual(intel_machine.flags["ZF"], 0) self.assertEqual(intel_machine.flags["SF"], 1)
def test_cmp_l(self): vmachine.registers["EAX"] = 0 vmachine.registers["EBX"] = 1 vmachine.flags["ZF"] = 0 vmachine.flags["SF"] = 0 assemble("cmp eax, ebx", vmachine) self.assertEqual(vmachine.flags["ZF"], 0) self.assertEqual(vmachine.flags["SF"], 1)
def test_interrupt(self): vmachine.re_init() test_code = self.read_test_code("tests/test_interrupt.asm") assemble(test_code, vmachine) self.assertEqual(vmachine.registers["EAX"], 71) self.assertEqual(vmachine.registers["EBX"], 6) self.assertEqual(vmachine.registers["ECX"], 1) self.assertEqual(vmachine.registers["ESP"], 63) self.assertEqual(vmachine.memory["6"], 71)
def test_slt_eq(self): mips_machine.registers["T1"] = 1 mips_machine.registers["T2"] = 1 mips_machine.flags["ZF"] = 0 mips_machine.flags["SF"] = 0 assemble("slt $t3, $t1, $t2", 'mips', mips_machine) self.assertEqual(mips_machine.flags["ZF"], 1) self.assertEqual(mips_machine.flags["SF"], 0) self.assertEqual(mips_machine.registers["T3"], 0)
def test_cmp_eq(self): intel_machine.registers["EAX"] = 1 intel_machine.registers["EBX"] = 1 intel_machine.flags["ZF"] = 0 intel_machine.flags["SF"] = 0 intel_machine.base = "dec" assemble("cmp eax, ebx", 'intel', intel_machine) self.assertEqual(intel_machine.flags["ZF"], 1) self.assertEqual(intel_machine.flags["SF"], 0)
def test_sra(self): riscv_machine.registers["X8"] = 10 riscv_machine.registers["X9"] = 4 assemble("40000 SRA X10, X8, X9", riscv_machine) self.assertEqual(riscv_machine.registers["X10"], 0) riscv_machine.registers["X8"] = -10 riscv_machine.registers["X9"] = 4 assemble("40000 SRA X10, X8, X9", riscv_machine) self.assertEqual(riscv_machine.registers["X10"], 15)
def test_nor(self): for i in range(0, NUM_TESTS): a = random.randint(MIN_TEST, MAX_TEST) b = random.randint(MIN_TEST, MAX_TEST) correct = opfunc.inv(opfunc.or_(a, b)) mips_machine.registers["R8"] = a mips_machine.registers["R9"] = b assemble("40000 NOR R10, R8, R9", mips_machine) self.assertEqual(mips_machine.registers["R10"], correct)
def test_key(self): vmachine.re_init() test_code = self.read_test_code("tests/key_test.asm") assemble(test_code, vmachine) self.assertEqual(vmachine.registers["EAX"], 71) self.assertEqual(vmachine.registers["EBX"], 71) self.assertEqual(vmachine.registers["ECX"], 1) self.assertEqual(vmachine.registers["ESP"], 63) self.assertEqual(vmachine.memory["9"], 83)
def test_arithmetic_shift(self): vmachine.re_init() test_code = self.read_test_code("tests/arithmetic_shift.asm") assemble(test_code, vmachine) self.assertEqual(vmachine.registers["EAX"], 4) self.assertEqual(vmachine.registers["EBX"], 10) self.assertEqual(vmachine.registers["ECX"], 8) self.assertEqual(vmachine.registers["EDX"], 8) self.assertEqual(vmachine.memory["4"], 4)
def test_nor(self): for i in range(0, NUM_TESTS): a = random.randint(MIN_TEST, MAX_TEST) b = random.randint(MIN_TEST, MAX_TEST) correct = opfunc.inv(opfunc.or_(a, b)) mips_machine.registers["T1"] = a mips_machine.registers["T2"] = b assemble("nor $t3, $t1, $t2", 'mips', mips_machine) self.assertEqual(mips_machine.registers["T3"], correct)
def test_jmp(self): """ Jump to a random location from 0 to MAX_INSTRUCTIONS. Assert IP is set to that location by jump. """ for i in range(NUM_TESTS): vmachine.re_init() label_loc = random.randint(FIRST_INST_ADDRESS,MAX_INSTRUCTIONS) vmachine.labels["test_label"] = label_loc assemble("jmp test_label", vmachine) self.assertEqual(vmachine.get_ip(), label_loc)
def test_jmp(self): """ Jump to a random location from 1 to MAX_INSTRUCTIONS. Assert IP is set to that location by jump. """ for i in range(NUM_TESTS): intel_machine.re_init() intel_machine.base = "dec" label_addr = random.randint(FIRST_INST_ADDRESS, MAX_INSTRUCTIONS) intel_machine.labels["test_label"] = label_addr assemble("jmp test_label", 'att', intel_machine) self.assertEqual(intel_machine.get_ip(), label_addr)
def two_op_test_unsigned(self, operator, instr, low1=MIN_TEST, high1=MAX_TEST, low2=MIN_TEST, high2=MAX_TEST): for _ in range(0, NUM_TESTS): a = abs(random.randint(low1, high1)) b = abs(random.randint(low2, high2)) correct = operator(a, b) riscv_machine.registers["X8"] = a riscv_machine.registers["X9"] = b riscv_machine.base = "hex" assemble("40000 " + instr + " X10, X8, X9", 'riscv', riscv_machine) self.assertEqual(riscv_machine.registers["X10"], correct)
def test_push_and_pop(self): correct_stack = [None] * ( STACK_TOP + 1) # Note: size(correct_stack) = size(stack + memory) for i in range(STACK_TOP, STACK_BOTTOM - 1, -1): # Traverse the stack registers. a = random.randint(MIN_TEST, MAX_TEST) correct_stack[i] = a vmachine.registers["EAX"] = a assemble("push eax", vmachine) for i in range(STACK_BOTTOM, STACK_TOP + 1): assemble("pop ebx", vmachine) self.assertEqual(vmachine.registers["EBX"], correct_stack[i])
def two_op_test_imm(self, operator, instr, low1=MIN_TEST, high1=MAX_TEST, low2=MIN_TEST, high2=MAX_TEST): for _ in range(0, NUM_TESTS): a = random.randint(low1, high1) b = random.randint(low2, high2) hex_string = hex(b) correct = operator(a, int(hex(b), 16)) riscv_machine.registers["X9"] = a riscv_machine.base = "hex" assemble("40000 " + instr + " X10, X9, " + hex_string, 'riscv', riscv_machine) self.assertEqual(riscv_machine.registers["X10"], correct)
def one_op_test(self, operator, instr, low1=MIN_TEST, high1=MAX_TEST): for i in range(0, NUM_TESTS): a = random.randint(low1, high1) correct = operator(a) sp = wasm_machine.get_sp() wasm_machine.stack[hex(sp).split('x')[-1].upper()] = a wasm_machine.inc_sp() assemble(instr, wasm_machine) wasm_machine.dec_sp() sp = wasm_machine.get_sp() position = hex(sp).split('x')[-1].upper() self.assertEqual(wasm_machine.stack[position], correct)