[M3devel] calling conventions (small proposal)

Jay K jay.krell at cornell.edu
Tue Feb 23 08:33:10 CET 2010


I don't understand.
 
 
Assuming there are precious few calling conventions in the world, beyond 1 per platform, it seems fine as I propose.
 
 
Oh, I think I see what you mean though. If you imagine multiple platforms with multiple calling conventions, then you'd want to intercede one portable name that is then redefined on a per-platform basis?
 
 
My proposal either
  assumes there is one (set of) platform with any calling conventions (the same ones)
 
 
  OR, at least, that the names don't overlap across platforms with different meaning.
 
 
That is, NT386 has __stcall, __cdecl.
I write:
 
 
INTERFACE Foo;
<*__stdcall*>PROCEDURE Bar();
 
 
then future platform WIERD comes along and it has a calling convention "wierdcall".
In this unlikely hypothetical world, I'd propose you write:
 
 
<*wierdcall*><*__stdcall*>PROCEDURE Bar();
 
 
All platforms would be taught to recognize the pragma wierdcall, and the interpretation would be to do nothing except for target WIERD.
 
 
The problem becomes if target WIERD has conventions, say, wierdcall and __stdcall, and you want __stcall on NT386 but wierdcall on WIERD.
 
 
Then the above is ambiguous.
 
 
But you could repair the unlikely problem after the fact, by using longer/diferent names when clashes come along.
 
We'd stomp on __stdcall today for NT386, because it has been around a long time and is likely to remain unique.
 
 
If WIERD comes along later with __stdcall, ok, we'd just call it weird__stdcall, and you'd write:
 
 
<*wierd__stdcall*><*__stdcall*>PROCEDURE Foo();
 
 
?
 
 
If you wrote <*wierdcall__stdcall*><*wierdcall*>PROCEDURE Foo();
 
that would be an error, at least when targeting target WIERD.
 
 
Just as, today, I hope, <*__stdcall*><*__cdecl*>PROCEDURE Foo() is an error.
 
This is *slightly* complicated -- the long term hypothetical proposal is that multiple calling convension pragmas be allowed, depending on what exactly they are.
 
 
Again remember that it is highly unusual for any platform to have multiple calling conventions, so this "problem" is not likely to grow.
 
 
Does ARM have serious issues here?
I know they have all kinds of execution modes.
But I think Debian, for example, has two ARM platforms, and one calling convention each. ?
 
 
Again, minimal is
1) allow existing NT386 syntax on all targets
2) possibly allow existing NT386 procedure pragma on modules/interfaces
 
 
Is your desire to annotate something with "FOOCALL" and then experiment in m3makefile with mapping FOOCALL to one convention or another?
And it would be multiple files, so the terseness of an interface/module pragma is not terse enough, it'd be too much to copy/paste?
 
 
I can see that scenario.
 
 
Can we at least agree on my #1, maybe my #2, and extend it after that?
 
 
#1 is about two lines of change.
I'll do it pretty soon. I just haven't gotten to it yet.
 
 
 - Jay


----------------------------------------
> From: darko at darko.org
> To: jay.krell at cornell.edu
> CC: hosking at cs.purdue.edu; m3devel at elegosoft.com
> Subject: RE: [M3devel] calling conventions (small proposal)
> Date: Tue, 23 Feb 2010 17:44:01 +1100
>
> Calling convention is almost a linking issue it seems pretty good idea to move it to the makefile somehow since it reduces portability otherwise
>
> -original message-
> Subject: RE: [M3devel] calling conventions (small proposal)
> From: Jay K 
> Date: 23/02/2010 3:37 pm
>
>
> You mean like:
>
>
> module("foo")
> module_calling_convention("foo", "__stdcall")
> % default calling convention for module foo
>
>
> or
> calling_convention("foocall", "__stdcall")
> calling_convention("barcall", "__cdecl")
>
>
> foo.m3:
> <*foocall*> PROCEDURE Foo()...
> <*barcall*> PROCEDURE Bar()...
>
>
> Almost anything is possible -- what with the quake implementation and Modula-3 front end being the same program, but I'd rather not.
>
>
> The integration of quake and Modula-3..like.. "confuses" me.
> That is, it blurs the line as to what /should/ be done vs. what /can/ be done, because it makes so many things easy.
>
> If I look for analogies however..in C and C++ you can do something like easily enough
> Makefile:
> !if WIN32
> CFLAGS=-DFOOCALL=__stdcall -DBARCALL=__cdecl
> !else
> CFLAGS=-DFOOCALL= -DBARCALL=
> !endif
>
>
> so maybe not a bad idea?
>
>
>
>
> To repeat myself, we already have the following valid working syntax, on NT386:
>
>
> foo.i3
> <*__stdcall*> PROCEDURE Foo()...
>
> foo.m3
> <*__stdcall*> PROCEDURE Foo()...
>
> They have to match I believe.
> Of course the procedure doesn't necessarily occur in the .i3 file.
>
>
> My proposal is two part.
>
> 1) Accept the existing syntax on all platforms.
> The interpretion is "do nothing" on most platforms.
>
>
> 2) Allow the existing pragmas on interface/module also:
>
> <*__stdcall*> INTERFACE Foo...
>
> <*__stdcall*> MODULE Foo...
>
>
> #1 is sufficient and a very small change and introduces no new syntax, merely allows existing NT386-specific syntax to be used on all platforms.
>
>
> #2 allows for less repetition.
>
>
> This will let me use the possibly more efficient non-default calling convention for hand.c replacement.
>
>
> And possibly avoid having two nearly identical OpenGL.i3 files.
>
>
> - Jay
>
>
> ----------------------------------------
>> From: darko at darko.org
>> To: jay.krell at cornell.edu
>> CC: hosking at cs.purdue.edu; m3devel at elegosoft.com
>> Subject: RE: [M3devel] calling conventions (small proposal)
>> Date: Tue, 23 Feb 2010 15:03:55 +1100
>>
>> Can we have the pragma refer to a symbol defined in the makefile which nominates the actual calling convention?
>>
>> -original message-
>> Subject: RE: [M3devel] calling conventions (small proposal)
>> From: Jay K
>> Date: 23/02/2010 12:20 pm
>>
>>
>> Two parts (sort of).
>>
>>
>> 1)
>> We do have what you describe -- __stdcall C code that Modula-3 calls.
>> And then, for example, we have OpenGL.i3 for Win32 and non-Win32 that are nearly identical, except that Win32 has calling conventions.
>> I hope to get rid of that duplication. Later rather than earlier.
>>
>>
>>
>> 2)
>> I want to write Modula-3 code that is __stdcall.
>> We already have this, in platform specific code, e.g. the parameter to CreateThread.
>> However I want to write code that is "otherwise" portable.
>> In particular the replacements for hand.c
>>
>>
>> Declaring a calling convention should render the whole thing non-portable, should not cause one to copy/paste everything and just add/remove one identifier. We historically have had far too much duplication of nearly identical code in Modula-3.
>>
>>
>>
>> 2b) More generally I'm interested in trying __stdcall because it leads to smaller code (for certain code gen strategies. There might be a way in which __cdecl is smaller -- where you allocate room for all your calls up front and store to the stack, instead of push/pop -- currently every call costs the call and an add esp. Whereas with __stdcall the "add" is in the callee instead of the caller, same number of instructions executed, but fewer contributing to code size).
>>
>>
>> 2c) More generally even if it isn't a significant win, I definitely believe it should be possible. A lot of "otherwise" portable C and C++ code is written this way -- to have explicit calling conventions on systems that have any, and "just the normal" on others. Only one platform in heavy use today has this messed up notion of varying calling convention.
>>
>>
>>
>> - Jay
>>
>>
>> ________________________________
>>> From: hosking at cs.purdue.edu
>>> Date: Mon, 22 Feb 2010 20:05:46 -0500
>>> To: jay.krell at cornell.edu
>>> CC: m3devel at elegosoft.com; darko at darko.org
>>> Subject: Re: [M3devel] calling conventions (small proposal)
>>>
>>>
>>>
>>> So, do you mean you want to have C code to which Modula-3 interfaces are defined that has the calling convention?
>>> Again, I am very wary of platform-dependent pragmas in supposedly portable code!
>>>
>>> Antony Hosking | Associate Professor | Computer Science | Purdue University
>>> 305 N. University Street | West Lafayette | IN 47907 | USA
>>> Office +1 765 494 6001 | Mobile +1 765 427 5484
>>>
>>>
>>>
>>>
>>>
>>>
>>> On 22 Feb 2010, at 17:59, Jay K wrote:
>>>
>>> There is an analog to Modula-3.
>>> Setting the calling convention on platforms that have them.
>>> "Doing nothing" on others.
>>>
>>> - Jay
>>>
>>>
>>> ________________________________
>>> From: hosking at cs.purdue.edu
>>> Date: Mon, 22 Feb 2010 17:45:12 -0500
>>> To: jay.krell at cornell.edu
>>> CC: m3devel at elegosoft.com; darko at darko.org
>>> Subject: Re: [M3devel] calling conventions (small proposal)
>>>
>>> This is C code...
>>>
>>> On 22 Feb 2010, at 16:10, Jay K wrote:
>>>
>>>>> But why would you have platform-dependent pragmas in code that is not platform-dependent?
>>>
>>>
>>> example of mostly portable + pragma:
>>>
>>>  
>>> hand.c:
>>>  
>>> #if !defined(_MSC_VER) && !defined(__stdcall)
>>> #define __stdcall /* nothing */
>>> #endif
>>>  
>>> void __stdcall set_singleton
>>> ANSI(( ulong a, ulong* s))
>>> KR((a, s) ulong a; ulong* s;)
>>> {
>>> ulong a_word = a / SET_GRAIN;
>>> ulong a_bit = a % SET_GRAIN;
>>> s[a_word] |= (1UL << a_bit);
>>> }
>>>  
>>>
>>> (gcc on Windows #defines __stdcall to __attribute__(something))
>>>  
>>>
>>> Not the best example -- this function doesn't seem well motivated.
>>> We probably need a CG.i3 function to do div and mod in one go, since
>>> the processors usually expose that.
>>> Though this case is with a co! nstant power of two, so..
>>> And m3front would be a little pressed to notice the opportunity?
>>>
>>>
>>> - Jay
>>>
>>>
>>> ________________________________
>>> From: hosking at cs.purdue.edu
>>> Date: Mon, 22 Feb 2010 11:01:57 -0500
>>> To: jay.krell at cornell.edu
>>> CC: m3devel at elegosoft.com; darko at darko.org
>>> Subject: Re: [M3devel] calling conventions (small proposal)
>>>
>>> Pragmas should never give errors.
>>> If you are proposing that all platforms recognise the pragmas, but most do nothing with them, then I guess OK. But why would you have platform-dependent pragmas in code that is not platform-dependent?
>>>
>>> Antony Hosking | Associate Professor | Computer Science | Purdue University
>>> 305 N. University Street | West Lafayette | IN 47907 | USA
>>> Office +1 765 494 6001 | Mobile +1 765 427 5484
>>>
>>>
>>>
>>>
>>> On 22 Feb 2010, at 04:52, Jay K wrote:
>>>
>>> I wouldn't mind
>>> - an error
>>> - or a way to mark a pragma as needing an error vs. being ok with a warning
>>> Though perhaps that shouldn't be a pragma but some other syntax not in <* *>.
>>> In fact, maybe this stuff doesn't belong in <* *>. I don't care much what
>>> the syntax is, but there is a legitimate need to note calling conventions,
>>> a syntax is already in use. I'd rather not invent a new syntax.
>>>
>>>
>>> The word "ignore" isn't relevant.
>>> Sorry if I was confusing.
>>> The proposal is that all targets recognize the pragmas __stdcall, __cdecl, etc.
>>> but that most platforms interpret them as doing nothing.
>>> The pragmas already exist.
>>> "Recognize and do nothing" is much different ! than "ign! ore stuff that isn't recognized".
>>>
>>>
>>> - Jay
>>>
>>> ________________________________
>>> Subject: Re: [M3devel] calling conventions (small proposal)
>>> From: hosking at cs.purdue.edu
>>> Date: Sun, 21 Feb 2010 16:52:20 -0500
>>> CC: jay.krell at cornell.edu; m3devel at elegosoft.com
>>> To: darko at darko.org
>>>
>>> The compiler does continue to compile having warned that the pragma has no meaning.
>>>
>>> So, yes, they are ignored, but I want a warning.
>>>
>>> I even want a warning if I write <**>.
>>>
>>>
>>> On 21 Feb 2010, at 16:47, Darko wrote:
>>>
>>> I thought that was the point of pragmas, that the compiler could freely ignore them and that they did not involve the correctness of the program.
>>>
>>>
>>> On 22/02/2010, at 8:42 AM, Tony Hosking wrote:
>>>
>>> Yes, but my point is that a pragma that has no meaning *should* give a warning. Otherwise, why did I write it.
>>>
>>> On 21 Feb 2010, at 16:16, Jay K wrote:
>>>
>>> To be clear, I don't propose ignoring all unrecognized pragmas.
>>> Just calling conventions.
>>> You could interpret it as:
>>> The pragmas *are* recognized, on all targets, but they have no meaning on most.
>>> The meaning is "do nothing".
>>>
>>>
>>> Look at the situation in C for AMD64_NT. Calling conventions are accepted for compatibility
>>> with I386_NT source. And they all mean nothing. This lets people maintain
>>> one portable code base, and they *don't* even need to do so much as:
>>> #ifndef _X86_
>>> #define __stdcall /* nothing */
>>> #define __cdecl /* nothing */
>>> #define __fastcall /* nothing */
>>> #endif
>>>
>>>
>>> I'd be willing to prune the "big" list of calling conventions down to just two: __stdcall, __cdecl.
>>> The rest are a pointless proliferation of synonyms.
>>> Though that'd proba! bly gr! atuitously break stuff (of course I can fix the entire cm3 tree in
>>> a few minutes, that's not the issue).
>>>
>>>
>>> Separate file would work, but I'd really rather stuff be all together.
>>> Once you separate things, one version goes stale.
>>>
>>>
>>> - Jay
>>>
>>> ________________________________
>>> Subject: Re: [M3devel] calling conventions (small proposal)
>>> From: hosking at cs.purdue.edu
>>> Date: Sun, 21 Feb 2010 15:54:13 -0500
>>> CC: jay.krell at cornell.edu; m3devel at elegosoft.com
>>> To: darko at darko.org
>>>
>>> Accepting and silently ignoring sounds very dangerous!
>>>
>>> I want my compiler to warn me when I use a pragma that is unrecognised for my particular target.
>>>
>>> Silence is deadly!
>>>
>>> On 21 Feb 2010, at 15:09, Darko wrote:
>>>
>>> This is a good idea. An alternate proposal would be to put the calling conventions in an external file, but this change would seem to be the simplest and in line with the stated definition of pragamas.
>>>
>>>
>>>
>>> On 21/02/2010, at 10:52 PM, Jay K wrote:
>>>
>>> 1) All platforms should accept, but silently ignore, the NT386/I386_CYGWIN/etc. calling conventions:
>>> at least __stdcall, and __cdecl
>>> Probably all the synonyms: C, WINAPI, CALLBACK, WINAPIV, APIENTRY, APIPRIVATE, PASCAL,
>>>
>>> This is a very small change.
>>>
>>>
>>> This is will allow:
>>> a) possibly merging the two nearly identical OpenGL.i3 files
>>> b) implementing functions in Modula-3 that are portable, but use __stdcall, possibly for perf
>>> I intend to that for hand.c's replacement, soon.
>>>
>>>
>>> Maybe experiment as to the perf.
>>> __stdcall is supposed to be faster, because the code is smaller.
>>> But __cdecl might be able to compete by using stores to the stack instead of pushes?
>>> I'd have to see how that compares in size, and it does increase stack usage som! e.
>>> !
>>>
>>> Probably not worth large scale experimenting/changing, but maybe nice to mark
>>> new functions/interfaces as __stdcall (see next point).
>>>
>>>
>>> I was actually thinking of trying flat out changing the default, but I think that is too difficult,
>>> what with all the C<=>Modula-3 transitions. And not worth it given other
>>> more valuable work to do.
>>>
>>>
>>> 2) The calling convention pragmas should be allowed on an interface, to set
>>> the default for an interface.
>>>
>>> 2b) and I guess as well on a module, for unexported functions
>>>
>>> I assert that other than __stdcall and __cdecl on NT386, nothing else is
>>> particularly interesting here. There is __fastcall, maybe interesting.
>>> It has different meanings to different compilers.
>>> I'd rather keep this all fairly constrained.
>>>
>>> No other platform has more than one calling convention, so this doesn't
>>> have be to further generalized. B! esides, ! as long as no platform uses
>>> the same name to mean multipl e things, ok.
>>> Mac68K Classic?
>>> Mac68K CFM?
>>> Win16?
>>> MS-DOS?
>>>
>>>
>>> (I did recently acquire a working Mac68K, as well it is easily
>>> run on a modern PPC Mac; far down the list, but...)
>>>
>>>
>>> - Jay
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>
> 		 	   		  



More information about the M3devel mailing list