From 7ab5fc798049711148bb42fcdb714859debedb64 Mon Sep 17 00:00:00 2001 From: tom_at_work Date: Sun, 26 Nov 2006 21:35:57 +0000 Subject: [PATCH] - cleanup, fixed range check error in cgcpu git-svn-id: trunk@5501 - --- compiler/powerpc64/cgcpu.pas | 20 ++++++++++++- compiler/powerpc64/nppcmat.pas | 52 ++++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/compiler/powerpc64/cgcpu.pas b/compiler/powerpc64/cgcpu.pas index e77c0d3653..d4a3bb2c5b 100644 --- a/compiler/powerpc64/cgcpu.pas +++ b/compiler/powerpc64/cgcpu.pas @@ -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 diff --git a/compiler/powerpc64/nppcmat.pas b/compiler/powerpc64/nppcmat.pas index ac77a87e84..1344f142d7 100644 --- a/compiler/powerpc64/nppcmat.pas +++ b/compiler/powerpc64/nppcmat.pas @@ -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;