* 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 -
This commit is contained in:
florian 2018-01-09 20:04:49 +00:00
parent 4014f900cb
commit 11a3d8762a
3 changed files with 15 additions and 15 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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.