From e7aa3861301fac1308f4a70c5ede400edbdc9531 Mon Sep 17 00:00:00 2001
From: Recolic Keghart <root@recolic.net>
Date: Sat, 28 Dec 2019 22:49:38 +0800
Subject: [PATCH] >  Manual commit:  Implemented more instructions for
 bit-test. Now passing most tests except 2. U201614531 recolic Linux RECOLICPC
 5.4.6-arch3-1 #1 SMP PREEMPT Tue, 24 Dec 2019 04:36:53 +0000 x86_64 GNU/Linux
  22:49:38 up  4:23,  1 user,  load average: 0.44, 0.78, 0.65
 e61ade3efdb6b2a065905e25e190ebb73554f4d1

---
 nemu/src/cpu/exec/arith.cc       |  2 +-
 nemu/src/cpu/exec/data-mov.cc    |  6 ++--
 nemu/src/cpu/exec/logic.cc       | 62 +++++++++++++++++++++++++-------
 nexus-am/tests/cputest/tests/r.c | 47 ------------------------
 4 files changed, 54 insertions(+), 63 deletions(-)
 delete mode 100644 nexus-am/tests/cputest/tests/r.c

diff --git a/nemu/src/cpu/exec/arith.cc b/nemu/src/cpu/exec/arith.cc
index fb376f9..7fbd98c 100644
--- a/nemu/src/cpu/exec/arith.cc
+++ b/nemu/src/cpu/exec/arith.cc
@@ -42,7 +42,7 @@ namespace EHelperImpl {
   
   
   make_EHelper(cmp) {
-    rlib::println("debug: cmp: id_dest=", *id_dest, ", id_src=", *id_src);
+    // 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);
   
diff --git a/nemu/src/cpu/exec/data-mov.cc b/nemu/src/cpu/exec/data-mov.cc
index 8e61839..78d7a61 100644
--- a/nemu/src/cpu/exec/data-mov.cc
+++ b/nemu/src/cpu/exec/data-mov.cc
@@ -62,11 +62,13 @@ namespace EHelperImpl {
   }
   
   make_EHelper(cltd) {
+    // r: dbt
     if (decoding.is_operand_size_16) {
-      TODO();
+      rtl_sext(&t0, &reg_l(R_EAX), 2);
+      rtl_shri(&reg_l(R_EDX), &t0, 16);
     }
     else {
-      TODO();
+      rtl_sari(&reg_l(R_EDX), &reg_l(R_EAX), 31);
     }
   
     print_asm(decoding.is_operand_size_16 ? "cwtl" : "cltd");
diff --git a/nemu/src/cpu/exec/logic.cc b/nemu/src/cpu/exec/logic.cc
index 764b95e..151e210 100644
--- a/nemu/src/cpu/exec/logic.cc
+++ b/nemu/src/cpu/exec/logic.cc
@@ -4,14 +4,11 @@
 void sign_extend_if_required(const Operand &dest, Operand &src) {
   if(dest.width > src.width) {
     rtl_sext(&src.val, &src.val, src.width);
-    src.imm = src.val;
     src.width = dest.width;
   }
 }
 
 namespace EHelperImpl {
-  using vaddr_t = uint32_t;
-
   make_EHelper(test) {
     // `and` without write_back.
     sign_extend_if_required(*id_dest, *id_src);
@@ -24,9 +21,9 @@ namespace EHelperImpl {
   }
   
   make_EHelper(and_) {
-    rlib::printfln("before test, id_dest={}, src={}", *id_dest, *id_src);
+    // rlib::printfln("debug: before test, id_dest={}, src={}", *id_dest, *id_src);
     sign_extend_if_required(*id_dest, *id_src);
-    rlib::printfln("after test, id_dest={}, src={}", *id_dest, *id_src);
+    // rlib::printfln("debug: after test, id_dest={}, src={}", *id_dest, *id_src);
   
     rtl_and(&id_dest->val, &id_dest->val, &id_src->val);
     operand_write(id_dest, &id_dest->val);
@@ -50,28 +47,49 @@ namespace EHelperImpl {
   }
   
   make_EHelper(or_) {
-    TODO();
+    sign_extend_if_required(*id_dest, *id_src);
+  
+    rtl_or(&id_dest->val, &id_dest->val, &id_src->val);
+    operand_write(id_dest, &id_dest->val);
+  
+    rtl_update_ZFSF(&id_dest->val, id_dest->width);
+    cpu_eflags::get<cpu_eflags::CF>() = cpu_eflags::get<cpu_eflags::OF>() = false;
   
     print_asm_template2(or);
   }
   
   make_EHelper(sar) {
-    TODO();
-    // unnecessary to update CF and OF in NEMU
+    // r: dbt
+    // warning: unnecessary to update CF and OF in NEMU
+    if (id_dest->width == 1) {
+    	id_dest->val = (int8_t)id_dest->val;
+    }
+    else if (id_dest->width == 2) {
+    	id_dest->val = (int16_t)id_dest->val;
+    }
+    rtl_sar(&t2, &id_dest->val, &id_src->val);
+    operand_write(id_dest, &t2);
+    rtl_update_ZFSF(&t2, id_dest->width);
   
     print_asm_template2(sar);
   }
   
   make_EHelper(shl) {
-    TODO();
+    // r: dbt
     // unnecessary to update CF and OF in NEMU
-  
+    rtl_shl(&t2, &id_dest->val, &id_src->val);
+    operand_write(id_dest, &t2);
+    rtl_update_ZFSF(&t2, id_dest->width);  
+
     print_asm_template2(shl);
   }
   
   make_EHelper(shr) {
-    TODO();
+    // r: dbt
     // unnecessary to update CF and OF in NEMU
+    rtl_shr(&t2, &id_dest->val, &id_src->val);
+    operand_write(id_dest, &t2);
+    rtl_update_ZFSF(&t2, id_dest->width);
   
     print_asm_template2(shr);
   }
@@ -86,13 +104,31 @@ namespace EHelperImpl {
   }
   
   make_EHelper(not_) {
-    TODO();
+    rtl_not(&id_dest->val, &id_dest->val);
+    operand_write(id_dest, &id_dest->val);
   
     print_asm_template1(not);
   }
   
   make_EHelper(rol) {
-    TODO();
+    // r: dbt
+	  rtl_shl(&t0, &id_dest->val, &id_src->val);
+	  if (decoding.is_operand_size_16) {
+	  	t3 = 0;
+	  	rtl_addi(&t1, &t3, 16);
+	  	rtl_sub(&t1, &t1, &id_src->val);
+	  	rtl_shr(&t2, &id_dest->val, &t1);
+	  } else {
+	  	t3 = 0;
+	  	rtl_addi(&t1, &t3, 32);
+	  	rtl_sub(&t1, &t1, &id_src->val);
+	  	rtl_shr(&t2, &id_dest->val, &t1);
+	  }
+	  rtl_or(&t0, &t0, &t2);
+	  operand_write(id_dest, &t0);
+
+	  // unnecessary to update CF and OF in NEMU
+	  rtl_update_ZFSF(&t0, id_dest->width);
   
     print_asm_template1(rol);
   }
diff --git a/nexus-am/tests/cputest/tests/r.c b/nexus-am/tests/cputest/tests/r.c
deleted file mode 100644
index a2a1bea..0000000
--- a/nexus-am/tests/cputest/tests/r.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "trap.h"
-
-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, 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 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 ++) {
-			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(i == NR_DATA);
-
-	return 0;
-}
-- 
GitLab