From 11a3d8762a9a24f01369ae2f60749e571627925c Mon Sep 17 00:00:00 2001 From: florian Date: Tue, 9 Jan 2018 20:04:49 +0000 Subject: [PATCH] * patch by J. Gareth Moreton: - Moved the part that emits the CMOV command outside of the if-else block, because it's the same in both branches and was just duplicated code. - Moved a comment about powers of 2 to be right before the correct if-else block. - Added a couple of comments to explain what the algorithm is doing to obtain the remainder. - Added missing "writeln('ok');" (since 'tmoddiv3.pp' has it) and program header to 'tmoddiv4.pp'. - Changed program name from "testfile2" to "tmoddiv3" in 'tmoddiv3.pp'. git-svn-id: trunk@37939 - --- compiler/x86/nx86mat.pas | 26 ++++++++++++-------------- tests/test/cg/tmoddiv3.pp | 2 +- tests/test/cg/tmoddiv4.pp | 2 ++ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/compiler/x86/nx86mat.pas b/compiler/x86/nx86mat.pas index d0b20aa562..473e4991ac 100644 --- a/compiler/x86/nx86mat.pas +++ b/compiler/x86/nx86mat.pas @@ -524,9 +524,9 @@ interface end; end; end - { unsigned modulus by a (+/-)power-of-2 constant? } else if (nodetype=modn) and (right.nodetype=ordconstn) and not(is_signed(left.resultdef)) then begin + { unsigned modulus by a (+/-)power-of-2 constant? } if isabspowerof2(tordconstnode(right).value,power) then begin emit_const_reg(A_AND,opsize,(aint(1) shl power)-1,hreg1); @@ -554,12 +554,6 @@ interface emit_reg_reg(A_XOR,opsize,location.register,location.register); cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS); emit_reg_reg(A_CMP,opsize,hreg2,hreg1); - - { Emit conditional move that depends on the carry flag } - instr:=TAiCpu.op_reg_reg(A_CMOVcc,opsize,hreg3,location.register); - instr.condition := C_AE; - current_asmdata.CurrAsmList.concat(instr); - cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS); end else begin @@ -568,14 +562,15 @@ interface cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS); emit_const_reg(A_CMP,opsize,aint(d),hreg1); - - { Emit conditional move that depends on the carry flag } - instr:=TAiCpu.op_reg_reg(A_CMOVcc,opsize,hreg3,location.register); - instr.condition := C_AE; - current_asmdata.CurrAsmList.concat(instr); - cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS); end; + { Emit conditional move that depends on the carry flag being zero, + that is, the comparison result is above or equal } + instr:=TAiCpu.op_reg_reg(A_CMOVcc,opsize,hreg3,location.register); + instr.condition := C_AE; + current_asmdata.CurrAsmList.concat(instr); + cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS); + emit_reg_reg(A_ADD,opsize,hreg1,location.register); end else @@ -600,8 +595,11 @@ interface dec(s); end; if s<>0 then - emit_const_reg(A_SHR,opsize,aint(s),regd); + emit_const_reg(A_SHR,opsize,aint(s),regd); { R/EDX now contains the quotient } + { Now multiply the quotient by the original denominator and + subtract the product from the original numerator to get + the remainder. } if (cgsize in [OS_64,OS_S64]) then { Cannot use 64-bit constants in IMUL } begin hreg3:=cg.getintregister(current_asmdata.CurrAsmList,cgsize); diff --git a/tests/test/cg/tmoddiv3.pp b/tests/test/cg/tmoddiv3.pp index bfcd59d9d6..4a9360de2c 100644 --- a/tests/test/cg/tmoddiv3.pp +++ b/tests/test/cg/tmoddiv3.pp @@ -1,4 +1,4 @@ -program testfile2; +program tmoddiv3; const TestValues: array[0..9] of LongWord = (500, 1, 0, 995, $7FFFFFFF, $80000000, $80000001, $80000002, $FFFFFFFF, 1000000); diff --git a/tests/test/cg/tmoddiv4.pp b/tests/test/cg/tmoddiv4.pp index 3ad24e46a2..1f8e1d393f 100644 --- a/tests/test/cg/tmoddiv4.pp +++ b/tests/test/cg/tmoddiv4.pp @@ -1,3 +1,4 @@ +program tmoddiv4; const TestValues: array[0..10] of QWord = (500, 1, 0, 995, $100000000, $100000001, $7FFFFFFFFFFFFFFF, QWord($8000000000000000), QWord($8000000000000001), QWord($8000000000000002), 1000000); @@ -107,4 +108,5 @@ begin Writeln(Y); DoCheck; end; + writeln('ok'); end.