Browse Source

+ RiscV: make use of the fl* rd,symbol,rd pseudoinstruction

florian 6 months ago
parent
commit
1202b2612f

+ 1 - 1
compiler/aasmtai.pas

@@ -2991,7 +2991,7 @@ implementation
               and not(r.refaddr in [addr_full,addr_gotpageoffset,addr_gotpage])
 {$endif aarch64}
 {$ifdef riscv}
-              and not(opcode=A_LA)
+              and not(opcode in [A_LA,A_FLD,A_FLQ,A_FLW])
 {$endif riscv}
               then
               internalerror(200502052);

+ 10 - 0
compiler/riscv/aasmcpu.pas

@@ -63,6 +63,7 @@ uses
          constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: aint);
          constructor op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: aint);
          constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
+         constructor op_reg_ref_reg(op : tasmop;_op1: tregister; const _op2: treference;_op3 : tregister);
          constructor op_const_reg_reg(op : tasmop;_op1 : aint;_op2, _op3 : tregister);
          constructor op_const_reg_const(op : tasmop;_op1 : aint;_op2 : tregister;_op3 : aint);
          constructor op_const_const_const(op : tasmop;_op1 : aint;_op2 : aint;_op3 : aint);
@@ -261,6 +262,15 @@ uses cutils, cclasses;
          loadref(2,_op3);
       end;
 
+     constructor taicpu.op_reg_ref_reg(op : tasmop;_op1: tregister; const _op2: treference;_op3 : tregister);
+       begin
+         inherited create(op);
+         ops:=3;
+         loadreg(0,_op1);
+         loadref(1,_op2);
+         loadreg(2,_op3);
+      end;
+
     constructor taicpu.op_const_reg_reg(op : tasmop;_op1 : aint;_op2, _op3 : tregister);
       begin
          inherited create(op);

+ 1 - 1
compiler/riscv/agrvgas.pas

@@ -126,7 +126,7 @@ unit agrvgas;
                if (offset=0) then
                  s:=s+gas_regname(base)+','+gas_regname(index)
                else
-                 internalerror(2006052502);
+                 internalerror(2025011102);
              end
            else
              Internalerror(2021030602);

+ 21 - 8
compiler/riscv/cgrv.pas

@@ -868,21 +868,34 @@ unit cgrv;
         l: TAsmLabel;
       begin
         href:=ref;
-        fixref(list,href);      
 
-        if href.refaddr=addr_pcrel then
+        { can we use the fl* rd,symbol,rd pseudoinstruction? }
+        if (assigned(href.symbol) or (href.offset<>0)) then
           begin
-            tmpreg:=getintregister(list,OS_ADDR);
-            a_loadaddr_ref_reg(list,href,tmpreg);
-            reference_reset_base(href,tmpreg,0,ctempposinvalid,0,ref.volatility);
-          end;
+            if (href.base<>NR_NO) or (href.index<>NR_NO) then
+              fixref(list,href)
+            else
+              href.refaddr:=addr_full;
+          end
+        else
+          fixref(list,href);
 
         if fromsize=OS_F32 then
           op:=A_FLW
+        else if fromsize=OS_F64 then
+          op:=A_FLD
+        else if fromsize=OS_F128 then
+          op:=A_FLQ
         else
-          op:=A_FLD;
+          Internalerror(2025011101);
 
-        list.concat(taicpu.op_reg_ref(op,reg,href));
+        if href.refaddr in [addr_pcrel,addr_full] then
+          begin
+            tmpreg:=getintregister(list,OS_ADDR);
+            list.concat(taicpu.op_reg_ref_reg(op,reg,href,tmpreg));
+          end
+        else
+          list.concat(taicpu.op_reg_ref(op,reg,href));
 
         if fromsize<>tosize then
           a_loadfpu_reg_reg(list,fromsize,tosize,reg,reg);

+ 1 - 1
compiler/riscv/cpubase.pas

@@ -157,7 +157,7 @@ uses
 {$endif RISCV64}
 
         { Q-extension }
-//        A_FLD,A_FSD,
+        A_FLQ,A_FSQ,
 //        A_FMADD_D,A_FMSUB_D,A_FNMSUB_D,A_FNMADD_D,
 //        A_FADD_D,A_FSUB_D,A_FMUL_D,A_FDIV_D,
 //        A_FSQRT_D,A_FSGNJ_D,A_FSGNJN_D,A_FSGNJX_D,

+ 1 - 0
compiler/riscv/itcpugas.pas

@@ -148,6 +148,7 @@ unit itcpugas;
 {$endif RISCV64}
 
         { q-extension }
+        'flq','fsq',
         'fmax.q','fmax.q',
 
         { Machine mode }