- cleanup, fixed range check error in cgcpu

git-svn-id: trunk@5501 -
This commit is contained in:
tom_at_work 2006-11-26 21:35:57 +00:00
parent 17acf22a48
commit 7ab5fc7980
2 changed files with 69 additions and 3 deletions

View File

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

View File

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