From 80f8c13fa9e6f57c67e88cf43175f6d5c106dfec Mon Sep 17 00:00:00 2001 From: Recolic Keghart <root@recolic.net> Date: Fri, 27 Dec 2019 03:20:34 -0800 Subject: [PATCH] > Manual commit: bugfix for arith OF flag. Fucking noob poster posting wrong solution on github. sucks. U201614531 recolic Linux RECOLICMPC 4.19.84-1-MANJARO #1 SMP PREEMPT Wed Nov 13 00:07:37 UTC 2019 x86_64 GNU/Linux 03:20:34 up 21 days, 4:48, 1 user, load average: 0.42, 0.35, 0.46 36c3bd2a1e7a29f7c346bc4d23ed07323dec4c6b --- nemu/src/cpu/decode/decode.cc | 1 - nemu/src/cpu/exec/arith.cc | 34 ++++++++++++++++---------- nemu/src/monitor/debug/ui.cc | 3 ++- nexus-am/tests/cputest/tests/r.c | 41 +++++++++++++++++++++++++------- 4 files changed, 56 insertions(+), 23 deletions(-) diff --git a/nemu/src/cpu/decode/decode.cc b/nemu/src/cpu/decode/decode.cc index 94c08ab..620d666 100644 --- a/nemu/src/cpu/decode/decode.cc +++ b/nemu/src/cpu/decode/decode.cc @@ -286,7 +286,6 @@ namespace DHelperImpl { make_DHelper(J) { make_DopHelper_funcname(SI)(eip, id_dest, false); - rlib::println("debug: J decoder: id_dest=", *id_dest); rtl_sext(&id_dest->imm, &id_dest->imm, id_dest->width); // the target address can be computed in the decode stage decoding.jmp_eip = id_dest->simm + *eip; diff --git a/nemu/src/cpu/exec/arith.cc b/nemu/src/cpu/exec/arith.cc index 8f6c9cb..fb376f9 100644 --- a/nemu/src/cpu/exec/arith.cc +++ b/nemu/src/cpu/exec/arith.cc @@ -8,10 +8,13 @@ namespace EHelperImpl { rtl_sext(&t2, &id_src->val, id_src->width); rtl_add(&t0, &t1, &t2); - t3 = (t0 < t1); - rtl_set_CF(&t3); - t3 = ((((int32_t)(t1) >= 0) ^ (((int32_t)(t2) >= 0 ))) && (((int32_t)(t0) < 0) ^ (((int32_t)(t2) >= 0 )) )); - rtl_set_OF(&t3); + + cpu_eflags::get<cpu_eflags::CF>() = (t0 < t1); + + bool operandsSameSign = not ((t1 xor t2) bitand 0x80000000); + bool resFlippedSign = ((t1 xor t0) bitand 0x80000000); + cpu_eflags::get<cpu_eflags::OF>() = resFlippedSign and operandsSameSign; + rtl_update_ZFSF(&t0, 4); operand_write(id_dest, &t0); @@ -23,10 +26,13 @@ namespace EHelperImpl { rtl_sext(&t2, &id_src->val, id_src->width); rtl_sub(&t0, &t1, &t2); - t3 = (t0 > t1); - rtl_set_CF(&t3); - t3 = ((((int32_t)(t1) < 0) == (((int32_t)(t2) >> 31) == 0)) && (((int32_t)(t0) < 0) != ((int32_t)(t1) < 0))); - rtl_set_OF(&t3); + + cpu_eflags::get<cpu_eflags::CF>() = (t0 > t1); + + bool operandsSameSign = not ((t1 xor t2) bitand 0x80000000); + bool resFlippedSign = ((t1 xor t0) bitand 0x80000000); + cpu_eflags::get<cpu_eflags::OF>() = resFlippedSign and not operandsSameSign; + rtl_update_ZFSF(&t0, 4); operand_write(id_dest, &t0); @@ -36,14 +42,18 @@ namespace EHelperImpl { make_EHelper(cmp) { + rlib::println("debug: cmp: id_dest=", *id_dest, ", id_src=", *id_src); rtl_sext(&t1, &id_dest->val, id_dest->width); rtl_sext(&t2, &id_src->val, id_src->width); rtl_sub(&t0, &t1, &t2); - t3 = (t0 > t1); - rtl_set_CF(&t3); - t3 = ((((int32_t)(t1) < 0) == (((int32_t)(t2) >> 31) == 0)) && (((int32_t)(t0) < 0) != ((int32_t)(t1) < 0))); - rtl_set_OF(&t3); + + cpu_eflags::get<cpu_eflags::CF>() = (t0 > t1); + + bool operandsSameSign = not ((t1 xor t2) bitand 0x80000000); + bool resFlippedSign = ((t1 xor t0) bitand 0x80000000); + cpu_eflags::get<cpu_eflags::OF>() = resFlippedSign and not operandsSameSign; + rtl_update_ZFSF(&t0, 4); print_asm_template2(cmp); diff --git a/nemu/src/monitor/debug/ui.cc b/nemu/src/monitor/debug/ui.cc index ddb92d2..086b21a 100644 --- a/nemu/src/monitor/debug/ui.cc +++ b/nemu/src/monitor/debug/ui.cc @@ -174,7 +174,8 @@ static int cmd_info(char *_args) { println("Registers:"); printfln("%eax={}, %ebx={}, %ecx={}, %edx={}", dumpReg(cpu.eax), dumpReg(cpu.ebx), dumpReg(cpu.ecx), dumpReg(cpu.edx)); printfln("%esp={}, %ebp={}, %esi={}, %edi={}", dumpReg(cpu.esp), dumpReg(cpu.ebp), dumpReg(cpu.esi), dumpReg(cpu.edi)); - printfln("%eip={}", dumpReg(cpu.eip)); + printfln("%eip={}, CF/OF/SF/ZF={}/{}/{}/{}", dumpReg(cpu.eip), cpu_eflags::get<cpu_eflags::CF>(), + cpu_eflags::get<cpu_eflags::OF>(), cpu_eflags::get<cpu_eflags::SF>(), cpu_eflags::get<cpu_eflags::ZF>()); } else if(string(_args).strip() == "w") { println("Watchpoints:"); diff --git a/nexus-am/tests/cputest/tests/r.c b/nexus-am/tests/cputest/tests/r.c index ca75670..a2a1bea 100644 --- a/nexus-am/tests/cputest/tests/r.c +++ b/nexus-am/tests/cputest/tests/r.c @@ -1,24 +1,47 @@ #include "trap.h" -int add(int a, int b) { - int c = a + b; - return c; +int min3(int x, int y, int z) { + int m; + if(x < y) { m = x; } + else { m = y; } + if(z < m) m = z; + return m; } -int test_data[] = {0, 1, 2}; -int ans[] = {0, 1, 2,1,2,3,2,3,4}; +//int test_data[] = {0, 0x7fffffff, 0x80000000, 0xffffffff}; +//int ans [] = {0, 0, -2147483648, -1, 0, 0, -2147483648, -1, -2147483648, -2147483648, -2147483648, -2147483648, -1, -1, -2147483648, -1, 0, 0, -2147483648, -1, 0, 2147483647, -2147483648, -1, -2147483648, -2147483648, -2147483648, -2147483648, -1, -1, -2147483648, -1, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -1, -1, -2147483648, -1, -1, -1, -2147483648, -1, -2147483648, -2147483648, -2147483648, -2147483648, -1, -1, -2147483648, -1}; + +int test_data[] = {1,2}; +int ans [] = {1,1,1, 1,1,1, 1,1,2}; #define NR_DATA (sizeof(test_data) / sizeof(test_data[0])) int main() { - int i, j, ans_idx = 0; + int rmax = 0; + if(test_data[0] < test_data[1]) + rmax = test_data[1]; + else + rmax = test_data[0]; + nemu_assert(rmax == test_data[1]); + return 0; + + + + + int i, j, k, ans_idx = 0; + //nemu_assert(min3(4,6,8) == 4); + for(i = 0; i < NR_DATA; i ++) { for(j = 0; j < NR_DATA; j ++) { - nemu_assert(1); + for(k = 0; k < NR_DATA; k ++) { + nemu_assert(min3(test_data[i], test_data[j], test_data[k]) == ans[ans_idx ++]); + } + //nemu_assert(k == NR_DATA); } - nemu_assert(j == NR_DATA); + //nemu_assert(j == NR_DATA); } - nemu_assert(i == NR_DATA); + + //nemu_assert(i == NR_DATA); return 0; } -- GitLab