mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-06 09:07:59 +02: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;
|
||||
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_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',
|
||||
@ -225,6 +225,15 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{$ifopt r+}
|
||||
{$r-}
|
||||
{$define rangeon}
|
||||
{$endif}
|
||||
|
||||
{$ifopt q+}
|
||||
{$q-}
|
||||
{$define overflowon}
|
||||
{$endif}
|
||||
{ helper function which calculate "magic" values for replacement of unsigned
|
||||
division by constant operation by multiplication. See the PowerPC compiler
|
||||
developer manual for more information }
|
||||
@ -316,6 +325,15 @@ begin
|
||||
end;
|
||||
magic_s := p - N; { resulting shift }
|
||||
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
|
||||
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,
|
||||
defutil,
|
||||
cgbase, cgutils, cgobj, pass_1, pass_2,
|
||||
ncon, procinfo,
|
||||
ncon, procinfo, nbas, nld, nadd,
|
||||
cpubase, cpuinfo,
|
||||
ncgutil, cgcpu, rgobj;
|
||||
|
||||
@ -65,8 +65,56 @@ uses
|
||||
*****************************************************************************}
|
||||
|
||||
function tppcmoddivnode.pass_1: tnode;
|
||||
var
|
||||
statementnode : tstatementnode;
|
||||
temp_left, temp_right : ttempcreatenode;
|
||||
left_copy, right_copy : tnode;
|
||||
block : tblocknode;
|
||||
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
|
||||
include(current_procinfo.flags, pi_do_call);
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user