Browse Source

* tcgtypeconvnode.second_proc_to_procvar converted to the high level code
generator, so it can now handle i8086 near and far pointers generically
- removed almost all of t8086typeconvnode.second_proc_procvar, since it's no
longer needed. Only a few assertions are left there to ensure that we don't
accidentally attempt to take the address of a near procedure in a far code
memory model, because the calling conventions are incompatible.

git-svn-id: trunk@27677 -

nickysn 11 years ago
parent
commit
187c2af20e
2 changed files with 19 additions and 98 deletions
  1. 6 85
      compiler/i8086/n8086cnv.pas
  2. 13 13
      compiler/ncgcnv.pas

+ 6 - 85
compiler/i8086/n8086cnv.pas

@@ -62,93 +62,14 @@ implementation
 
 
 
 
     procedure t8086typeconvnode.second_proc_to_procvar;
     procedure t8086typeconvnode.second_proc_to_procvar;
-      var
-        tmpreg: tregister;
-        tmpref: treference;
       begin
       begin
-        if not is_proc_far(tabstractprocdef(resultdef)) then
-          begin
-            if current_settings.x86memorymodel in x86_far_code_models then
-              internalerror(2014041302);
-            inherited;
-            exit;
-          end;
-
-        if not is_proc_far(tabstractprocdef(left.resultdef)) then
+        if is_proc_far(tabstractprocdef(resultdef))<>
+           (current_settings.x86memorymodel in x86_far_code_models) then
+          internalerror(2014041302);
+        if is_proc_far(tabstractprocdef(left.resultdef))<>
+           (current_settings.x86memorymodel in x86_far_code_models) then
           internalerror(2014041303);
           internalerror(2014041303);
-
-        if tabstractprocdef(resultdef).is_addressonly then
-          begin
-            location_reset(location,LOC_REGISTER,OS_32);
-            { only a code pointer? (when taking the address of classtype.method
-              we also only get a code pointer even though the resultdef is a
-              procedure of object, and hence is_addressonly would return false)
-             }
-  	    if left.location.size = OS_32 then
-              begin
-                case left.location.loc of
-                  LOC_REFERENCE,LOC_CREFERENCE:
-                    begin
-                      { the procedure symbol is encoded in reference.symbol -> take address }
-                      location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
-                      cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.location.reference,location.register);
-                      tmpref:=left.location.reference;
-                      tmpref.refaddr:=addr_seg;
-                      cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_16,OS_16,tmpref,GetNextReg(location.register));
-                    end;
-                  else
-                    internalerror(2013031501)
-                end;
-              end
-            else
-              begin
-                { conversion from a procedure of object/nested procvar to plain procvar }
-                case left.location.loc of
-                  LOC_REFERENCE,LOC_CREFERENCE:
-                    begin
-                      location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
-                      { code field is the first one }
-                      cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.reference,location.register);
-                    end;
-                  LOC_REGISTER,LOC_CREGISTER:
-                    begin
-                      if target_info.endian=endian_little then
-                        location.register:=left.location.register
-                      else
-                        location.register:=left.location.registerhi;
-                    end;
-                  else
-                    internalerror(2013031502)
-                end;
-              end;
-          end
-        else
-          begin
-            if not tabstractprocdef(left.resultdef).is_addressonly then
-              location_copy(location,left.location)
-            else
-              begin
-                { assigning a global function to a nested procvar -> create
-                  tmethodpointer record and set the "frame pointer" to nil }
-                if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
-                  internalerror(2013031503);
-                location_reset_ref(location,LOC_REFERENCE,int_cgsize(6),sizeof(pint));
-                tg.gethltemp(current_asmdata.CurrAsmList,resultdef,resultdef.size,tt_normal,location.reference);
-                tmpreg:=cg.getaddressregister(current_asmdata.CurrAsmList);
-                cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.location.reference,tmpreg);
-                cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_16,OS_16,tmpreg,location.reference);
-                tmpref:=left.location.reference;
-                tmpref.refaddr:=addr_seg;
-                inc(location.reference.offset,2);
-                cg.a_load_ref_ref(current_asmdata.CurrAsmList,OS_16,OS_16,tmpref,location.reference);
-                { setting the frame pointer to nil is not strictly necessary
-                  since the global procedure won't use it, but it can help with
-                  debugging }
-                inc(location.reference.offset,2);
-                cg.a_load_const_ref(current_asmdata.CurrAsmList,OS_ADDR,0,location.reference);
-                dec(location.reference.offset,4);
-              end;
-          end;
+        inherited;
       end;
       end;
 
 
 
 

+ 13 - 13
compiler/ncgcnv.pas

@@ -515,19 +515,19 @@ interface
       begin
       begin
         if tabstractprocdef(resultdef).is_addressonly then
         if tabstractprocdef(resultdef).is_addressonly then
           begin
           begin
-            location_reset(location,LOC_REGISTER,OS_ADDR);
+            location_reset(location,LOC_REGISTER,def_cgsize(voidcodepointertype));
             { only a code pointer? (when taking the address of classtype.method
             { only a code pointer? (when taking the address of classtype.method
               we also only get a code pointer even though the resultdef is a
               we also only get a code pointer even though the resultdef is a
               procedure of object, and hence is_addressonly would return false)
               procedure of object, and hence is_addressonly would return false)
              }
              }
-	    if left.location.size = OS_ADDR then
+	    if left.location.size = def_cgsize(voidcodepointertype) then
               begin
               begin
                 case left.location.loc of
                 case left.location.loc of
                   LOC_REFERENCE,LOC_CREFERENCE:
                   LOC_REFERENCE,LOC_CREFERENCE:
                     begin
                     begin
                       { the procedure symbol is encoded in reference.symbol -> take address }
                       { the procedure symbol is encoded in reference.symbol -> take address }
-                      location.register:=cg.getaddressregister(current_asmdata.CurrAsmList);
-                      cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.location.reference,location.register);
+                      location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidcodepointertype);
+                      hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.resultdef,voidcodepointertype,left.location.reference,location.register);
                     end;
                     end;
                   else
                   else
                     internalerror(2013031501)
                     internalerror(2013031501)
@@ -539,9 +539,9 @@ interface
                 case left.location.loc of
                 case left.location.loc of
                   LOC_REFERENCE,LOC_CREFERENCE:
                   LOC_REFERENCE,LOC_CREFERENCE:
                     begin
                     begin
-                      location.register:=cg.getaddressregister(current_asmdata.CurrAsmList);
+                      location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidcodepointertype);
                       { code field is the first one }
                       { code field is the first one }
-                      cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,left.location.reference,location.register);
+                      hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,voidcodepointertype,voidcodepointertype,left.location.reference,location.register);
                     end;
                     end;
                   LOC_REGISTER,LOC_CREGISTER:
                   LOC_REGISTER,LOC_CREGISTER:
                     begin
                     begin
@@ -565,17 +565,17 @@ interface
                   tmethodpointer record and set the "frame pointer" to nil }
                   tmethodpointer record and set the "frame pointer" to nil }
                 if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
                 if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
                   internalerror(2013031503);
                   internalerror(2013031503);
-                location_reset_ref(location,LOC_REFERENCE,int_cgsize(sizeof(pint)*2),sizeof(pint));
+                location_reset_ref(location,LOC_REFERENCE,int_cgsize(resultdef.size),sizeof(pint));
                 tg.gethltemp(current_asmdata.CurrAsmList,resultdef,resultdef.size,tt_normal,location.reference);
                 tg.gethltemp(current_asmdata.CurrAsmList,resultdef,resultdef.size,tt_normal,location.reference);
-                tmpreg:=cg.getaddressregister(current_asmdata.CurrAsmList);
-                cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.location.reference,tmpreg);
-                cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpreg,location.reference);
+                tmpreg:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidcodepointertype);
+                hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.resultdef,voidcodepointertype,left.location.reference,tmpreg);
+                hlcg.a_load_reg_ref(current_asmdata.CurrAsmList,voidcodepointertype,voidcodepointertype,tmpreg,location.reference);
                 { setting the frame pointer to nil is not strictly necessary
                 { setting the frame pointer to nil is not strictly necessary
                   since the global procedure won't use it, but it can help with
                   since the global procedure won't use it, but it can help with
                   debugging }
                   debugging }
-                inc(location.reference.offset,sizeof(pint));
-                cg.a_load_const_ref(current_asmdata.CurrAsmList,OS_ADDR,0,location.reference);
-                dec(location.reference.offset,sizeof(pint));
+                inc(location.reference.offset,voidcodepointertype.size);
+                hlcg.a_load_const_ref(current_asmdata.CurrAsmList,voidpointertype,0,location.reference);
+                dec(location.reference.offset,voidcodepointertype.size);
               end;
               end;
           end;
           end;
       end;
       end;