wiki:PortToIA-32

Version 7 (modified by gb, 7 years ago) (diff)

--

Notes on an IA-32 port

A port of OpenMCL to IA-32 (Intel's name for the 32 bit x86 architecture) would be a win for several reasons.

The most obvious reason would be to support Apple hardware that isn't 64-bit capable. This includes the first-generation Intel-based iMac, MacBook, MacBook Pro, and all Intel-based Mac Minis. Of course, support for non-Apple IA-32 hardware would also be nice.

Another reason would be to support access to Cocoa and Carbon (and other frameworks) on Intel-based Macintoshes running Mac OS X Tiger.

Although Apple has announced that Cocoa will be 64 bit in Leopard, they have publically confirmed that Carbon won't be. Therefore, a 32 bit lisp would still be needed to use Carbon, even on Leopard running on 64 bit hardware.

It would be interesting to support the AMD Geode LX (as used in the  OLPC laptop) as the minimum processor. This processor supports the P6 family instructions, including MMX instructions. We can therefore use the conditional move instructions, and maybe some MMX instructions to help out with bignums.

On the other hand, the AMD Geode LX processor doesn't support any of the SSE/SSE2/SSE3 instructions; this means that we'd have to use the x87 FPU (which is sort of funky). This would require modifications to the compiler, which believes that every floating point register can be accessed independently.

It might be reasonable to target the Core Solo/Duo? processor, at least to begin with. This would cover all Intel-based Macintosh systems ever shipped, and would allow us to avoid adding x87 FPU support for now.

Register usage and tagging

(See also  http://openmcl.clozure.com/Doc/index.html#Register-usage-and-tagging)

We want to keep the precise GC, but the limited number of registers that we have will probably make it impossible to statically partition the register file into immediate and tagged sets.

Anyway, we're looking at something like this:

eax 	 imm0
ecx 	 nargs, temp0
edx 	 imm1
ebx 	 fn
esp 	 stack pointer
ebp 	 frame pointer
esi 	 arg_z
edi 	 arg_y

We will augment this with a dynamic scheme: we will set or clear a bit in thread-private memory whenever a register transitions from one class to another. The GC will then look at these flag bits to decide how to treat the registers. (This may make the lispy register names confusing, since at times imm0 might actually contain a node, or arg_y an immediate.)

Callee-saved "non-volatile" registers are probably a non-starter.

The tagging scheme can basically follow the PPC32 port. An important difference is that the three-bit tag #b101, which is for NIL on PPC32, would be used for a thing called a tagged return addresses on IA-32. (More on this later.)

Threads

We don't have the __thread storage class on Darwin, so we will need to use i386_set_ldt to install a segment descriptor for each thread into the LDT. When a thread's segment descriptor is loaded into the %fs segment register, %fs can be used to refer to thread-local storage.

(This implies an 8K limit to the number of threads, by the way. Probably not a big deal for a 32 bit lisp.)