Browse Source

+ OptPass1FSGNJ optimization

florian 7 months ago
parent
commit
e082fe9752
1 changed files with 49 additions and 0 deletions
  1. 49 0
      compiler/riscv/aoptcpurv.pas

+ 49 - 0
compiler/riscv/aoptcpurv.pas

@@ -49,6 +49,7 @@ type
     function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
     function OptPass1OP(var p: tai): boolean;
     function OptPass1FOP(var p: tai;mvop: tasmop): boolean;
+    function OptPass1FSGNJ(var p: tai;mvop: tasmop): boolean;
 
     function OptPass1Add(var p: tai): boolean;
     procedure RemoveInstr(var orig: tai; moveback: boolean=true);
@@ -246,6 +247,51 @@ implementation
     end;
 
 
+  function TRVCpuAsmOptimizer.OptPass1FSGNJ(var p: tai; mvop: tasmop): boolean;
+    var
+      hp1 : tai;
+    begin
+      result:=false;
+      { replace
+          <mvop>  %reg1,%reg2,%reg2
+          <FOp>   %reg3,%reg1,%reg1
+          dealloc %reg2
+
+        by
+
+          <FOp>   %reg3,%reg2,%reg2
+        ?
+      }
+      if GetNextInstruction(p,hp1) and
+        (((mvop=A_FSGNJ_S) and (taicpu(hp1).opcode in [A_FADD_S,A_FSUB_S,A_FMUL_S,A_FDIV_S,A_FSQRT_S,
+              A_FNEG_S,A_FMADD_S,A_FMSUB_S,A_FNMSUB_S,A_FNMADD_S,A_FMIN_S,A_FMAX_S,A_FCVT_D_S,
+              A_FEQ_S])) or
+         ((mvop=A_FSGNJ_D) and (taicpu(hp1).opcode in [A_FADD_D,A_FSUB_D,A_FMUL_D,A_FDIV_D,A_FSQRT_D,
+              A_FNEG_D,A_FMADD_D,A_FMSUB_D,A_FNMSUB_D,A_FNMADD_D,A_FMIN_D,A_FMAX_D,A_FCVT_S_D,
+              A_FEQ_D]))) and
+        (MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[1]^) or
+        ((taicpu(hp1).ops>=3) and MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[2]^)) or
+        ((taicpu(hp1).ops>=4) and MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[3]^))) and
+        RegEndOfLife(taicpu(p).oper[0]^.reg, taicpu(hp1)) then
+        begin
+          if MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[1]^) then
+            taicpu(hp1).loadreg(1,taicpu(p).oper[1]^.reg);
+          if (taicpu(hp1).ops>=3) and MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[2]^) then
+            taicpu(hp1).loadreg(2,taicpu(p).oper[1]^.reg);
+          if (taicpu(hp1).ops>=4) and MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[3]^) then
+            taicpu(hp1).loadreg(3,taicpu(p).oper[1]^.reg);
+
+          AllocRegBetween(taicpu(p).oper[1]^.reg,p,hp1,UsedRegs);
+
+          DebugMsg('Peephole FMVFOp2FOp performed', hp1);
+
+          RemoveInstr(p);
+
+          result:=true;
+        end
+    end;
+
+
   procedure TRVCpuAsmOptimizer.RemoveInstr(var orig: tai; moveback: boolean = true);
     var
       n: tai;
@@ -779,6 +825,9 @@ implementation
               A_FMADD_D,A_FMSUB_D,A_FNMSUB_D,A_FNMADD_D,
               A_FMIN_D,A_FMAX_D:
                 result:=OptPass1FOP(p,A_FSGNJ_D);
+              A_FSGNJ_S,
+              A_FSGNJ_D:
+                result:=OptPass1FSGNJ(p,taicpu(p).opcode);
               else
                 ;
             end;