瀏覽代碼

* moved the i8086-specific threadvar generation code from
ti8086loadnode.pass_generate_code to ti8086loadnode.generate_threadvar_access

git-svn-id: trunk@31699 -

nickysn 10 年之前
父節點
當前提交
aa57e7e835
共有 1 個文件被更改,包括 86 次插入69 次删除
  1. 86 69
      compiler/i8086/n8086ld.pas

+ 86 - 69
compiler/i8086/n8086ld.pas

@@ -38,6 +38,7 @@ interface
         protected
          procedure generate_nested_access(vs: tsym); override;
          procedure generate_absaddr_access(vs: tabsolutevarsym); override;
+         procedure generate_threadvar_access(gvs: tstaticvarsym); override;
         public
          procedure pass_generate_code;override;
       end;
@@ -93,11 +94,9 @@ implementation
         inherited;
       end;
 
-    procedure ti8086loadnode.pass_generate_code;
+    procedure ti8086loadnode.generate_threadvar_access(gvs: tstaticvarsym);
       var
-        gvs: tstaticvarsym;
         segref: treference;
-        refsym: TAsmSymbol;
         segreg: TRegister;
         newsize: TCgSize;
         norelocatelab: TAsmLabel;
@@ -106,6 +105,87 @@ implementation
         paraloc1 : tcgpara;
         hregister: TRegister;
         href: treference;
+      begin
+        if current_settings.x86memorymodel=mm_huge then
+          begin
+            if (cs_compilesystem in current_settings.moduleswitches) then
+              begin
+                inherited generate_threadvar_access(gvs);
+                exit;
+              end;
+
+            { we don't know the size of all arrays }
+            newsize:=def_cgsize(resultdef);
+            { alignment is overridden per case below }
+            location_reset_ref(location,LOC_REFERENCE,newsize,resultdef.alignment);
+
+            {
+              Thread var loading is optimized to first check if
+              a relocate function is available. When the function
+              is available it is called to retrieve the address.
+              Otherwise the address is loaded with the symbol
+
+              The code needs to be in the order to first handle the
+              call and then the address load to be sure that the
+              register that is used for returning is the same (PFV)
+            }
+            current_asmdata.getjumplabel(norelocatelab);
+            current_asmdata.getjumplabel(endrelocatelab);
+            { make sure hregister can't allocate the register necessary for the parameter }
+            pvd:=search_system_type('TRELOCATETHREADVARHANDLER').typedef;
+            if pvd.typ<>procvardef then
+              internalerror(2012120901);
+            paraloc1.init;
+            paramanager.getintparaloc(current_asmdata.CurrAsmList,tprocvardef(pvd),1,paraloc1);
+            hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,pvd);
+            segreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_16);
+            reference_reset_symbol(segref,current_asmdata.RefAsmSymbol('FPC_THREADVAR_RELOCATE'),0,0);
+            segref.refaddr:=addr_seg;
+            cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_16,OS_16,segref,segreg);
+            reference_reset_symbol(href,current_asmdata.RefAsmSymbol('FPC_THREADVAR_RELOCATE'),0,pvd.size);
+            href.segment:=segreg;
+            hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,pvd,pvd,href,hregister);
+            hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,pvd,OC_EQ,0,hregister,norelocatelab);
+            { don't save the allocated register else the result will be destroyed later }
+            if not(vo_is_weak_external in gvs.varoptions) then
+              reference_reset_symbol(href,current_asmdata.RefAsmSymbol(gvs.mangledname),0,sizeof(pint))
+            else
+              reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0,sizeof(pint));
+            cg.a_load_ref_cgpara(current_asmdata.CurrAsmList,OS_32,href,paraloc1);
+            paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
+            paraloc1.done;
+            cg.allocallcpuregisters(current_asmdata.CurrAsmList);
+            cg.a_call_reg(current_asmdata.CurrAsmList,hregister);
+            cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
+            cg.getcpuregister(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
+            cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
+            hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidpointertype);
+            cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_ADDR,NR_FUNCTION_RESULT_REG,hregister);
+            cg.a_jmp_always(current_asmdata.CurrAsmList,endrelocatelab);
+            cg.a_label(current_asmdata.CurrAsmList,norelocatelab);
+            { no relocation needed, load the address of the variable only, the
+              layout of a threadvar is (4 bytes pointer):
+                0 - Threadvar index
+                4 - Threadvar value in single threading }
+            if not(vo_is_weak_external in gvs.varoptions) then
+              reference_reset_symbol(href,current_asmdata.RefAsmSymbol(gvs.mangledname),sizeof(pint),sizeof(pint))
+            else
+              reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),sizeof(pint),sizeof(pint));
+            hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,resultdef,voidpointertype,href,hregister);
+            cg.a_label(current_asmdata.CurrAsmList,endrelocatelab);
+            hlcg.reference_reset_base(location.reference,voidpointertype,hregister,0,location.reference.alignment);
+          end
+        else
+          inherited generate_threadvar_access(gvs);
+      end;
+
+    procedure ti8086loadnode.pass_generate_code;
+      var
+        gvs: tstaticvarsym;
+        segref: treference;
+        refsym: TAsmSymbol;
+        segreg: TRegister;
+        newsize: TCgSize;
       begin
         if current_settings.x86memorymodel=mm_huge then
           begin
@@ -122,72 +202,9 @@ implementation
                   { Thread variable }
                   else if (vo_is_thread_var in gvs.varoptions) then
                     begin
-                      if (cs_compilesystem in current_settings.moduleswitches) then
-                        begin
-                          inherited pass_generate_code;
-                          exit;
-                        end;
-
-                      { we don't know the size of all arrays }
-                      newsize:=def_cgsize(resultdef);
-                      { alignment is overridden per case below }
-                      location_reset_ref(location,LOC_REFERENCE,newsize,resultdef.alignment);
-
-                      {
-                        Thread var loading is optimized to first check if
-                        a relocate function is available. When the function
-                        is available it is called to retrieve the address.
-                        Otherwise the address is loaded with the symbol
-
-                        The code needs to be in the order to first handle the
-                        call and then the address load to be sure that the
-                        register that is used for returning is the same (PFV)
-                      }
-                      current_asmdata.getjumplabel(norelocatelab);
-                      current_asmdata.getjumplabel(endrelocatelab);
-                      { make sure hregister can't allocate the register necessary for the parameter }
-                      pvd:=search_system_type('TRELOCATETHREADVARHANDLER').typedef;
-                      if pvd.typ<>procvardef then
-                        internalerror(2012120901);
-                      paraloc1.init;
-                      paramanager.getintparaloc(current_asmdata.CurrAsmList,tprocvardef(pvd),1,paraloc1);
-                      hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,pvd);
-                      segreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_16);
-                      reference_reset_symbol(segref,current_asmdata.RefAsmSymbol('FPC_THREADVAR_RELOCATE'),0,0);
-                      segref.refaddr:=addr_seg;
-                      cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_16,OS_16,segref,segreg);
-                      reference_reset_symbol(href,current_asmdata.RefAsmSymbol('FPC_THREADVAR_RELOCATE'),0,pvd.size);
-                      href.segment:=segreg;
-                      hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,pvd,pvd,href,hregister);
-                      hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,pvd,OC_EQ,0,hregister,norelocatelab);
-                      { don't save the allocated register else the result will be destroyed later }
-                      if not(vo_is_weak_external in gvs.varoptions) then
-                        reference_reset_symbol(href,current_asmdata.RefAsmSymbol(gvs.mangledname),0,sizeof(pint))
-                      else
-                        reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0,sizeof(pint));
-                      cg.a_load_ref_cgpara(current_asmdata.CurrAsmList,OS_32,href,paraloc1);
-                      paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
-                      paraloc1.done;
-                      cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-                      cg.a_call_reg(current_asmdata.CurrAsmList,hregister);
-                      cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
-                      cg.getcpuregister(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
-                      cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
-                      hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidpointertype);
-                      cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_ADDR,NR_FUNCTION_RESULT_REG,hregister);
-                      cg.a_jmp_always(current_asmdata.CurrAsmList,endrelocatelab);
-                      cg.a_label(current_asmdata.CurrAsmList,norelocatelab);
-                      { no relocation needed, load the address of the variable only, the
-                        layout of a threadvar is (4 bytes pointer):
-                          0 - Threadvar index
-                          4 - Threadvar value in single threading }
-                      if not(vo_is_weak_external in gvs.varoptions) then
-                        reference_reset_symbol(href,current_asmdata.RefAsmSymbol(gvs.mangledname),sizeof(pint),sizeof(pint))
-                      else
-                        reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),sizeof(pint),sizeof(pint));
-                      hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,resultdef,voidpointertype,href,hregister);
-                      cg.a_label(current_asmdata.CurrAsmList,endrelocatelab);
-                      hlcg.reference_reset_base(location.reference,voidpointertype,hregister,0,location.reference.alignment);
+                      { this will be handled in ti8086loadnode.generate_threadvar_access }
+                      inherited pass_generate_code;
+                      exit;
                     end
                   { Normal (or external) variable }
                   else