Changes between Version 29 and Version 30 of PortToIA-32

Apr 20, 2008, 5:04:18 AM (11 years ago)

update section on register usage


  • PortToIA-32

    v29 v30  
    4040(See also
     42The tagging scheme can basically follow the PPC32 port.  An important
     43difference is that the three-bit tag #b101, which is for NIL on PPC32,
     44is used for a thing called a tagged return addresses on IA-32.
     45(More on this later.)
    4247We want to keep the precise GC, but the limited number of registers
    6469contain a node, or arg_y an immediate.)
     71Another potential idea involves the direction flag (DF) in EFLAGS.
     72The lisp can't use any of the string instructions, so it would be possible to
     73use this bit for other purposes.  When DF is clear, this could tell the GC that
     74the normal register partitioning (as above) is in effect.
     75When DF is set, this could indicate that an alternate register
     76register partitioning would be in effect, e.g.,
     79eax      imm0
     80ecx      imm2
     81edx      imm1
     82ebx      arg_z
     83esp      stack pointer
     84ebp      frame pointer
     85esi      arg_y
     86edi      fn
     89We'd need to be careful save the state of the flags and clear DF before calling foreign code.
     91(I got the idea of using a bit in EFLAGS to distinguish between two modes of register usage from
     93One further idea is to arrange that no lisp object can be located at an
     94address below 2^24^.  Since no valid vector index can be as great as 2^24^
     95(the value of ARRAY-TOTAL-SIZE-LIMIT), this means that we could store unboxed
     96array indicies in node registers and still have the GC reliably distinguish
     97nodes from other values.  (The main win to this would be making AREF easy.
     98It wouldn't be necessary to fool around marking registers as immediates.)
    66100Callee-saved "non-volatile" registers are probably a non-starter.
    68 The tagging scheme can basically follow the PPC32 port.  An important
    69 difference is that the three-bit tag #b101, which is for NIL on PPC32,
    70 would be used for a thing called a tagged return addresses on IA-32.
    71 (More on this later.)
     102=== TCR additions ===
     104==== Node spill area ====
     105Since we have so few registers, we have a static spill area of 4 words in
     106each lisp thread's TCR.  The GC treats these as roots, and the convention
     107is that they're caller-saved.  (At the moment, the compiler knows nothing
     108of this spill area, and it's used only from LAP functions and subprimitives.)
     110We do have to be careful about clearing out this spill area so that the GC
     111doesn't hang onto objects that would otherwise be garbage.  PROCESS-INTERRUPT
     112will need to save and restore these values, and we might need
     113to say that any callback (including traps) does so as well.  (There's enough
     114complexity already in traps and callbacks that saving/restoring the spill area isn't likely
     115to add substantial overhead.)
     117==== Unboxed words ====
     118There are also a couple of words in the TCR that are used for unboxed values.
     119We could build a frame on the tsp, but that's rather expensive.
     121One situation that comes to mind involves dividing an ''n''-digit bignum by a single
     122digit:  we need registers
     123to contain the bignum dividend, the result (the bignum quotient), and an index register.  The
     124DIV instruction requires the use of EDX:EAX pair.  That means we're out of registers (fn,
     125ebp, and esp are all in use), and have to store the single digit divisor somewhere else.
     126We'd typically keep an unboxed value in an MMX register, but we can't use an MMX register as an operand to DIV.
     127Therefore we have to
     128use a memory operand: the unboxed word in the TCR.
     130==== next-method-context ====
     131The CLOS implementation sometimes uses an invisible argument to pass
     132context information for CALL-NEXT-METHOD.  On other ports, this is a register
     133that's not part of the normal calling sequence, but on IA-32, all the registers
     134are spoken for: arg_y and arg_z contain the last two arguments, temp1 is used as
     135nargs, and temp0 is the function about to be called.
     136We therefore pass the next-method-context via a slot in the TCR.  (No, it's not pretty.)
     137The GC will have to
     138treat this as a root, and we might want to arrange to clear it out somehow so
     139that it doesn't hang onto something that's otherwise garbage.
    73141==== Comment by gb on Wed Aug  1 22:16:05 2007 ====