[M3devel] generating target-independent C in backend?

Jay K jay.krell at cornell.edu
Mon Jan 28 07:44:29 CET 2013

 Currently the C output is target-specific. 
 I want to generate one set of C output for all platforms. 
 So you just download one portable "m3.tar.gz".

 Is there agreement on this goal? 
 Others might help? 
 And no generally object to my changes to make it so? 

Here are the obstacles to getting there as I understand:
 win32 vs. posix (or more generally, logic on the m3makefile's that change what source is compiled) 
 jmpbuf size 
 word size/layout 

I believe the "layout rules" (padding/alignment) are now fairly target independent,
EXCEPT that endianness and word size vary.
That is, interop with C has been compromised.

jmpbuf size is probably the easiest to fix.
In the near term, solve it like I already tried.
jmpbuf x
to void*x = 0;
    x = x ? x : alloca(sizeof_jmpbuf);

#include <setjmp.h>
extern const size_t sizeof_jmpbuf = sizeof(jmpbuf)
(plus possible Cygwin hack -- they accidentally blow up the size by a factor of 4)

long term:
 generate C++ and no more setjmp/longjmp, or possibly C on OpenVMS, Tru64, and NT, possibly #ifdefed 

Endianness is partly solved by moving the "floating point cracking" code to C.
But that doesn't suffice.
There remain bitfields in the runtime, I don't think they can/should be removed, and their layout
is endian-specific. Maybe we can just change layout to not be endian specific?
I don't care to enable or keep working interop with C bitfields.

win32 vs. posix (also pthreads vs. user threads)
requires "something" in the "builder", interacting with the backend perhaps, or with bootstrapping
Basically whenever there is an "if" in quake, you kind of need to go down both paths, but communicate the condition
to the next level down.

Like if we had FooPosix.m3 and FooWin32.m3

we either want both
FooPosix.c and FooWin32.c generated and we'll only compile one of them,
or Foo.m3 with both contents concatenated but with an #if/#else/#endif between them.

But what if we had FooWin32.i3 and FooPosix.i3?
We can't let FooPosix.i3 be fixible BarWin32.m3.
Like, we want to compile everything to C, but not otherwise "infect" the compilation system with the conceptual output.
Does that make sense?

The layout problem is tricky.
We need separate notions in the backend for UINT32, UINT64, and size_t; and INT32, INT64, and ptrdiff_t (INTEGER).
We can't have the frontend resolve to a specific size, at least not without maintaining some notion of the abstraction that the backend sees.
The existing typeids might suffice.

As well, records/fields have to treated differently, or in an extra way.
That is, we can pass computed sizes and offsets to the backend, and we'd also have to pass other information,
and the backend could chose which to use. A reasonably easy approach is to pass a list of integers to add up
and maybe multiple, and besides the obvious 1, 2, 4, 8, there'd also be stand-in values for "size_t", like maybe -1.
This might be deducable from the declarations we have about arrays and records.

It is also tempting to give up on the majority of this.
If we solve the jmpbuf problem..including, heck, just blow up jmpbufs to 1K, or use C++ exception handling, then there
are only a few targets remainaing:
 32bit little endian posix 
 64bit little endian posix 
 32bit little big posix 
 64bit little big posix  
 32bit little endian NT  
 64bit little endian NT  
 big endian NT doesn't really exist (Xbox 360?).

We could distribute 6 source archives and let the user chose?
Seems too lame to me.
But that might be the short term solution.


 - Jay

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20130128/2b216461/attachment-0001.html>

More information about the M3devel mailing list