The first step is to get the VM to compile and run a boot image in interpreted mode. It mostly consists of portable C, but there are at least three architecture-specific details which need to be filled out; getting the native stack pointer, native stack frame format, and flushing the instruction cache. I haven't done any research as to whenever the latter is necessary, nor have I studied the ABI extensively yet, so I only filled in the first item for now. All in all, I added the following new files, together with a
While testing, I ran into a major problem. A data stack underflow would send the runtime into an endless cycle of signal 11 errors, at seemingly random addresses! This is not what is supposed to happen. When the Unix signal handler receives a memory access violation, it pulls the native stack pointer at the time of the fault out of the signal context, then walks the native stack for compiled Factor frames. Since the ARM port doesn't compile yet this should be a no-op, but in fact the native stack pointer from the faulting context looked like a seemingly arbitrary address.
After some head-scratching, it really seemed like the
ucontext_tstructure had a different layout in the glibc headers than what the kernel was giving us, and Googling confirmed my suspicions. Turns out this is a known problem and it is already fixed in the glibc trunk, which has not made it to Debian-stable yet. Most less-conservative ARM distros might already have the latest headers. If yours doesn't, you can apply the patch in the e-mail linked above with the following sequence of commands:
copy and paste the patch here
patch -p8 < ucontext.patch
Alternatively, upgrade your entire libc, but that is not for the faint of heart.
With signal handling working, I ran into a second problem; floating point values saved in the boot image were corrupt. A quick call to
double>bits .brevealed that the most significant and least significant cells of the float were swapped from what ARM expects. Fixing this was easy, I added a new bootstrap profile for ARM chips:
Now, all unit tests expect those testing the compiler passed. I stubbed out the compiler backend but didn't write any substantial code for it yet:
For the last several days, I have been studying ARM assembly language, and tomorrow I will begin writing the assembler. Hopefully by the end of the week, I'll have everything except FFI calls compiling. Getting FFI and callbacks right is always the trickiest part, but with ARM I don't have to deal with floating point registers so perhaps it might even be easy.
Anyway, today's efforts were a success:
Factor 0.88 on linux/arm