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, ®_l(R_EAX), 2); + rtl_shri(®_l(R_EDX), &t0, 16); } else { - TODO(); + rtl_sari(®_l(R_EDX), ®_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