Browse Source

* fixed usigned overflow checking

Jonas Maebe 21 years ago
parent
commit
e4312930d1
1 changed files with 91 additions and 29 deletions
  1. 91 29
      compiler/powerpc/nppcadd.pas

+ 91 - 29
compiler/powerpc/nppcadd.pas

@@ -55,7 +55,7 @@ interface
       symconst,symdef,paramgr,
       symconst,symdef,paramgr,
       aasmbase,aasmtai,aasmcpu,defutil,htypechk,
       aasmbase,aasmtai,aasmcpu,defutil,htypechk,
       cgbase,cpuinfo,pass_1,pass_2,regvars,
       cgbase,cpuinfo,pass_1,pass_2,regvars,
-      cpupara,
+      cpupara,cgcpu,
       ncon,nset,
       ncon,nset,
       ncgutil,tgobj,rgobj,rgcpu,cgobj,cg64f32;
       ncgutil,tgobj,rgobj,rgcpu,cgobj,cg64f32;
 
 
@@ -1022,24 +1022,47 @@ interface
           end
           end
         else
         else
           begin
           begin
-            case nodetype of
-              addn:
-                begin
-                  op1 := A_ADDC;
-                  op2 := A_ADDEO_;
-                end;
-              subn:
-                begin
-                  op1 := A_SUBC;
-                  op2 := A_SUBFEO_;
+            if is_signed(resulttype.def) then
+              begin
+                case nodetype of
+                  addn:
+                    begin
+                      op1 := A_ADDC;
+                      op2 := A_ADDEO;
+                    end;
+                  subn:
+                    begin
+                      op1 := A_SUBC;
+                      op2 := A_SUBFEO;
+                    end;
+                  else
+                    internalerror(2002072806);
+                end
+              end
+            else
+              begin
+                case nodetype of
+                  addn:
+                    begin
+                      op1 := A_ADDC;
+                      op2 := A_ADDE;
+                    end;
+                  subn:
+                    begin
+                      op1 := A_SUBC;
+                      op2 := A_SUBFE;
+                    end;
                 end;
                 end;
-              else
-                internalerror(2002072806);
-            end;
+              end;
             exprasmlist.concat(taicpu.op_reg_reg_reg(op1,location.registerlow,
             exprasmlist.concat(taicpu.op_reg_reg_reg(op1,location.registerlow,
               left.location.registerlow,right.location.registerlow));
               left.location.registerlow,right.location.registerlow));
             exprasmlist.concat(taicpu.op_reg_reg_reg(op2,location.registerhigh,
             exprasmlist.concat(taicpu.op_reg_reg_reg(op2,location.registerhigh,
               right.location.registerhigh,left.location.registerhigh));
               right.location.registerhigh,left.location.registerhigh));
+            if not(is_signed(resulttype.def)) then
+              if nodetype = addn then
+                exprasmlist.concat(taicpu.op_reg_reg(A_CMPLW,location.registerhigh,left.location.registerhigh))
+              else
+                exprasmlist.concat(taicpu.op_reg_reg(A_CMPLW,left.location.registerhigh,location.registerhigh));
             cg.g_overflowcheck(exprasmlist,location,resulttype.def);
             cg.g_overflowcheck(exprasmlist,location,resulttype.def);
           end;
           end;
 
 
@@ -1249,10 +1272,11 @@ interface
     { is also being used for xor, and "mul", "sub, or and comparative }
     { is also being used for xor, and "mul", "sub, or and comparative }
     { operators                                                }
     { operators                                                }
       var
       var
-         cmpop      : boolean;
          cgop       : topcg;
          cgop       : topcg;
          op         : tasmop;
          op         : tasmop;
          tmpreg     : tregister;
          tmpreg     : tregister;
+         hl         : tasmlabel;
+         cmpop      : boolean;
 
 
          { true, if unsigned types are compared }
          { true, if unsigned types are compared }
          unsigned : boolean;
          unsigned : boolean;
@@ -1407,19 +1431,54 @@ interface
          else
          else
            // overflow checking is on and we have an addn, subn or muln
            // overflow checking is on and we have an addn, subn or muln
            begin
            begin
-             case nodetype of
-               addn:
-                 op := A_ADDO_;
-               subn:
-                 op := A_SUBO_;
-               muln:
-                  op := A_MULLWO_;
-               else
-                 internalerror(2002072601);
-             end;
-             exprasmlist.concat(taicpu.op_reg_reg_reg(op,location.register,
-               left.location.register,right.location.register));
-             cg.g_overflowcheck(exprasmlist,location,resulttype.def);
+             if is_signed(resulttype.def) then
+               begin
+                 case nodetype of
+                   addn:
+                     op := A_ADDO;
+                   subn:
+                     op := A_SUBO;
+                   muln:
+                     op := A_MULLWO;
+                   else
+                     internalerror(2002072601);
+                 end;
+                 exprasmlist.concat(taicpu.op_reg_reg_reg(op,location.register,
+                   left.location.register,right.location.register));
+              end
+            else
+              begin
+                case nodetype of
+                  addn:
+                    begin
+                      exprasmlist.concat(taicpu.op_reg_reg_reg(A_ADD,location.register,
+                        left.location.register,right.location.register));
+                      exprasmlist.concat(taicpu.op_reg_reg(A_CMPLW,location.register,left.location.register));
+                      cg.g_overflowcheck(exprasmlist,location,resulttype.def);
+                    end;
+                  subn:
+                    begin
+                      exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUB,location.register,
+                        left.location.register,right.location.register));
+                      exprasmlist.concat(taicpu.op_reg_reg(A_CMPLW,left.location.register,location.register));
+                      cg.g_overflowcheck(exprasmlist,location,resulttype.def);
+                    end;
+                  muln:
+                    begin
+                      { calculate the upper 32 bits of the product, = 0 if no overflow }
+                      exprasmlist.concat(taicpu.op_reg_reg_reg(A_MULHWU_,location.register,
+                        left.location.register,right.location.register));
+                      { calculate the real result }
+                      exprasmlist.concat(taicpu.op_reg_reg_reg(A_MULLW,location.register,
+                        left.location.register,right.location.register));
+                      { g_overflowcheck generates a OC_AE instead of OC_EQ :/ }
+                      objectlibrary.getlabel(hl);
+                      tcgppc(cg).a_jmp_cond(exprasmlist,OC_EQ,hl);
+                      cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
+                      cg.a_label(exprasmlist,hl);
+                    end;
+                end;
+              end;
            end;
            end;
 
 
          release_reg_left_right;
          release_reg_left_right;
@@ -1430,7 +1489,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.38  2003-10-17 14:52:07  peter
+  Revision 1.39  2003-12-08 21:18:44  jonas
+    * fixed usigned overflow checking
+
+  Revision 1.38  2003/10/17 14:52:07  peter
     * fixed ppc build
     * fixed ppc build
 
 
   Revision 1.37  2003/10/17 01:22:08  florian
   Revision 1.37  2003/10/17 01:22:08  florian