Bläddra i källkod

+ support for LLVM metadata constant string parameters
o they are implemented as a new metadata register class, whereby the
subregister indicates the metadata type (currently always a string)
and the superregister is an index in the metadata array (which
contains the strings). LLVM metadata can only be passed as parameters
to intrinsics in bitcode, so moves of metadata into other registers
triggers internal errors and when moving them into parameters, we
replace the parameter's register with the metadata register (and look
up the corresponding string when writing out the bitcode)

git-svn-id: trunk@43816 -

Jonas Maebe 5 år sedan
förälder
incheckning
9bd33f7a45

+ 1 - 1
compiler/aarch64/aasmcpu.pas

@@ -552,7 +552,7 @@ implementation
       const
       const
         { invalid sizes for aarch64 are 0 }
         { invalid sizes for aarch64 are 0 }
         subreg2bytesize: array[TSubRegister] of byte =
         subreg2bytesize: array[TSubRegister] of byte =
-          (0,0,0,0,4,8,0,0,0,4,8,0,0,0,0,0,0,0,0,0,0,0,0,8,16);
+          (0,0,0,0,4,8,0,0,0,4,8,0,0,0,0,0,0,0,0,0,0,0,0,8,16,0);
       var
       var
         scalefactor: byte;
         scalefactor: byte;
       begin
       begin

+ 7 - 3
compiler/cgbase.pas

@@ -211,7 +211,9 @@ interface
         R_SPECIALREGISTER, { = 5 }
         R_SPECIALREGISTER, { = 5 }
         R_ADDRESSREGISTER, { = 6 }
         R_ADDRESSREGISTER, { = 6 }
         { used on llvm, every temp gets its own "base register" }
         { used on llvm, every temp gets its own "base register" }
-        R_TEMPREGISTER     { = 7 }
+        R_TEMPREGISTER,    { = 7 }
+        { used on llvm for tracking metadata (every unique metadata has its own base register) }
+        R_METADATAREGISTER { = 8 }
       );
       );
 
 
       { Sub registers }
       { Sub registers }
@@ -242,8 +244,10 @@ interface
         R_SUBFLAGOVERFLOW,  { = 20; Overflow flag }
         R_SUBFLAGOVERFLOW,  { = 20; Overflow flag }
         R_SUBFLAGINTERRUPT, { = 21; Interrupt enable flag }
         R_SUBFLAGINTERRUPT, { = 21; Interrupt enable flag }
         R_SUBFLAGDIRECTION, { = 22; Direction flag }
         R_SUBFLAGDIRECTION, { = 22; Direction flag }
-        R_SUBMM8B,  { = 23; for part of v regs on aarch64 }
-        R_SUBMM16B  { = 24; for part of v regs on aarch64 }
+        R_SUBMM8B,          { = 23; for part of v regs on aarch64 }
+        R_SUBMM16B,         { = 24; for part of v regs on aarch64 }
+        { subregisters for the metadata register (llvm) }
+        R_SUBMETASTRING     { = 25 }
       );
       );
       TSubRegisterSet = set of TSubRegister;
       TSubRegisterSet = set of TSubRegister;
 
 

+ 5 - 0
compiler/fmodule.pas

@@ -153,6 +153,7 @@ interface
         llvmcompilerusedsyms : TFPObjectList; { a list of asmsymbols and their defs that need to be added to llvm.compiler.used (so they're not removed by llvm optimisation passes) }
         llvmcompilerusedsyms : TFPObjectList; { a list of asmsymbols and their defs that need to be added to llvm.compiler.used (so they're not removed by llvm optimisation passes) }
         llvminitprocs,
         llvminitprocs,
         llvmfiniprocs : TFPList;
         llvmfiniprocs : TFPList;
+        llvmmetadatastrings: TFPHashList; { metadata strings (mapping string -> superregister) }
 {$endif llvm}
 {$endif llvm}
         ansistrdef    : tobject; { an ansistring def redefined for the current module }
         ansistrdef    : tobject; { an ansistring def redefined for the current module }
         wpoinfo       : tunitwpoinfobase; { whole program optimization-related information that is generated during the current run for this unit }
         wpoinfo       : tunitwpoinfobase; { whole program optimization-related information that is generated during the current run for this unit }
@@ -605,6 +606,7 @@ implementation
         llvmcompilerusedsyms:=TFPObjectList.Create(true);
         llvmcompilerusedsyms:=TFPObjectList.Create(true);
         llvminitprocs:=TFPList.Create;
         llvminitprocs:=TFPList.Create;
         llvmfiniprocs:=TFPList.Create;
         llvmfiniprocs:=TFPList.Create;
+        llvmmetadatastrings:=TFPHashList.Create;
 {$endif llvm}
 {$endif llvm}
         ansistrdef:=nil;
         ansistrdef:=nil;
         wpoinfo:=nil;
         wpoinfo:=nil;
@@ -738,6 +740,7 @@ implementation
         llvmcompilerusedsyms.free;
         llvmcompilerusedsyms.free;
         llvminitprocs.free;
         llvminitprocs.free;
         llvmfiniprocs.free;
         llvmfiniprocs.free;
+        llvmmetadatastrings.free;
 {$endif llvm}
 {$endif llvm}
         ansistrdef:=nil;
         ansistrdef:=nil;
         wpoinfo.free;
         wpoinfo.free;
@@ -816,6 +819,8 @@ implementation
         llvminitprocs:=TFPList.Create;
         llvminitprocs:=TFPList.Create;
         llvmfiniprocs.free;
         llvmfiniprocs.free;
         llvmfiniprocs:=TFPList.Create;
         llvmfiniprocs:=TFPList.Create;
+        llvmmetadatastrings.free;
+        llvmmetadatastrings:=TFPHashList.Create;
 {$endif llvm}
 {$endif llvm}
         wpoinfo.free;
         wpoinfo.free;
         wpoinfo:=nil;
         wpoinfo:=nil;

+ 84 - 6
compiler/llvm/aasmllvmmetadata.pas

@@ -27,7 +27,9 @@ unit aasmllvmmetadata;
 interface
 interface
 
 
   uses
   uses
-    aasmtai, aasmcnst,
+    globtype,cclasses,
+    cgbase,
+    aasmtai,aasmcnst,
     symtype;
     symtype;
 
 
   type
   type
@@ -55,6 +57,10 @@ interface
       smeta_DIMacroFile
       smeta_DIMacroFile
     );
     );
 
 
+//   represented by a tai_simpletypedconst() with inside a metadata struct,
+//   or as a metadata register (for parameters)
+//    tai_llvmmetadatastring = class
+
     tai_llvmbasemetadatanode = class abstract(tai_aggregatetypedconst)
     tai_llvmbasemetadatanode = class abstract(tai_aggregatetypedconst)
      strict protected
      strict protected
       function getname: ansistring; virtual; abstract;
       function getname: ansistring; virtual; abstract;
@@ -67,10 +73,10 @@ interface
     (* !0 = !{ type1 value1, ... } *)
     (* !0 = !{ type1 value1, ... } *)
     tai_llvmunnamedmetadatanode = class(tai_llvmbasemetadatanode)
     tai_llvmunnamedmetadatanode = class(tai_llvmbasemetadatanode)
      strict private class var
      strict private class var
-      snextid: cardinal;
-      class function getnextid: cardinal;
+      snextid: TSuperRegister;
+      class function getnextid: TSuperRegister;
      strict protected
      strict protected
-      fnameval: cardinal;
+      fnameval: TSuperRegister;
      public
      public
       constructor create; reintroduce;
       constructor create; reintroduce;
       function getname: ansistring; override;
       function getname: ansistring; override;
@@ -104,17 +110,31 @@ interface
       property value: tai_llvmbasemetadatanode read fvalue;
       property value: tai_llvmbasemetadatanode read fvalue;
     end;
     end;
 
 
-      { !name = !kindname(field1: value1, ...) }
+    { !name = !kindname(field1: value1, ...) }
     tai_llvmspecialisedmetadatanode = class(tai_llvmunnamedmetadatanode)
     tai_llvmspecialisedmetadatanode = class(tai_llvmunnamedmetadatanode)
       { identifies name and fieldnames }
       { identifies name and fieldnames }
       kind: tspecialisedmetadatanodekind;
       kind: tspecialisedmetadatanodekind;
     end;
     end;
 
 
+    tllvmmetadata = class
+     strict private
+       class function addstring(const s: TSymstr): TSuperRegister;
+       class function regtostring(reg: TRegister): TSymStr;
+     public
+
+      class function getstringreg(const s: TSymstr): TRegister;
+      class function getpcharreg(p: pchar; len: longint): TRegister;
+      class function getregstring(reg: TRegister): TSymStr;
+    end;
+
     function llvm_getmetadatareftypedconst(metadata: tai_llvmbasemetadatanode): tai_simpletypedconst;
     function llvm_getmetadatareftypedconst(metadata: tai_llvmbasemetadatanode): tai_simpletypedconst;
 
 
+
 implementation
 implementation
 
 
   uses
   uses
+    verbose,
+    fmodule,
     symdef;
     symdef;
 
 
   function llvm_getmetadatareftypedconst(metadata: tai_llvmbasemetadatanode): tai_simpletypedconst;
   function llvm_getmetadatareftypedconst(metadata: tai_llvmbasemetadatanode): tai_simpletypedconst;
@@ -135,7 +155,7 @@ implementation
     end;
     end;
 
 
 
 
-  class function tai_llvmunnamedmetadatanode.getnextid: cardinal;
+  class function tai_llvmunnamedmetadatanode.getnextid: TSuperRegister;
     begin
     begin
       result:=snextid;
       result:=snextid;
       inc(snextid);
       inc(snextid);
@@ -183,5 +203,63 @@ implementation
     end;
     end;
 
 
 
 
+/////////////////////////////////////////////////
+
+  class function tllvmmetadata.addstring(const s: TSymStr): TSuperRegister;
+    var
+      index: longint;
+    begin
+      index:=current_module.llvmmetadatastrings.Add(s,nil);
+      if index>high(result) then
+        internalerror(2019122806);
+      result:=index;
+    end;
+
+
+  class function tllvmmetadata.regtostring(reg: TRegister): TSymStr;
+    begin
+      if getregtype(reg)<>R_METADATAREGISTER then
+        internalerror(2019122807);
+      if getsubreg(reg)<>R_SUBMETASTRING then
+        internalerror(2019122808);
+      result:=current_module.llvmmetadatastrings.NameOfIndex(getsupreg(reg));
+    end;
+
+
+  class function tllvmmetadata.getstringreg(const s: TSymstr): TRegister;
+    var
+      supreg: TSuperRegister;
+      index: longint;
+    begin
+      index:=current_module.llvmmetadatastrings.FindIndexOf(s);
+      if index<>-1 then
+        supreg:=index
+      else
+        supreg:=addstring(s);
+      result:=newreg(R_METADATAREGISTER,supreg,R_SUBMETASTRING);
+    end;
+
+
+  class function tllvmmetadata.getpcharreg(p: pchar; len: longint): TRegister;
+    var
+      str: TSymStr;
+    begin
+      if len>0 then
+        begin
+          setlength(str,len);
+          move(p[0],str[1],len);
+          result:=getstringreg(str);
+        end
+      else
+        result:=getstringreg('');
+    end;
+
+
+  class function tllvmmetadata.getregstring(reg: TRegister): TSymStr;
+    begin
+      result:=regtostring(reg);
+    end;
+
+
 end.
 end.
 
 

+ 9 - 4
compiler/llvm/agllvm.pas

@@ -272,11 +272,16 @@ implementation
 
 
     function getregisterstring(reg: tregister): ansistring;
     function getregisterstring(reg: tregister): ansistring;
       begin
       begin
-        if getregtype(reg)=R_TEMPREGISTER then
-          result:='%tmp.'
+        if getregtype(reg)=R_METADATAREGISTER then
+          result:='!"'+tllvmmetadata.getregstring(reg)+'"'
         else
         else
-          result:='%reg.'+tostr(byte(getregtype(reg)))+'_';
-        result:=result+tostr(getsupreg(reg));
+          begin
+            if getregtype(reg)=R_TEMPREGISTER then
+              result:='%tmp.'
+            else
+              result:='%reg.'+tostr(byte(getregtype(reg)))+'_';
+            result:=result+tostr(getsupreg(reg));
+          end;
       end;
       end;
 
 
 
 

+ 24 - 0
compiler/llvm/hlcgllvm.pas

@@ -39,6 +39,7 @@ uses
     thlcgllvm = class(thlcgobj)
     thlcgllvm = class(thlcgobj)
       constructor create;
       constructor create;
 
 
+      procedure a_load_reg_cgpara(list: TAsmList; size: tdef; r: tregister; const cgpara: TCGPara); override;
       procedure a_load_ref_cgpara(list: TAsmList; size: tdef; const r: treference; const cgpara: TCGPara); override;
       procedure a_load_ref_cgpara(list: TAsmList; size: tdef; const r: treference; const cgpara: TCGPara); override;
       procedure a_load_const_cgpara(list: TAsmList; tosize: tdef; a: tcgint; const cgpara: TCGPara); override;
       procedure a_load_const_cgpara(list: TAsmList; tosize: tdef; a: tcgint; const cgpara: TCGPara); override;
      protected
      protected
@@ -189,6 +190,18 @@ implementation
     end;
     end;
 
 
 
 
+  procedure thlcgllvm.a_load_reg_cgpara(list: TAsmList; size: tdef; r: tregister; const cgpara: TCGPara);
+    begin
+      if size<>llvm_metadatatype then
+        begin
+          inherited;
+          exit;
+        end;
+      { overwrite with the reference to the metadata (stored in the register's supreg) }
+      cgpara.location^.register:=r;
+    end;
+
+
   procedure thlcgllvm.a_load_ref_cgpara(list: TAsmList; size: tdef; const r: treference; const cgpara: TCGPara);
   procedure thlcgllvm.a_load_ref_cgpara(list: TAsmList; size: tdef; const r: treference; const cgpara: TCGPara);
     var
     var
       tmpref, initialref, ref: treference;
       tmpref, initialref, ref: treference;
@@ -610,6 +623,8 @@ implementation
     var
     var
       fromsize: tdef;
       fromsize: tdef;
     begin
     begin
+      if tosize=llvm_metadatatype then
+        internalerror(2019122804);
       if tosize.size<=ptrsinttype.size then
       if tosize.size<=ptrsinttype.size then
         fromsize:=ptrsinttype
         fromsize:=ptrsinttype
       else
       else
@@ -655,6 +670,9 @@ implementation
       hreg2: tregister;
       hreg2: tregister;
       tmpsize: tdef;
       tmpsize: tdef;
     begin
     begin
+      if (fromsize=llvm_metadatatype) or
+         (tosize=llvm_metadatatype) then
+        internalerror(2019122802);
       sref:=make_simple_ref(list,ref,tosize);
       sref:=make_simple_ref(list,ref,tosize);
       hreg:=register;
       hreg:=register;
       (* typecast the pointer to the value instead of the value itself if
       (* typecast the pointer to the value instead of the value itself if
@@ -724,6 +742,9 @@ implementation
       tmpreg: tregister;
       tmpreg: tregister;
       tmpintdef: tdef;
       tmpintdef: tdef;
     begin
     begin
+      if (fromsize=llvm_metadatatype) or
+         (tosize=llvm_metadatatype) then
+        internalerror(2019122801);
       op:=llvmconvop(fromsize,tosize,true);
       op:=llvmconvop(fromsize,tosize,true);
       { converting from pointer to something else and vice versa is only
       { converting from pointer to something else and vice versa is only
         possible via an intermediate pass to integer. Same for "something else"
         possible via an intermediate pass to integer. Same for "something else"
@@ -858,6 +879,9 @@ implementation
       sref: treference;
       sref: treference;
       hreg: tregister;
       hreg: tregister;
     begin
     begin
+      if (fromsize=llvm_metadatatype) or
+         (tosize=llvm_metadatatype) then
+        internalerror(2019122803);
       sref:=make_simple_ref(list,ref,fromsize);
       sref:=make_simple_ref(list,ref,fromsize);
       { "named register"? }
       { "named register"? }
       if sref.refaddr=addr_full then
       if sref.refaddr=addr_full then

+ 3 - 1
compiler/llvm/llvmdef.pas

@@ -359,7 +359,9 @@ implementation
             end;
             end;
           pointerdef :
           pointerdef :
             begin
             begin
-              if is_voidpointer(def) then
+              if def=llvm_metadatatype then
+                encodedstr:=encodedstr+'metadata'
+              else if is_voidpointer(def) then
                 encodedstr:=encodedstr+'i8*'
                 encodedstr:=encodedstr+'i8*'
               else
               else
                 begin
                 begin

+ 6 - 0
compiler/llvm/llvmpara.pas

@@ -127,6 +127,12 @@ unit llvmpara;
               if not(paraloc^.loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER]) then
               if not(paraloc^.loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER]) then
                 internalerror(2019011902);
                 internalerror(2019011902);
               reducetosingleregparaloc(paraloc,hp.paraloc[side].def,paraloc^.register);
               reducetosingleregparaloc(paraloc,hp.paraloc[side].def,paraloc^.register);
+            end
+          else if paraloc^.def=llvm_metadatatype then
+            begin
+              paraloc^.Loc:=LOC_REGISTER;
+              // will be overwritten with a "register" whose superregister is an index in the LLVM metadata table
+              paraloc^.register:=NR_INVALID;
             end;
             end;
         end;
         end;
     end;
     end;

+ 49 - 3
compiler/llvm/nllvmcon.pas

@@ -37,6 +37,9 @@ interface
        end;
        end;
 
 
        tllvmstringconstnode = class(tcgstringconstnode)
        tllvmstringconstnode = class(tcgstringconstnode)
+          constructor createpchar(s: pchar; l: longint; def: tdef); override;
+          function pass_typecheck: tnode; override;
+          function pass_1: tnode; override;
           procedure pass_generate_code; override;
           procedure pass_generate_code; override;
        protected
        protected
           procedure load_dynstring(const strpointerdef: tdef; const elementdef: tdef; const winlikewidestring: boolean); override;
           procedure load_dynstring(const strpointerdef: tdef; const elementdef: tdef; const winlikewidestring: boolean); override;
@@ -47,20 +50,63 @@ implementation
     uses
     uses
       globtype,globals,verbose,cutils,
       globtype,globals,verbose,cutils,
       symbase,symtable,symconst,symdef,symsym,defutil,
       symbase,symtable,symconst,symdef,symsym,defutil,
-      aasmdata,aasmcnst,
+      aasmbase,aasmdata,aasmcnst,
       ncon,
       ncon,
-      llvmbase,aasmllvm,hlcgobj,
-      cgbase,cgutils;
+      llvmbase,aasmllvm,aasmllvmmetadata,hlcgobj,
+      cgbase,cgutils,
+      cpubase;
 
 
 {*****************************************************************************
 {*****************************************************************************
                            tllvmstringconstnode
                            tllvmstringconstnode
 *****************************************************************************}
 *****************************************************************************}
 
 
+    constructor tllvmstringconstnode.createpchar(s: pchar; l: longint; def: tdef);
+      begin
+        inherited;
+        if def=llvm_metadatatype then
+          begin
+            { astringdef is only used if the constant type is ansitring }
+            cst_type:=cst_ansistring;
+            astringdef:=def;
+          end;
+      end;
+
+
+    function tllvmstringconstnode.pass_typecheck: tnode;
+      begin
+        if astringdef<>llvm_metadatatype then
+          begin
+            result:=inherited;
+            exit;
+          end;
+        resultdef:=llvm_metadatatype;
+        result:=nil;
+      end;
+
+
+    function tllvmstringconstnode.pass_1: tnode;
+      begin
+        if astringdef<>llvm_metadatatype then
+          begin
+            result:=inherited;
+            exit;
+          end;
+        expectloc:=LOC_CREGISTER;
+        result:=nil;
+      end;
+
+
     procedure tllvmstringconstnode.pass_generate_code;
     procedure tllvmstringconstnode.pass_generate_code;
       var
       var
         datadef, resptrdef: tdef;
         datadef, resptrdef: tdef;
         hreg: tregister;
         hreg: tregister;
       begin
       begin
+        if astringdef=llvm_metadatatype then
+          begin
+            location_reset(location,LOC_CREGISTER,OS_ADDR);
+            location.register:=tllvmmetadata.getpcharreg(value_str,len);
+            exit;
+          end;
         inherited pass_generate_code;
         inherited pass_generate_code;
         if cst_type in [cst_conststring,cst_shortstring] then
         if cst_type in [cst_conststring,cst_shortstring] then
           begin
           begin

+ 5 - 8
compiler/psystem.pas

@@ -543,6 +543,10 @@ implementation
         addtype('$qwordbool',bool64type);
         addtype('$qwordbool',bool64type);
 {$ifdef llvm}
 {$ifdef llvm}
         addtype('$llvmbool1',llvmbool1type);
         addtype('$llvmbool1',llvmbool1type);
+        llvm_metadatatype:=cpointerdef.create(voidtype);
+        { if this gets renamed, also adjust agllvm so it still writes the identifier of this type as "metadata" }
+        addtype('$metadata',llvm_metadatatype);
+        addtype('LLVMMetadata',llvm_metadatatype);
 {$endif llvm}
 {$endif llvm}
         addtype('$char_pointer',charpointertype);
         addtype('$char_pointer',charpointertype);
         addtype('$widechar_pointer',widecharpointertype);
         addtype('$widechar_pointer',widecharpointertype);
@@ -620,11 +624,6 @@ implementation
         addfield(hrecst,cfieldvarsym.create('$parentfp',vs_value,parentfpvoidpointertype,[]));
         addfield(hrecst,cfieldvarsym.create('$parentfp',vs_value,parentfpvoidpointertype,[]));
         nestedprocpointertype:=crecorddef.create('',hrecst);
         nestedprocpointertype:=crecorddef.create('',hrecst);
         addtype('$nestedprocpointer',nestedprocpointertype);
         addtype('$nestedprocpointer',nestedprocpointertype);
-{$ifdef llvm}
-        llvm_metadatatype:=cpointerdef.create(voidtype);
-        { if this gets renamed, also adjust agllvm so it still writes the identifier of this type as "metadata" }
-        addtype('$metadata',llvm_metadatatype);
-{$endif}
         symtablestack.pop(systemunit);
         symtablestack.pop(systemunit);
       end;
       end;
 
 
@@ -725,6 +724,7 @@ implementation
 {$endif x86}
 {$endif x86}
 {$ifdef llvm}
 {$ifdef llvm}
         loadtype('llvmbool1',llvmbool1type);
         loadtype('llvmbool1',llvmbool1type);
+        loadtype('metadata',llvm_metadatatype);
 {$endif llvm}
 {$endif llvm}
         loadtype('file',cfiletype);
         loadtype('file',cfiletype);
         if not(target_info.system in systems_managed_vm) then
         if not(target_info.system in systems_managed_vm) then
@@ -740,9 +740,6 @@ implementation
           end;
           end;
         loadtype('methodpointer',methodpointertype);
         loadtype('methodpointer',methodpointertype);
         loadtype('nestedprocpointer',nestedprocpointertype);
         loadtype('nestedprocpointer',nestedprocpointertype);
-{$ifdef llvm}
-        loadtype('metadata',llvm_metadatatype);
-{$endif}
         loadtype('HRESULT',hresultdef);
         loadtype('HRESULT',hresultdef);
         loadtype('TTYPEKIND',typekindtype);
         loadtype('TTYPEKIND',typekindtype);
         set_default_int_types;
         set_default_int_types;

+ 2 - 2
compiler/x86/aasmcpu.pas

@@ -2474,9 +2474,9 @@ implementation
           (0, 1, 2, 3, 6, 7, 5, 4);
           (0, 1, 2, 3, 6, 7, 5, 4);
         maxsupreg: array[tregistertype] of tsuperregister=
         maxsupreg: array[tregistertype] of tsuperregister=
 {$ifdef x86_64}
 {$ifdef x86_64}
-          (0, 16, 9, 8, 32, 32, 8, 0);
+          (0, 16, 9, 8, 32, 32, 8, 0, 0);
 {$else x86_64}
 {$else x86_64}
-          (0,  8, 9, 8,  8, 32, 8, 0);
+          (0,  8, 9, 8,  8, 32, 8, 0, 0);
 {$endif x86_64}
 {$endif x86_64}
       var
       var
         rs: tsuperregister;
         rs: tsuperregister;

+ 2 - 2
compiler/x86/cpubase.pas

@@ -481,7 +481,7 @@ implementation
 
 
     function reg_cgsize(const reg: tregister): tcgsize;
     function reg_cgsize(const reg: tregister): tcgsize;
       const subreg2cgsize:array[Tsubregister] of Tcgsize =
       const subreg2cgsize:array[Tsubregister] of Tcgsize =
-            (OS_NO,OS_8,OS_8,OS_16,OS_32,OS_64,OS_NO,OS_NO,OS_NO,OS_F32,OS_F64,OS_NO,OS_M128,OS_M256,OS_M512,OS_NO,OS_NO,OS_NO,OS_NO,OS_NO,OS_NO,OS_NO,OS_NO,OS_NO,OS_NO);
+            (OS_NO,OS_8,OS_8,OS_16,OS_32,OS_64,OS_NO,OS_NO,OS_NO,OS_F32,OS_F64,OS_NO,OS_M128,OS_M256,OS_M512,OS_NO,OS_NO,OS_NO,OS_NO,OS_NO,OS_NO,OS_NO,OS_NO,OS_NO,OS_NO,OS_NO);
       begin
       begin
         case getregtype(reg) of
         case getregtype(reg) of
           R_INTREGISTER :
           R_INTREGISTER :
@@ -517,7 +517,7 @@ implementation
     function reg2opsize(r:Tregister):topsize;
     function reg2opsize(r:Tregister):topsize;
       const
       const
         subreg2opsize : array[tsubregister] of topsize =
         subreg2opsize : array[tsubregister] of topsize =
-          (S_NO,S_B,S_B,S_W,S_L,S_Q,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO);
+          (S_NO,S_B,S_B,S_W,S_L,S_Q,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO);
       begin
       begin
         reg2opsize:=S_L;
         reg2opsize:=S_L;
         case getregtype(r) of
         case getregtype(r) of