Bladeren bron

+ support to generate software based floating point exception checking
(enabled by -CE)

git-svn-id: branches/laksen/riscv_new@39639 -

florian 7 jaren geleden
bovenliggende
commit
999cbd94b8
3 gewijzigde bestanden met toevoegingen van 42 en 5 verwijderingen
  1. 26 0
      compiler/riscv/cgrv.pas
  2. 3 1
      compiler/riscv/nrvadd.pas
  3. 13 4
      compiler/riscv/nrvinl.pas

+ 26 - 0
compiler/riscv/cgrv.pas

@@ -69,6 +69,8 @@ unit cgrv;
         procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override;
         procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister); override;
         procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override;
+
+        procedure g_check_for_fpu_exception(list: TAsmList); override;
       protected
         function  fixref(list: TAsmList; var ref: treference): boolean;
         procedure maybeadjustresult(list: TAsmList; op: topcg; size: tcgsize; dst: tregister);
@@ -555,6 +557,7 @@ unit cgrv;
             list.concat(ai);
             rg[R_FPUREGISTER].add_move_instruction(ai);
           end;
+        g_check_for_fpu_exception(list);
       end;
 
 
@@ -713,4 +716,27 @@ unit cgrv;
           a_load_reg_reg(list,OS_INT,size,dst,dst)
       end;
 
+
+    procedure tcgrv.g_check_for_fpu_exception(list: TAsmList);
+      var
+        r : TRegister;
+        ai: taicpu;
+        l: TAsmLabel;
+      begin
+        if cs_check_fpu_exceptions in current_settings.localswitches then
+          begin
+            r:=getintregister(list,OS_INT);
+            list.concat(taicpu.op_reg(A_FRFLAGS,r));
+            current_asmdata.getjumplabel(l);
+            ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,r,NR_X0,l,0);
+            ai.is_jmp:=true;
+            ai.condition:=C_EQ;
+            list.concat(ai);
+            alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+            cg.a_call_name(current_asmdata.CurrAsmList,'FPC_THROWFPUEXCEPTION',false);
+            dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+            a_label(list,l);
+          end;
+      end;
+
 end.

+ 3 - 1
compiler/riscv/nrvadd.pas

@@ -399,11 +399,13 @@ implementation
         // emit the actual operation
         if not cmpop then
           begin
-            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register))
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register));
+            cg.g_check_for_fpu_exception(current_asmdata.CurrAsmList);
           end
         else
           begin
             current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register));
+            cg.g_check_for_fpu_exception(current_asmdata.CurrAsmList);
 
             if inv then
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_XORI,location.register,location.register,1));

+ 13 - 4
compiler/riscv/nrvinl.pas

@@ -125,11 +125,17 @@ implementation
         load_fpu_location;
         case left.location.size of
           OS_F32:
-            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FSQRT_S,location.register,
-              left.location.register));
+            begin
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FSQRT_S,location.register,
+                left.location.register));
+              cg.g_check_for_fpu_exception(current_asmdata.CurrAsmList);
+            end;
           OS_F64:
-            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FSQRT_D,location.register,
-              left.location.register));
+            begin
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FSQRT_D,location.register,
+                left.location.register));
+              cg.g_check_for_fpu_exception(current_asmdata.CurrAsmList);
+             end
           else
             inherited;
         end;
@@ -161,8 +167,10 @@ implementation
          else
            op := A_FMUL_D;
          current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,left.location.register));
+         cg.g_check_for_fpu_exception(current_asmdata.CurrAsmList);
        end;
 
+
      procedure trvinlinenode.second_fma;
        const
          op : array[os_f32..os_f64,false..true,false..true] of TAsmOp =
@@ -233,6 +241,7 @@ implementation
              location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
 
              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg_reg(op[def_cgsize(resultdef), negproduct,negop3],location.register,paraarray[1].location.register,paraarray[2].location.register,paraarray[2].location.register));
+             cg.g_check_for_fpu_exception(current_asmdata.CurrAsmList);
            end
          else
            internalerror(2014032301);