Browse Source

LLVM: support for -Sv (manual vector usage)

Override register type for vectors to "integer registers" because we don't
use mmregister on LLVM (they're all virtual, so it doesn't matter)
Jonas Maebe 2 years ago
parent
commit
657b9a6203
2 changed files with 83 additions and 0 deletions
  1. 11 0
      compiler/llvm/hlcgllvm.pas
  2. 72 0
      compiler/llvm/nllvmadd.pas

+ 11 - 0
compiler/llvm/hlcgllvm.pas

@@ -54,6 +54,7 @@ uses
 
       procedure recordnewsymloc(list: TAsmList; sym: tsym; def: tdef; const ref: treference); override;
 
+      class function def2regtyp(def: tdef): tregistertype; override;
      public
       procedure a_bit_test_reg_reg_reg(list: TAsmList; bitnumbersize, valuesize, destsize: tdef; bitnumber, value, destreg: tregister); override;
       procedure a_bit_set_reg_reg(list: TAsmList; doset: boolean; bitnumbersize, destsize: tdef; bitnumber, dest: tregister); override;
@@ -436,6 +437,16 @@ implementation
     end;
 
 
+  class function thlcgllvm.def2regtyp(def: tdef): tregistertype;
+    begin
+      if (def.typ=arraydef) and
+         tarraydef(def).is_hwvector then
+        result:=R_INTREGISTER
+      else
+        result:=inherited;
+    end;
+
+
   procedure thlcgllvm.a_bit_test_reg_reg_reg(list: TAsmList; bitnumbersize, valuesize, destsize: tdef; bitnumber, value, destreg: tregister);
     var
       tmpbitnumberreg: tregister;

+ 72 - 0
compiler/llvm/nllvmadd.pas

@@ -41,6 +41,7 @@ interface
         procedure second_cmp64bit; override;
         procedure second_addfloat; override;
         procedure second_cmpfloat; override;
+        procedure second_opvector; override;
       end;
 
 
@@ -356,6 +357,77 @@ implementation
       second_addfloat;
     end;
 
+  procedure tllvmaddnode.second_opvector;
+
+    var
+      lv, rv: tdef;
+      hreg: tregister;
+      tempref: treference;
+      op: tllvmop;
+      isfloat: boolean;
+    begin
+      if not is_vector(left.resultdef) or
+         not is_vector(right.resultdef) or
+         not is_vector(resultdef) or
+         not tarraydef(resultdef).is_hwvector then
+        internalerror(2022090710);
+
+      pass_left_right;
+      if (nf_swapped in flags) then
+        swapleftright;
+
+      isfloat:=tarraydef(left.resultdef).elementdef.typ=floatdef;
+      case nodetype of
+        addn :
+          if isfloat then
+            op:=la_fadd
+          else
+            op:=la_add;
+        muln :
+          if isfloat then
+            op:=la_fmul
+          else
+            op:=la_mul;
+        subn :
+          if isfloat then
+            op:=la_fsub
+          else
+            op:=la_sub;
+        slashn :
+          if isfloat then
+            op:=la_fdiv
+          else if is_signed(tarraydef(left.resultdef).elementdef) then
+            op:=la_sdiv
+          else
+            op:=la_udiv;
+        xorn:
+          if not isfloat then
+            op:=la_xor
+          else
+            internalerror(2022090711);
+        orn:
+          if not isfloat then
+            op:=la_or
+          else
+            internalerror(2022090712);
+        andn:
+          if not isfloat then
+            op:=la_and
+          else
+            internalerror(2022090712);
+        else
+          internalerror(200610073);
+      end;
+
+      location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
+      lv:=to_hwvectordef(tarraydef(left.resultdef),false);
+      rv:=to_hwvectordef(tarraydef(right.resultdef),false);
+      hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,lv,false);
+      hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,rv,false);
+      location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
+      current_asmdata.CurrAsmList.concat(taillvm.op_reg_size_reg_reg(op,location.register,lv,left.location.register,right.location.register));
+    end;
+
 
 begin
   caddnode:=tllvmaddnode;