From 6376008f9f59e3c8f077843848021fc064a233c9 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 15 May 2019 00:44:59 -0700 Subject: 5159 One more instruction where I forgot to update the carry flag. --- subx/015immediate_addressing.cc | 79 +++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 11 deletions(-) (limited to 'subx') diff --git a/subx/015immediate_addressing.cc b/subx/015immediate_addressing.cc index 4210c024..4212b80f 100644 --- a/subx/015immediate_addressing.cc +++ b/subx/015immediate_addressing.cc @@ -1012,27 +1012,84 @@ case 7: { ZF = (tmp1 == 0); const int64_t tmp2 = static_cast(*signed_arg1) - signed_arg2; OF = (tmp1 != tmp2); + const uint32_t unsigned_arg1 = static_cast(*signed_arg1); + const uint32_t unsigned_arg2 = static_cast(signed_arg2); + const uint32_t tmp3 = unsigned_arg1 - unsigned_arg2; + const uint64_t tmp4 = static_cast(unsigned_arg1) - unsigned_arg2; + CF = (tmp3 != tmp4); trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); break; } :(code) -void test_compare_imm32_with_r32_lesser() { - Reg[EBX].i = 0x0d0c0b07; +void test_compare_rm32_with_imm32_lesser_unsigned_and_signed() { + Reg[EAX].i = 0x0a0b0c07; run( "== 0x1\n" // code segment // op ModR/M SIB displacement immediate - " 81 fb 0a 0b 0c 0d \n" // compare 0x0d0c0b0a with EBX - // ModR/M in binary: 11 (direct mode) 111 (subop compare) 011 (dest EBX) + " 81 f8 0d 0c 0b 0a \n" // compare EAX with imm32 + // ModR/M in binary: 11 (direct mode) 111 (subop compare) 000 (dest EAX) ); CHECK_TRACE_CONTENTS( "run: combine imm32 with r/m32\n" - "run: r/m32 is EBX\n" - "run: imm32 is 0x0d0c0b0a\n" + "run: r/m32 is EAX\n" + "run: imm32 is 0x0a0b0c0d\n" + "run: subop compare\n" + "run: SF=1; ZF=0; CF=1; OF=0\n" + ); +} + +void test_compare_rm32_with_imm32_lesser_unsigned_and_signed_due_to_overflow() { + Reg[EAX].i = 0x7fffffff; // largest positive signed integer + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 81 f8 00 00 00 80\n" // compare EAX with smallest negative signed integer + // ModR/M in binary: 11 (direct mode) 111 (subop compare) 000 (dest EAX) + ); + CHECK_TRACE_CONTENTS( + "run: combine imm32 with r/m32\n" + "run: r/m32 is EAX\n" + "run: imm32 is 0x80000000\n" + "run: subop compare\n" + "run: SF=1; ZF=0; CF=1; OF=1\n" + ); +} + +void test_compare_rm32_with_imm32_lesser_signed() { + Reg[EAX].i = 0xffffffff; // -1 + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 81 f8 01 00 00 00\n" // compare EAX with 1 + // ModR/M in binary: 11 (direct mode) 111 (subop compare) 000 (dest EAX) + ); + CHECK_TRACE_CONTENTS( + "run: combine imm32 with r/m32\n" + "run: r/m32 is EAX\n" + "run: imm32 is 0x00000001\n" + "run: subop compare\n" "run: SF=1; ZF=0; CF=0; OF=0\n" ); } +void test_compare_rm32_with_imm32_lesser_unsigned() { + Reg[EAX].i = 0x00000001; // 1 + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 81 f8 ff ff ff ff\n" // compare EAX with -1 + // ModR/M in binary: 11 (direct mode) 111 (subop compare) 000 (dest EAX) + ); + CHECK_TRACE_CONTENTS( + "run: combine imm32 with r/m32\n" + "run: r/m32 is EAX\n" + "run: imm32 is 0xffffffff\n" + "run: subop compare\n" + "run: SF=0; ZF=0; CF=1; OF=0\n" + ); +} + :(code) void test_compare_imm32_with_r32_equal() { Reg[EBX].i = 0x0d0c0b0a; @@ -1071,20 +1128,20 @@ void test_compare_imm32_with_mem_at_r32_greater() { :(code) void test_compare_imm32_with_mem_at_r32_lesser() { - Reg[EBX].i = 0x2000; + Reg[EAX].i = 0x2000; run( "== 0x1\n" // code segment // op ModR/M SIB displacement immediate - " 81 3b 0a 0b 0c 0d \n" // compare 0x0d0c0b0a with *EBX - // ModR/M in binary: 00 (indirect mode) 111 (subop compare) 011 (dest EBX) + " 81 38 0a 0b 0c 0d \n" // compare 0x0d0c0b0a with *EAX + // ModR/M in binary: 00 (indirect mode) 111 (subop compare) 000 (dest EAX) "== 0x2000\n" // data segment "07 0b 0c 0d\n" // 0x0d0c0b07 ); CHECK_TRACE_CONTENTS( "run: combine imm32 with r/m32\n" - "run: effective address is 0x00002000 (EBX)\n" + "run: effective address is 0x00002000 (EAX)\n" "run: imm32 is 0x0d0c0b0a\n" - "run: SF=1; ZF=0; CF=0; OF=0\n" + "run: SF=1; ZF=0; CF=1; OF=0\n" ); } -- cgit 1.4.1-2-gfad0 From 4ff14e821ee86c40866a1400dc67a4206271b9b5 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 15 May 2019 00:48:48 -0700 Subject: 5160 --- subx/013direct_addressing.cc | 4 ++-- subx/014indirect_addressing.cc | 8 ++++---- subx/015immediate_addressing.cc | 10 ---------- 3 files changed, 6 insertions(+), 16 deletions(-) (limited to 'subx') diff --git a/subx/013direct_addressing.cc b/subx/013direct_addressing.cc index 2914e0dd..3f7d40d6 100644 --- a/subx/013direct_addressing.cc +++ b/subx/013direct_addressing.cc @@ -338,7 +338,7 @@ void test_negate_r32() { run( "== 0x1\n" // code segment // op ModR/M SIB displacement immediate - " f7 db \n" // negate EBX + " f7 db \n" // negate EBX // ModR/M in binary: 11 (direct mode) 011 (subop negate) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( @@ -375,7 +375,7 @@ void test_negate_can_overflow() { run( "== 0x1\n" // code segment // op ModR/M SIB displacement immediate - " f7 db \n" // negate EBX + " f7 db \n" // negate EBX // ModR/M in binary: 11 (direct mode) 011 (subop negate) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( diff --git a/subx/014indirect_addressing.cc b/subx/014indirect_addressing.cc index a281921f..ce523b3f 100644 --- a/subx/014indirect_addressing.cc +++ b/subx/014indirect_addressing.cc @@ -7,7 +7,7 @@ void test_add_r32_to_mem_at_r32() { run( "== 0x1\n" // code segment // op ModR/M SIB displacement immediate - " 01 18 \n" // add EBX to *EAX + " 01 18 \n" // add EBX to *EAX // ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) "== 0x2000\n" // data segment "01 00 00 00\n" // 0x00000001 @@ -42,7 +42,7 @@ void test_add_mem_at_r32_to_r32() { run( "== 0x1\n" // code segment // op ModR/M SIB displacement immediate - " 03 18 \n" // add *EAX to EBX + " 03 18 \n" // add *EAX to EBX // ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) "== 0x2000\n" // data segment "01 00 00 00\n" // 0x00000001 @@ -146,7 +146,7 @@ void test_subtract_r32_from_mem_at_r32() { run( "== 0x1\n" // code segment // op ModR/M SIB displacement immediate - " 29 18 \n" // subtract EBX from *EAX + " 29 18 \n" // subtract EBX from *EAX // ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) "== 0x2000\n" // data segment "0a 00 00 00\n" // 0x0000000a @@ -336,7 +336,7 @@ void test_or_r32_with_mem_at_r32() { run( "== 0x1\n" // code segment // op ModR/M SIB displacement immediate - " 09 18 #\n" // EBX with *EAX + " 09 18 #\n" // EBX with *EAX // ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) "== 0x2000\n" // data segment "0d 0c 0b 0a\n" // 0x0a0b0c0d diff --git a/subx/015immediate_addressing.cc b/subx/015immediate_addressing.cc index 4212b80f..8a5a3c20 100644 --- a/subx/015immediate_addressing.cc +++ b/subx/015immediate_addressing.cc @@ -30,7 +30,6 @@ void test_add_imm32_to_EAX_signed_overflow() { "== 0x1\n" // code segment // op ModR/M SIB displacement immediate " 05 01 00 00 00 \n" // add 1 to EAX - // ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) ); CHECK_TRACE_CONTENTS( "run: add imm32 0x00000001 to EAX\n" @@ -46,7 +45,6 @@ void test_add_imm32_to_EAX_unsigned_overflow() { "== 0x1\n" // code segment // op ModR/M SIB displacement immediate " 05 01 00 00 00 \n" // add 1 to EAX - // ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) ); CHECK_TRACE_CONTENTS( "run: add imm32 0x00000001 to EAX\n" @@ -61,7 +59,6 @@ void test_add_imm32_to_EAX_unsigned_and_signed_overflow() { "== 0x1\n" // code segment // op ModR/M SIB displacement immediate " 05 00 00 00 80 \n" // add 0x80000000 to EAX - // ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) ); CHECK_TRACE_CONTENTS( "run: add imm32 0x80000000 to EAX\n" @@ -251,7 +248,6 @@ void test_subtract_imm32_from_EAX_signed_overflow() { "== 0x1\n" // code segment // op ModR/M SIB displacement immediate " 2d ff ff ff 7f \n" // subtract largest positive signed integer from EAX - // ModR/M in binary: 00 (indirect mode) 101 (subop subtract) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( "run: subtract imm32 0x7fffffff from EAX\n" @@ -266,7 +262,6 @@ void test_subtract_imm32_from_EAX_unsigned_overflow() { "== 0x1\n" // code segment // op ModR/M SIB displacement immediate " 2d 01 00 00 00 \n" // subtract 1 from EAX - // ModR/M in binary: 00 (indirect mode) 101 (subop subtract) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( "run: subtract imm32 0x00000001 from EAX\n" @@ -281,7 +276,6 @@ void test_subtract_imm32_from_EAX_signed_and_unsigned_overflow() { "== 0x1\n" // code segment // op ModR/M SIB displacement immediate " 2d 00 00 00 80 \n" // subtract smallest negative signed integer from EAX - // ModR/M in binary: 00 (indirect mode) 101 (subop subtract) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( "run: subtract imm32 0x80000000 from EAX\n" @@ -923,7 +917,6 @@ void test_compare_EAX_with_imm32_lesser_unsigned_and_signed() { "== 0x1\n" // code segment // op ModR/M SIB displacement immediate " 3d 0d 0c 0b 0a \n" // compare EAX with imm32 - // ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) ); CHECK_TRACE_CONTENTS( "run: compare EAX with imm32 0x0a0b0c0d\n" @@ -937,7 +930,6 @@ void test_compare_EAX_with_imm32_lesser_unsigned_and_signed_due_to_overflow() { "== 0x1\n" // code segment // op ModR/M SIB displacement immediate " 3d 00 00 00 80\n" // compare EAX with smallest negative signed integer - // ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) ); CHECK_TRACE_CONTENTS( "run: compare EAX with imm32 0x80000000\n" @@ -951,7 +943,6 @@ void test_compare_EAX_with_imm32_lesser_signed() { "== 0x1\n" // code segment // op ModR/M SIB displacement immediate " 3d 01 00 00 00\n" // compare EAX with 1 - // ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) ); CHECK_TRACE_CONTENTS( "run: compare EAX with imm32 0x00000001\n" @@ -965,7 +956,6 @@ void test_compare_EAX_with_imm32_lesser_unsigned() { "== 0x1\n" // code segment // op ModR/M SIB displacement immediate " 3d ff ff ff ff\n" // compare EAX with -1 - // ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) ); CHECK_TRACE_CONTENTS( "run: compare EAX with imm32 0xffffffff\n" -- cgit 1.4.1-2-gfad0 From 7944f15210d0dd715b1b90a53d30602c09dfac8e Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 15 May 2019 00:49:48 -0700 Subject: 5161 --- subx/015immediate_addressing.cc | 54 ++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'subx') diff --git a/subx/015immediate_addressing.cc b/subx/015immediate_addressing.cc index 8a5a3c20..c5469792 100644 --- a/subx/015immediate_addressing.cc +++ b/subx/015immediate_addressing.cc @@ -82,7 +82,7 @@ void test_add_imm32_to_r32() { // ModR/M in binary: 11 (direct mode) 000 (subop add) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: r/m32 is EBX\n" "run: imm32 is 0x0d0c0b0a\n" "run: subop add\n" @@ -91,8 +91,8 @@ void test_add_imm32_to_r32() { } :(before "End Single-Byte Opcodes") -case 0x81: { // combine imm32 with r/m32 - trace(Callstack_depth+1, "run") << "combine imm32 with r/m32" << end(); +case 0x81: { // combine r/m32 with imm32 + trace(Callstack_depth+1, "run") << "combine r/m32 with imm32" << end(); const uint8_t modrm = next(); int32_t* signed_arg1 = effective_address(modrm); const int32_t signed_arg2 = next32(); @@ -135,7 +135,7 @@ void test_add_imm32_to_r32_signed_overflow() { // ModR/M in binary: 11 (direct mode) 000 (subop add) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: r/m32 is EBX\n" "run: imm32 is 0x00000001\n" "run: subop add\n" @@ -153,7 +153,7 @@ void test_add_imm32_to_r32_unsigned_overflow() { // ModR/M in binary: 11 (direct mode) 011 (subop add) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: r/m32 is EBX\n" "run: imm32 is 0x00000001\n" "run: subop add\n" @@ -171,7 +171,7 @@ void test_add_imm32_to_r32_unsigned_and_signed_overflow() { // ModR/M in binary: 11 (direct mode) 011 (subop add) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: r/m32 is EBX\n" "run: imm32 is 0x80000000\n" "run: subop add\n" @@ -194,7 +194,7 @@ void test_add_imm32_to_mem_at_r32() { "01 00 00 00\n" // 0x00000001 ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: effective address is 0x00002000 (EBX)\n" "run: imm32 is 0x0d0c0b0a\n" "run: subop add\n" @@ -297,7 +297,7 @@ void test_subtract_imm32_from_mem_at_r32() { "0a 00 00 00\n" // 0x0000000a ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: effective address is 0x00002000 (EBX)\n" "run: imm32 is 0x00000001\n" "run: subop subtract\n" @@ -337,7 +337,7 @@ void test_subtract_imm32_from_mem_at_r32_signed_overflow() { "00 00 00 80\n" // smallest negative signed integer ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: effective address is 0x00002000 (EBX)\n" "run: effective address contains 80000000\n" "run: imm32 is 0x7fffffff\n" @@ -358,7 +358,7 @@ void test_subtract_imm32_from_mem_at_r32_unsigned_overflow() { "00 00 00 00\n" // 0 ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: effective address is 0x00002000 (EBX)\n" "run: effective address contains 0\n" "run: imm32 is 0x00000001\n" @@ -379,7 +379,7 @@ void test_subtract_imm32_from_mem_at_r32_signed_and_unsigned_overflow() { "00 00 00 00\n" // 0 ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: effective address is 0x00002000 (EBX)\n" "run: effective address contains 0\n" "run: imm32 is 0x80000000\n" @@ -400,7 +400,7 @@ void test_subtract_imm32_from_r32() { // ModR/M in binary: 11 (direct mode) 101 (subop subtract) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: r/m32 is EBX\n" "run: imm32 is 0x00000001\n" "run: subop subtract\n" @@ -649,7 +649,7 @@ void test_and_imm32_with_mem_at_r32() { "ff 00 00 00\n" // 0x000000ff ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: effective address is 0x00002000 (EBX)\n" "run: imm32 is 0x0d0c0b0a\n" "run: subop and\n" @@ -684,7 +684,7 @@ void test_and_imm32_with_r32() { // ModR/M in binary: 11 (direct mode) 100 (subop and) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: r/m32 is EBX\n" "run: imm32 is 0x0d0c0b0a\n" "run: subop and\n" @@ -741,7 +741,7 @@ void test_or_imm32_with_mem_at_r32() { "a0 b0 c0 d0\n" // 0xd0c0b0a0 ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: effective address is 0x00002000 (EBX)\n" "run: imm32 is 0x0d0c0b0a\n" "run: subop or\n" @@ -774,7 +774,7 @@ void test_or_imm32_with_r32() { // ModR/M in binary: 11 (direct mode) 001 (subop or) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: r/m32 is EBX\n" "run: imm32 is 0x0d0c0b0a\n" "run: subop or\n" @@ -831,7 +831,7 @@ void test_xor_imm32_with_mem_at_r32() { "a0 b0 c0 d0\n" // 0xd0c0b0a0 ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: effective address is 0x00002000 (EBX)\n" "run: imm32 is 0x0d0c0b0a\n" "run: subop xor\n" @@ -864,7 +864,7 @@ void test_xor_imm32_with_r32() { // ModR/M in binary: 11 (direct mode) 110 (subop xor) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: r/m32 is EBX\n" "run: imm32 is 0x0d0c0b0a\n" "run: subop xor\n" @@ -987,7 +987,7 @@ void test_compare_imm32_with_r32_greater() { // ModR/M in binary: 11 (direct mode) 111 (subop compare) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: r/m32 is EBX\n" "run: imm32 is 0x0d0c0b07\n" "run: SF=0; ZF=0; CF=0; OF=0\n" @@ -1021,7 +1021,7 @@ void test_compare_rm32_with_imm32_lesser_unsigned_and_signed() { // ModR/M in binary: 11 (direct mode) 111 (subop compare) 000 (dest EAX) ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: r/m32 is EAX\n" "run: imm32 is 0x0a0b0c0d\n" "run: subop compare\n" @@ -1038,7 +1038,7 @@ void test_compare_rm32_with_imm32_lesser_unsigned_and_signed_due_to_overflow() { // ModR/M in binary: 11 (direct mode) 111 (subop compare) 000 (dest EAX) ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: r/m32 is EAX\n" "run: imm32 is 0x80000000\n" "run: subop compare\n" @@ -1055,7 +1055,7 @@ void test_compare_rm32_with_imm32_lesser_signed() { // ModR/M in binary: 11 (direct mode) 111 (subop compare) 000 (dest EAX) ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: r/m32 is EAX\n" "run: imm32 is 0x00000001\n" "run: subop compare\n" @@ -1072,7 +1072,7 @@ void test_compare_rm32_with_imm32_lesser_unsigned() { // ModR/M in binary: 11 (direct mode) 111 (subop compare) 000 (dest EAX) ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: r/m32 is EAX\n" "run: imm32 is 0xffffffff\n" "run: subop compare\n" @@ -1090,7 +1090,7 @@ void test_compare_imm32_with_r32_equal() { // ModR/M in binary: 11 (direct mode) 111 (subop compare) 011 (dest EBX) ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: r/m32 is EBX\n" "run: imm32 is 0x0d0c0b0a\n" "run: SF=0; ZF=1; CF=0; OF=0\n" @@ -1109,7 +1109,7 @@ void test_compare_imm32_with_mem_at_r32_greater() { "0a 0b 0c 0d\n" // 0x0d0c0b0a ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: effective address is 0x00002000 (EBX)\n" "run: imm32 is 0x0d0c0b07\n" "run: SF=0; ZF=0; CF=0; OF=0\n" @@ -1128,7 +1128,7 @@ void test_compare_imm32_with_mem_at_r32_lesser() { "07 0b 0c 0d\n" // 0x0d0c0b07 ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: effective address is 0x00002000 (EAX)\n" "run: imm32 is 0x0d0c0b0a\n" "run: SF=1; ZF=0; CF=1; OF=0\n" @@ -1148,7 +1148,7 @@ void test_compare_imm32_with_mem_at_r32_equal() { "0a 0b 0c 0d\n" // 0x0d0c0b0a ); CHECK_TRACE_CONTENTS( - "run: combine imm32 with r/m32\n" + "run: combine r/m32 with imm32\n" "run: effective address is 0x00002000 (EBX)\n" "run: imm32 is 0x0d0c0b0a\n" "run: SF=0; ZF=1; CF=0; OF=0\n" -- cgit 1.4.1-2-gfad0 From b888e42867d43e1ef2b308b42a7af7dbac578c87 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 15 May 2019 00:58:25 -0700 Subject: 5162 --- subx/015immediate_addressing.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'subx') diff --git a/subx/015immediate_addressing.cc b/subx/015immediate_addressing.cc index c5469792..bfedac21 100644 --- a/subx/015immediate_addressing.cc +++ b/subx/015immediate_addressing.cc @@ -754,13 +754,13 @@ case 1: { trace(Callstack_depth+1, "run") << "subop or" << end(); // bitwise ops technically operate on unsigned numbers, but it makes no // difference - *signed_arg1 |= signed_arg2; \ - trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *signed_arg1 << end(); \ - SF = (*signed_arg1 >> 31); \ - ZF = (*signed_arg1 == 0); \ - CF = false; \ - OF = false; \ - trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); \ + *signed_arg1 |= signed_arg2; + trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *signed_arg1 << end(); + SF = (*signed_arg1 >> 31); + ZF = (*signed_arg1 == 0); + CF = false; + OF = false; + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); break; } -- cgit 1.4.1-2-gfad0 From cecb9d7688a2a969cd28b8cfef8370f2c83e8a16 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 15 May 2019 01:07:22 -0700 Subject: 5163 A few more places with flag corrections. --- subx/013direct_addressing.cc | 28 ++++++++++++++++++---------- subx/015immediate_addressing.cc | 10 +++++++++- 2 files changed, 27 insertions(+), 11 deletions(-) (limited to 'subx') diff --git a/subx/013direct_addressing.cc b/subx/013direct_addressing.cc index 3f7d40d6..9c314b02 100644 --- a/subx/013direct_addressing.cc +++ b/subx/013direct_addressing.cc @@ -279,6 +279,8 @@ case 0xf7: { Reg[EAX].u = result & 0xffffffff; Reg[EDX].u = result >> 32; OF = (Reg[EDX].u != 0); + CF = OF; + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << Reg[EAX].u << end(); break; } @@ -360,11 +362,14 @@ case 3: { // negate r/m32 OF = true; break; } - *arg1 = -(*arg1); - trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); - SF = (*arg1 >> 31); - ZF = (*arg1 == 0); + int32_t result = -(*arg1); + SF = (result >> 31); + ZF = (result == 0); OF = false; + CF = (*arg1 != 0); + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); + *arg1 = result; + trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } @@ -518,9 +523,12 @@ case 0xd3: { bool pnsb = (*arg1 & 0x40000000); OF = (msb != pnsb); } - *arg1 = (*arg1 << count); - ZF = (*arg1 == 0); - SF = (*arg1 < 0); + int32_t result = (*arg1 << count); + ZF = (result == 0); + SF = (result < 0); + CF = (*arg1 << (count-1)) & 0x80000000; + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); + *arg1 = result; trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } @@ -561,6 +569,7 @@ case 7: { // shift right r/m32 by CL, preserving sign SF = (*arg1 < 0); // OF is only defined if count is 1 if (count == 1) OF = false; + // CF undefined trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } @@ -638,6 +647,7 @@ case 5: { // shift right r/m32 by CL, padding zeroes ZF = (*uarg1 == 0); // result is always positive by definition SF = false; + // CF undefined trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } @@ -822,9 +832,7 @@ case 2: { // not r/m32 trace(Callstack_depth+1, "run") << "subop: not" << end(); *arg1 = ~(*arg1); trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); - SF = (*arg1 >> 31); - ZF = (*arg1 == 0); - OF = false; + // no flags affected break; } diff --git a/subx/015immediate_addressing.cc b/subx/015immediate_addressing.cc index bfedac21..478e3592 100644 --- a/subx/015immediate_addressing.cc +++ b/subx/015immediate_addressing.cc @@ -449,6 +449,8 @@ case 0xc1: { *arg1 = (*arg1 << count); ZF = (*arg1 == 0); SF = (*arg1 < 0); + // CF undefined + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } @@ -483,11 +485,15 @@ void test_shift_right_arithmetic_r32_with_imm8() { case 7: { // shift right r/m32 by CL, preserving sign trace(Callstack_depth+1, "run") << "subop: shift right by CL bits, while preserving sign" << end(); uint8_t count = next() & 0x1f; - *arg1 = (*arg1 >> count); + int32_t result = (*arg1 >> count); ZF = (*arg1 == 0); SF = (*arg1 < 0); // OF is only defined if count is 1 if (count == 1) OF = false; + // CF + CF = ((*arg1 >> (count-1)) & 0x1); + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); + *arg1 = result; trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } @@ -562,6 +568,8 @@ case 5: { // shift right r/m32 by CL, preserving sign ZF = (*uarg1 == 0); // result is always positive by definition SF = false; + // CF undefined + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } -- cgit 1.4.1-2-gfad0