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