2
0
Эх сурвалжийг харах

+ support of proper unordered floating point comparisons

florian 3 долоо хоног өмнө
parent
commit
be04dc238b
1 өөрчлөгдсөн 36 нэмэгдсэн , 11 устгасан
  1. 36 11
      compiler/riscv/nrvadd.pas

+ 36 - 11
compiler/riscv/nrvadd.pas

@@ -59,11 +59,10 @@ implementation
       globtype,systems,
       cutils,verbose,globals,
       symconst,symdef,paramgr,
-      aasmbase,aasmtai,aasmdata,aasmcpu,defutil,htypechk,
+      aasmbase,aasmdata,aasmcpu,defutil,
       cgbase,cpuinfo,pass_1,pass_2,
-      cpupara,cgcpu,cgutils,procinfo,
-      ncon,nset,
-      ncgutil,tgobj,rgobj,rgcpu,cgobj,hlcgobj;
+      cpupara,cgutils,procinfo,
+      ncgutil,cgobj,hlcgobj;
 
 {$undef AVOID_OVERFLOW}
 {$ifopt Q+}
@@ -351,7 +350,11 @@ implementation
         op    : TAsmOp;
         cmpop,
         singleprec , inv: boolean;
+        l1, l2: TAsmLabel;
+        tmpreg1, tmpreg2: TRegister;
       begin
+        l1:=nil;
+        l2:=nil;
         pass_left_and_right;
         if (nf_swapped in flags) then
           swapleftright;
@@ -442,19 +445,39 @@ implementation
         hlcg.location_force_fpureg(current_asmdata.CurrAsmList,right.location,right.resultdef,true);
         hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
 
-        // initialize de result
+        { initialize the result and check floats for Nan}
         if not cmpop then
           begin
             location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
-            location.register := cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
+            location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
           end
         else
-         begin
-           location_reset(location,LOC_REGISTER,OS_8);
-           location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-         end;
+          begin
+            tmpreg1:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
+            tmpreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
+
+            if singleprec then
+              begin
+                current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_FEQ_S,tmpreg1,right.location.register,right.location.register));
+                current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_FEQ_S,tmpreg2,left.location.register,left.location.register));
+              end
+            else
+              begin
+                current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_FEQ_D,tmpreg1,right.location.register,right.location.register));
+                current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_FEQ_D,tmpreg2,left.location.register,left.location.register));
+              end;
+
+            location_reset(location,LOC_REGISTER,OS_8);
+            location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
 
-        // emit the actual operation
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_AND,location.register,tmpreg1,tmpreg2));
+
+            current_asmdata.getjumplabel(l1);
+
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_sym(A_BEQZ,location.register,l1));
+          end;
+
+        { 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));
@@ -465,6 +488,8 @@ implementation
             current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register));
             cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
 
+            cg.a_label(current_asmdata.CurrAsmList,l1);
+
             if inv then
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_XORI,location.register,location.register,1));
           end;