2 % (c) The AQUA Project, Glasgow University, 1993-1995
5 \section[I386Code]{The Native (I386) Machine Code}
8 #define ILIT2(x) ILIT(x)
9 #include "HsVersions.h"
13 Cond(..), Imm(..), Operand(..), Size(..),
14 Base(..), Index(..), Displacement(..),
15 I386Code(..),I386Instr(..),I386Regs,
21 baseRegOffset, stgRegMap, callerSaves,
27 st0, st1, eax, ebx, ecx, edx, esi, edi, ebp, esp,
29 freeRegs, reservedRegs
31 -- and, for self-sufficiency ...
34 import AbsCSyn ( MagicId(..) )
35 import AsmRegAlloc ( MachineCode(..), MachineRegisters(..), FutureLive(..),
36 Reg(..), RegUsage(..), RegLiveness(..)
39 import CgCompInfo ( mAX_Double_REG, mAX_Float_REG, mAX_Vanilla_REG )
40 import CLabel ( CLabel, pprCLabel, externallyVisibleCLabel, charToC )
42 import Maybes ( Maybe(..), maybeToBool )
43 import OrdList ( OrdList, mkUnitList, flattenOrdList )
51 %************************************************************************
53 \subsection[I386Reg]{The Native (I386) Machine Register Table}
55 %************************************************************************
57 - All registers except 7 (esp) are available for use.
58 - Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
59 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
60 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
61 - Registers 8-15 hold extended floating point values.
63 ToDo: Deal with stg registers that live as offsets from BaseReg!(JSM)
67 gReg,fReg :: Int -> Int
71 st0, st1, st2, st3, st4, st5, st6, st7, eax, ebx, ecx, edx, esp :: Reg
72 eax = case (gReg 0) of { IBOX(g0) -> FixedReg g0 }
73 ebx = case (gReg 1) of { IBOX(g1) -> FixedReg g1 }
74 ecx = case (gReg 2) of { IBOX(g2) -> FixedReg g2 }
75 edx = case (gReg 3) of { IBOX(g3) -> FixedReg g3 }
76 esi = case (gReg 4) of { IBOX(g4) -> FixedReg g4 }
77 edi = case (gReg 5) of { IBOX(g5) -> FixedReg g5 }
78 ebp = case (gReg 6) of { IBOX(g6) -> FixedReg g6 }
79 esp = case (gReg 7) of { IBOX(g7) -> FixedReg g7 }
80 st0 = realReg (fReg 0)
81 st1 = realReg (fReg 1)
82 st2 = realReg (fReg 2)
83 st3 = realReg (fReg 3)
84 st4 = realReg (fReg 4)
85 st5 = realReg (fReg 5)
86 st6 = realReg (fReg 6)
87 st7 = realReg (fReg 7)
89 realReg n@IBOX(i) = if _IS_TRUE_(freeReg i) then MappedReg i else FixedReg i
93 %************************************************************************
95 \subsection[TheI386Code]{The datatype for i386 assembly language}
97 %************************************************************************
99 Here is a definition of the I386 assembly language.
103 data Imm = ImmInt Int
104 | ImmInteger Integer -- Sigh.
105 | ImmCLbl CLabel -- AbstractC Label (with baggage)
106 | ImmLab Unpretty -- Simple string label (underscored)
107 | ImmLit Unpretty -- Simple string
110 strImmLit s = ImmLit (uppStr s)
136 data Operand = OpReg Reg -- register
137 | OpImm Imm -- immediate value
138 | OpAddr Addr -- memory reference
141 data Addr = Addr Base Index Displacement
145 type Base = Maybe Reg
146 type Index = Maybe (Reg, Int) -- Int is 2, 4 or 8
147 type Displacement = Imm
153 MOV Size Operand Operand
154 | MOVZX Size Operand Operand -- size is the size of operand 2
155 | MOVSX Size Operand Operand -- size is the size of operand 2
157 -- Load effective address (also a very useful three-operand add instruction :-)
159 | LEA Size Operand Operand
163 | ADD Size Operand Operand
164 | SUB Size Operand Operand
166 -- Multiplication (signed and unsigned), Division (signed and unsigned),
167 -- result in %eax, %edx.
169 | IMUL Size Operand Operand
172 -- Simple bit-twiddling.
174 | AND Size Operand Operand
175 | OR Size Operand Operand
176 | XOR Size Operand Operand
178 | NEGI Size Operand -- NEG instruction (name clash with Cond)
179 | SHL Size Operand Operand -- 1st operand must be an Imm
180 | SAR Size Operand Operand -- 1st operand must be an Imm
181 | SHR Size Operand Operand -- 1st operand must be an Imm
184 -- Float Arithmetic. -- ToDo for 386
186 -- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single instructions
187 -- right up until we spit them out.
189 | SAHF -- stores ah into flags
191 | FADD Size Operand -- src
193 | FIADD Size Addr -- src
195 | FCOM Size Operand -- src
197 | FDIV Size Operand -- src
199 | FIDIV Size Addr -- src
200 | FDIVR Size Operand -- src
202 | FIDIVR Size Addr -- src
203 | FICOM Size Addr -- src
204 | FILD Size Addr Reg -- src, dst
205 | FIST Size Addr -- dst
206 | FLD Size Operand -- src
209 | FMUL Size Operand -- src
211 | FIMUL Size Addr -- src
215 | FST Size Operand -- dst
216 | FSTP Size Operand -- dst
217 | FSUB Size Operand -- src
219 | FISUB Size Addr -- src
220 | FSUBR Size Operand -- src
222 | FISUBR Size Addr -- src
224 | FCOMP Size Operand -- src
232 | TEST Size Operand Operand
233 | CMP Size Operand Operand
243 | JMP Operand -- target
244 | JXX Cond CLabel -- target
249 | CLTD -- sign extend %eax into %edx:%eax
254 | COMMENT FAST_STRING
255 | SEGMENT CodeSegment
256 | ASCII Bool String -- needs backslash conversion?
259 type I386Code = OrdList I386Instr
263 %************************************************************************
265 \subsection[TheI386Pretty]{Pretty-printing the I386 Assembly Language}
267 %************************************************************************
271 printLabeledCodes :: PprStyle -> [I386Instr] -> Unpretty
272 printLabeledCodes sty codes = uppAboves (map (pprI386Instr sty) codes)
276 Printing the pieces...
280 pprReg :: Size -> Reg -> Unpretty
282 pprReg s (FixedReg i) = pprI386Reg s i
283 pprReg s (MappedReg i) = pprI386Reg s i
284 pprReg s other = uppStr (show other) -- should only happen when debugging
286 pprI386Reg :: Size -> FAST_INT -> Unpretty
287 pprI386Reg B i = uppPStr
289 ILIT( 0) -> SLIT("%al"); ILIT( 1) -> SLIT("%bl");
290 ILIT( 2) -> SLIT("%cl"); ILIT( 3) -> SLIT("%dl");
291 _ -> SLIT("very naughty I386 byte register")
294 pprI386Reg HB i = uppPStr
296 ILIT( 0) -> SLIT("%ah"); ILIT( 1) -> SLIT("%bh");
297 ILIT( 2) -> SLIT("%ch"); ILIT( 3) -> SLIT("%dh");
298 _ -> SLIT("very naughty I386 high byte register")
301 pprI386Reg S i = uppPStr
303 ILIT( 0) -> SLIT("%ax"); ILIT( 1) -> SLIT("%bx");
304 ILIT( 2) -> SLIT("%cx"); ILIT( 3) -> SLIT("%dx");
305 ILIT( 4) -> SLIT("%si"); ILIT( 5) -> SLIT("%di");
306 ILIT( 6) -> SLIT("%bp"); ILIT( 7) -> SLIT("%sp");
307 _ -> SLIT("very naughty I386 word register")
310 pprI386Reg L i = uppPStr
312 ILIT( 0) -> SLIT("%eax"); ILIT( 1) -> SLIT("%ebx");
313 ILIT( 2) -> SLIT("%ecx"); ILIT( 3) -> SLIT("%edx");
314 ILIT( 4) -> SLIT("%esi"); ILIT( 5) -> SLIT("%edi");
315 ILIT( 6) -> SLIT("%ebp"); ILIT( 7) -> SLIT("%esp");
316 _ -> SLIT("very naughty I386 double word register")
319 pprI386Reg F i = uppPStr
322 ILIT( 8) -> SLIT("%st(0)"); ILIT( 9) -> SLIT("%st(1)");
323 ILIT(10) -> SLIT("%st(2)"); ILIT(11) -> SLIT("%st(3)");
324 ILIT(12) -> SLIT("%st(4)"); ILIT(13) -> SLIT("%st(5)");
325 ILIT(14) -> SLIT("%st(6)"); ILIT(15) -> SLIT("%st(7)");
326 _ -> SLIT("very naughty I386 float register")
329 pprI386Reg D i = uppPStr
332 ILIT( 8) -> SLIT("%st(0)"); ILIT( 9) -> SLIT("%st(1)");
333 ILIT(10) -> SLIT("%st(2)"); ILIT(11) -> SLIT("%st(3)");
334 ILIT(12) -> SLIT("%st(4)"); ILIT(13) -> SLIT("%st(5)");
335 ILIT(14) -> SLIT("%st(6)"); ILIT(15) -> SLIT("%st(7)");
336 _ -> SLIT("very naughty I386 float register")
339 pprCond :: Cond -> Unpretty -- ToDo
342 GEU -> SLIT("ae"); LU -> SLIT("b");
343 EQ -> SLIT("e"); GT -> SLIT("g");
344 GE -> SLIT("ge"); GU -> SLIT("a");
345 LT -> SLIT("l"); LE -> SLIT("le");
346 LEU -> SLIT("be"); NE -> SLIT("ne");
347 NEG -> SLIT("s"); POS -> SLIT("ns");
348 ALWAYS -> SLIT("mp"); -- hack
349 _ -> error "Spix: iI386Code: unknown conditional!"
352 pprDollImm :: PprStyle -> Imm -> Unpretty
354 pprDollImm sty i = uppBesides [ uppPStr SLIT("$"), pprImm sty i]
356 pprImm :: PprStyle -> Imm -> Unpretty
358 pprImm sty (ImmInt i) = uppInt i
359 pprImm sty (ImmInteger i) = uppInteger i
360 pprImm sty (ImmCLbl l) = pprCLabel sty l
361 pprImm sty (ImmLab l) = l
363 --pprImm (PprForAsm _ False _) (ImmLab s) = s
364 --pprImm _ (ImmLab s) = uppBeside (uppChar '_') s
366 pprImm sty (ImmLit s) = s
368 pprAddr :: PprStyle -> Addr -> Unpretty
369 pprAddr sty (ImmAddr imm off)
370 = uppBesides [pprImm sty imm,
371 if off > 0 then uppChar '+' else uppPStr SLIT(""),
372 if off == 0 then uppPStr SLIT("") else uppInt off
374 pprAddr sty (Addr Nothing Nothing displacement)
375 = uppBesides [pprDisp sty displacement]
376 pprAddr sty (Addr base index displacement)
377 = uppBesides [pprDisp sty displacement,
384 pprBase (Just r) = uppBesides [pprReg L r,
386 Nothing -> uppPStr SLIT("")
389 pprBase _ = uppPStr SLIT("")
390 pprIndex (Just (r,i)) = uppBesides [pprReg L r, uppChar ',', uppInt i]
391 pprIndex _ = uppPStr SLIT("")
393 pprDisp sty (ImmInt 0) = uppPStr SLIT("")
394 --pprDisp sty (ImmInteger 0) = uppPStr SLIT("")
395 pprDisp sty d = pprImm sty d
397 pprOperand :: PprStyle -> Size -> Operand -> Unpretty
398 pprOperand sty s (OpReg r) = pprReg s r
399 pprOperand sty s (OpImm i) = pprDollImm sty i
400 pprOperand sty s (OpAddr ea) = pprAddr sty ea
402 pprSize :: Size -> Unpretty
413 pprSizeOp :: PprStyle -> FAST_STRING -> Size -> Operand -> Unpretty
414 pprSizeOp sty name size op1 =
420 pprOperand sty size op1
423 pprSizeOpOp :: PprStyle -> FAST_STRING -> Size -> Operand -> Operand -> Unpretty
424 pprSizeOpOp sty name size op1 op2 =
430 pprOperand sty size op1,
432 pprOperand sty size op2
435 pprSizeOpReg :: PprStyle -> FAST_STRING -> Size -> Operand -> Reg -> Unpretty
436 pprSizeOpReg sty name size op1 reg =
442 pprOperand sty size op1,
447 pprSizeAddr :: PprStyle -> FAST_STRING -> Size -> Addr -> Unpretty
448 pprSizeAddr sty name size op =
457 pprSizeAddrReg :: PprStyle -> FAST_STRING -> Size -> Addr -> Reg -> Unpretty
458 pprSizeAddrReg sty name size op dst =
469 pprOpOp :: PprStyle -> FAST_STRING -> Size -> Operand -> Operand -> Unpretty
470 pprOpOp sty name size op1 op2 =
475 pprOperand sty size op1,
477 pprOperand sty size op2
480 pprSizeOpOpCoerce :: PprStyle -> FAST_STRING -> Size -> Size -> Operand -> Operand -> Unpretty
481 pprSizeOpOpCoerce sty name size1 size2 op1 op2 =
482 uppBesides [ uppChar '\t', uppPStr name, uppChar ' ',
483 pprOperand sty size1 op1,
485 pprOperand sty size2 op2
488 pprCondInstr :: PprStyle -> FAST_STRING -> Cond -> Unpretty -> Unpretty
489 pprCondInstr sty name cond arg =
490 uppBesides [ uppChar '\t', uppPStr name, pprCond cond, uppChar ' ', arg]
492 pprI386Instr :: PprStyle -> I386Instr -> Unpretty
493 pprI386Instr sty (MOV size (OpReg src) (OpReg dst)) -- hack
496 pprI386Instr sty (MOV size src dst)
497 = pprSizeOpOp sty SLIT("mov") size src dst
498 pprI386Instr sty (MOVZX size src dst) = pprSizeOpOpCoerce sty SLIT("movzx") L size src dst
499 pprI386Instr sty (MOVSX size src dst) = pprSizeOpOpCoerce sty SLIT("movxs") L size src dst
501 -- here we do some patching, since the physical registers are only set late
502 -- in the code generation.
503 pprI386Instr sty (LEA size (OpAddr (Addr src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
505 = pprSizeOpOp sty SLIT("add") size (OpReg reg2) dst
506 pprI386Instr sty (LEA size (OpAddr (Addr src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
508 = pprSizeOpOp sty SLIT("add") size (OpReg reg1) dst
509 pprI386Instr sty (LEA size (OpAddr (Addr src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
511 = pprI386Instr sty (ADD size (OpImm displ) dst)
512 pprI386Instr sty (LEA size src dst) = pprSizeOpOp sty SLIT("lea") size src dst
514 pprI386Instr sty (ADD size (OpImm (ImmInt (-1))) dst)
515 = pprSizeOp sty SLIT("dec") size dst
516 pprI386Instr sty (ADD size (OpImm (ImmInt 1)) dst)
517 = pprSizeOp sty SLIT("inc") size dst
518 pprI386Instr sty (ADD size src dst)
519 = pprSizeOpOp sty SLIT("add") size src dst
520 pprI386Instr sty (SUB size src dst) = pprSizeOpOp sty SLIT("sub") size src dst
521 pprI386Instr sty (IMUL size op1 op2) = pprSizeOpOp sty SLIT("imul") size op1 op2
522 pprI386Instr sty (IDIV size op) = pprSizeOp sty SLIT("idiv") size op
524 pprI386Instr sty (AND size src dst) = pprSizeOpOp sty SLIT("and") size src dst
525 pprI386Instr sty (OR size src dst) = pprSizeOpOp sty SLIT("or") size src dst
526 pprI386Instr sty (XOR size src dst) = pprSizeOpOp sty SLIT("xor") size src dst
527 pprI386Instr sty (NOT size op) = pprSizeOp sty SLIT("not") size op
528 pprI386Instr sty (NEGI size op) = pprSizeOp sty SLIT("neg") size op
529 pprI386Instr sty (SHL size imm dst) = pprSizeOpOp sty SLIT("shl") size imm dst
530 pprI386Instr sty (SAR size imm dst) = pprSizeOpOp sty SLIT("sar") size imm dst
531 pprI386Instr sty (SHR size imm dst) = pprSizeOpOp sty SLIT("shr") size imm dst
533 pprI386Instr sty (CMP size src dst) = pprSizeOpOp sty SLIT("cmp") size src dst
534 pprI386Instr sty (TEST size src dst) = pprSizeOpOp sty SLIT("test") size src dst
535 pprI386Instr sty (PUSH size op) = pprSizeOp sty SLIT("push") size op
536 pprI386Instr sty (POP size op) = pprSizeOp sty SLIT("pop") size op
538 pprI386Instr sty (NOP) = uppPStr SLIT("\tnop")
539 pprI386Instr sty (CLTD) = uppPStr SLIT("\tcltd")
541 pprI386Instr sty (SETCC cond op) = pprCondInstr sty SLIT("set") cond (pprOperand sty B op)
543 pprI386Instr sty (JXX cond lab) = pprCondInstr sty SLIT("j") cond (pprCLabel sty lab)
545 pprI386Instr sty (JMP (OpImm imm)) = uppBeside (uppPStr SLIT("\tjmp ")) (pprImm sty imm)
546 pprI386Instr sty (JMP op) = uppBeside (uppPStr SLIT("\tjmp *")) (pprOperand sty L op)
548 pprI386Instr sty (CALL imm) =
549 uppBesides [ uppPStr SLIT("\tcall "), pprImm sty imm ]
551 pprI386Instr sty SAHF = uppPStr SLIT("\tsahf")
552 pprI386Instr sty FABS = uppPStr SLIT("\tfabs")
554 pprI386Instr sty (FADD sz src@(OpAddr _))
555 = uppBesides [uppPStr SLIT("\tfadd"), pprSize sz, uppChar ' ', pprOperand sty sz src]
556 pprI386Instr sty (FADD sz src)
557 = uppPStr SLIT("\tfadd")
558 pprI386Instr sty FADDP
559 = uppPStr SLIT("\tfaddp")
560 pprI386Instr sty (FMUL sz src)
561 = uppBesides [uppPStr SLIT("\tfmul"), pprSize sz, uppChar ' ', pprOperand sty sz src]
562 pprI386Instr sty FMULP
563 = uppPStr SLIT("\tfmulp")
564 pprI386Instr sty (FIADD size op) = pprSizeAddr sty SLIT("fiadd") size op
565 pprI386Instr sty FCHS = uppPStr SLIT("\tfchs")
566 pprI386Instr sty (FCOM size op) = pprSizeOp sty SLIT("fcom") size op
567 pprI386Instr sty FCOS = uppPStr SLIT("\tfcos")
568 pprI386Instr sty (FIDIV size op) = pprSizeAddr sty SLIT("fidiv") size op
569 pprI386Instr sty (FDIV sz src)
570 = uppBesides [uppPStr SLIT("\tfdiv"), pprSize sz, uppChar ' ', pprOperand sty sz src]
571 pprI386Instr sty FDIVP
572 = uppPStr SLIT("\tfdivp")
573 pprI386Instr sty (FDIVR sz src)
574 = uppBesides [uppPStr SLIT("\tfdivr"), pprSize sz, uppChar ' ', pprOperand sty sz src]
575 pprI386Instr sty FDIVRP
576 = uppPStr SLIT("\tfdivpr")
577 pprI386Instr sty (FIDIVR size op) = pprSizeAddr sty SLIT("fidivr") size op
578 pprI386Instr sty (FICOM size op) = pprSizeAddr sty SLIT("ficom") size op
579 pprI386Instr sty (FILD sz op reg) = pprSizeAddrReg sty SLIT("fild") sz op reg
580 pprI386Instr sty (FIST size op) = pprSizeAddr sty SLIT("fist") size op
581 pprI386Instr sty (FLD sz (OpImm (ImmCLbl src)))
582 = uppBesides [uppPStr SLIT("\tfld"),pprSize sz,uppChar ' ',pprCLabel sty src]
583 pprI386Instr sty (FLD sz src)
584 = uppBesides [uppPStr SLIT("\tfld"),pprSize sz,uppChar ' ',pprOperand sty sz src]
585 pprI386Instr sty FLD1 = uppPStr SLIT("\tfld1")
586 pprI386Instr sty FLDZ = uppPStr SLIT("\tfldz")
587 pprI386Instr sty (FIMUL size op) = pprSizeAddr sty SLIT("fimul") size op
588 pprI386Instr sty FRNDINT = uppPStr SLIT("\tfrndint")
589 pprI386Instr sty FSIN = uppPStr SLIT("\tfsin")
590 pprI386Instr sty FSQRT = uppPStr SLIT("\tfsqrt")
591 pprI386Instr sty (FST sz dst)
592 = uppBesides [uppPStr SLIT("\tfst"), pprSize sz, uppChar ' ', pprOperand sty sz dst]
593 pprI386Instr sty (FSTP sz dst)
594 = uppBesides [uppPStr SLIT("\tfstp"), pprSize sz, uppChar ' ', pprOperand sty sz dst]
595 pprI386Instr sty (FISUB size op) = pprSizeAddr sty SLIT("fisub") size op
596 pprI386Instr sty (FSUB sz src)
597 = uppBesides [uppPStr SLIT("\tfsub"), pprSize sz, uppChar ' ', pprOperand sty sz src]
598 pprI386Instr sty FSUBP
599 = uppPStr SLIT("\tfsubp")
600 pprI386Instr sty (FSUBR size src)
601 = pprSizeOp sty SLIT("fsubr") size src
602 pprI386Instr sty FSUBRP
603 = uppPStr SLIT("\tfsubpr")
604 pprI386Instr sty (FISUBR size op)
605 = pprSizeAddr sty SLIT("fisubr") size op
606 pprI386Instr sty FTST = uppPStr SLIT("\tftst")
607 pprI386Instr sty (FCOMP sz op)
608 = uppBesides [uppPStr SLIT("\tfcomp"), pprSize sz, uppChar ' ', pprOperand sty sz op]
609 pprI386Instr sty FUCOMPP = uppPStr SLIT("\tfucompp")
610 pprI386Instr sty FXCH = uppPStr SLIT("\tfxch")
611 pprI386Instr sty FNSTSW = uppPStr SLIT("\tfnstsw %ax")
612 pprI386Instr sty FNOP = uppPStr SLIT("")
614 pprI386Instr sty (LABEL clab) =
616 if (externallyVisibleCLabel clab) then
617 uppBesides [uppPStr SLIT(".globl "), pprLab, uppChar '\n']
623 where pprLab = pprCLabel sty clab
625 pprI386Instr sty (COMMENT s) = uppBeside (uppPStr SLIT("# ")) (uppPStr s)
627 pprI386Instr sty (SEGMENT TextSegment)
628 = uppPStr SLIT(".text\n\t.align 4")
630 pprI386Instr sty (SEGMENT DataSegment)
631 = uppPStr SLIT(".data\n\t.align 2")
633 pprI386Instr sty (ASCII False str) =
635 uppStr "\t.asciz \"",
640 pprI386Instr sty (ASCII True str) = uppBeside (uppStr "\t.ascii \"") (asciify str 60)
642 asciify :: String -> Int -> Unpretty
643 asciify [] _ = uppStr ("\\0\"")
644 asciify s n | n <= 0 = uppBeside (uppStr "\"\n\t.ascii \"") (asciify s 60)
645 asciify ('\\':cs) n = uppBeside (uppStr "\\\\") (asciify cs (n-1))
646 asciify ('\"':cs) n = uppBeside (uppStr "\\\"") (asciify cs (n-1))
647 asciify (c:cs) n | isPrint c = uppBeside (uppChar c) (asciify cs (n-1))
648 asciify [c] _ = uppBeside (uppStr (charToC c)) (uppStr ("\\0\""))
649 asciify (c:(cs@(d:_))) n | isDigit d =
650 uppBeside (uppStr (charToC c)) (asciify cs 0)
652 uppBeside (uppStr (charToC c)) (asciify cs (n-1))
654 pprI386Instr sty (DATA s xs) = uppInterleave (uppChar '\n') (map pp_item xs)
655 where pp_item x = case s of
656 B -> uppBeside (uppPStr SLIT("\t.byte\t")) (pprImm sty x)
657 HB-> uppBeside (uppPStr SLIT("\t.byte\t")) (pprImm sty x)
658 S -> uppBeside (uppPStr SLIT("\t.word\t")) (pprImm sty x)
659 L -> uppBeside (uppPStr SLIT("\t.long\t")) (pprImm sty x)
660 F -> uppBeside (uppPStr SLIT("\t.long\t")) (pprImm sty x)
661 D -> uppBeside (uppPStr SLIT("\t.double\t")) (pprImm sty x)
665 %************************************************************************
667 \subsection[Schedule]{Register allocation information}
669 %************************************************************************
673 data I386Regs = SRegs BitSet BitSet
675 instance MachineRegisters I386Regs where
676 mkMRegs xs = SRegs (mkBS ints) (mkBS floats')
678 (ints, floats) = partition (< 8) xs
679 floats' = map (subtract 8) floats
681 possibleMRegs FloatRep (SRegs _ floats) = [ x + 8 | x <- listBS floats]
682 possibleMRegs DoubleRep (SRegs _ floats) = [ x + 8 | x <- listBS floats]
683 possibleMRegs _ (SRegs ints _) = listBS ints
685 useMReg (SRegs ints floats) n =
686 if n _LT_ ILIT(8) then SRegs (ints `minusBS` singletonBS IBOX(n)) floats
687 else SRegs ints (floats `minusBS` singletonBS (IBOX(n _SUB_ ILIT(8))))
689 useMRegs (SRegs ints floats) xs =
690 SRegs (ints `minusBS` ints')
691 (floats `minusBS` floats')
693 SRegs ints' floats' = mkMRegs xs
695 freeMReg (SRegs ints floats) n =
696 if n _LT_ ILIT(8) then SRegs (ints `unionBS` singletonBS IBOX(n)) floats
697 else SRegs ints (floats `unionBS` singletonBS (IBOX(n _SUB_ ILIT(8))))
699 freeMRegs (SRegs ints floats) xs =
700 SRegs (ints `unionBS` ints')
701 (floats `unionBS` floats')
703 SRegs ints' floats' = mkMRegs xs
705 instance MachineCode I386Instr where
706 regUsage = i386RegUsage
707 regLiveness = i386RegLiveness
708 patchRegs = i386PatchRegs
710 -- We spill just below the stack pointer, leaving two words per spill location.
711 spillReg dyn (MemoryReg i pk)
713 (mkUnitList (MOV (kindToSize pk) (OpReg dyn) (OpAddr (spRel (-2 * i)))))
714 loadReg (MemoryReg i pk) dyn
716 (mkUnitList (MOV (kindToSize pk) (OpAddr (spRel (-2 * i))) (OpReg dyn)))
718 --spRel gives us a stack relative addressing mode for volatile temporaries
719 --and for excess call arguments.
722 :: Int -- desired stack offset in words, positive or negative
724 spRel n = Addr (Just esp) Nothing (ImmInt (n * 4))
726 kindToSize :: PrimRep -> Size
727 kindToSize PtrRep = L
728 kindToSize CodePtrRep = L
729 kindToSize DataPtrRep = L
730 kindToSize RetRep = L
731 kindToSize CostCentreRep = L
732 kindToSize CharRep = L
733 kindToSize IntRep = L
734 kindToSize WordRep = L
735 kindToSize AddrRep = L
736 kindToSize FloatRep = F
737 kindToSize DoubleRep = D
738 kindToSize ArrayRep = L
739 kindToSize ByteArrayRep = L
740 kindToSize StablePtrRep = L
741 kindToSize MallocPtrRep = L
745 @i386RegUsage@ returns the sets of src and destination registers used by
746 a particular instruction. Machine registers that are pre-allocated
747 to stgRegs are filtered out, because they are uninteresting from a
748 register allocation standpoint. (We wouldn't want them to end up on
753 i386RegUsage :: I386Instr -> RegUsage
754 i386RegUsage instr = case instr of
755 MOV sz src dst -> usage2 src dst
756 MOVZX sz src dst -> usage2 src dst
757 MOVSX sz src dst -> usage2 src dst
758 LEA sz src dst -> usage2 src dst
759 ADD sz src dst -> usage2 src dst
760 SUB sz src dst -> usage2 src dst
761 IMUL sz src dst -> usage2 src dst
762 IDIV sz src -> usage (eax:edx:opToReg src) [eax,edx]
763 AND sz src dst -> usage2 src dst
764 OR sz src dst -> usage2 src dst
765 XOR sz src dst -> usage2 src dst
766 NOT sz op -> usage1 op
767 NEGI sz op -> usage1 op
768 SHL sz imm dst -> usage1 dst -- imm has to be an Imm
769 SAR sz imm dst -> usage1 dst -- imm has to be an Imm
770 SHR sz imm dst -> usage1 dst -- imm has to be an Imm
771 PUSH sz op -> usage (opToReg op) []
772 POP sz op -> usage [] (opToReg op)
773 TEST sz src dst -> usage (opToReg src ++ opToReg dst) []
774 CMP sz src dst -> usage (opToReg src ++ opToReg dst) []
775 SETCC cond op -> usage [] (opToReg op)
776 JXX cond label -> usage [] []
777 JMP op -> usage (opToReg op) freeRegs
778 CALL imm -> usage [] callClobberedRegs
779 CLTD -> usage [eax] [edx]
781 SAHF -> usage [eax] []
782 FABS -> usage [st0] [st0]
783 FADD sz src -> usage (st0:opToReg src) [st0] -- allFPRegs
784 FADDP -> usage [st0,st1] [st0] -- allFPRegs
785 FIADD sz asrc -> usage (addrToRegs asrc) [st0]
786 FCHS -> usage [st0] [st0]
787 FCOM sz src -> usage (st0:opToReg src) []
788 FCOS -> usage [st0] [st0]
789 FDIV sz src -> usage (st0:opToReg src) [st0]
790 FDIVP -> usage [st0,st1] [st0]
791 FDIVRP -> usage [st0,st1] [st0]
792 FIDIV sz asrc -> usage (addrToRegs asrc) [st0]
793 FDIVR sz src -> usage (st0:opToReg src) [st0]
794 FIDIVR sz asrc -> usage (addrToRegs asrc) [st0]
795 FICOM sz asrc -> usage (addrToRegs asrc) []
796 FILD sz asrc dst -> usage (addrToRegs asrc) [dst] -- allFPRegs
797 FIST sz adst -> usage (st0:addrToRegs adst) []
798 FLD sz src -> usage (opToReg src) [st0] -- allFPRegs
799 FLD1 -> usage [] [st0] -- allFPRegs
800 FLDZ -> usage [] [st0] -- allFPRegs
801 FMUL sz src -> usage (st0:opToReg src) [st0]
802 FMULP -> usage [st0,st1] [st0]
803 FIMUL sz asrc -> usage (addrToRegs asrc) [st0]
804 FRNDINT -> usage [st0] [st0]
805 FSIN -> usage [st0] [st0]
806 FSQRT -> usage [st0] [st0]
807 FST sz (OpReg r) -> usage [st0] [r]
808 FST sz dst -> usage (st0:opToReg dst) []
809 FSTP sz (OpReg r) -> usage [st0] [r] -- allFPRegs
810 FSTP sz dst -> usage (st0:opToReg dst) [] -- allFPRegs
811 FSUB sz src -> usage (st0:opToReg src) [st0] -- allFPRegs
812 FSUBR sz src -> usage (st0:opToReg src) [st0] -- allFPRegs
813 FISUB sz asrc -> usage (addrToRegs asrc) [st0]
814 FSUBP -> usage [st0,st1] [st0] -- allFPRegs
815 FSUBRP -> usage [st0,st1] [st0] -- allFPRegs
816 FISUBR sz asrc -> usage (addrToRegs asrc) [st0]
817 FTST -> usage [st0] []
818 FCOMP sz op -> usage (st0:opToReg op) [st0] -- allFPRegs
819 FUCOMPP -> usage [st0, st1] [] -- allFPRegs
820 FXCH -> usage [st0, st1] [st0, st1]
821 FNSTSW -> usage [] [eax]
826 usage2 :: Operand -> Operand -> RegUsage
827 usage2 op (OpReg reg) = usage (opToReg op) [reg]
828 usage2 op (OpAddr ea) = usage (opToReg op ++ addrToRegs ea) []
829 usage2 op (OpImm imm) = usage (opToReg op) []
830 usage1 :: Operand -> RegUsage
831 usage1 (OpReg reg) = usage [reg] [reg]
832 usage1 (OpAddr ea) = usage (addrToRegs ea) []
833 allFPRegs = [st0,st1,st2,st3,st4,st5,st6,st7]
834 --callClobberedRegs = [ eax, ecx, edx ] -- according to gcc, anyway.
835 callClobberedRegs = [eax]
837 -- General purpose register collecting functions.
839 opToReg (OpReg reg) = [reg]
840 opToReg (OpImm imm) = []
841 opToReg (OpAddr ea) = addrToRegs ea
843 addrToRegs (Addr base index _) = baseToReg base ++ indexToReg index
844 where baseToReg Nothing = []
845 baseToReg (Just r) = [r]
846 indexToReg Nothing = []
847 indexToReg (Just (r,_)) = [r]
848 addrToRegs (ImmAddr _ _) = []
850 usage src dst = RU (mkUniqSet (filter interesting src))
851 (mkUniqSet (filter interesting dst))
853 interesting (FixedReg _) = False
857 freeRegs = freeMappedRegs (\ x -> x) [0..15]
859 freeMappedRegs :: (Int -> Int) -> [Int] -> [Reg]
861 freeMappedRegs modify nums
866 modified_i = case (modify n) of { IBOX(x) -> x }
868 if _IS_TRUE_(freeReg modified_i) then (MappedReg modified_i) : acc else acc
870 freeSet :: UniqSet Reg
871 freeSet = mkUniqSet freeRegs
874 noUsage = RU emptyUniqSet emptyUniqSet
877 endUsage = RU emptyUniqSet freeSet
881 @i386RegLiveness@ takes future liveness information and modifies it according to
882 the semantics of branches and labels. (An out-of-line branch clobbers the liveness
883 passed back by the following instruction; a forward local branch passes back the
884 liveness from the target label; a conditional branch merges the liveness from the
885 target and the liveness from its successor; a label stashes away the current liveness
886 in the future liveness environment).
889 i386RegLiveness :: I386Instr -> RegLiveness -> RegLiveness
890 i386RegLiveness instr info@(RL live future@(FL all env)) = case instr of
892 JXX _ lbl -> RL (lookup lbl `unionUniqSets` live) future
893 JMP _ -> RL emptyUniqSet future
894 CALL _ -> RL live future
895 LABEL lbl -> RL live (FL (all `unionUniqSets` live) (addToFM env lbl live))
899 lookup lbl = case lookupFM env lbl of
901 Nothing -> trace ("Missing " ++ (uppShow 80 (pprCLabel (PprForAsm (\_->False) False id) lbl)) ++
902 " in future?") emptyUniqSet
906 @i386PatchRegs@ takes an instruction (possibly with MemoryReg/UnmappedReg registers) and
907 changes all register references according to the supplied environment.
911 i386PatchRegs :: I386Instr -> (Reg -> Reg) -> I386Instr
912 i386PatchRegs instr env = case instr of
913 MOV sz src dst -> patch2 (MOV sz) src dst
914 MOVZX sz src dst -> patch2 (MOVZX sz) src dst
915 MOVSX sz src dst -> patch2 (MOVSX sz) src dst
916 LEA sz src dst -> patch2 (LEA sz) src dst
917 ADD sz src dst -> patch2 (ADD sz) src dst
918 SUB sz src dst -> patch2 (SUB sz) src dst
919 IMUL sz src dst -> patch2 (IMUL sz) src dst
920 IDIV sz src -> patch1 (IDIV sz) src
921 AND sz src dst -> patch2 (AND sz) src dst
922 OR sz src dst -> patch2 (OR sz) src dst
923 XOR sz src dst -> patch2 (XOR sz) src dst
924 NOT sz op -> patch1 (NOT sz) op
925 NEGI sz op -> patch1 (NEGI sz) op
926 SHL sz imm dst -> patch1 (SHL sz imm) dst
927 SAR sz imm dst -> patch1 (SAR sz imm) dst
928 SHR sz imm dst -> patch1 (SHR sz imm) dst
929 TEST sz src dst -> patch2 (TEST sz) src dst
930 CMP sz src dst -> patch2 (CMP sz) src dst
931 PUSH sz op -> patch1 (PUSH sz) op
932 POP sz op -> patch1 (POP sz) op
933 SETCC cond op -> patch1 (SETCC cond) op
934 JMP op -> patch1 JMP op
935 FADD sz src -> FADD sz (patchOp src)
936 FIADD sz asrc -> FIADD sz (lookupAddr asrc)
937 FCOM sz src -> patch1 (FCOM sz) src
938 FDIV sz src -> FDIV sz (patchOp src)
939 --FDIVP sz src -> FDIVP sz (patchOp src)
940 FIDIV sz asrc -> FIDIV sz (lookupAddr asrc)
941 FDIVR sz src -> FDIVR sz (patchOp src)
942 --FDIVRP sz src -> FDIVRP sz (patchOp src)
943 FIDIVR sz asrc -> FIDIVR sz (lookupAddr asrc)
944 FICOM sz asrc -> FICOM sz (lookupAddr asrc)
945 FILD sz asrc dst -> FILD sz (lookupAddr asrc) (env dst)
946 FIST sz adst -> FIST sz (lookupAddr adst)
947 FLD sz src -> patch1 (FLD sz) (patchOp src)
948 FMUL sz src -> FMUL sz (patchOp src)
949 --FMULP sz src -> FMULP sz (patchOp src)
950 FIMUL sz asrc -> FIMUL sz (lookupAddr asrc)
951 FST sz dst -> FST sz (patchOp dst)
952 FSTP sz dst -> FSTP sz (patchOp dst)
953 FSUB sz src -> FSUB sz (patchOp src)
954 --FSUBP sz src -> FSUBP sz (patchOp src)
955 FISUB sz asrc -> FISUB sz (lookupAddr asrc)
956 FSUBR sz src -> FSUBR sz (patchOp src)
957 --FSUBRP sz src -> FSUBRP sz (patchOp src)
958 FISUBR sz asrc -> FISUBR sz (lookupAddr asrc)
959 FCOMP sz src -> FCOMP sz (patchOp src)
963 patch1 insn op = insn (patchOp op)
964 patch2 insn src dst = insn (patchOp src) (patchOp dst)
966 patchOp (OpReg reg) = OpReg (env reg)
967 patchOp (OpImm imm) = OpImm imm
968 patchOp (OpAddr ea) = OpAddr (lookupAddr ea)
970 lookupAddr (Addr base index disp)
971 = Addr (lookupBase base) (lookupIndex index) disp
972 where lookupBase Nothing = Nothing
973 lookupBase (Just r) = Just (env r)
974 lookupIndex Nothing = Nothing
975 lookupIndex (Just (r,i)) = Just (env r, i)
976 lookupAddr (ImmAddr imm off)
981 Sometimes, we want to be able to modify addresses at compile time.
982 (Okay, just for chrCode of a fetch.)
986 is13Bits :: Int -> Bool
989 is13Bits :: Integer -> Bool
992 is13Bits :: Integral a => a -> Bool
993 is13Bits x = x >= -4096 && x < 4096
995 offset :: Addr -> Int -> Maybe Addr
996 offset (Addr reg index (ImmInt n)) off
997 = Just (Addr reg index (ImmInt n2))
1000 offset (Addr reg index (ImmInteger n)) off
1001 = Just (Addr reg index (ImmInt (fromInteger n2)))
1002 where n2 = n + toInteger off
1004 offset (ImmAddr imm off1) off2
1005 = Just (ImmAddr imm off3)
1006 where off3 = off1 + off2
1008 offset _ _ = Nothing
1011 If you value your sanity, do not venture below this line.
1015 -- platform.h is generate and tells us what the target architecture is
1016 #include "../../includes/platform.h"
1017 #define STOLEN_X86_REGS 5
1018 #include "../../includes/MachRegs.h"
1019 #include "../../includes/i386-unknown-linuxaout.h"
1021 -- Redefine the literals used for I386 register names in the header
1022 -- files. Gag me with a spoon, eh?
1040 #define CALLER_SAVES_Hp
1041 -- ToDo: rm when we give esp back
1045 baseRegOffset :: MagicId -> Int
1046 baseRegOffset StkOReg = OFFSET_StkO
1047 baseRegOffset (VanillaReg _ ILIT2(1)) = OFFSET_R1
1048 baseRegOffset (VanillaReg _ ILIT2(2)) = OFFSET_R2
1049 baseRegOffset (VanillaReg _ ILIT2(3)) = OFFSET_R3
1050 baseRegOffset (VanillaReg _ ILIT2(4)) = OFFSET_R4
1051 baseRegOffset (VanillaReg _ ILIT2(5)) = OFFSET_R5
1052 baseRegOffset (VanillaReg _ ILIT2(6)) = OFFSET_R6
1053 baseRegOffset (VanillaReg _ ILIT2(7)) = OFFSET_R7
1054 baseRegOffset (VanillaReg _ ILIT2(8)) = OFFSET_R8
1055 baseRegOffset (FloatReg ILIT2(1)) = OFFSET_Flt1
1056 baseRegOffset (FloatReg ILIT2(2)) = OFFSET_Flt2
1057 baseRegOffset (FloatReg ILIT2(3)) = OFFSET_Flt3
1058 baseRegOffset (FloatReg ILIT2(4)) = OFFSET_Flt4
1059 baseRegOffset (DoubleReg ILIT2(1)) = OFFSET_Dbl1
1060 baseRegOffset (DoubleReg ILIT2(2)) = OFFSET_Dbl2
1061 baseRegOffset TagReg = OFFSET_Tag
1062 baseRegOffset RetReg = OFFSET_Ret
1063 baseRegOffset SpA = OFFSET_SpA
1064 baseRegOffset SuA = OFFSET_SuA
1065 baseRegOffset SpB = OFFSET_SpB
1066 baseRegOffset SuB = OFFSET_SuB
1067 baseRegOffset Hp = OFFSET_Hp
1068 baseRegOffset HpLim = OFFSET_HpLim
1069 baseRegOffset LivenessReg = OFFSET_Liveness
1070 --baseRegOffset ActivityReg = OFFSET_Activity
1072 baseRegOffset BaseReg = panic "baseRegOffset:BaseReg"
1073 baseRegOffset StdUpdRetVecReg = panic "baseRegOffset:StgUpdRetVecReg"
1074 baseRegOffset StkStubReg = panic "baseRegOffset:StkStubReg"
1075 baseRegOffset CurCostCentre = panic "baseRegOffset:CurCostCentre"
1076 baseRegOffset VoidReg = panic "baseRegOffset:VoidReg"
1079 callerSaves :: MagicId -> Bool
1080 #ifdef CALLER_SAVES_Base
1081 callerSaves BaseReg = True
1083 #ifdef CALLER_SAVES_StkO
1084 callerSaves StkOReg = True
1086 #ifdef CALLER_SAVES_R1
1087 callerSaves (VanillaReg _ ILIT2(1)) = True
1089 #ifdef CALLER_SAVES_R2
1090 callerSaves (VanillaReg _ ILIT2(2)) = True
1092 #ifdef CALLER_SAVES_R3
1093 callerSaves (VanillaReg _ ILIT2(3)) = True
1095 #ifdef CALLER_SAVES_R4
1096 callerSaves (VanillaReg _ ILIT2(4)) = True
1098 #ifdef CALLER_SAVES_R5
1099 callerSaves (VanillaReg _ ILIT2(5)) = True
1101 #ifdef CALLER_SAVES_R6
1102 callerSaves (VanillaReg _ ILIT2(6)) = True
1104 #ifdef CALLER_SAVES_R7
1105 callerSaves (VanillaReg _ ILIT2(7)) = True
1107 #ifdef CALLER_SAVES_R8
1108 callerSaves (VanillaReg _ ILIT2(8)) = True
1110 #ifdef CALLER_SAVES_FltReg1
1111 callerSaves (FloatReg ILIT2(1)) = True
1113 #ifdef CALLER_SAVES_FltReg2
1114 callerSaves (FloatReg ILIT2(2)) = True
1116 #ifdef CALLER_SAVES_FltReg3
1117 callerSaves (FloatReg ILIT2(3)) = True
1119 #ifdef CALLER_SAVES_FltReg4
1120 callerSaves (FloatReg ILIT2(4)) = True
1122 #ifdef CALLER_SAVES_DblReg1
1123 callerSaves (DoubleReg ILIT2(1)) = True
1125 #ifdef CALLER_SAVES_DblReg2
1126 callerSaves (DoubleReg ILIT2(2)) = True
1128 #ifdef CALLER_SAVES_Tag
1129 callerSaves TagReg = True
1131 #ifdef CALLER_SAVES_Ret
1132 callerSaves RetReg = True
1134 #ifdef CALLER_SAVES_SpA
1135 callerSaves SpA = True
1137 #ifdef CALLER_SAVES_SuA
1138 callerSaves SuA = True
1140 #ifdef CALLER_SAVES_SpB
1141 callerSaves SpB = True
1143 #ifdef CALLER_SAVES_SuB
1144 callerSaves SuB = True
1146 #ifdef CALLER_SAVES_Hp
1147 callerSaves Hp = True
1149 #ifdef CALLER_SAVES_HpLim
1150 callerSaves HpLim = True
1152 #ifdef CALLER_SAVES_Liveness
1153 callerSaves LivenessReg = True
1155 #ifdef CALLER_SAVES_Activity
1156 --callerSaves ActivityReg = True
1158 #ifdef CALLER_SAVES_StdUpdRetVec
1159 callerSaves StdUpdRetVecReg = True
1161 #ifdef CALLER_SAVES_StkStub
1162 callerSaves StkStubReg = True
1164 callerSaves _ = False
1166 stgRegMap :: MagicId -> Maybe Reg
1169 stgRegMap BaseReg = Just (FixedReg ILIT(REG_Base))
1172 stgRegMap StkOReg = Just (FixedReg ILIT(REG_StkOReg))
1175 stgRegMap (VanillaReg _ ILIT2(1)) = Just (FixedReg ILIT(REG_R1))
1178 stgRegMap (VanillaReg _ ILIT2(2)) = Just (FixedReg ILIT(REG_R2))
1181 stgRegMap (VanillaReg _ ILIT2(3)) = Just (FixedReg ILIT(REG_R3))
1184 stgRegMap (VanillaReg _ ILIT2(4)) = Just (FixedReg ILIT(REG_R4))
1187 stgRegMap (VanillaReg _ ILIT2(5)) = Just (FixedReg ILIT(REG_R5))
1190 stgRegMap (VanillaReg _ ILIT2(6)) = Just (FixedReg ILIT(REG_R6))
1193 stgRegMap (VanillaReg _ ILIT2(7)) = Just (FixedReg ILIT(REG_R7))
1196 stgRegMap (VanillaReg _ ILIT2(8)) = Just (FixedReg ILIT(REG_R8))
1199 stgRegMap (FloatReg ILIT2(1)) = Just (FixedReg ILIT(REG_Flt1))
1202 stgRegMap (FloatReg ILIT2(2)) = Just (FixedReg ILIT(REG_Flt2))
1205 stgRegMap (FloatReg ILIT2(3)) = Just (FixedReg ILIT(REG_Flt3))
1208 stgRegMap (FloatReg ILIT2(4)) = Just (FixedReg ILIT(REG_Flt4))
1211 stgRegMap (DoubleReg ILIT2(1)) = Just (FixedReg ILIT(REG_Dbl1))
1214 stgRegMap (DoubleReg ILIT2(2)) = Just (FixedReg ILIT(REG_Dbl2))
1217 stgRegMap TagReg = Just (FixedReg ILIT(REG_TagReg))
1220 stgRegMap RetReg = Just (FixedReg ILIT(REG_Ret))
1223 stgRegMap SpA = Just (FixedReg ILIT(REG_SpA))
1226 stgRegMap SuA = Just (FixedReg ILIT(REG_SuA))
1229 stgRegMap SpB = Just (FixedReg ILIT(REG_SpB))
1232 stgRegMap SuB = Just (FixedReg ILIT(REG_SuB))
1235 stgRegMap Hp = Just (FixedReg ILIT(REG_Hp))
1238 stgRegMap HpLim = Just (FixedReg ILIT(REG_HpLim))
1241 stgRegMap LivenessReg = Just (FixedReg ILIT(REG_Liveness))
1244 --stgRegMap ActivityReg = Just (FixedReg ILIT(REG_Activity))
1246 #ifdef REG_StdUpdRetVec
1247 stgRegMap StdUpdRetVecReg = Just (FixedReg ILIT(REG_StdUpdRetVec))
1250 stgRegMap StkStubReg = Just (FixedReg ILIT(REG_StkStub))
1253 stgRegMap _ = Nothing
1257 Here is the list of registers we can use in register allocation.
1260 freeReg :: FAST_INT -> FAST_BOOL
1262 --freeReg ILIT(esp) = _FALSE_ -- %esp is our stack pointer.
1265 freeReg ILIT(REG_Base) = _FALSE_
1268 freeReg ILIT(REG_StkO) = _FALSE_
1271 freeReg ILIT(REG_R1) = _FALSE_
1274 freeReg ILIT(REG_R2) = _FALSE_
1277 freeReg ILIT(REG_R3) = _FALSE_
1280 freeReg ILIT(REG_R4) = _FALSE_
1283 freeReg ILIT(REG_R5) = _FALSE_
1286 freeReg ILIT(REG_R6) = _FALSE_
1289 freeReg ILIT(REG_R7) = _FALSE_
1292 freeReg ILIT(REG_R8) = _FALSE_
1295 freeReg ILIT(REG_Flt1) = _FALSE_
1298 freeReg ILIT(REG_Flt2) = _FALSE_
1301 freeReg ILIT(REG_Flt3) = _FALSE_
1304 freeReg ILIT(REG_Flt4) = _FALSE_
1307 freeReg ILIT(REG_Dbl1) = _FALSE_
1310 freeReg ILIT(REG_Dbl2) = _FALSE_
1313 freeReg ILIT(REG_Tag) = _FALSE_
1316 freeReg ILIT(REG_Ret) = _FALSE_
1319 freeReg ILIT(REG_SpA) = _FALSE_
1322 freeReg ILIT(REG_SuA) = _FALSE_
1325 freeReg ILIT(REG_SpB) = _FALSE_
1328 freeReg ILIT(REG_SuB) = _FALSE_
1331 freeReg ILIT(REG_Hp) = _FALSE_
1334 freeReg ILIT(REG_HpLim) = _FALSE_
1337 freeReg ILIT(REG_Liveness) = _FALSE_
1340 --freeReg ILIT(REG_Activity) = _FALSE_
1342 #ifdef REG_StdUpdRetVec
1343 freeReg ILIT(REG_StdUpdRetVec) = _FALSE_
1346 freeReg ILIT(REG_StkStub) = _FALSE_
1350 | n _EQ_ (ILIT(REG_Dbl1) _ADD_ ILIT(1)) = _FALSE_
1353 | n _EQ_ (ILIT(REG_Dbl2) _ADD_ ILIT(1)) = _FALSE_
1356 | otherwise = _TRUE_
1358 reservedRegs :: [Int]
1360 --reservedRegs = [NCG_Reserved_I1, NCG_Reserved_I2,
1361 -- NCG_Reserved_F1, NCG_Reserved_F2,
1362 -- NCG_Reserved_D1, NCG_Reserved_D2]