瀏覽代碼

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 年之前
父節點
當前提交
a6c7ed5e61
共有 4 個文件被更改,包括 40 次插入9 次删除
  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
                               end
                             else
                             else
                             { array -> array }
                             { 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).lowrange=tarraydef(def_to).lowrange) and
                                 (tarraydef(def_from).highrange=tarraydef(def_to).highrange) 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).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
                               begin
                                 eq:=te_equal
                                 eq:=te_equal
                               end;
                               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 }
     { Returns the range type of an ordinal type in the sense of ISO-10206 }
     function get_iso_range_type(def: tdef): tdef;
     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;
     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 }
     { some type helper routines for MMX support }
     function is_mmx_able_array(p : tdef) : boolean;
     function is_mmx_able_array(p : tdef) : boolean;
 
 
@@ -1424,10 +1427,13 @@ implementation
     function is_vector(p : tdef) : boolean;
     function is_vector(p : tdef) : boolean;
       begin
       begin
         result:=(p.typ=arraydef) and
         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;
       end;
 
 
 
 
@@ -1504,6 +1510,23 @@ implementation
       end;
       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;
     function is_mmx_able_array(p : tdef) : boolean;
       begin
       begin
 {$ifdef SUPPORT_MMX}
 {$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
               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);
                 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 }
               { 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
             end
 
 
          { this is a little bit dangerous, also the left type }
          { 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
         if equal_defs(p.resultdef,def) and
            (p.resultdef.typ=def.typ) and
            (p.resultdef.typ=def.typ) and
            not is_bitpacked_access(p) 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
            ((p.blocktype=bt_const) or
             not ctypeconvnode.target_specific_need_equal_typeconv(p.resultdef,def)) then
             not ctypeconvnode.target_specific_need_equal_typeconv(p.resultdef,def)) then
           begin
           begin