mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-10 06:29:30 +01:00
- cleanup, fixed range check error in cgcpu
git-svn-id: trunk@5501 -
This commit is contained in:
parent
17acf22a48
commit
7ab5fc7980
@ -196,7 +196,7 @@ end;
|
|||||||
|
|
||||||
function cgsize2string(const size : TCgSize) : string;
|
function cgsize2string(const size : TCgSize) : string;
|
||||||
const
|
const
|
||||||
cgsize_strings : array[TCgSize] of string[6] = (
|
cgsize_strings : array[TCgSize] of string[7] = (
|
||||||
'OS_NO', 'OS_8', 'OS_16', 'OS_32', 'OS_64', 'OS_128', 'OS_S8', 'OS_S16', 'OS_S32',
|
'OS_NO', 'OS_8', 'OS_16', 'OS_32', 'OS_64', 'OS_128', 'OS_S8', 'OS_S16', 'OS_S32',
|
||||||
'OS_S64', 'OS_S128', 'OS_F32', 'OS_F64', 'OS_F80', 'OS_C64', 'OS_F128',
|
'OS_S64', 'OS_S128', 'OS_F32', 'OS_F64', 'OS_F80', 'OS_C64', 'OS_F128',
|
||||||
'OS_M8', 'OS_M16', 'OS_M32', 'OS_M64', 'OS_M128', 'OS_MS8', 'OS_MS16', 'OS_MS32',
|
'OS_M8', 'OS_M16', 'OS_M32', 'OS_M64', 'OS_M128', 'OS_MS8', 'OS_MS16', 'OS_MS32',
|
||||||
@ -225,6 +225,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{$ifopt r+}
|
||||||
|
{$r-}
|
||||||
|
{$define rangeon}
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
{$ifopt q+}
|
||||||
|
{$q-}
|
||||||
|
{$define overflowon}
|
||||||
|
{$endif}
|
||||||
{ helper function which calculate "magic" values for replacement of unsigned
|
{ helper function which calculate "magic" values for replacement of unsigned
|
||||||
division by constant operation by multiplication. See the PowerPC compiler
|
division by constant operation by multiplication. See the PowerPC compiler
|
||||||
developer manual for more information }
|
developer manual for more information }
|
||||||
@ -316,6 +325,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
magic_s := p - N; { resulting shift }
|
magic_s := p - N; { resulting shift }
|
||||||
end;
|
end;
|
||||||
|
{$ifdef rangeon}
|
||||||
|
{$r+}
|
||||||
|
{$undef rangeon}
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
{$ifdef overflowon}
|
||||||
|
{$q+}
|
||||||
|
{$undef overflowon}
|
||||||
|
{$endif}
|
||||||
|
|
||||||
{ finds positive and negative powers of two of the given value, returning the
|
{ finds positive and negative powers of two of the given value, returning the
|
||||||
power and whether it's a negative power or not in addition to the actual result
|
power and whether it's a negative power or not in addition to the actual result
|
||||||
|
|||||||
@ -56,7 +56,7 @@ uses
|
|||||||
aasmbase, aasmcpu, aasmtai,aasmdata,
|
aasmbase, aasmcpu, aasmtai,aasmdata,
|
||||||
defutil,
|
defutil,
|
||||||
cgbase, cgutils, cgobj, pass_1, pass_2,
|
cgbase, cgutils, cgobj, pass_1, pass_2,
|
||||||
ncon, procinfo,
|
ncon, procinfo, nbas, nld, nadd,
|
||||||
cpubase, cpuinfo,
|
cpubase, cpuinfo,
|
||||||
ncgutil, cgcpu, rgobj;
|
ncgutil, cgcpu, rgobj;
|
||||||
|
|
||||||
@ -65,8 +65,56 @@ uses
|
|||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
function tppcmoddivnode.pass_1: tnode;
|
function tppcmoddivnode.pass_1: tnode;
|
||||||
|
var
|
||||||
|
statementnode : tstatementnode;
|
||||||
|
temp_left, temp_right : ttempcreatenode;
|
||||||
|
left_copy, right_copy : tnode;
|
||||||
|
block : tblocknode;
|
||||||
begin
|
begin
|
||||||
result := inherited pass_1;
|
result := nil;
|
||||||
|
(*
|
||||||
|
// this code replaces all mod nodes by the equivalent div/mul/sub sequence
|
||||||
|
// on node level, which might be advantageous when doing CSE on that level
|
||||||
|
// However, optimal modulo code for some cases (in particular a 'x mod 2^n-1'
|
||||||
|
// operation) can not be expressed using nodes, so this is commented out for now
|
||||||
|
if (nodetype = modn) then begin
|
||||||
|
block := internalstatements(statementnode);
|
||||||
|
|
||||||
|
temp_left := ctempcreatenode.create(left.resultdef, left.resultdef.size, tt_persistent, true);
|
||||||
|
addstatement(statementnode, temp_left);
|
||||||
|
addstatement(statementnode, cassignmentnode.create(ctemprefnode.create(temp_left), left.getcopy));
|
||||||
|
|
||||||
|
if (right.nodetype <> ordconstn) then begin
|
||||||
|
// implementated optimization: use temps to store the right value, otherwise
|
||||||
|
// it is calculated twice when simply copying it which might result in side
|
||||||
|
// effects
|
||||||
|
temp_right := ctempcreatenode.create(right.resultdef, right.resultdef.size, tt_persistent, true);
|
||||||
|
addstatement(statementnode, temp_right);
|
||||||
|
addstatement(statementnode, cassignmentnode.create(ctemprefnode.create(temp_right), right.getcopy));
|
||||||
|
|
||||||
|
addstatement(statementnode, cassignmentnode.create(ctemprefnode.create(temp_left),
|
||||||
|
caddnode.create(subn, ctemprefnode.create(temp_left),
|
||||||
|
caddnode.create(muln, cmoddivnode.create(divn, ctemprefnode.create(temp_left), ctemprefnode.create(temp_right)),
|
||||||
|
ctemprefnode.create(temp_right)))));
|
||||||
|
|
||||||
|
addstatement(statementnode, ctempdeletenode.create(temp_right));
|
||||||
|
end else begin
|
||||||
|
// in case this is a modulo by a constant operation, do not use a temp for the
|
||||||
|
// right hand side, because otherwise the div optimization will not recognize this
|
||||||
|
// fact (and there is no constant propagator/recognizer in the compiler),
|
||||||
|
// resulting in suboptimal code.
|
||||||
|
addstatement(statementnode, cassignmentnode.create(ctemprefnode.create(temp_left),
|
||||||
|
caddnode.create(subn, ctemprefnode.create(temp_left),
|
||||||
|
caddnode.create(muln, cmoddivnode.create(divn, ctemprefnode.create(temp_left), right.getcopy),
|
||||||
|
right.getcopy))));
|
||||||
|
end;
|
||||||
|
addstatement(statementnode, ctempdeletenode.create_normal_temp(temp_left));
|
||||||
|
addstatement(statementnode, ctemprefnode.create(temp_left));
|
||||||
|
result := block;
|
||||||
|
end;
|
||||||
|
*)
|
||||||
|
if (not assigned(result)) then
|
||||||
|
result := inherited pass_1;
|
||||||
if not assigned(result) then
|
if not assigned(result) then
|
||||||
include(current_procinfo.flags, pi_do_call);
|
include(current_procinfo.flags, pi_do_call);
|
||||||
end;
|
end;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user