From 298b717d990f345061f8bf145f5fa07b46fb4868 Mon Sep 17 00:00:00 2001
From: Recolic Keghart <root@recolic.net>
Date: Sun, 29 Dec 2019 03:11:31 +0800
Subject: [PATCH] >  Manual commit:  add movs, reconstruct arith. U201614531
 recolic Linux RECOLICPC 5.4.6-arch3-1 #1 SMP PREEMPT Tue, 24 Dec 2019
 04:36:53 +0000 x86_64 GNU/Linux  03:11:31 up  8:45,  1 user,  load average:
 0.32, 0.54, 0.71 9d85abd478d81af6df0544f9fb8670238f902f2

---
 nemu/include/cpu/decode.h     |  1 +
 nemu/include/cpu/reg.h        |  2 +-
 nemu/src/cpu/exec/all-instr.h |  1 +
 nemu/src/cpu/exec/arith.cc    | 43 +++++++++++++++++------------------
 nemu/src/cpu/exec/data-mov.cc | 26 +++++++++++++++++++++
 nemu/src/cpu/exec/exec.cc     |  2 +-
 6 files changed, 51 insertions(+), 24 deletions(-)

diff --git a/nemu/include/cpu/decode.h b/nemu/include/cpu/decode.h
index 720c93f..26109f7 100644
--- a/nemu/include/cpu/decode.h
+++ b/nemu/include/cpu/decode.h
@@ -87,6 +87,7 @@ namespace DHelperImpl {
   make_DHelper(I_E2G);
   make_DHelper(I_G2E);
   make_DHelper(I);
+  make_DHelper(O);
   make_DHelper(r);
   make_DHelper(E);
   make_DHelper(setcc_E);
diff --git a/nemu/include/cpu/reg.h b/nemu/include/cpu/reg.h
index a0ee636..0fd8c65 100644
--- a/nemu/include/cpu/reg.h
+++ b/nemu/include/cpu/reg.h
@@ -35,7 +35,7 @@ typedef union {
 extern CPU_state cpu;
 
 namespace cpu_eflags {
-  enum {CF = 0, PF, AF, ZF, SF, OF, SIZE_OF_EFLAGS};
+  enum {CF = 0, PF, AF, ZF, SF, OF, DF, SIZE_OF_EFLAGS};
   template <size_t Which>
   inline bool &get() {
     static bool actual_buffer[SIZE_OF_EFLAGS];
diff --git a/nemu/src/cpu/exec/all-instr.h b/nemu/src/cpu/exec/all-instr.h
index 9f47be6..7b965e3 100644
--- a/nemu/src/cpu/exec/all-instr.h
+++ b/nemu/src/cpu/exec/all-instr.h
@@ -8,6 +8,7 @@ make_EHelper(pop);
 make_EHelper(pusha);
 make_EHelper(popa);
 make_EHelper(leave);
+make_EHelper(movs);
 make_EHelper(movsx);
 make_EHelper(movzx);
 make_EHelper(cltd);
diff --git a/nemu/src/cpu/exec/arith.cc b/nemu/src/cpu/exec/arith.cc
index 7fbd98c..f4ac3ff 100644
--- a/nemu/src/cpu/exec/arith.cc
+++ b/nemu/src/cpu/exec/arith.cc
@@ -60,37 +60,36 @@ namespace EHelperImpl {
   }
   
   make_EHelper(inc) {
-  	rtl_addi(&t2, &id_dest->val, 1);
-  	operand_write(id_dest, &t2);
-  	rtl_update_ZFSF(&t2, id_dest->width);
-  	rtl_xor(&t0, &id_dest->val, &id_src->val);
-  	rtl_not(&t0, &t0);
-  	rtl_xor(&t1, &id_dest->val, &t2);
-  	rtl_and(&t0, &t0, &t1);
-  	rtl_msb(&t0, &t0, id_dest->width);
-  	rtl_set_OF(&t0);
+    cpu_eflags::get<cpu_eflags::OF>() = id_dest->val == 0x7fffffff;
+
+  	++ id_dest->val;
+  	operand_write(id_dest, &id_dest->val);
+
+  	rtl_update_ZFSF(&id_dest->val, id_dest->width);
   
     print_asm_template1(inc);
   }
   
   make_EHelper(dec) {
-    rtl_subi(&t2, &id_dest->val, 1);
-  	operand_write(id_dest, &t2);
-  
-  	rtl_update_ZFSF(&t2, id_dest->width);
-  
-  	rtl_xor(&t0, &id_dest->val, &id_src->val);
-  	rtl_xor(&t1, &id_dest->val, &t2);
-  	rtl_and(&t0, &t0, &t1);
-  	rtl_msb(&t0, &t0, id_dest->width);
-  	rtl_set_OF(&t0);
-  
+    cpu_eflags::get<cpu_eflags::OF>() = id_dest->val == 0x80000000;
+
+  	-- id_dest->val;
+  	operand_write(id_dest, &id_dest->val);
+
+  	rtl_update_ZFSF(&id_dest->val, id_dest->width);
+
     print_asm_template1(dec);
   }
   
   make_EHelper(neg) {
-    TODO();
-  
+    cpu_eflags::get<cpu_eflags::CF>() = id_dest->val != 0;
+    cpu_eflags::get<cpu_eflags::OF>() = id_dest->val == 0x80000000;
+
+    id_dest->val = - id_dest->val;
+  	operand_write(id_dest, &id_dest->val);
+
+  	rtl_update_ZFSF(&id_dest->val, id_dest->width);
+
     print_asm_template1(neg);
   }
   
diff --git a/nemu/src/cpu/exec/data-mov.cc b/nemu/src/cpu/exec/data-mov.cc
index 78d7a61..c890af2 100644
--- a/nemu/src/cpu/exec/data-mov.cc
+++ b/nemu/src/cpu/exec/data-mov.cc
@@ -102,4 +102,30 @@ namespace EHelperImpl {
     operand_write(id_dest, &id_src->addr);
     print_asm_template2(lea);
   }
+
+  make_EHelper(movs) {
+    // movsb, movsw, movsd
+
+    // address size is always 32bit.
+    const auto source_index = cpu.esi,
+      dest_index = cpu.edi;
+    
+    auto copy_bytes = 4;
+    if(decoding.opcode == 0xa4) {
+      // movsb
+      copy_bytes = 1;
+    }
+    else if(decoding.is_operand_size_16) {
+      // movsw
+      // r: dbt
+      copy_bytes = 2;
+    }
+    else {
+      // movsd
+    }
+
+    vaddr_write(dest_index, vaddr_read(source_index, 4), copy_bytes);
+    
+    print_asm_template2(movs);
+  }
 } // end namespace
diff --git a/nemu/src/cpu/exec/exec.cc b/nemu/src/cpu/exec/exec.cc
index 67ab9e7..3c67656 100644
--- a/nemu/src/cpu/exec/exec.cc
+++ b/nemu/src/cpu/exec/exec.cc
@@ -111,7 +111,7 @@ opcode_entry opcode_table [512] = {
 	/* 0x98 */	EX(cwtl), EX(cltd), IDEX(I,call), EMPTY,
 	/* 0x9c */	EMPTY, EMPTY, EMPTY, EMPTY,
 	/* 0xa0 */	IDEXW(O2a, mov, 1), IDEX(O2a, mov), IDEXW(a2O, mov, 1), IDEX(a2O, mov),
-	/* 0xa4 */	EMPTY, EMPTY, EMPTY, EMPTY,
+	/* 0xa4 */  EX(movs), EX(movs), EMPTY, EMPTY,
 	/* 0xa8 */	IDEXW(I2a,test,1), IDEX(I2a,test), EMPTY, EMPTY,
 	/* 0xac */	EMPTY, EMPTY, EMPTY, EMPTY,
 	/* 0xb0 */	IDEXW(mov_I2r, mov, 1), IDEXW(mov_I2r, mov, 1), IDEXW(mov_I2r, mov, 1), IDEXW(mov_I2r, mov, 1),
-- 
GitLab