Pārlūkot izejas kodu

* unified RiscV32 and RiscV64 overflow checking code

florian 1 mēnesi atpakaļ
vecāks
revīzija
f3aa0e27a4
3 mainītis faili ar 31 papildinājumiem un 178 dzēšanām
  1. 30 16
      compiler/riscv/cgrv.pas
  2. 0 8
      compiler/riscv32/cgcpu.pas
  3. 1 154
      compiler/riscv64/cgcpu.pas

+ 30 - 16
compiler/riscv/cgrv.pas

@@ -70,6 +70,7 @@ unit cgrv;
         procedure g_profilecode(list: TAsmList); override;
 
         procedure g_overflowcheck_loc(list: TAsmList; const Loc: tlocation; def: tdef; ovloc: tlocation); override;
+        procedure g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef); override;
 
         { fpu move instructions }
         procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override;
@@ -233,9 +234,12 @@ unit cgrv;
         paraloc1, paraloc2: tcgpara;
         ai: taicpu;
         tmpreg1, tmpreg2: TRegister;
+        signed: Boolean;
       begin
+        signed:=tcgsize2unsigned[size]<>size;
         if setflags and
-          { do we know overflow checking for this operation? fix me! }(size in [OS_32,OS_S32]) and (op in [OP_ADD,OP_SUB,OP_MUL,OP_IMUL,OP_IDIV,OP_NEG]) then
+          { do we know overflow checking for this operation? fix me! }(size in [OS_32,OS_S32{$ifdef RISCV64},OS_S64,OS_64{$endif RISCV64}]) and
+          (op in [OP_ADD,OP_SUB,OP_MUL,OP_IMUL,OP_IDIV,OP_NEG]) then
           begin
             ovloc.loc:=LOC_JUMP;
             current_asmdata.getjumplabel(ovloc.truelabel);
@@ -286,7 +290,7 @@ unit cgrv;
                 list.concat(taicpu.op_reg_reg_reg(A_SRAW,dst,src2,src1));
                 maybeadjustresult(list,op,size,dst);
               end
-            else if (op=OP_SUB) and
+            else if (op=OP_SUB) and not(setflags) and
                (size in [OS_32,OS_S32]) then
               begin
                 list.concat(taicpu.op_reg_reg_reg(A_SUBW,dst,src2,src1));
@@ -336,7 +340,7 @@ unit cgrv;
               end
             else
               begin
-                if setflags and (op=OP_MUL) and (size=OS_32) then
+                if setflags and (op=OP_MUL) and (size in [OS_32{$ifdef RISCV64},OS_64{$endif RISCV64}]) then
                   begin
                     tmpreg1:=getintregister(list,size);
                     list.concat(taicpu.op_reg_reg_reg(A_MULHU,tmpreg1,src2,src1));
@@ -344,7 +348,7 @@ unit cgrv;
                 else
                   tmpreg1:=NR_NO;
                 list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1));
-                if setflags and (size in [OS_S32,OS_32]) then
+                if setflags and (size in [OS_S32,OS_32{$ifdef RISCV64},OS_S64,OS_64{$endif RISCV64}]) then
                   begin
                     case op of
                       OP_ADD:
@@ -369,7 +373,7 @@ unit cgrv;
                         end;
                       OP_SUB:
                         begin
-                          if size=OS_S32 then
+                          if signed then
                             begin
                               tmpreg1:=getintregister(list,size);
                               list.concat(taicpu.op_reg_reg_reg(A_SLT,tmpreg1,src2,dst));
@@ -377,14 +381,21 @@ unit cgrv;
                               list.concat(taicpu.op_reg_reg_const(A_SLTI,tmpreg2,src1,0));
                               a_cmp_reg_reg_label(list,OS_INT,OC_EQ,tmpreg1,tmpreg2,ovloc.falselabel)
                             end
-                          else if size=OS_32 then
+                          else
                             begin
+{$ifdef RISCV64}
+                              { no overflow if result<=src2 }
+                              if size in [OS_S32,OS_32] then
+                                begin
+                                  tmpreg1:=getintregister(list,OS_INT);
+                                  a_load_reg_reg(list,size,OS_64,dst,tmpreg1);
+                                  dst:=tmpreg1;
+                                end;
+{$endif RISCV64}
                               ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,src2,dst,ovloc.falselabel,0);
                               ai.condition:=C_GEU;
                               list.concat(ai);
-                            end
-                          else
-                            Internalerror(2025102002);
+                            end;
                           a_jmp_always(list,ovloc.truelabel);
                         end;
                       OP_MUL:
@@ -402,7 +413,7 @@ unit cgrv;
                               tmpreg1:=getintregister(list,size);
                               list.concat(taicpu.op_reg_reg_reg(A_MULH,tmpreg1,src2,src1));
                               tmpreg2:=getintregister(list,size);
-                              list.concat(taicpu.op_reg_reg_const(A_SRAI,tmpreg2,dst,31));
+                              list.concat(taicpu.op_reg_reg_const(A_SRAI,tmpreg2,dst,sizeof(aint)*8-1));
                               a_cmp_reg_reg_label(list,OS_INT,OC_EQ,tmpreg1,tmpreg2,ovloc.falselabel);
                             end
                           else
@@ -450,7 +461,7 @@ unit cgrv;
             exit;
           end;
 
-        if op=OP_SUB then
+        if (op=OP_SUB) and not(setflags) then
           begin
             op:=OP_ADD;
             a:=-a;
@@ -458,19 +469,19 @@ unit cgrv;
 
 {$ifdef RISCV64}
         if (op=OP_SHL) and
-               (size=OS_S32) then
+          (size=OS_S32) then
           begin
             list.concat(taicpu.op_reg_reg_const(A_SLLIW,dst,src,a));
             maybeadjustresult(list,op,size,dst);
           end
         else if (op=OP_SHR) and
-               (size=OS_S32) then
+          (size=OS_S32) then
           begin
             list.concat(taicpu.op_reg_reg_const(A_SRLIW,dst,src,a));
             maybeadjustresult(list,op,size,dst);
           end
         else if (op=OP_SAR) and
-               (size=OS_S32) then
+          (size=OS_S32) then
           begin
             list.concat(taicpu.op_reg_reg_const(A_SRAIW,dst,src,a));
             maybeadjustresult(list,op,size,dst);
@@ -862,8 +873,6 @@ unit cgrv;
 
     procedure tcgrv.g_overflowcheck_loc(list: TAsmList; const Loc: tlocation; def: tdef; ovloc: tlocation);
       begin
-        if not(cs_check_overflow in current_settings.localswitches) then
-          exit;
         { no overflow checking yet generated }
         if ovloc.loc=LOC_VOID then
           exit;
@@ -875,6 +884,11 @@ unit cgrv;
       end;
 
 
+    procedure tcgrv.g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef);
+      begin
+      end;
+
+
     procedure tcgrv.a_call_reg(list : TAsmList;reg: tregister);
       begin
         list.concat(taicpu.op_reg_reg(A_JALR,NR_RETURN_ADDRESS_REG,reg));

+ 0 - 8
compiler/riscv32/cgcpu.pas

@@ -44,8 +44,6 @@ unit cgcpu;
         procedure a_mul_reg_reg_pair(list: TAsmList;size: tcgsize; src1,src2,dstlo,dsthi: tregister); override;
 
         procedure g_concatcopy(list : TAsmList;const source,dest : treference;len : tcgint);override;
-
-        procedure g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef); override;
      end;
 
      tcg64frv = class(tcg64f32)
@@ -304,12 +302,6 @@ unit cgcpu;
       end;
 
 
-    procedure tcgrv32.g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef);
-      begin
-
-      end;
-
-
     procedure tcg64frv.a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
       var
         tmpreg1: TRegister;

+ 1 - 154
compiler/riscv64/cgcpu.pas

@@ -41,10 +41,6 @@ unit cgcpu;
         procedure a_load_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override;     
         procedure a_load_const_reg(list: TAsmList; size: tcgsize; a: tcgint; register: tregister); override;
 
-        procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister; setflags: boolean; var ovloc: tlocation); override;
-
-        procedure g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef); override;
-
         procedure g_concatcopy(list: TAsmList; const source, dest: treference; len: aint); override;
       end;
 
@@ -154,6 +150,7 @@ implementation
           end;
       end;
 
+
     procedure tcgrv64.a_load_const_reg(list: TAsmList; size: tcgsize; a: tcgint; register: tregister);
       var
         l: TAsmLabel;
@@ -203,156 +200,6 @@ implementation
       end;
 
 
-    procedure tcgrv64.a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister; setflags: boolean; var ovloc: tlocation);
-        var
-        signed: Boolean;
-        l: TAsmLabel;
-        tmpreg, tmpreg0: tregister;
-        ai: taicpu;
-      begin
-        signed:=tcgsize2unsigned[size]<>size;
-        ovloc.loc:=LOC_VOID;
-
-        if setflags then
-          case op of
-            OP_ADD:
-              begin
-                current_asmdata.getjumplabel(l);
-
-                list.Concat(taicpu.op_reg_reg_reg(A_ADD,dst,src2,src1));
-
-                if signed then
-                  begin
-                    {
-                      t0=src1<0
-                      t1=result<src2
-                      overflow if t0<>t1
-                    }
-                    tmpreg0:=getintregister(list,OS_INT);
-                    tmpreg:=getintregister(list,OS_INT);
-                    list.Concat(taicpu.op_reg_reg_reg(A_SLT,tmpreg0,src1,NR_X0));
-                    list.Concat(taicpu.op_reg_reg_reg(A_SLT,tmpreg,dst,src2));
-
-                    ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,tmpreg,tmpreg0,l,0);
-                    ai.condition:=C_EQ;
-                    list.concat(ai);
-                  end
-                else
-                  begin
-                    {
-                      jump if sum>=x
-                    }
-                    if size in [OS_S32,OS_32] then
-                      begin
-                        tmpreg:=getintregister(list,OS_INT);
-                        a_load_reg_reg(list,size,OS_64,dst,tmpreg);
-                        dst:=tmpreg;
-                      end;
-
-                    ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,dst,src2,l,0);
-                    ai.condition:=C_GEU;
-                    list.concat(ai);
-                  end;
-
-                a_call_name(list,'FPC_OVERFLOW',false);
-                a_label(list,l);
-              end;
-            OP_SUB:
-              begin
-                current_asmdata.getjumplabel(l);
-
-                if size in [OS_S32,OS_32] then
-                  list.Concat(taicpu.op_reg_reg_reg(A_SUBW,dst,src2,src1))
-                else
-                  list.Concat(taicpu.op_reg_reg_reg(A_SUB,dst,src2,src1));
-
-                if signed then
-                  begin
-                    tmpreg0:=getintregister(list,OS_INT);
-                    tmpreg:=getintregister(list,OS_INT);
-                    list.Concat(taicpu.op_reg_reg_reg(A_SLT,tmpreg0,NR_X0,src1));
-                    list.Concat(taicpu.op_reg_reg_reg(A_SLT,tmpreg,dst,src2));
-
-                    ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,tmpreg,tmpreg0,l,0);
-                    ai.condition:=C_EQ;
-                    list.concat(ai);
-                  end
-                else
-                  begin
-                    { no overflow if result<=src2 }
-                    if size in [OS_S32,OS_32] then
-                      begin
-                        tmpreg:=getintregister(list,OS_INT);
-                        a_load_reg_reg(list,size,OS_64,dst,tmpreg);
-                        dst:=tmpreg;
-                      end;
-
-                    ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,src2,dst,l,0);
-                    ai.condition:=C_GEU;
-                    list.concat(ai);
-                  end;
-
-                a_call_name(list,'FPC_OVERFLOW',false);
-                a_label(list,l);
-              end;
-            OP_IMUL:
-              begin
-                { No overflow if upper result is same as sign of result }
-                current_asmdata.getjumplabel(l);
-
-                tmpreg:=getintregister(list,OS_INT);
-                tmpreg0:=getintregister(list,OS_INT);
-                list.Concat(taicpu.op_reg_reg_reg(A_MUL,dst,src1,src2));
-                list.Concat(taicpu.op_reg_reg_reg(A_MULH,tmpreg,src1,src2));
-
-                list.concat(taicpu.op_reg_reg_const(A_SRAI,tmpreg0,dst,63));
-
-                a_cmp_reg_reg_label(list,OS_INT,OC_EQ,tmpreg,tmpreg0,l);
-
-                a_call_name(list,'FPC_OVERFLOW',false);
-                a_label(list,l);
-              end;
-            OP_MUL:
-              begin
-                { No overflow if upper result is 0 }
-                current_asmdata.getjumplabel(l);
-
-                tmpreg:=getintregister(list,OS_INT);
-                list.Concat(taicpu.op_reg_reg_reg(A_MUL,dst,src1,src2));
-                list.Concat(taicpu.op_reg_reg_reg(A_MULHU,tmpreg,src1,src2));
-
-                a_cmp_reg_reg_label(list,OS_INT,OC_EQ,tmpreg,NR_X0,l);
-
-                a_call_name(list,'FPC_OVERFLOW',false);
-                a_label(list,l);
-              end;
-            OP_IDIV:
-              begin
-                { Only overflow if dst is all 1's }
-                current_asmdata.getjumplabel(l);
-
-                tmpreg:=getintregister(list,OS_INT);
-                list.Concat(taicpu.op_reg_reg_reg(A_DIV,dst,src1,src2));
-                list.Concat(taicpu.op_reg_reg_const(A_ADDI,tmpreg,dst,1));
-
-                a_cmp_reg_reg_label(list,OS_INT,OC_NE,tmpreg,NR_X0,l);
-
-                a_call_name(list,'FPC_OVERFLOW',false);
-                a_label(list,l);
-              end;
-            else
-              internalerror(2019051032);
-          end
-        else
-          inherited a_op_reg_reg_reg_checkoverflow(list,op,size,src1,src2,dst,false,ovloc);
-      end;
-
-
-    procedure tcgrv64.g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef);
-      begin
-      end;
-
-
     procedure tcgrv64.g_concatcopy(list: TAsmList; const source, dest: treference; len: aint);
       var
         tmpreg1, hreg, countreg: TRegister;