[M3devel] gcc 4.5 and how to pass the static link

Jay K jay.krell at cornell.edu
Sat Jun 26 14:51:47 CEST 2010


ok, I got "man vs. boy" to work.


Now I'm going back and revisiting some diffs I have, try to reduce them.
There isn't much.


I'm going to commit something that will seem odd,
and isn't easy to explain, and that I might not fully understand.


Here is what I suspect though.


In gcc 4.3, how to pass a static chain is always the same for each architecture.
 I think.
 
 
In 4.5, it depends on the function being called. At least for some architectures.
See the function ix86_static_chain.
x86 functions can have varying calling conventions, so how to pass
the static chain can vary from function to function.


This doesn't make complete sense for Modula-3 though.
We pass the static chain for function pointers as well.
 And gcc never does, because function pointers are "flattened" via "trampolines".
 That is, the caller of a function pointer doesn't have to pass a static link.
 A trampoline is built to pass it.
 Err. It does make partial sense. Function pointers still have calling conventions.


calls.c:prepare_call_address:
  if (static_chain_value != 0)
    {
      rtx chain;

      gcc_assert (fndecl);
      chain = targetm.calls.static_chain (fndecl, false);
      static_chain_value = convert_memory_address (Pmode, static_chain_value);

      emit_move_insn (chain, static_chain_value);
      if (REG_P (chain))
    use_reg (call_fusage, chain);
    }


the assertion fails here:

m3-sys/m3link:

PROCEDURE ForEachUnit (VAR s: State;  p: UnitProc) =
  VAR x: MxMap.Contents;  u: Mx.Unit;
  BEGIN
    x := MxMap.GetData (s.base.interfaces);
    FOR i := 0 TO LAST (x^) DO
      u := x[i].value;
      IF (u # NIL) THEN p (s, u) END;    *** here ***
    END;
    x := MxMap.GetData (s.base.modules);
    FOR i := 0 TO LAST (x^) DO
      u := x[i].value;
      IF (u # NIL) THEN p (s, u) END;
    END;
    x := MxMap.GetData (s.base.virtuals);
    FOR i := 0 TO LAST (x^) DO
      u := x[i].value;
      IF (u # NIL) THEN p (s, u) END;
    END;
  END ForEachUnit;
  
  
So I'm going to quite alter that code to allow null and in such case
use the register 4.3 would have (ECX).


Arguably even for non-null we should do that.
We only support __cdecl and __stdcall, and ECX is correct for either.
gcc supports __fastcall and it appears possibly custom calling conventions.


 - Jay
 		 	   		  


More information about the M3devel mailing list