فهرست منبع

* refactored general loc->cgpara loading code in ncgcal into helpers in
ncgutil it can be used elsewhere too
- removed the code that checks for 64 bit integer types in the float
para loading code, since is_64bit() can never return true for a
floatdef

git-svn-id: trunk@15318 -

Jonas Maebe 15 سال پیش
والد
کامیت
e9b62c1294
2فایلهای تغییر یافته به همراه195 افزوده شده و 171 حذف شده
  1. 2 171
      compiler/ncgcal.pas
  2. 193 0
      compiler/ncgutil.pas

+ 2 - 171
compiler/ncgcal.pas

@@ -119,11 +119,6 @@ implementation
 
 
     procedure tcgcallparanode.push_value_para;
-{$ifdef i386}
-      var
-        href   : treference;
-        size   : longint;
-{$endif i386}
       begin
         { we've nothing to push when the size of the parameter is 0 }
         if left.resultdef.size=0 then
@@ -139,173 +134,9 @@ implementation
           be handled by cpupara }
 
         if left.resultdef.typ=floatdef then
-         begin
-{$ifdef i386}
-           if tempcgpara.location^.loc<>LOC_REFERENCE then
-             internalerror(200309291);
-           case left.location.loc of
-             LOC_FPUREGISTER,
-             LOC_CFPUREGISTER:
-               begin
-                 size:=align(TCGSize2Size[left.location.size],tempcgpara.alignment);
-                 if tempcgpara.location^.reference.index=NR_STACK_POINTER_REG then
-                   begin
-                     cg.g_stackpointer_alloc(current_asmdata.CurrAsmList,size);
-                     reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint));
-                   end
-                 else
-                   reference_reset_base(href,tempcgpara.location^.reference.index,tempcgpara.location^.reference.offset,tempcgpara.alignment);
-                 cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,left.location.size,left.location.size,left.location.register,href);
-               end;
-             LOC_MMREGISTER,
-             LOC_CMMREGISTER:
-               begin
-                 size:=align(tfloatdef(left.resultdef).size,tempcgpara.alignment);
-                 if tempcgpara.location^.reference.index=NR_STACK_POINTER_REG then
-                   begin
-                     cg.g_stackpointer_alloc(current_asmdata.CurrAsmList,size);
-                     reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint));
-                   end
-                 else
-                   reference_reset_base(href,tempcgpara.location^.reference.index,tempcgpara.location^.reference.offset,tempcgpara.alignment);
-                 cg.a_loadmm_reg_ref(current_asmdata.CurrAsmList,left.location.size,left.location.size,left.location.register,href,mms_movescalar);
-               end;
-             LOC_REFERENCE,
-             LOC_CREFERENCE :
-               begin
-                 size:=align(left.resultdef.size,tempcgpara.alignment);
-                 if (not use_fixed_stack) and
-                    (tempcgpara.location^.reference.index=NR_STACK_POINTER_REG) then
-                   cg.a_load_ref_cgpara(current_asmdata.CurrAsmList,left.location.size,left.location.reference,tempcgpara)
-                 else
-                   begin
-                     reference_reset_base(href,tempcgpara.location^.reference.index,tempcgpara.location^.reference.offset,tempcgpara.alignment);
-                     cg.g_concatcopy(current_asmdata.CurrAsmList,left.location.reference,href,size);
-                   end;
-               end;
-             else
-               internalerror(2002042430);
-           end;
-{$else i386}
-           case left.location.loc of
-             LOC_MMREGISTER,
-             LOC_CMMREGISTER:
-               case tempcgpara.location^.loc of
-                 LOC_REFERENCE,
-                 LOC_CREFERENCE,
-                 LOC_MMREGISTER,
-                 LOC_CMMREGISTER,
-                 LOC_REGISTER,
-                 LOC_CREGISTER :
-                   cg.a_loadmm_reg_cgpara(current_asmdata.CurrAsmList,left.location.size,left.location.register,tempcgpara,mms_movescalar);
-                 LOC_FPUREGISTER,
-                 LOC_CFPUREGISTER:
-                   begin
-                     location_force_fpureg(current_asmdata.CurrAsmList,left.location,false);
-                     cg.a_loadfpu_reg_cgpara(current_asmdata.CurrAsmList,left.location.size,left.location.register,tempcgpara);
-                   end;
-                 else
-                   internalerror(200204249);
-               end;
-             LOC_FPUREGISTER,
-             LOC_CFPUREGISTER:
-               case tempcgpara.location^.loc of
-                 LOC_MMREGISTER,
-                 LOC_CMMREGISTER:
-                   begin
-                     location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,false);
-                     cg.a_loadmm_reg_cgpara(current_asmdata.CurrAsmList,left.location.size,left.location.register,tempcgpara,mms_movescalar);
-                   end;
-                 { Some targets pass floats in normal registers }
-                 LOC_REGISTER,
-                 LOC_CREGISTER,
-                 LOC_REFERENCE,
-                 LOC_CREFERENCE,
-                 LOC_FPUREGISTER,
-                 LOC_CFPUREGISTER:
-                   cg.a_loadfpu_reg_cgpara(current_asmdata.CurrAsmList,left.location.size,left.location.register,tempcgpara);
-                 else
-                   internalerror(2002042433);
-               end;
-             LOC_REFERENCE,
-             LOC_CREFERENCE:
-               case tempcgpara.location^.loc of
-                 LOC_MMREGISTER,
-                 LOC_CMMREGISTER:
-                   cg.a_loadmm_ref_cgpara(current_asmdata.CurrAsmList,left.location.size,left.location.reference,tempcgpara,mms_movescalar);
-                 { Some targets pass floats in normal registers }
-                 LOC_REGISTER,
-                 LOC_CREGISTER,
-                 LOC_REFERENCE,
-                 LOC_CREFERENCE,
-                 LOC_FPUREGISTER,
-                 LOC_CFPUREGISTER:
-                   cg.a_loadfpu_ref_cgpara(current_asmdata.CurrAsmList,left.location.size,left.location.reference,tempcgpara);
-                 else
-                   internalerror(2002042431);
-               end;
-             LOC_REGISTER,
-             LOC_CREGISTER :
-               begin
-{$ifndef cpu64bitalu}
-                 { use cg64 only for int64, not for 8 byte records }
-                 if is_64bit(left.resultdef) then
-                   cg64.a_load64_loc_cgpara(current_asmdata.CurrAsmList,left.location,tempcgpara)
-                 else
-{$endif not cpu64bitalu}
-                   begin
-{$ifndef cpu64bitalu}
-                     { Only a_load_ref_cgpara supports multiple locations, when the
-                       value is still a const or in a register then write it
-                       to a reference first. This situation can be triggered
-                       by typecasting an int64 constant to a record of 8 bytes }
-                     if left.location.size in [OS_64,OS_S64] then
-                       location_force_mem(current_asmdata.CurrAsmList,left.location);
-{$endif not cpu64bitalu}
-                     cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,tempcgpara);
-                   end;
-               end;
-             else
-               internalerror(2002042432);
-           end;
-{$endif i386}
-         end
+          gen_loadfpu_loc_cgpara(current_asmdata.CurrAsmList,left.location,tempcgpara,left.resultdef.size)
         else
-         begin
-           case left.location.loc of
-             LOC_CONSTANT,
-             LOC_REGISTER,
-             LOC_CREGISTER,
-             LOC_REFERENCE,
-             LOC_CREFERENCE :
-               begin
-{$ifndef cpu64bitalu}
-                 { use cg64 only for int64, not for 8 byte records }
-                 if is_64bit(left.resultdef) then
-                   cg64.a_load64_loc_cgpara(current_asmdata.CurrAsmList,left.location,tempcgpara)
-                 else
-{$endif not cpu64bitalu}
-                   begin
-{$ifndef cpu64bitalu}
-                     { Only a_load_ref_cgpara supports multiple locations, when the
-                       value is still a const or in a register then write it
-                       to a reference first. This situation can be triggered
-                       by typecasting an int64 constant to a record of 8 bytes }
-                     if left.location.size in [OS_64,OS_S64] then
-                       location_force_mem(current_asmdata.CurrAsmList,left.location);
-{$endif not cpu64bitalu}
-                     cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,tempcgpara);
-                   end;
-               end;
-{$ifdef SUPPORT_MMX}
-             LOC_MMXREGISTER,
-             LOC_CMMXREGISTER:
-               cg.a_loadmm_reg_cgpara(current_asmdata.CurrAsmList,OS_M64,left.location.register,tempcgpara,nil);
-{$endif SUPPORT_MMX}
-             else
-               internalerror(200204241);
-           end;
-         end;
+          gen_load_locnonfpu_cgpara(current_asmdata.CurrAsmList,left.location,tempcgpara,is_64bit(left.resultdef))
       end;
 
 

+ 193 - 0
compiler/ncgutil.pas

@@ -65,6 +65,12 @@ interface
     procedure location_force_mem(list:TAsmList;var l:tlocation);
     procedure location_force_mmregscalar(list:TAsmList;var l: tlocation;maybeconst:boolean);
     procedure location_force_mmreg(list:TAsmList;var l: tlocation;maybeconst:boolean);
+
+    { load a location of a floatdef into a cgpara }
+    procedure gen_loadfpu_loc_cgpara(list:TAsmList;const l: tlocation;const cgpara: tcgpara;locintsize: longint);
+    { load a location of a non-floatdef into a cgpara }
+    procedure gen_load_locnonfpu_cgpara(list:TAsmList;const l: tlocation;const cgpara: tcgpara; is64bitint: boolean);
+
     procedure register_maybe_adjust_setbase(list: TAsmList; var l: tlocation; setbase: aint);
 
     { Retrieve the location of the data pointed to in location l, when the location is
@@ -775,6 +781,193 @@ implementation
       end;
 
 
+    procedure gen_loadfpu_loc_cgpara(list: TAsmList; const l: tlocation;const cgpara: tcgpara;locintsize: longint);
+    var
+{$ifdef i386}
+        href   : treference;
+        size   : longint;
+{$else i386}
+        tmploc : tlocation;
+{$endif i386}
+      begin
+{$ifdef i386}
+           if cgpara.location^.loc<>LOC_REFERENCE then
+             internalerror(200309291);
+           case l.loc of
+             LOC_FPUREGISTER,
+             LOC_CFPUREGISTER:
+               begin
+                 size:=align(locintsize,cgpara.alignment);
+                 if (not use_fixed_stack) and
+                    (cgpara.location^.reference.index=NR_STACK_POINTER_REG) then
+                   begin
+                     cg.g_stackpointer_alloc(list,size);
+                     reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint));
+                   end
+                 else
+                   reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
+                 cg.a_loadfpu_reg_ref(list,l.size,l.size,l.register,href);
+               end;
+             LOC_MMREGISTER,
+             LOC_CMMREGISTER:
+               begin
+                 { can't use TCGSize2Size[l.size], because the size of an
+                   80 bit extended parameter can be either 10 or 12 bytes }
+                 size:=align(locintsize,cgpara.alignment);
+                 if (not use_fixed_stack) and
+                    (cgpara.location^.reference.index=NR_STACK_POINTER_REG) then
+                   begin
+                     cg.g_stackpointer_alloc(list,size);
+                     reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint));
+                   end
+                 else
+                   reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
+                 cg.a_loadmm_reg_ref(list,l.size,l.size,l.register,href,mms_movescalar);
+               end;
+             LOC_REFERENCE,
+             LOC_CREFERENCE :
+               begin
+                 size:=align(locintsize,cgpara.alignment);
+                 if (not use_fixed_stack) and
+                    (cgpara.location^.reference.index=NR_STACK_POINTER_REG) then
+                   cg.a_load_ref_cgpara(list,l.size,l.reference,cgpara)
+                 else
+                   begin
+                     reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
+                     cg.g_concatcopy(list,l.reference,href,size);
+                   end;
+               end;
+             else
+               internalerror(2002042430);
+           end;
+{$else i386}
+           case l.loc of
+             LOC_MMREGISTER,
+             LOC_CMMREGISTER:
+               case cgpara.location^.loc of
+                 LOC_REFERENCE,
+                 LOC_CREFERENCE,
+                 LOC_MMREGISTER,
+                 LOC_CMMREGISTER,
+                 LOC_REGISTER,
+                 LOC_CREGISTER :
+                   cg.a_loadmm_reg_cgpara(list,l.size,l.register,cgpara,mms_movescalar);
+                 LOC_FPUREGISTER,
+                 LOC_CFPUREGISTER:
+                   begin
+                     tmploc:=l;
+                     location_force_fpureg(list,tmploc,false);
+                     cg.a_loadfpu_reg_cgpara(list,tmploc.size,tmploc.register,cgpara);
+                   end;
+                 else
+                   internalerror(200204249);
+               end;
+             LOC_FPUREGISTER,
+             LOC_CFPUREGISTER:
+               case cgpara.location^.loc of
+                 LOC_MMREGISTER,
+                 LOC_CMMREGISTER:
+                   begin
+                     tmploc:=l;
+                     location_force_mmregscalar(list,tmploc,false);
+                     cg.a_loadmm_reg_cgpara(list,tmploc.size,tmploc.register,cgpara,mms_movescalar);
+                   end;
+                 { Some targets pass floats in normal registers }
+                 LOC_REGISTER,
+                 LOC_CREGISTER,
+                 LOC_REFERENCE,
+                 LOC_CREFERENCE,
+                 LOC_FPUREGISTER,
+                 LOC_CFPUREGISTER:
+                   cg.a_loadfpu_reg_cgpara(list,l.size,l.register,cgpara);
+                 else
+                   internalerror(2002042433);
+               end;
+             LOC_REFERENCE,
+             LOC_CREFERENCE:
+               case cgpara.location^.loc of
+                 LOC_MMREGISTER,
+                 LOC_CMMREGISTER:
+                   cg.a_loadmm_ref_cgpara(list,l.size,l.reference,cgpara,mms_movescalar);
+                 { Some targets pass floats in normal registers }
+                 LOC_REGISTER,
+                 LOC_CREGISTER,
+                 LOC_REFERENCE,
+                 LOC_CREFERENCE,
+                 LOC_FPUREGISTER,
+                 LOC_CFPUREGISTER:
+                   cg.a_loadfpu_ref_cgpara(list,l.size,l.reference,cgpara);
+                 else
+                   internalerror(2002042431);
+               end;
+             LOC_REGISTER,
+             LOC_CREGISTER :
+               begin
+{$ifndef cpu64bitalu}
+                  { Only a_load_ref_cgpara supports multiple locations, when the
+                    value is still a const or in a register then write it
+                    to a reference first. This situation can be triggered
+                    by typecasting an int64 constant to a record of 8 bytes }
+                  tmploc:=l;
+                  if tmploc.size in [OS_64,OS_S64] then
+                    location_force_mem(list,tmploc);
+                  cg.a_load_loc_cgpara(list,tmploc,cgpara);
+{$else not cpu64bitalu}
+                  cg.a_load_loc_cgpara(list,l,cgpara);
+{$endif not cpu64bitalu}
+               end;
+             else
+               internalerror(2002042432);
+           end;
+{$endif i386}
+      end;
+
+
+    procedure gen_load_locnonfpu_cgpara(list: TAsmList; const l: tlocation;const cgpara: tcgpara; is64bitint: boolean);
+{$ifndef cpu64bitalu}
+      var
+        tmploc: tlocation;
+{$endif not cpu64bitalu}
+      begin
+        case l.loc of
+          LOC_CONSTANT,
+          LOC_REGISTER,
+          LOC_CREGISTER,
+          LOC_REFERENCE,
+          LOC_CREFERENCE :
+            begin
+{$ifndef cpu64bitalu}
+              { use cg64 only for int64, not for 8 byte records }
+              if is64bitint then
+                cg64.a_load64_loc_cgpara(list,l,cgpara)
+              else
+{$endif not cpu64bitalu}
+                begin
+{$ifndef cpu64bitalu}
+                  { Only a_load_ref_cgpara supports multiple locations, when the
+                    value is still a const or in a register then write it
+                    to a reference first. This situation can be triggered
+                    by typecasting an int64 constant to a record of 8 bytes }
+                  tmploc:=l;
+                  if tmploc.size in [OS_64,OS_S64] then
+                    location_force_mem(list,tmploc);
+                  cg.a_load_loc_cgpara(list,tmploc,cgpara);
+{$else not cpu64bitalu}
+                  cg.a_load_loc_cgpara(list,l,cgpara);
+{$endif not cpu64bitalu}
+                end;
+            end;
+{$ifdef SUPPORT_MMX}
+          LOC_MMXREGISTER,
+          LOC_CMMXREGISTER:
+            cg.a_loadmm_reg_cgpara(list,OS_M64,l.register,cgpara,nil);
+{$endif SUPPORT_MMX}
+          else
+            internalerror(200204241);
+        end;
+      end;
+
+
     procedure register_maybe_adjust_setbase(list: TAsmList; var l: tlocation; setbase: aint);
       var
         tmpreg: tregister;