From b07319133dcbd3da318cd7559f0dc95305b19c43 Mon Sep 17 00:00:00 2001 From: Recolic Keghart <root@recolic.net> Date: Thu, 26 Dec 2019 17:50:19 +0800 Subject: [PATCH] > Manual commit: [DO NOT BUILD] tmp save my work U201614531 recolic Linux RECOLICPC 5.4.2-arch1-1 #1 SMP PREEMPT Thu, 05 Dec 2019 12:29:40 +0000 x86_64 GNU/Linux 17:50:19 up 3 days, 22:58, 1 user, load average: 0.86, 0.51, 0.48 66e2b24dcce06cb614c08d513ef02c8b8d206c20 --- nemu/Makefile | 2 +- nemu/include/cpu/rtl.h | 13 ++++++- nemu/include/util.h | 12 ------ nemu/include/util/util.h | 18 +++++++++ nemu/src/cpu/exec/arith.cc | 73 ++++++++++++++++++++++------------- nemu/src/cpu/exec/cc.cc | 29 ++++++++++---- nemu/src/cpu/exec/data-mov.cc | 10 ++++- nemu/src/cpu/exec/logic.cc | 12 +++++- 8 files changed, 118 insertions(+), 51 deletions(-) delete mode 100644 nemu/include/util.h create mode 100644 nemu/include/util/util.h diff --git a/nemu/Makefile b/nemu/Makefile index 6c8e56e..2a7eb67 100644 --- a/nemu/Makefile +++ b/nemu/Makefile @@ -19,7 +19,7 @@ include Makefile.git CXX ?= g++ LD = $(CXX) INCLUDES = $(addprefix -I, $(INC_DIR)) -CFLAGS += -O2 -MMD -Wall -ggdb3 $(INCLUDES) -fomit-frame-pointer +CFLAGS += -O2 -MMD -Wall -ggdb3 $(INCLUDES) -fomit-frame-pointer -std=c++17 CFLAGS += -DDIFF_TEST_QEMU # Files to be compiled diff --git a/nemu/include/cpu/rtl.h b/nemu/include/cpu/rtl.h index ef1f014..273f134 100644 --- a/nemu/include/cpu/rtl.h +++ b/nemu/include/cpu/rtl.h @@ -5,6 +5,7 @@ #include "util/c_op.h" #include "cpu/relop.h" #include "cpu/rtl-wrapper.h" +#include <util/util.h> extern rtlreg_t t0, t1, t2, t3, at; @@ -159,7 +160,17 @@ static inline void rtl_not(rtlreg_t *dest, const rtlreg_t* src1) { static inline void rtl_sext(rtlreg_t* dest, const rtlreg_t* src1, int width) { // dest <- signext(src1[(width * 8 - 1) .. 0]) - TODO(); + switch(width) { + case 1: + *dest = rlib::signed_extend_low_bytes<1>(*src1); + return; + case 2: + *dest = rlib::signed_extend_low_bytes<2>(*src1); + return; + case 4: + *dest = rlib::signed_extend_low_bytes<4>(*src1); + return; + } } template <int OperandBytes> diff --git a/nemu/include/util.h b/nemu/include/util.h deleted file mode 100644 index b46505e..0000000 --- a/nemu/include/util.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef RLIB_HUST_UTIL_HPP_ -#define RLIB_HUST_UTIL_HPP_ 1 - -#include <common.h> - -namespace rlib { - static inline int32_t signed_extend_low8b(const int32_t &val) { - return (int8_t)val; - } -} - -#endif diff --git a/nemu/include/util/util.h b/nemu/include/util/util.h new file mode 100644 index 0000000..330a1d9 --- /dev/null +++ b/nemu/include/util/util.h @@ -0,0 +1,18 @@ +#ifndef RLIB_HUST_UTIL_HPP_ +#define RLIB_HUST_UTIL_HPP_ 1 + +#include <common.h> + +namespace rlib { + template <size_t BytesCount> + static inline int32_t signed_extend_low_bytes(const int32_t &val) { + static_assert(BytesCount == 1 || BytesCount == 2 || BytesCount == 4); + if constexpr(BytesCount == 1) + return (int8_t)val; + else if constexpr(BytesCount == 2) + return (int16_t)val; + else return val; + } +} + +#endif diff --git a/nemu/src/cpu/exec/arith.cc b/nemu/src/cpu/exec/arith.cc index f3a983c..0a10a39 100644 --- a/nemu/src/cpu/exec/arith.cc +++ b/nemu/src/cpu/exec/arith.cc @@ -1,36 +1,32 @@ #include "cpu/exec.h" -#include <util.h> +#include <util/util.h> make_EHelper(add) { - TODO(); + rtl_sext(&t1, &id_dest->val, id_dest->width); + 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); + rtl_update_ZFSF(&t0, 4); + operand_write(id_dest, &t0); print_asm_template2(add); } make_EHelper(sub) { - t1 = id_dest->val; - - if(id_src->width == 1 && id_dest->width > 1) { - uint32_t extended = rlib::signed_extend_low8b(id_src->simm); - rtl_sub(&id_dest->val, &id_dest->val, &extended); - } - else { - rtl_sub(&id_dest->val, &id_dest->val, &id_src->imm); - } - //int sr = get_s(id_dest->val, id_dest->width); - operand_write(id_dest, &id_dest->val); + rtl_sext(&t1, &id_dest->val, id_dest->width); + rtl_sext(&t2, &id_src->val, id_src->width); - rtl_setrelop(RELOP_LTU, &t0, &t1, &id_dest->val); - rtl_set_CF(&t0); - - rtl_xor(&t0, &t1, &id_src->val); - rtl_xor(&t2, &id_dest->val, &t1); - rtl_and(&t0, &t0, &t2); - rtl_msb(&t0, &t0, id_dest->width); - rtl_set_OF(&t0); - - rtl_update_ZFSF(&id_dest->val, id_dest->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); + rtl_update_ZFSF(&t0, 4); + operand_write(id_dest, &t0); print_asm_template2(sub); } @@ -38,19 +34,44 @@ make_EHelper(sub) { make_EHelper(cmp) { - TODO(); + 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); + rtl_update_ZFSF(&t0, 4); print_asm_template2(cmp); } make_EHelper(inc) { - TODO(); + 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); print_asm_template1(inc); } make_EHelper(dec) { - TODO(); + 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); print_asm_template1(dec); } diff --git a/nemu/src/cpu/exec/cc.cc b/nemu/src/cpu/exec/cc.cc index 793991b..3af0622 100644 --- a/nemu/src/cpu/exec/cc.cc +++ b/nemu/src/cpu/exec/cc.cc @@ -14,14 +14,27 @@ void rtl_setcc(rtlreg_t* dest, uint8_t subcode) { // TODO: Query EFLAGS to determine whether the condition code is satisfied. // dest <- ( cc is satisfied ? 1 : 0) switch (subcode & 0xe) { - case CC_O: - case CC_B: - case CC_E: - case CC_BE: - case CC_S: - case CC_L: - case CC_LE: - TODO(); + case CC_O: //0 + *dest = cpu_eflags::get<cpu_eflags::OF>(); + break; + case CC_B: //2 + *dest = cpu_eflags::get<cpu_eflags::CF>(); + break; + case CC_E: //4 + *dest = cpu_eflags::get<cpu_eflags::ZF>(); + break; + case CC_BE: //6 + *dest = ((cpu_eflags::get<cpu_eflags::CF>()) || (cpu_eflags::get<cpu_eflags::ZF>())); + break; + case CC_S: //8 + *dest = cpu_eflags::get<cpu_eflags::SF>(); + break; + case CC_L: //12 c + *dest = (cpu_eflags::get<cpu_eflags::SF>() != cpu_eflags::get<cpu_eflags::OF>()); + break; + case CC_LE: //14 e + *dest = ((cpu_eflags::get<cpu_eflags::ZF>()) || (cpu_eflags::get<cpu_eflags::SF>() != cpu_eflags::get<cpu_eflags::OF>())); + break; default: panic("should not reach here"); case CC_P: panic("n86 does not have PF"); } diff --git a/nemu/src/cpu/exec/data-mov.cc b/nemu/src/cpu/exec/data-mov.cc index bff93e3..6182ede 100644 --- a/nemu/src/cpu/exec/data-mov.cc +++ b/nemu/src/cpu/exec/data-mov.cc @@ -47,7 +47,15 @@ make_EHelper(popa) { } make_EHelper(leave) { - TODO(); + rtl_mv(&cpu.esp, &cpu.ebp); + if(decoding.is_operand_size_16) { + rtlreg_t tmpReg; + rtl_pop<2>(&tmpReg); + reg_w(R_BP) = (uint16_t)tmpReg; + } + else { + rtl_pop<4>(&cpu.ebp); + } print_asm("leave"); } diff --git a/nemu/src/cpu/exec/logic.cc b/nemu/src/cpu/exec/logic.cc index 50d56e2..dd28dfc 100644 --- a/nemu/src/cpu/exec/logic.cc +++ b/nemu/src/cpu/exec/logic.cc @@ -2,13 +2,21 @@ #include "cpu/cc.h" make_EHelper(test) { - TODO(); + // `and` without write_back. + rtl_and(&t1, &id_dest->val, &id_src->val); + + rtl_update_ZFSF(&t1, id_dest->width); + cpu_eflags::get<cpu_eflags::CF>() = cpu_eflags::get<cpu_eflags::OF>() = false; print_asm_template2(test); } make_EHelper(and) { - TODO(); + rtl_and(&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(and); } -- GitLab