+
+%************************************************************************
+%* *
+\subsection{Free, reserved, call-clobbered, and argument registers}
+%* *
+%************************************************************************
+
+@freeRegs@ is the list of registers we can use in register allocation.
+@freeReg@ (below) says if a particular register is free.
+
+With a per-instruction clobber list, we might be able to get some of
+these back, but it's probably not worth the hassle.
+
+@callClobberedRegs@ ... the obvious.
+
+@argRegs@: assuming a call with N arguments, what registers will be
+used to hold arguments? (NB: it doesn't know whether the arguments
+are integer or floating-point...)
+
+findReservedRegs tells us which regs can be used as spill temporaries.
+The list of instructions for which we are attempting allocation is
+supplied. This is so that we can (at least for x86) examine it to
+discover which registers are being used in a fixed way -- for example,
+%eax and %edx are used by integer division, so they can't be used as
+spill temporaries. However, most instruction lists don't do integer
+division, so we don't want to rule them out altogether.
+
+findReservedRegs returns not a list of spill temporaries, but a list
+of list of them. This is so that the allocator can attempt allocating
+with at first no spill temps, then if that fails, increasing numbers.
+For x86 it is important that we minimise the number of regs reserved
+as spill temporaries, since there are so few. For Alpha and Sparc
+this isn't a concern; we just ignore the supplied code list and return
+a singleton list which we know will satisfy all spill demands.
+
+\begin{code}
+findReservedRegs :: [Instr] -> [[RegNo]]
+findReservedRegs instrs
+#if alpha_TARGET_ARCH
+ = [[NCG_Reserved_I1, NCG_Reserved_I2,
+ NCG_Reserved_F1, NCG_Reserved_F2]]
+#endif
+#if sparc_TARGET_ARCH
+ = [[NCG_Reserved_I1, NCG_Reserved_I2,
+ NCG_Reserved_F1, NCG_Reserved_F2,
+ NCG_Reserved_D1, NCG_Reserved_D2]]
+#endif
+#if i386_TARGET_ARCH
+ -- Sigh. This is where it gets complicated.
+ = -- first of all, try without any at all.
+ map (map mappedRegNo) (
+ [ [],
+ -- if that doesn't work, try one integer reg (which might fail)
+ -- and two float regs (which will always fix any float insns)
+ [ecx, fake4,fake5]
+ ]
+ -- dire straits (but still correct): see if we can bag %eax and %edx
+ ++ if any hasFixedEAXorEDX instrs
+ then [] -- bummer
+ else [ [ecx,edx,fake4,fake5],
+ [ecx,edx,eax,fake4,fake5] ]
+ )
+#endif
+\end{code}
+