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 năm trước cách đây
mục cha
commit
187c2af20e
2 tập tin đã thay đổi với 19 bổ sung98 xóa
  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;
-      var
-        tmpreg: tregister;
-        tmpref: treference;
       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);
-
-        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;
 
 

+ 13 - 13
compiler/ncgcnv.pas

@@ -515,19 +515,19 @@ interface
       begin
         if tabstractprocdef(resultdef).is_addressonly then
           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
               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_ADDR then
+	    if left.location.size = def_cgsize(voidcodepointertype) 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.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;
                   else
                     internalerror(2013031501)
@@ -539,9 +539,9 @@ interface
                 case left.location.loc of
                   LOC_REFERENCE,LOC_CREFERENCE:
                     begin
-                      location.register:=cg.getaddressregister(current_asmdata.CurrAsmList);
+                      location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidcodepointertype);
                       { 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;
                   LOC_REGISTER,LOC_CREGISTER:
                     begin
@@ -565,17 +565,17 @@ interface
                   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(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);
-                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
                   since the global procedure won't use it, but it can help with
                   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;