Browse Source

vector support: use vector result types

Set the result of a vector add node to a vector type.

Ensure that that these vector types are still asignment-compatible with
regular array types (may want to change this when we expose vector types),
and don't remove type conversions from vector types to array types (so the
code generator pass can still rely on the resultdef being a vector type)
Jonas Maebe 2 years ago
parent
commit
a6c7ed5e61
4 changed files with 40 additions and 9 deletions
  1. 6 3
      compiler/defcmp.pas
  2. 28 5
      compiler/defutil.pas
  3. 1 1
      compiler/nadd.pas
  4. 5 0
      compiler/ncnv.pas

+ 6 - 3
compiler/defcmp.pas

@@ -1289,12 +1289,15 @@ implementation
                               end
                             else
                             { array -> array }
-                             if not(m_tp7 in current_settings.modeswitches) and
-                                not(m_delphi in current_settings.modeswitches) and
+                             if ((not(m_tp7 in current_settings.modeswitches) and
+                                  not(m_delphi in current_settings.modeswitches)) or
+                                { allow assigning vector results to regular
+                                  arrays. TODO: change once we expose vector types }
+                                 tarraydef(def_from).is_hwvector) and
                                 (tarraydef(def_from).lowrange=tarraydef(def_to).lowrange) and
                                 (tarraydef(def_from).highrange=tarraydef(def_to).highrange) and
                                 equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) and
-                                equal_defs(tarraydef(def_from).rangedef,tarraydef(def_to).rangedef) then
+                                (compare_defs_ext(tarraydef(def_from).rangedef,tarraydef(def_to).rangedef,nothingn,hct,hpd,[])>te_incompatible) then
                               begin
                                 eq:=te_equal
                               end;

+ 28 - 5
compiler/defutil.pas

@@ -330,9 +330,12 @@ interface
     { Returns the range type of an ordinal type in the sense of ISO-10206 }
     function get_iso_range_type(def: tdef): tdef;
 
-    { type being a vector? }
+    { is the type a vector, or can it be transparently used as one? }
     function is_vector(p : tdef) : boolean;
 
+    { return a real/hardware vectordef representing this def }
+    function to_hwvectordef(p: tdef; nil_on_error: boolean): tdef;
+
     { some type helper routines for MMX support }
     function is_mmx_able_array(p : tdef) : boolean;
 
@@ -1424,10 +1427,13 @@ implementation
     function is_vector(p : tdef) : boolean;
       begin
         result:=(p.typ=arraydef) and
-                not(is_special_array(p)) and
-                (tarraydef(p).elementdef.typ in [floatdef,orddef]) {and
-                (tarraydef(p).elementdef.typ=floatdef) and
-                (tfloatdef(tarraydef(p).elementdef).floattype in [s32real,s64real])};
+                (tarraydef(p).is_hwvector or
+                 (not(is_special_array(p)) and
+                  (tarraydef(p).elementdef.typ in [floatdef,orddef]) {and
+                  (tarraydef(p).elementdef.typ=floatdef) and
+                  (tfloatdef(tarraydef(p).elementdef).floattype in [s32real,s64real])}
+                 )
+                );
       end;
 
 
@@ -1504,6 +1510,23 @@ implementation
       end;
 
 
+    function to_hwvectordef(p: tdef; nil_on_error: boolean): tdef;
+      begin
+        result:=nil;
+        if p.typ=arraydef then
+          begin
+            if tarraydef(p).is_hwvector then
+              result:=p
+            else if fits_in_mm_register(p) then
+              result:=carraydef.getreusable_vector(tarraydef(p).elementdef,tarraydef(p).elecount)
+            else if not nil_on_error then
+              internalerror(2022090811);
+          end
+        else if not nil_on_error then
+          internalerror(2022090810);
+      end;
+
+
     function is_mmx_able_array(p : tdef) : boolean;
       begin
 {$ifdef SUPPORT_MMX}

+ 1 - 1
compiler/nadd.pas

@@ -3067,7 +3067,7 @@ implementation
               if not(nodetype in [addn,subn,xorn,orn,andn,muln,slashn]) then
                 CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename);
               { both defs must be equal, so taking left or right as resultdef doesn't matter }
-              resultdef:=left.resultdef;
+              resultdef:=to_hwvectordef(left.resultdef,false);
             end
 
          { this is a little bit dangerous, also the left type }

+ 5 - 0
compiler/ncnv.pas

@@ -360,6 +360,11 @@ implementation
         if equal_defs(p.resultdef,def) and
            (p.resultdef.typ=def.typ) and
            not is_bitpacked_access(p) and
+           { result of a hardware vector node must remain a hardware
+             vector of the same kind (will match to tc_equal with regular arrays
+             of same dimension/eledef) }
+           not((p.resultdef.typ=arraydef) and
+               tarraydef(p.resultdef).is_hwvector) and
            ((p.blocktype=bt_const) or
             not ctypeconvnode.target_specific_need_equal_typeconv(p.resultdef,def)) then
           begin