fpc/tests/test/cg/tmoddiv2.pp
2014-07-06 08:26:37 +00:00

363 lines
11 KiB
ObjectPascal

program mymodtest;
{$MODE DELPHI}
{$ASSERTIONS ON}
// Pascal implementation of signed modulus by power of 2 constant algorithm
function my_modulus(x, m : integer) : integer;
var
temp, mask1, mask2 : integer;
begin
m := abs(m-1);
temp := x and m;
if (x < 0) then begin // = sign bit
mask2 := -1;
end else begin
mask2 := 0;
end;
if (temp <> 0) then begin // note: temp >= 0
mask1 := -1;
end else begin
mask1 := 0;
end;
my_modulus := temp or ((not m) and mask1 and mask2);
end;
function i32_modulus(x, m : integer) : integer;
var
temp : integer;
begin
temp := x div m;
i32_modulus := x - (temp*m);
end;
function u32_modulus(x, m : dword) : dword;
var
temp : dword;
begin
temp := x div m;
u32_modulus := x - (temp*m);
end;
var
i : integer;
j, k : longint;
res, res2 : longint;
y, z : dword;
begin
randseed := 1; // just take any, but repeatable
write('positive int32 division test...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := 19;
assert((j div 19) = (j div k), 'Wrong int32 division by 19 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
write('Negative int32 division test...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := -19;
assert((j div -19) = (j div k), 'Wrong int32 division by -19 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
write('positive int32 division test...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := 3;
assert((j div 3) = (j div k), 'Wrong int32 division by 3 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
write('Negative int32 division test...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := -3;
assert((j div -3) = (j div k), 'Wrong int32 division by -3 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
write('positive int32 division test...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := 7;
assert((j div 7) = (j div k), 'Wrong int32 division by 7 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
write('Negative int32 division test...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := -7;
assert((j div -7) = (j div k), 'Wrong int32 division by -7 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
write('positive int32 division test...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := 5;
assert((j div 5) = (j div k), 'Wrong int32 division by 5 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
write('Negative int32 division test...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := -5;
assert((j div -5) = (j div k), 'Wrong int32 division by -5 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
write('positive int32 division test...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := 512;
assert((j div 512) = (j div k), 'Wrong int32 division by 512 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
write('Negative int32 division test...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := -512;
assert((j div -512) = (j div k), 'Wrong int32 division by -512 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
//-----------------------------------------------------------------
write('positive int32 modulus test (19)...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := 19;
assert((j mod 19) = (i32_modulus(j,k)), 'Wrong int32 modulus by 19 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
write('Negative int32 modulus test (-19)...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := -19;
res := j mod -19;
res2 := i32_modulus(j, k);
assert((res = res2), 'Int32 mod by -19 j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2) + ' is ' + hexstr(res, 8) + ' ' + hexstr(res2, 8));
end;
writeln('Success.');
write('positive int32 modulus test (3)...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := 3;
assert((j mod 3) = (i32_modulus(j,k)), 'Wrong int32 modulus by 3 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
write('Negative int32 modulus test (-3)...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := -3;
res := j mod -3;
res2 := i32_modulus(j, k);
assert((res = res2), 'Int32 mod by -3 j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2) + ' is ' + hexstr(res, 8) + ' ' + hexstr(res2, 8));
end;
writeln('Success.');
write('positive int32 modulus test (5)...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := 5;
assert((j mod 5) = (i32_modulus(j,k)), 'Wrong int32 modulus by 5 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
write('Negative int32 modulus test (-5)...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := -5;
res := j mod -5;
res2 := i32_modulus(j, k);
assert((res = res2), 'Int32 mod by -5 j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2) + ' is ' + hexstr(res, 8) + ' ' + hexstr(res2, 8));
end;
writeln('Success.');
write('positive int32 modulus test (7)...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := 7;
assert((j mod 7) = (i32_modulus(j,k)), 'Wrong int32 modulus by 7 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
write('Negative int32 modulus test (-7)...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := -7;
res := j mod -7;
res2 := i32_modulus(j, k);
assert((res = res2), 'Int32 mod by -7 j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2) + ' is ' + hexstr(res, 8) + ' ' + hexstr(res2, 8));
end;
writeln('Success.');
write('positive int32 modulus test (512)...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := 512;
assert((j mod 512) = (i32_modulus(j,k)), 'Wrong int32 modulus by 512 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
end;
writeln('Success.');
write('Negative int32 modulus test (-512)...');
for i := -10000 to 10000 do begin
j := random(high(integer));
if (random(2) = 1) then j := -j;
k := -512;
res := j mod -512;
res2 := i32_modulus(j, k);
assert((res = res2), 'Int32 mod by -512 j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2) + ' is ' + hexstr(res, 8) + ' ' + hexstr(res2, 8));
end;
writeln('Success.');
write('positive uint32 division test (19)...');
for i := -10000 to 10000 do begin
y := random(high(integer));
if (random(2) = 1) then y := 2 * y;
z := 19;
assert((y div 19) = (y div z), 'Wrong uint32 division by 19 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
end;
writeln('Success.');
write('positive uint32 modulus test (19)...');
for i := -10000 to 10000 do begin
y := random(high(integer));
if (random(2) = 1) then y := 2 * y;
z := 19;
assert((y mod 19) = (u32_modulus(y,z)), 'Wrong uint32 modulus by 19 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
end;
writeln('Success.');
write('positive uint32 division test (3)...');
for i := -10000 to 10000 do begin
y := random(high(integer));
if (random(2) = 1) then y := 2 * y;
z := 3;
assert((y div 3) = (y div z), 'Wrong uint32 division by 3 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
end;
writeln('Success.');
write('positive uint32 modulus test (3)...');
for i := -10000 to 10000 do begin
y := random(high(integer));
if (random(2) = 1) then y := 2 * y;
z := 3;
assert((y mod 3) = (u32_modulus(y,z)), 'Wrong uint32 modulus by 3 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
end;
writeln('Success.');
write('positive uint32 division test (5)...');
for i := -10000 to 10000 do begin
y := random(high(integer));
if (random(2) = 1) then y := 2 * y;
z := 5;
assert((y div 5) = (y div z), 'Wrong uint32 division by 5 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
end;
writeln('Success.');
write('positive uint32 modulus test (5)...');
for i := -10000 to 10000 do begin
y := random(high(integer));
if (random(2) = 1) then y := 2 * y;
z := 5;
assert((y mod 5) = (u32_modulus(y,z)), 'Wrong uint32 modulus by 5 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
end;
writeln('Success.');
write('positive uint32 division test (7)...');
for i := -10000 to 10000 do begin
y := random(high(integer));
if (random(2) = 1) then y := 2 * y;
z := 7;
assert((y div 7) = (y div z), 'Wrong uint32 division by 7 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
end;
writeln('Success.');
write('positive uint32 modulus test (7)...');
for i := -10000 to 10000 do begin
y := random(high(integer));
if (random(2) = 1) then y := 2 * y;
z := 7;
assert((y mod 7) = (u32_modulus(y,z)), 'Wrong uint32 modulus by 7 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
end;
writeln('Success.');
write('positive uint32 division test (512)...');
for i := -10000 to 10000 do begin
y := random(high(integer));
if (random(2) = 1) then y := 2 * y;
z := 512;
assert((y div 512) = (y div z), 'Wrong uint32 division by 512 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
end;
writeln('Success.');
write('positive uint32 modulus test (512)...');
for i := -10000 to 10000 do begin
y := random(high(integer));
if (random(2) = 1) then y := 2 * y;
z := 512;
assert((y mod 512) = (u32_modulus(y,z)), 'Wrong uint32 modulus by 512 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
end;
writeln('Success.');
{ extra test for div by constant optimization }
write('positive uint32 division test ($deadbeef)...');
for i := -10000 to 10000 do begin
y := random(high(integer));
if (random(2) = 1) then y := 2 * y;
z := $deadbeef;
assert((y div $deadbeef) = (y div z), 'Wrong uint32 division by $deadbeaf for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
end;
writeln('Success.');
write('positive uint32 division test ($b16beef)...');
for i := -10000 to 10000 do begin
y := random(high(integer));
if (random(2) = 1) then y := 2 * y;
z := $b16beef;
assert((y div $b16beef) = (y div z), 'Wrong uint32 division by $b16beef for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
end;
writeln('Success.');
end.