Browse Source

+ RiscV: make use of the fneg.* instruction

florian 6 months ago
parent
commit
c3110dfaa9

+ 1 - 1
compiler/riscv/cpubase.pas

@@ -40,7 +40,7 @@ uses
         { Pseudo instructions }
         A_NOP,A_CALL,A_LA,A_LLA,A_LGA,A_LI,A_MV,A_NOT,A_NEG,A_NEGW,
         A_SEXT_B,A_SEXT_H,A_ZEXT_B,A_ZEXT_H,A_SEQZ,A_SNEG,A_SLTZ,A_SGTZ,
-        A_FMV_S,A_FABS_S,A_FNEG_S,A_FMV_D,A_FABS_D,A_FNEG_D,
+        A_FMV_S,A_FABS_S,A_FNEG_S,A_FMV_D,A_FABS_D,A_FNEG_D,A_FNEG_Q,
         A_BEQZ,A_BNEZ,A_BLEZ,A_BGEZ,A_BLTZ,A_BGTZ,A_BGT,A_BLE,
         A_BGTU,A_BLEU,A_J,A_JR,A_RET,A_TAIL,
         { normal opcodes }

+ 1 - 1
compiler/riscv/itcpugas.pas

@@ -32,7 +32,7 @@ unit itcpugas;
       gas_op2str: array[tasmop] of string[14] = ('<none>',
         'nop','call','la','lla','lga','li','mv','not','neg','negw',
         'sext.b','sext.h','zext.b','zext.h','seqz','sneg','sltz','sgtz',
-        'fmv.s','fabs.s','fneg.s','fmv.d','fabs.d','fneg.d',
+        'fmv.s','fabs.s','fneg.s','fmv.d','fabs.d','fneg.d','fneg.q',
         'beqz','bnez','blez','bgez','bltz','bgtz','gt','ble',
         'bgtu','bleu','j','jr','ret','tail',
         'lui','auipc','jal','jalr',

+ 74 - 0
compiler/riscv/nrvmat.pas

@@ -0,0 +1,74 @@
+{
+    Copyright (c) 1998-2002 by Florian Klaempfl
+
+    Generate RiscV assembler for math nodes
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit nrvmat;
+
+{$I fpcdefs.inc}
+
+  interface
+
+    uses
+      ncgmat;
+
+    type
+      trvunaryminusnode = class(tcgunaryminusnode)
+        procedure second_float;override;
+      end;
+
+implementation
+
+    uses
+      globtype,
+      verbose,
+      nmat,
+      cpubase,
+      aasmdata,aasmcpu,
+      cgbase,cgobj,cgcpu,cgutils,
+      symdef,
+      hlcgobj,
+      defutil,
+      pass_2;
+
+
+    procedure trvunaryminusnode.second_float;
+      begin
+        secondpass(left);
+        location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
+        location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
+        hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
+        case tfloatdef(left.resultdef).floattype of
+          s32real:
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FNEG_S,location.register,left.location.register));
+          s64real:
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FNEG_D,location.register,left.location.register));
+          s128real:
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FNEG_Q,location.register,left.location.register));
+          else
+            Internalerror(2025010901);
+        end;
+        cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
+      end;
+
+
+begin
+  cunaryminusnode := trvunaryminusnode;
+end.
+

+ 1 - 1
compiler/riscv32/nrv32mat.pas

@@ -41,7 +41,7 @@ interface
         procedure second_64bit;override;
       end;
 
-      trv32unaryminusnode = class(tcgunaryminusnode)
+      trv32unaryminusnode = class(trvunaryminusnode)
       end;
 
       trv32notnode = class(tcgnotnode)

+ 3 - 2
compiler/riscv64/nrv64mat.pas

@@ -26,7 +26,8 @@ unit nrv64mat;
   interface
 
     uses
-      node,nmat, ncgmat,
+      node, nmat, ncgmat,
+      nrvmat,
       cgbase;
 
     type
@@ -40,7 +41,7 @@ unit nrv64mat;
       trv64shlshrnode = class(tcgshlshrnode)
       end;
 
-      trv64unaryminusnode = class(tcgunaryminusnode)
+      trv64unaryminusnode = class(trvunaryminusnode)
       end;
 
       trv64notnode = class(tcgnotnode)