2
0
Эх сурвалжийг харах

syscalls: unify call reference creation across 4 different CPU archs. less copypasted code, brings x86_64 AROS support up to speed

git-svn-id: trunk@35034 -
Károly Balogh 8 жил өмнө
parent
commit
f5f895e2a3

+ 2 - 22
compiler/arm/narmcal.pas

@@ -54,36 +54,16 @@ implementation
   procedure tarmcallnode.do_syscall;
     var
       tmpref: treference;
-      libparaloc: pcgparalocation;
-      hsym: tsym;
     begin
       case target_info.system of
         system_arm_aros:
             begin
               if (po_syscall_baselast in tprocdef(procdefinition).procoptions) then
                 begin
-                  current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall - BaseLast')));
+                  current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall')));
 
                   cg.getcpuregister(current_asmdata.CurrAsmList,NR_R12);
-                  hsym:=tsym(procdefinition.parast.Find('syscalllib'));
-                  if not assigned(hsym) then
-                    internalerror(2016110605);
-                  libparaloc:=tparavarsym(hsym).paraloc[callerside].location;
-                  if not assigned(libparaloc) then
-                    internalerror(2016110604);
-
-                  case libparaloc^.loc of
-                    LOC_REGISTER:
-                      reference_reset_base(tmpref,libparaloc^.register,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
-                    LOC_REFERENCE:
-                      begin
-                        reference_reset_base(tmpref,libparaloc^.reference.index,libparaloc^.reference.offset,sizeof(pint),[]);
-                        cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_R12);
-                        reference_reset_base(tmpref,NR_R12,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
-                      end;
-                    else
-                      internalerror(2016110603);
-                  end;
+                  get_syscall_call_ref(tmpref,NR_R12);
 
                   cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_R12);
                   cg.a_call_reg(current_asmdata.CurrAsmList,NR_R12);

+ 5 - 20
compiler/i386/n386cal.pas

@@ -63,36 +63,21 @@ implementation
     procedure ti386callnode.do_syscall;
       var
         tmpref: treference;
-        libparaloc: pcgparalocation;
       begin
         case target_info.system of
           system_i386_aros:
             begin
-              if (po_syscall_baselast in tprocdef(procdefinition).procoptions) then
+              if ([po_syscall_baselast, po_syscall_basereg] * tprocdef(procdefinition).procoptions) <> [] then
                 begin
-                  current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall - BaseLast on Stack')));
-                  { re-read the libbase pushed first on the stack, instead of just trusting the
-                    mangledname will work. this is important for example for threadvar libbases.
-                    and this way they also don't need to be resolved twice then. (KB) }
-                  libparaloc:=paralocs[procdefinition.paras.count-1]^.location;
-                  if libparaloc^.loc <> LOC_REFERENCE then
-                    internalerror(2016090203);
-                  reference_reset_base(tmpref,libparaloc^.reference.index,libparaloc^.reference.offset,sizeof(pint),[]);
+                  current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall')));
+
                   cg.getcpuregister(current_asmdata.CurrAsmList,NR_EAX);
-                  cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_EAX);
-                  reference_reset_base(tmpref,NR_EAX,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
+                  get_syscall_call_ref(tmpref,NR_EAX);
+
                   current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_CALL,S_NO,tmpref));
                   cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_EAX);
                   exit;
                 end;
-             if (po_syscall_basereg in tprocdef(procdefinition).procoptions) then
-                begin
-                  current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall - RegBase in EAX')));
-                  { libbase must be in EAX already, so just piggyback that, and dereference it }
-                  reference_reset_base(tmpref,NR_EAX,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
-                  current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_CALL,S_NO,tmpref));
-                  exit;
-                end;
               internalerror(2016090104);
             end;
           else

+ 37 - 0
compiler/ncgcal.pas

@@ -79,6 +79,9 @@ interface
           procedure extra_pre_call_code;virtual;
           procedure extra_call_code;virtual;
           procedure extra_post_call_code;virtual;
+
+          function get_syscall_libbase_paraloc: pcgparalocation;virtual;
+          procedure get_syscall_call_ref(out tmpref: treference; reg: tregister);virtual;
           procedure do_syscall;virtual;abstract;
 
           { The function result is returned in a tcgpara. This tcgpara has to
@@ -436,6 +439,40 @@ implementation
       begin
       end;
 
+    function tcgcallnode.get_syscall_libbase_paraloc: pcgparalocation;
+      var
+        hsym: tsym;
+      begin
+        hsym:=tsym(procdefinition.parast.Find('syscalllib'));
+        if not assigned(hsym) then
+          internalerror(2016110605);
+        result:=tparavarsym(hsym).paraloc[callerside].location;
+        if not assigned(result) then
+          internalerror(2016110604);
+      end;
+
+    procedure tcgcallnode.get_syscall_call_ref(out tmpref: treference; reg: tregister);
+      var
+        libparaloc: pcgparalocation;
+      begin
+        libparaloc:=get_syscall_libbase_paraloc;
+
+        case libparaloc^.loc of
+          LOC_REGISTER:
+            reference_reset_base(tmpref,libparaloc^.register,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
+          LOC_REFERENCE:
+            begin
+              reference_reset_base(tmpref,libparaloc^.reference.index,libparaloc^.reference.offset,sizeof(pint),[]);
+              cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,reg);
+              reference_reset_base(tmpref,reg,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
+            end;
+          else
+            begin
+              reference_reset(tmpref,0,[]);
+              internalerror(2016090202);
+            end;
+        end;
+      end;
 
     function tcgcallnode.can_call_ref(var ref: treference): boolean;
       begin

+ 2 - 24
compiler/powerpc/nppccal.pas

@@ -43,7 +43,7 @@ implementation
     uses
       globtype,systems,
       cutils,verbose,globals,
-      symconst,symtype,symbase,symsym,symcpu,symtable,defutil,paramgr,parabase,
+      symconst,symbase,symsym,symcpu,symtable,defutil,paramgr,parabase,
       cgbase,pass_2,
       cpuinfo,cpubase,aasmbase,aasmtai,aasmdata,aasmcpu,
       nmem,nld,ncnv,
@@ -83,8 +83,6 @@ implementation
 
       var
         tmpref: treference;
-        libparaloc: pcgparalocation;
-        hsym: tsym;
       begin
         case target_info.system of
           system_powerpc_amiga:
@@ -101,27 +99,7 @@ implementation
                    po_syscall_baselast,po_syscall_basereg] * tprocdef(procdefinition).procoptions) <> [] then
                 begin
                   cg.getcpuregister(current_asmdata.CurrAsmList,NR_R12);
-
-                  hsym:=tsym(procdefinition.parast.Find('syscalllib'));
-                  if not assigned(hsym) then
-                    internalerror(2016090501);
-                  libparaloc:=tparavarsym(hsym).paraloc[callerside].location;
-                  if not assigned(libparaloc) then
-                    internalerror(2016090502);
-
-                  case libparaloc^.loc of
-                    LOC_REGISTER:
-                      reference_reset_base(tmpref,libparaloc^.register,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
-                    LOC_REFERENCE:
-                      begin
-                        { this can happen for sysvbase; if we run out of regs, the libbase will be passed on the stack }
-                        reference_reset_base(tmpref,libparaloc^.reference.index,libparaloc^.reference.offset,sizeof(pint),[]);
-                        cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_R12);
-                        reference_reset_base(tmpref,NR_R12,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
-                      end;
-                    else
-                      internalerror(2016090202);
-                  end;
+                  get_syscall_call_ref(tmpref,NR_R12);
 
                   do_call_ref(tmpref);
                   cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R12);

+ 12 - 10
compiler/x86_64/nx64cal.pas

@@ -67,16 +67,18 @@ implementation
         case target_info.system of
           system_x86_64_aros:
             begin
-              // one syscall convention for AROS
-              current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall')));
-              reference_reset(tmpref,sizeof(pint),[]);
-              tmpref.symbol:=current_asmdata.RefAsmSymbol(tstaticvarsym(tcpuprocdef(procdefinition).libsym).mangledname,AT_FUNCTION);
-              cg.getcpuregister(current_asmdata.CurrAsmList,NR_RAX);
-              cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_RAX);
-              reference_reset_base(tmpref,NR_RAX,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
-              cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_RAX);
-              cg.a_call_reg(current_asmdata.CurrAsmList,NR_RAX);
-              cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_RAX);
+              if ([po_syscall_baselast,po_syscall_basereg] * tprocdef(procdefinition).procoptions) <> [] then
+                begin
+                  current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall')));
+
+                  cg.getcpuregister(current_asmdata.CurrAsmList,NR_RAX);
+                  get_syscall_call_ref(tmpref,NR_RAX);
+
+                  current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_CALL,S_NO,tmpref));
+                  cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_RAX);
+                  exit;
+                end;
+              internalerror(2016120101);
             end;
           else
             internalerror(2015062801);