Yesterday I reworked the note format to allow functions as first-class objects, and then I had an idea about how to implement the note compiler.
I’d already thought I could have the compiler emit assembly to avoid having to think about endianness, but I couldn’t figure out how to do other platform-specific stuff like 32- vs 64-bit, or choosing which of the three LWP ID to thread descriptor mapping styles to use. My idea was to not only output to the assembler but to input from the C preprocessor as well. That way I can do all the conditional stuff in there, driven by glibc’s include files and
Yeah, I think I can write a compiler that knows nothing about the platform it’s compiling for.
So, I spent all morning messing around with glibc’s build system. I’ve come up with this:
- Each machine’s
tls.hwill have some Infinity definitions following the ones for libthread_db. Here’s the one for x86_64:
/* Magic for libthread_db to know how to do THREAD_SELF. */ #define DB_THREAD_SELF_INCLUDE
/* For the FS constant. */ #define DB_THREAD_SELF CONST_THREAD_AREA (64, FS) /* Magic for Infinity to know how to do THREAD_SELF. */ #define I8_THREAD_SELF I8_TS_CONST_THREAD_AREA #define I8_TS_CTA_VALUE FS
I could probably generate the libthread_db ones from the Infinity ones… but… later.
- glibc has a script to generate assembler include files, to get constants and offsets from C headers into the assembler. I wrote a
tls-infinity.symfile that the build system turns into
- The source for
infinity_map_lwp2thr.i8. That includes
tls-infinity.hand, on x86_64, conditionally includes
infinity_lookup_th_unique_cta.i8to perform the mapping in the correct way for that platform.
infinity_map_lwp2thr.i8gets fed into the C preprocessor which a) does all the conditionality and b) expands all the constants (as a total bonus!)
This leaves me with this lovely file to write a compiler for.
I’ve never written a compiler.