Sfoglia il codice sorgente

m68k: some initial support for C ABIs which use an address register to return structs by address

git-svn-id: trunk@36592 -
Károly Balogh 8 anni fa
parent
commit
41f72a0e6d
2 ha cambiato i file con 24 aggiunte e 2 eliminazioni
  1. 8 0
      compiler/m68k/cpubase.pas
  2. 16 2
      compiler/m68k/cpupara.pas

+ 8 - 0
compiler/m68k/cpubase.pas

@@ -303,6 +303,14 @@ unit cpubase;
       {# Floating point results will be placed into this register }
       NR_FPU_RESULT_REG = NR_FP0;
 
+      {# This is m68k C ABI specific. Some ABIs expect the address of the
+         return struct result value in this register. Note that it could be
+         either A0 or A1, so later it must be decided on target/ABI specific
+         basis. We start with A1 now, because that's what Linux/m68k does
+         currently. (KB) }
+      RS_M68K_STRUCT_RESULT_REG: tsuperregister = RS_A1;
+      NR_M68K_STRUCT_RESULT_REG: tregister = NR_A1;
+
       NR_DEFAULTFLAGS = NR_SR;
       RS_DEFAULTFLAGS = RS_SR;
 

+ 16 - 2
compiler/m68k/cpupara.pas

@@ -357,15 +357,29 @@ unit cpupara;
             while (paralen > 0) do
               begin
                 paraloc:=hp.paraloc[side].add_location;
-
-                paraloc^.loc:=LOC_REFERENCE;
                 paraloc^.def:=get_paraloc_def(paradef,paralen,firstparaloc);
+
                 if (not (cs_fp_emulation in current_settings.moduleswitches)) and
                    (paradef.typ=floatdef) then
                   paraloc^.size:=int_float_cgsize(paralen)
                 else
                   paraloc^.size:=int_cgsize(paralen);
 
+                { various m68k based C ABIs used in the Unix world use a register to
+                  return a struct by address. we will probably need some kind of a
+                  switch to support these various ABIs when generating cdecl calls (KB) }
+                if ((vo_is_funcret in hp.varoptions) and
+                    (tprocdef(p).proccalloption in [pocall_cdecl,pocall_cppdecl]) and
+                    (target_info.system in [system_m68k_linux]) and
+                    (tprocdef(p).returndef.typ = recorddef)) then
+                  begin
+                    paraloc^.loc:=LOC_REGISTER;
+                    paraloc^.register:=NR_M68K_STRUCT_RESULT_REG;
+                    paralen:=0;
+                    continue;
+                  end;
+
+                paraloc^.loc:=LOC_REFERENCE;
                 paraloc^.reference.offset:=cur_stack_offset;
                 if (side = callerside) then
                   paraloc^.reference.index:=NR_STACK_POINTER_REG