From 8c1a69089bcb0be8ee869a3f83c3151a7083e27c Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sun, 12 May 2019 07:36:18 -0700 Subject: snapshot of carry flag implementation Tests failing. This approach seems wrong. I'm not sure even the tests are correct. Also, some open questions: 1. Should setting the overflow flag always set the carry flag? 2. Should the carry flag only be set on add/subtract/compare, or by all arithmetic ops? 3. Had to turn off the -ftrapv flag in `build`. Is there a way to detect overflow without actually causing overflow? Once we start setting CF correctly we have to implement jump above/below instructions (8- and 32-bit displacement variants). https://github.com/akkartik/mu/issues/30 --- subx/014indirect_addressing.cc | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'subx/014indirect_addressing.cc') diff --git a/subx/014indirect_addressing.cc b/subx/014indirect_addressing.cc index 8f0d3325..b8b3d6ce 100644 --- a/subx/014indirect_addressing.cc +++ b/subx/014indirect_addressing.cc @@ -320,7 +320,7 @@ void test_compare_mem_at_r32_with_r32_greater() { CHECK_TRACE_CONTENTS( "run: compare EBX with r/m32\n" "run: effective address is 0x00002000 (EAX)\n" - "run: SF=0; ZF=0; OF=0\n" + "run: SF=0; ZF=0; CF=0; OF=0\n" ); } @@ -339,7 +339,7 @@ void test_compare_mem_at_r32_with_r32_lesser() { CHECK_TRACE_CONTENTS( "run: compare EBX with r/m32\n" "run: effective address is 0x00002000 (EAX)\n" - "run: SF=1; ZF=0; OF=0\n" + "run: SF=1; ZF=0; CF=0; OF=0\n" ); } @@ -358,7 +358,7 @@ void test_compare_mem_at_r32_with_r32_equal() { CHECK_TRACE_CONTENTS( "run: compare EBX with r/m32\n" "run: effective address is 0x00002000 (EAX)\n" - "run: SF=0; ZF=1; OF=0\n" + "run: SF=0; ZF=1; CF=0; OF=0\n" ); } @@ -382,7 +382,7 @@ void test_compare_r32_with_mem_at_r32_greater() { CHECK_TRACE_CONTENTS( "run: compare r/m32 with EBX\n" "run: effective address is 0x00002000 (EAX)\n" - "run: SF=0; ZF=0; OF=0\n" + "run: SF=0; ZF=0; CF=0; OF=0\n" ); } @@ -391,14 +391,19 @@ case 0x3b: { // set SF if r32 < r/m32 const uint8_t modrm = next(); const uint8_t reg1 = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "compare r/m32 with " << rname(reg1) << end(); - const int32_t arg1 = Reg[reg1].i; - const int32_t* arg2 = effective_address(modrm); - const int32_t tmp1 = arg1 - *arg2; - SF = (tmp1 < 0); - ZF = (tmp1 == 0); - int64_t tmp2 = arg1 - *arg2; - OF = (tmp1 != tmp2); - trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; OF=" << OF << end(); + const int32_t signed_arg1 = Reg[reg1].i; + const int32_t* signed_arg2 = effective_address(modrm); + const int32_t signed_difference = signed_arg1 - *signed_arg2; + SF = (signed_difference < 0); + ZF = (signed_difference == 0); + int64_t full_signed_difference = signed_arg1 - *signed_arg2; + OF = (signed_difference != full_signed_difference); + const uint32_t unsigned_arg1 = static_cast(signed_arg1); + const uint32_t unsigned_arg2 = static_cast(*signed_arg2); + const uint32_t unsigned_difference = unsigned_arg1 - unsigned_arg2; + const uint64_t full_unsigned_difference = unsigned_arg1 - unsigned_arg2; + CF = (unsigned_difference != full_unsigned_difference); + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); break; } @@ -417,7 +422,7 @@ void test_compare_r32_with_mem_at_r32_lesser() { CHECK_TRACE_CONTENTS( "run: compare r/m32 with EBX\n" "run: effective address is 0x00002000 (EAX)\n" - "run: SF=1; ZF=0; OF=0\n" + "run: SF=1; ZF=0; CF=0; OF=0\n" ); } @@ -436,7 +441,7 @@ void test_compare_r32_with_mem_at_r32_equal() { CHECK_TRACE_CONTENTS( "run: compare r/m32 with EBX\n" "run: effective address is 0x00002000 (EAX)\n" - "run: SF=0; ZF=1; OF=0\n" + "run: SF=0; ZF=1; CF=0; OF=0\n" ); } -- cgit 1.4.1-2-gfad0