diff --git a/nemu/include/cpu/decode.h b/nemu/include/cpu/decode.h index 720c93fa456ec0ecb72c79c68d9329fc61130f23..26109f79cf4e092c6f919d456c30fd3fb3654e36 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 a0ee63680381e20a6acb65042c98db3d7635b3ab..0fd8c65de53aede981ae8557ea566eb5f55a4fd1 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 9f47be6a63d25b5da666879a2cbfca54c997495d..7b965e3d746677d41fd43aff9146f14f317f16a0 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 7fbd98cf98ba34a72f12a2f06b8ca75466183940..f4ac3ff052719908631016cfac08cba62b6d8bca 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 78d7a61d8ef288ed240114bb733b045ba798a11b..c890af268f76ccc11e7d4f20f881696df417899e 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 67ab9e7c1f81db6de5243a2b58826a7988a19fcc..3c67656de60b0c26d801a851b00a8a3dd5de09d2 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),