Browse Source

- cleanup, fixed range check error in cgcpu

git-svn-id: trunk@5501 -
tom_at_work 18 years ago
parent
commit
7ab5fc7980
2 changed files with 69 additions and 3 deletions
  1. 19 1
      compiler/powerpc64/cgcpu.pas
  2. 50 2
      compiler/powerpc64/nppcmat.pas

+ 19 - 1
compiler/powerpc64/cgcpu.pas

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

+ 50 - 2
compiler/powerpc64/nppcmat.pas

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