mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-10 23:38:06 +02:00
* 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:
parent
4014f900cb
commit
11a3d8762a
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user