فهرست منبع

* overflow checking for generic abs(<int64>)
* fix overflow checking on arm for 64 bit signed numbers
* arm uses generic abs(<int64>)

florian 1 سال پیش
والد
کامیت
c87213085f
3فایلهای تغییر یافته به همراه29 افزوده شده و 31 حذف شده
  1. 5 3
      compiler/arm/cgcpu.pas
  2. 15 26
      compiler/arm/narminl.pas
  3. 9 2
      compiler/ncginl.pas

+ 5 - 3
compiler/arm/cgcpu.pas

@@ -3663,10 +3663,10 @@ unit cgcpu;
               else
                 internalerror(2003083102);
             end;
+            ovloc.loc:=LOC_FLAGS;
             if size=OS_64 then
               begin
-                { the arm has an weired opinion how flags for SUB/ADD are handled }
-                ovloc.loc:=LOC_FLAGS;
+                { arm has a weired opinion how flags for SUB/ADD are handled }
                 case op of
                   OP_ADD:
                     ovloc.resflags:=F_CS;
@@ -3675,7 +3675,9 @@ unit cgcpu;
                   else
                     internalerror(2019050917);
                 end;
-              end;
+              end
+            else
+              ovloc.resflags:=F_VS;
           end
         else
           begin

+ 15 - 26
compiler/arm/narminl.pas

@@ -414,7 +414,7 @@ implementation
         opsize : tcgsize;
         ovloc: tlocation;
       begin
-        if GenerateThumbCode then
+        if GenerateThumbCode or is_64bitint(left.resultdef)  then
           begin
             inherited second_abs_long;
             exit;
@@ -422,35 +422,24 @@ implementation
 
         secondpass(left);
         opsize:=def_cgsize(left.resultdef);
-        if is_64bitint(left.resultdef) then
-          begin
-            hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
-            location:=left.location;
-            location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
-            location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
-            cg64.a_load64_reg_reg(current_asmdata.CurrAsmList,left.location.register64,location.register64);
-            cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_32,31,left.location.register64.reghi);
-            cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,left.location.register64.reghi,location.register64.reglo);
-            cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,left.location.register64.reghi,location.register64.reghi);
-            current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_SUB,location.register64.reglo,location.register64.reglo,left.location.register64.reghi), PF_S));
-            current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_SBC,location.register64.reghi,location.register64.reghi,left.location.register64.reghi), PF_S));
-          end
-        else
-          begin
-            hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
-            location:=left.location;
-            location.register:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
+        hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
+        location:=left.location;
+        location.register:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
 
-            cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
-            current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_MOV,location.register,left.location.register), PF_S));
+        cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
+        current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_MOV,location.register,left.location.register), PF_S));
 
-            if GenerateThumb2Code then
-              current_asmdata.CurrAsmList.concat(taicpu.op_cond(A_IT,C_MI));
+        if GenerateThumb2Code then
+          current_asmdata.CurrAsmList.concat(taicpu.op_cond(A_IT,C_MI));
 
+        if cs_check_overflow in current_settings.localswitches then
+          begin
             current_asmdata.CurrAsmList.concat(setoppostfix(setcondition(taicpu.op_reg_reg_const(A_RSB,location.register,location.register, 0), C_MI),PF_S));
-          end;
-        location_reset(ovloc,LOC_VOID,opsize);
-        cg.g_overflowCheck_loc(current_asmdata.CurrAsmList,ovloc,resultdef,ovloc);
+            location_reset(ovloc,LOC_VOID,opsize);
+            cg.g_overflowCheck_loc(current_asmdata.CurrAsmList,ovloc,resultdef,ovloc);
+          end
+        else
+          current_asmdata.CurrAsmList.concat(setcondition(taicpu.op_reg_reg_const(A_RSB,location.register,location.register, 0), C_MI));
 
         cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
       end;

+ 9 - 2
compiler/ncginl.pas

@@ -759,6 +759,7 @@ implementation
         tempreg1, tempreg2: tregister;
 {$if not(defined(cpu64bitalu))}
         tempreg64: tregister64;
+        ovloc: tlocation;
 {$endif not(defined(cpu64bitalu))}
       begin
         secondpass(left);
@@ -774,8 +775,14 @@ implementation
             cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_32,31,left.location.register64.reghi);
             tempreg64.reghi:=left.location.register64.reghi;
             tempreg64.reglo:=left.location.register64.reghi;
-            cg64.a_op64_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_64,tempreg64,location.register64);
-            cg64.a_op64_reg_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_64,tempreg64,location.register64,location.register64);
+            cg64.a_op64_reg_reg(current_asmdata.CurrAsmList,OP_XOR,def_cgsize(resultdef),tempreg64,location.register64);
+            if cs_check_overflow in current_settings.localswitches then
+              begin
+                cg64.a_op64_reg_reg_reg_checkoverflow(current_asmdata.CurrAsmList,OP_SUB,def_cgsize(resultdef),tempreg64,location.register64,location.register64,true,ovloc);
+                hlcg.g_overflowcheck_loc(current_asmdata.CurrAsmList,Location,resultdef,ovloc);
+              end
+            else
+              cg64.a_op64_reg_reg_reg(current_asmdata.CurrAsmList,OP_SUB,def_cgsize(resultdef),tempreg64,location.register64,location.register64);
           end
         else
 {$endif not(defined(cpu64bitalu))}