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,
16 strImmLit, --UNUSED: strImmLab,
21 baseRegOffset, stgRegMap, callerSaves,
27 st0, st1, eax, ebx, ecx, edx, esi, edi, ebp, esp,
29 freeRegs, reservedRegs,
31 -- and, for self-sufficiency ...
32 CLabel, CodeSegment, OrdList, PrimKind, Reg, UniqSet(..),
33 UniqFM, FiniteMap, Unique, MagicId, CSeq, BitSet
38 import AbsCSyn ( MagicId(..) )
39 import AsmRegAlloc ( MachineCode(..), MachineRegisters(..), FutureLive(..),
40 Reg(..), RegUsage(..), RegLiveness(..)
43 import CgCompInfo ( mAX_Double_REG, mAX_Float_REG, mAX_Vanilla_REG )
44 import CLabelInfo ( CLabel, pprCLabel, externallyVisibleCLabel, charToC )
46 import Maybes ( Maybe(..), maybeToBool )
47 import OrdList ( OrdList, mkUnitList, flattenOrdList )
49 import PrimKind ( PrimKind(..) )
56 %************************************************************************
58 \subsection[I386Reg]{The Native (I386) Machine Register Table}
60 %************************************************************************
62 - All registers except 7 (esp) are available for use.
63 - Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
64 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
65 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
66 - Registers 8-15 hold extended floating point values.
68 ToDo: Deal with stg registers that live as offsets from BaseReg!(JSM)
72 gReg,fReg :: Int -> Int
76 st0, st1, st2, st3, st4, st5, st6, st7, eax, ebx, ecx, edx, esp :: Reg
77 eax = case (gReg 0) of { IBOX(g0) -> FixedReg g0 }
78 ebx = case (gReg 1) of { IBOX(g1) -> FixedReg g1 }
79 ecx = case (gReg 2) of { IBOX(g2) -> FixedReg g2 }
80 edx = case (gReg 3) of { IBOX(g3) -> FixedReg g3 }
81 esi = case (gReg 4) of { IBOX(g4) -> FixedReg g4 }
82 edi = case (gReg 5) of { IBOX(g5) -> FixedReg g5 }
83 ebp = case (gReg 6) of { IBOX(g6) -> FixedReg g6 }
84 esp = case (gReg 7) of { IBOX(g7) -> FixedReg g7 }
85 st0 = realReg (fReg 0)
86 st1 = realReg (fReg 1)
87 st2 = realReg (fReg 2)
88 st3 = realReg (fReg 3)
89 st4 = realReg (fReg 4)
90 st5 = realReg (fReg 5)
91 st6 = realReg (fReg 6)
92 st7 = realReg (fReg 7)
94 realReg n@IBOX(i) = if _IS_TRUE_(freeReg i) then MappedReg i else FixedReg i
98 %************************************************************************
100 \subsection[TheI386Code]{The datatype for i386 assembly language}
102 %************************************************************************
104 Here is a definition of the I386 assembly language.
108 data Imm = ImmInt Int
109 | ImmInteger Integer -- Sigh.
110 | ImmCLbl CLabel -- AbstractC Label (with baggage)
111 | ImmLab Unpretty -- Simple string label (underscored)
112 | ImmLit Unpretty -- Simple string
115 --UNUSED:strImmLab s = ImmLab (uppStr s)
116 strImmLit s = ImmLit (uppStr s)
142 data Operand = OpReg Reg -- register
143 | OpImm Imm -- immediate value
144 | OpAddr Addr -- memory reference
147 data Addr = Addr Base Index Displacement
151 type Base = Maybe Reg
152 type Index = Maybe (Reg, Int) -- Int is 2, 4 or 8
153 type Displacement = Imm
159 MOV Size Operand Operand
160 | MOVZX Size Operand Operand -- size is the size of operand 2
161 | MOVSX Size Operand Operand -- size is the size of operand 2
163 -- Load effective address (also a very useful three-operand add instruction :-)
165 | LEA Size Operand Operand
169 | ADD Size Operand Operand
170 | SUB Size Operand Operand
172 -- Multiplication (signed and unsigned), Division (signed and unsigned),
173 -- result in %eax, %edx.
175 | IMUL Size Operand Operand
178 -- Simple bit-twiddling.
180 | AND Size Operand Operand
181 | OR Size Operand Operand
182 | XOR Size Operand Operand
184 | NEGI Size Operand -- NEG instruction (name clash with Cond)
185 | SHL Size Operand Operand -- 1st operand must be an Imm
186 | SAR Size Operand Operand -- 1st operand must be an Imm
187 | SHR Size Operand Operand -- 1st operand must be an Imm
190 -- Float Arithmetic. -- ToDo for 386
192 -- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single instructions
193 -- right up until we spit them out.
195 | SAHF -- stores ah into flags
197 | FADD Size Operand -- src
199 | FIADD Size Addr -- src
201 | FCOM Size Operand -- src
203 | FDIV Size Operand -- src
205 | FIDIV Size Addr -- src
206 | FDIVR Size Operand -- src
208 | FIDIVR Size Addr -- src
209 | FICOM Size Addr -- src
210 | FILD Size Addr Reg -- src, dst
211 | FIST Size Addr -- dst
212 | FLD Size Operand -- src
215 | FMUL Size Operand -- src
217 | FIMUL Size Addr -- src
221 | FST Size Operand -- dst
222 | FSTP Size Operand -- dst
223 | FSUB Size Operand -- src
225 | FISUB Size Addr -- src
226 | FSUBR Size Operand -- src
228 | FISUBR Size Addr -- src
230 | FCOMP Size Operand -- src
238 | TEST Size Operand Operand
239 | CMP Size Operand Operand
249 | JMP Operand -- target
250 | JXX Cond CLabel -- target
255 | CLTD -- sign extend %eax into %edx:%eax
260 | COMMENT FAST_STRING
261 | SEGMENT CodeSegment
262 | ASCII Bool String -- needs backslash conversion?
265 type I386Code = OrdList I386Instr
269 %************************************************************************
271 \subsection[TheI386Pretty]{Pretty-printing the I386 Assembly Language}
273 %************************************************************************
277 printLabeledCodes :: PprStyle -> [I386Instr] -> Unpretty
278 printLabeledCodes sty codes = uppAboves (map (pprI386Instr sty) codes)
282 Printing the pieces...
286 pprReg :: Size -> Reg -> Unpretty
288 pprReg s (FixedReg i) = pprI386Reg s i
289 pprReg s (MappedReg i) = pprI386Reg s i
290 pprReg s other = uppStr (show other) -- should only happen when debugging
292 pprI386Reg :: Size -> FAST_INT -> Unpretty
293 pprI386Reg B i = uppPStr
295 ILIT( 0) -> SLIT("%al"); ILIT( 1) -> SLIT("%bl");
296 ILIT( 2) -> SLIT("%cl"); ILIT( 3) -> SLIT("%dl");
297 _ -> SLIT("very naughty I386 byte register")
300 pprI386Reg HB i = uppPStr
302 ILIT( 0) -> SLIT("%ah"); ILIT( 1) -> SLIT("%bh");
303 ILIT( 2) -> SLIT("%ch"); ILIT( 3) -> SLIT("%dh");
304 _ -> SLIT("very naughty I386 high byte register")
307 pprI386Reg S i = uppPStr
309 ILIT( 0) -> SLIT("%ax"); ILIT( 1) -> SLIT("%bx");
310 ILIT( 2) -> SLIT("%cx"); ILIT( 3) -> SLIT("%dx");
311 ILIT( 4) -> SLIT("%si"); ILIT( 5) -> SLIT("%di");
312 ILIT( 6) -> SLIT("%bp"); ILIT( 7) -> SLIT("%sp");
313 _ -> SLIT("very naughty I386 word register")
316 pprI386Reg L i = uppPStr
318 ILIT( 0) -> SLIT("%eax"); ILIT( 1) -> SLIT("%ebx");
319 ILIT( 2) -> SLIT("%ecx"); ILIT( 3) -> SLIT("%edx");
320 ILIT( 4) -> SLIT("%esi"); ILIT( 5) -> SLIT("%edi");
321 ILIT( 6) -> SLIT("%ebp"); ILIT( 7) -> SLIT("%esp");
322 _ -> SLIT("very naughty I386 double word register")
325 pprI386Reg F i = uppPStr
328 ILIT( 8) -> SLIT("%st(0)"); ILIT( 9) -> SLIT("%st(1)");
329 ILIT(10) -> SLIT("%st(2)"); ILIT(11) -> SLIT("%st(3)");
330 ILIT(12) -> SLIT("%st(4)"); ILIT(13) -> SLIT("%st(5)");
331 ILIT(14) -> SLIT("%st(6)"); ILIT(15) -> SLIT("%st(7)");
332 _ -> SLIT("very naughty I386 float register")
335 pprI386Reg D i = uppPStr
338 ILIT( 8) -> SLIT("%st(0)"); ILIT( 9) -> SLIT("%st(1)");
339 ILIT(10) -> SLIT("%st(2)"); ILIT(11) -> SLIT("%st(3)");
340 ILIT(12) -> SLIT("%st(4)"); ILIT(13) -> SLIT("%st(5)");
341 ILIT(14) -> SLIT("%st(6)"); ILIT(15) -> SLIT("%st(7)");
342 _ -> SLIT("very naughty I386 float register")
345 pprCond :: Cond -> Unpretty -- ToDo
348 GEU -> SLIT("ae"); LU -> SLIT("b");
349 EQ -> SLIT("e"); GT -> SLIT("g");
350 GE -> SLIT("ge"); GU -> SLIT("a");
351 LT -> SLIT("l"); LE -> SLIT("le");
352 LEU -> SLIT("be"); NE -> SLIT("ne");
353 NEG -> SLIT("s"); POS -> SLIT("ns");
354 ALWAYS -> SLIT("mp"); -- hack
355 _ -> error "Spix: iI386Code: unknown conditional!"
358 pprDollImm :: PprStyle -> Imm -> Unpretty
360 pprDollImm sty i = uppBesides [ uppPStr SLIT("$"), pprImm sty i]
362 pprImm :: PprStyle -> Imm -> Unpretty
364 pprImm sty (ImmInt i) = uppInt i
365 pprImm sty (ImmInteger i) = uppInteger i
366 pprImm sty (ImmCLbl l) = pprCLabel sty l
367 pprImm sty (ImmLab l) = l
369 --pprImm (PprForAsm _ False _) (ImmLab s) = s
370 --pprImm _ (ImmLab s) = uppBeside (uppChar '_') s
372 pprImm sty (ImmLit s) = s
374 pprAddr :: PprStyle -> Addr -> Unpretty
375 pprAddr sty (ImmAddr imm off)
376 = uppBesides [pprImm sty imm,
377 if off > 0 then uppChar '+' else uppPStr SLIT(""),
378 if off == 0 then uppPStr SLIT("") else uppInt off
380 pprAddr sty (Addr Nothing Nothing displacement)
381 = uppBesides [pprDisp sty displacement]
382 pprAddr sty (Addr base index displacement)
383 = uppBesides [pprDisp sty displacement,
390 pprBase (Just r) = uppBesides [pprReg L r,
392 Nothing -> uppPStr SLIT("")
395 pprBase _ = uppPStr SLIT("")
396 pprIndex (Just (r,i)) = uppBesides [pprReg L r, uppChar ',', uppInt i]
397 pprIndex _ = uppPStr SLIT("")
399 pprDisp sty (ImmInt 0) = uppPStr SLIT("")
400 --pprDisp sty (ImmInteger 0) = uppPStr SLIT("")
401 pprDisp sty d = pprImm sty d
403 pprOperand :: PprStyle -> Size -> Operand -> Unpretty
404 pprOperand sty s (OpReg r) = pprReg s r
405 pprOperand sty s (OpImm i) = pprDollImm sty i
406 pprOperand sty s (OpAddr ea) = pprAddr sty ea
408 pprSize :: Size -> Unpretty
419 pprSizeOp :: PprStyle -> FAST_STRING -> Size -> Operand -> Unpretty
420 pprSizeOp sty name size op1 =
426 pprOperand sty size op1
429 pprSizeOpOp :: PprStyle -> FAST_STRING -> Size -> Operand -> Operand -> Unpretty
430 pprSizeOpOp sty name size op1 op2 =
436 pprOperand sty size op1,
438 pprOperand sty size op2
441 pprSizeOpReg :: PprStyle -> FAST_STRING -> Size -> Operand -> Reg -> Unpretty
442 pprSizeOpReg sty name size op1 reg =
448 pprOperand sty size op1,
453 pprSizeAddr :: PprStyle -> FAST_STRING -> Size -> Addr -> Unpretty
454 pprSizeAddr sty name size op =
463 pprSizeAddrReg :: PprStyle -> FAST_STRING -> Size -> Addr -> Reg -> Unpretty
464 pprSizeAddrReg sty name size op dst =
475 pprOpOp :: PprStyle -> FAST_STRING -> Size -> Operand -> Operand -> Unpretty
476 pprOpOp sty name size op1 op2 =
481 pprOperand sty size op1,
483 pprOperand sty size op2
486 pprSizeOpOpCoerce :: PprStyle -> FAST_STRING -> Size -> Size -> Operand -> Operand -> Unpretty
487 pprSizeOpOpCoerce sty name size1 size2 op1 op2 =
488 uppBesides [ uppChar '\t', uppPStr name, uppChar ' ',
489 pprOperand sty size1 op1,
491 pprOperand sty size2 op2
494 pprCondInstr :: PprStyle -> FAST_STRING -> Cond -> Unpretty -> Unpretty
495 pprCondInstr sty name cond arg =
496 uppBesides [ uppChar '\t', uppPStr name, pprCond cond, uppChar ' ', arg]
498 pprI386Instr :: PprStyle -> I386Instr -> Unpretty
499 pprI386Instr sty (MOV size (OpReg src) (OpReg dst)) -- hack
502 pprI386Instr sty (MOV size src dst)
503 = pprSizeOpOp sty SLIT("mov") size src dst
504 pprI386Instr sty (MOVZX size src dst) = pprSizeOpOpCoerce sty SLIT("movzx") L size src dst
505 pprI386Instr sty (MOVSX size src dst) = pprSizeOpOpCoerce sty SLIT("movxs") L size src dst
507 -- here we do some patching, since the physical registers are only set late
508 -- in the code generation.
509 pprI386Instr sty (LEA size (OpAddr (Addr src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
511 = pprSizeOpOp sty SLIT("add") size (OpReg reg2) dst
512 pprI386Instr sty (LEA size (OpAddr (Addr src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
514 = pprSizeOpOp sty SLIT("add") size (OpReg reg1) dst
515 pprI386Instr sty (LEA size (OpAddr (Addr src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
517 = pprI386Instr sty (ADD size (OpImm displ) dst)
518 pprI386Instr sty (LEA size src dst) = pprSizeOpOp sty SLIT("lea") size src dst
520 pprI386Instr sty (ADD size (OpImm (ImmInt (-1))) dst)
521 = pprSizeOp sty SLIT("dec") size dst
522 pprI386Instr sty (ADD size (OpImm (ImmInt 1)) dst)
523 = pprSizeOp sty SLIT("inc") size dst
524 pprI386Instr sty (ADD size src dst)
525 = pprSizeOpOp sty SLIT("add") size src dst
526 pprI386Instr sty (SUB size src dst) = pprSizeOpOp sty SLIT("sub") size src dst
527 pprI386Instr sty (IMUL size op1 op2) = pprSizeOpOp sty SLIT("imul") size op1 op2
528 pprI386Instr sty (IDIV size op) = pprSizeOp sty SLIT("idiv") size op
530 pprI386Instr sty (AND size src dst) = pprSizeOpOp sty SLIT("and") size src dst
531 pprI386Instr sty (OR size src dst) = pprSizeOpOp sty SLIT("or") size src dst
532 pprI386Instr sty (XOR size src dst) = pprSizeOpOp sty SLIT("xor") size src dst
533 pprI386Instr sty (NOT size op) = pprSizeOp sty SLIT("not") size op
534 pprI386Instr sty (NEGI size op) = pprSizeOp sty SLIT("neg") size op
535 pprI386Instr sty (SHL size imm dst) = pprSizeOpOp sty SLIT("shl") size imm dst
536 pprI386Instr sty (SAR size imm dst) = pprSizeOpOp sty SLIT("sar") size imm dst
537 pprI386Instr sty (SHR size imm dst) = pprSizeOpOp sty SLIT("shr") size imm dst
539 pprI386Instr sty (CMP size src dst) = pprSizeOpOp sty SLIT("cmp") size src dst
540 pprI386Instr sty (TEST size src dst) = pprSizeOpOp sty SLIT("test") size src dst
541 pprI386Instr sty (PUSH size op) = pprSizeOp sty SLIT("push") size op
542 pprI386Instr sty (POP size op) = pprSizeOp sty SLIT("pop") size op
544 pprI386Instr sty (NOP) = uppPStr SLIT("\tnop")
545 pprI386Instr sty (CLTD) = uppPStr SLIT("\tcltd")
547 pprI386Instr sty (SETCC cond op) = pprCondInstr sty SLIT("set") cond (pprOperand sty B op)
549 pprI386Instr sty (JXX cond lab) = pprCondInstr sty SLIT("j") cond (pprCLabel sty lab)
551 pprI386Instr sty (JMP (OpImm imm)) = uppBeside (uppPStr SLIT("\tjmp ")) (pprImm sty imm)
552 pprI386Instr sty (JMP op) = uppBeside (uppPStr SLIT("\tjmp *")) (pprOperand sty L op)
554 pprI386Instr sty (CALL imm) =
555 uppBesides [ uppPStr SLIT("\tcall "), pprImm sty imm ]
557 pprI386Instr sty SAHF = uppPStr SLIT("\tsahf")
558 pprI386Instr sty FABS = uppPStr SLIT("\tfabs")
560 pprI386Instr sty (FADD sz src@(OpAddr _))
561 = uppBesides [uppPStr SLIT("\tfadd"), pprSize sz, uppChar ' ', pprOperand sty sz src]
562 pprI386Instr sty (FADD sz src)
563 = uppPStr SLIT("\tfadd")
564 pprI386Instr sty FADDP
565 = uppPStr SLIT("\tfaddp")
566 pprI386Instr sty (FMUL sz src)
567 = uppBesides [uppPStr SLIT("\tfmul"), pprSize sz, uppChar ' ', pprOperand sty sz src]
568 pprI386Instr sty FMULP
569 = uppPStr SLIT("\tfmulp")
570 pprI386Instr sty (FIADD size op) = pprSizeAddr sty SLIT("fiadd") size op
571 pprI386Instr sty FCHS = uppPStr SLIT("\tfchs")
572 pprI386Instr sty (FCOM size op) = pprSizeOp sty SLIT("fcom") size op
573 pprI386Instr sty FCOS = uppPStr SLIT("\tfcos")
574 pprI386Instr sty (FIDIV size op) = pprSizeAddr sty SLIT("fidiv") size op
575 pprI386Instr sty (FDIV sz src)
576 = uppBesides [uppPStr SLIT("\tfdiv"), pprSize sz, uppChar ' ', pprOperand sty sz src]
577 pprI386Instr sty FDIVP
578 = uppPStr SLIT("\tfdivp")
579 pprI386Instr sty (FDIVR sz src)
580 = uppBesides [uppPStr SLIT("\tfdivr"), pprSize sz, uppChar ' ', pprOperand sty sz src]
581 pprI386Instr sty FDIVRP
582 = uppPStr SLIT("\tfdivpr")
583 pprI386Instr sty (FIDIVR size op) = pprSizeAddr sty SLIT("fidivr") size op
584 pprI386Instr sty (FICOM size op) = pprSizeAddr sty SLIT("ficom") size op
585 pprI386Instr sty (FILD sz op reg) = pprSizeAddrReg sty SLIT("fild") sz op reg
586 pprI386Instr sty (FIST size op) = pprSizeAddr sty SLIT("fist") size op
587 pprI386Instr sty (FLD sz (OpImm (ImmCLbl src)))
588 = uppBesides [uppPStr SLIT("\tfld"),pprSize sz,uppChar ' ',pprCLabel sty src]
589 pprI386Instr sty (FLD sz src)
590 = uppBesides [uppPStr SLIT("\tfld"),pprSize sz,uppChar ' ',pprOperand sty sz src]
591 pprI386Instr sty FLD1 = uppPStr SLIT("\tfld1")
592 pprI386Instr sty FLDZ = uppPStr SLIT("\tfldz")
593 pprI386Instr sty (FIMUL size op) = pprSizeAddr sty SLIT("fimul") size op
594 pprI386Instr sty FRNDINT = uppPStr SLIT("\tfrndint")
595 pprI386Instr sty FSIN = uppPStr SLIT("\tfsin")
596 pprI386Instr sty FSQRT = uppPStr SLIT("\tfsqrt")
597 pprI386Instr sty (FST sz dst)
598 = uppBesides [uppPStr SLIT("\tfst"), pprSize sz, uppChar ' ', pprOperand sty sz dst]
599 pprI386Instr sty (FSTP sz dst)
600 = uppBesides [uppPStr SLIT("\tfstp"), pprSize sz, uppChar ' ', pprOperand sty sz dst]
601 pprI386Instr sty (FISUB size op) = pprSizeAddr sty SLIT("fisub") size op
602 pprI386Instr sty (FSUB sz src)
603 = uppBesides [uppPStr SLIT("\tfsub"), pprSize sz, uppChar ' ', pprOperand sty sz src]
604 pprI386Instr sty FSUBP
605 = uppPStr SLIT("\tfsubp")
606 pprI386Instr sty (FSUBR size src)
607 = pprSizeOp sty SLIT("fsubr") size src
608 pprI386Instr sty FSUBRP
609 = uppPStr SLIT("\tfsubpr")
610 pprI386Instr sty (FISUBR size op)
611 = pprSizeAddr sty SLIT("fisubr") size op
612 pprI386Instr sty FTST = uppPStr SLIT("\tftst")
613 pprI386Instr sty (FCOMP sz op)
614 = uppBesides [uppPStr SLIT("\tfcomp"), pprSize sz, uppChar ' ', pprOperand sty sz op]
615 pprI386Instr sty FUCOMPP = uppPStr SLIT("\tfucompp")
616 pprI386Instr sty FXCH = uppPStr SLIT("\tfxch")
617 pprI386Instr sty FNSTSW = uppPStr SLIT("\tfnstsw %ax")
618 pprI386Instr sty FNOP = uppPStr SLIT("")
620 pprI386Instr sty (LABEL clab) =
622 if (externallyVisibleCLabel clab) then
623 uppBesides [uppPStr SLIT(".globl "), pprLab, uppChar '\n']
629 where pprLab = pprCLabel sty clab
631 pprI386Instr sty (COMMENT s) = uppBeside (uppPStr SLIT("# ")) (uppPStr s)
633 pprI386Instr sty (SEGMENT TextSegment)
634 = uppPStr SLIT(".text\n\t.align 4")
636 pprI386Instr sty (SEGMENT DataSegment)
637 = uppPStr SLIT(".data\n\t.align 2")
639 pprI386Instr sty (ASCII False str) =
641 uppStr "\t.asciz \"",
646 pprI386Instr sty (ASCII True str) = uppBeside (uppStr "\t.ascii \"") (asciify str 60)
648 asciify :: String -> Int -> Unpretty
649 asciify [] _ = uppStr ("\\0\"")
650 asciify s n | n <= 0 = uppBeside (uppStr "\"\n\t.ascii \"") (asciify s 60)
651 asciify ('\\':cs) n = uppBeside (uppStr "\\\\") (asciify cs (n-1))
652 asciify ('\"':cs) n = uppBeside (uppStr "\\\"") (asciify cs (n-1))
653 asciify (c:cs) n | isPrint c = uppBeside (uppChar c) (asciify cs (n-1))
654 asciify [c] _ = uppBeside (uppStr (charToC c)) (uppStr ("\\0\""))
655 asciify (c:(cs@(d:_))) n | isDigit d =
656 uppBeside (uppStr (charToC c)) (asciify cs 0)
658 uppBeside (uppStr (charToC c)) (asciify cs (n-1))
660 pprI386Instr sty (DATA s xs) = uppInterleave (uppChar '\n') (map pp_item xs)
661 where pp_item x = case s of
662 B -> uppBeside (uppPStr SLIT("\t.byte\t")) (pprImm sty x)
663 HB-> uppBeside (uppPStr SLIT("\t.byte\t")) (pprImm sty x)
664 S -> uppBeside (uppPStr SLIT("\t.word\t")) (pprImm sty x)
665 L -> uppBeside (uppPStr SLIT("\t.long\t")) (pprImm sty x)
666 F -> uppBeside (uppPStr SLIT("\t.long\t")) (pprImm sty x)
667 D -> uppBeside (uppPStr SLIT("\t.double\t")) (pprImm sty x)
671 %************************************************************************
673 \subsection[Schedule]{Register allocation information}
675 %************************************************************************
679 data I386Regs = SRegs BitSet BitSet
681 instance MachineRegisters I386Regs where
682 mkMRegs xs = SRegs (mkBS ints) (mkBS floats')
684 (ints, floats) = partition (< 8) xs
685 floats' = map (subtract 8) floats
687 possibleMRegs FloatKind (SRegs _ floats) = [ x + 8 | x <- listBS floats]
688 possibleMRegs DoubleKind (SRegs _ floats) = [ x + 8 | x <- listBS floats]
689 possibleMRegs _ (SRegs ints _) = listBS ints
691 useMReg (SRegs ints floats) n =
692 if n _LT_ ILIT(8) then SRegs (ints `minusBS` singletonBS IBOX(n)) floats
693 else SRegs ints (floats `minusBS` singletonBS (IBOX(n _SUB_ ILIT(8))))
695 useMRegs (SRegs ints floats) xs =
696 SRegs (ints `minusBS` ints')
697 (floats `minusBS` floats')
699 SRegs ints' floats' = mkMRegs xs
701 freeMReg (SRegs ints floats) n =
702 if n _LT_ ILIT(8) then SRegs (ints `unionBS` singletonBS IBOX(n)) floats
703 else SRegs ints (floats `unionBS` singletonBS (IBOX(n _SUB_ ILIT(8))))
705 freeMRegs (SRegs ints floats) xs =
706 SRegs (ints `unionBS` ints')
707 (floats `unionBS` floats')
709 SRegs ints' floats' = mkMRegs xs
711 instance MachineCode I386Instr where
712 -- Alas, we don't do anything clever with our OrdLists
714 -- flatten = flattenOrdList
716 regUsage = i386RegUsage
717 regLiveness = i386RegLiveness
718 patchRegs = i386PatchRegs
720 -- We spill just below the stack pointer, leaving two words per spill location.
721 spillReg dyn (MemoryReg i pk)
723 (mkUnitList (MOV (kindToSize pk) (OpReg dyn) (OpAddr (spRel (-2 * i)))))
724 loadReg (MemoryReg i pk) dyn
726 (mkUnitList (MOV (kindToSize pk) (OpAddr (spRel (-2 * i))) (OpReg dyn)))
728 --spRel gives us a stack relative addressing mode for volatile temporaries
729 --and for excess call arguments.
732 :: Int -- desired stack offset in words, positive or negative
734 spRel n = Addr (Just esp) Nothing (ImmInt (n * 4))
736 kindToSize :: PrimKind -> Size
737 kindToSize PtrKind = L
738 kindToSize CodePtrKind = L
739 kindToSize DataPtrKind = L
740 kindToSize RetKind = L
741 kindToSize InfoPtrKind = L
742 kindToSize CostCentreKind = L
743 kindToSize CharKind = L
744 kindToSize IntKind = L
745 kindToSize WordKind = L
746 kindToSize AddrKind = L
747 kindToSize FloatKind = F
748 kindToSize DoubleKind = D
749 kindToSize ArrayKind = L
750 kindToSize ByteArrayKind = L
751 kindToSize StablePtrKind = L
752 kindToSize MallocPtrKind = L
756 @i386RegUsage@ returns the sets of src and destination registers used by
757 a particular instruction. Machine registers that are pre-allocated
758 to stgRegs are filtered out, because they are uninteresting from a
759 register allocation standpoint. (We wouldn't want them to end up on
764 i386RegUsage :: I386Instr -> RegUsage
765 i386RegUsage instr = case instr of
766 MOV sz src dst -> usage2 src dst
767 MOVZX sz src dst -> usage2 src dst
768 MOVSX sz src dst -> usage2 src dst
769 LEA sz src dst -> usage2 src dst
770 ADD sz src dst -> usage2 src dst
771 SUB sz src dst -> usage2 src dst
772 IMUL sz src dst -> usage2 src dst
773 IDIV sz src -> usage (eax:edx:opToReg src) [eax,edx]
774 AND sz src dst -> usage2 src dst
775 OR sz src dst -> usage2 src dst
776 XOR sz src dst -> usage2 src dst
777 NOT sz op -> usage1 op
778 NEGI sz op -> usage1 op
779 SHL sz imm dst -> usage1 dst -- imm has to be an Imm
780 SAR sz imm dst -> usage1 dst -- imm has to be an Imm
781 SHR sz imm dst -> usage1 dst -- imm has to be an Imm
782 PUSH sz op -> usage (opToReg op) []
783 POP sz op -> usage [] (opToReg op)
784 TEST sz src dst -> usage (opToReg src ++ opToReg dst) []
785 CMP sz src dst -> usage (opToReg src ++ opToReg dst) []
786 SETCC cond op -> usage [] (opToReg op)
787 JXX cond label -> usage [] []
788 JMP op -> usage (opToReg op) freeRegs
789 CALL imm -> usage [] callClobberedRegs
790 CLTD -> usage [eax] [edx]
792 SAHF -> usage [eax] []
793 FABS -> usage [st0] [st0]
794 FADD sz src -> usage (st0:opToReg src) [st0] -- allFPRegs
795 FADDP -> usage [st0,st1] [st0] -- allFPRegs
796 FIADD sz asrc -> usage (addrToRegs asrc) [st0]
797 FCHS -> usage [st0] [st0]
798 FCOM sz src -> usage (st0:opToReg src) []
799 FCOS -> usage [st0] [st0]
800 FDIV sz src -> usage (st0:opToReg src) [st0]
801 FDIVP -> usage [st0,st1] [st0]
802 FDIVRP -> usage [st0,st1] [st0]
803 FIDIV sz asrc -> usage (addrToRegs asrc) [st0]
804 FDIVR sz src -> usage (st0:opToReg src) [st0]
805 FIDIVR sz asrc -> usage (addrToRegs asrc) [st0]
806 FICOM sz asrc -> usage (addrToRegs asrc) []
807 FILD sz asrc dst -> usage (addrToRegs asrc) [dst] -- allFPRegs
808 FIST sz adst -> usage (st0:addrToRegs adst) []
809 FLD sz src -> usage (opToReg src) [st0] -- allFPRegs
810 FLD1 -> usage [] [st0] -- allFPRegs
811 FLDZ -> usage [] [st0] -- allFPRegs
812 FMUL sz src -> usage (st0:opToReg src) [st0]
813 FMULP -> usage [st0,st1] [st0]
814 FIMUL sz asrc -> usage (addrToRegs asrc) [st0]
815 FRNDINT -> usage [st0] [st0]
816 FSIN -> usage [st0] [st0]
817 FSQRT -> usage [st0] [st0]
818 FST sz (OpReg r) -> usage [st0] [r]
819 FST sz dst -> usage (st0:opToReg dst) []
820 FSTP sz (OpReg r) -> usage [st0] [r] -- allFPRegs
821 FSTP sz dst -> usage (st0:opToReg dst) [] -- allFPRegs
822 FSUB sz src -> usage (st0:opToReg src) [st0] -- allFPRegs
823 FSUBR sz src -> usage (st0:opToReg src) [st0] -- allFPRegs
824 FISUB sz asrc -> usage (addrToRegs asrc) [st0]
825 FSUBP -> usage [st0,st1] [st0] -- allFPRegs
826 FSUBRP -> usage [st0,st1] [st0] -- allFPRegs
827 FISUBR sz asrc -> usage (addrToRegs asrc) [st0]
828 FTST -> usage [st0] []
829 FCOMP sz op -> usage (st0:opToReg op) [st0] -- allFPRegs
830 FUCOMPP -> usage [st0, st1] [] -- allFPRegs
831 FXCH -> usage [st0, st1] [st0, st1]
832 FNSTSW -> usage [] [eax]
837 usage2 :: Operand -> Operand -> RegUsage
838 usage2 op (OpReg reg) = usage (opToReg op) [reg]
839 usage2 op (OpAddr ea) = usage (opToReg op ++ addrToRegs ea) []
840 usage2 op (OpImm imm) = usage (opToReg op) []
841 usage1 :: Operand -> RegUsage
842 usage1 (OpReg reg) = usage [reg] [reg]
843 usage1 (OpAddr ea) = usage (addrToRegs ea) []
844 allFPRegs = [st0,st1,st2,st3,st4,st5,st6,st7]
845 --callClobberedRegs = [ eax, ecx, edx ] -- according to gcc, anyway.
846 callClobberedRegs = [eax]
848 -- General purpose register collecting functions.
850 opToReg (OpReg reg) = [reg]
851 opToReg (OpImm imm) = []
852 opToReg (OpAddr ea) = addrToRegs ea
854 addrToRegs (Addr base index _) = baseToReg base ++ indexToReg index
855 where baseToReg Nothing = []
856 baseToReg (Just r) = [r]
857 indexToReg Nothing = []
858 indexToReg (Just (r,_)) = [r]
859 addrToRegs (ImmAddr _ _) = []
861 usage src dst = RU (mkUniqSet (filter interesting src))
862 (mkUniqSet (filter interesting dst))
864 interesting (FixedReg _) = False
868 freeRegs = freeMappedRegs (\ x -> x) [0..15]
870 freeMappedRegs :: (Int -> Int) -> [Int] -> [Reg]
872 freeMappedRegs modify nums
877 modified_i = case (modify n) of { IBOX(x) -> x }
879 if _IS_TRUE_(freeReg modified_i) then (MappedReg modified_i) : acc else acc
881 freeSet :: UniqSet Reg
882 freeSet = mkUniqSet freeRegs
885 noUsage = RU emptyUniqSet emptyUniqSet
888 endUsage = RU emptyUniqSet freeSet
892 @i386RegLiveness@ takes future liveness information and modifies it according to
893 the semantics of branches and labels. (An out-of-line branch clobbers the liveness
894 passed back by the following instruction; a forward local branch passes back the
895 liveness from the target label; a conditional branch merges the liveness from the
896 target and the liveness from its successor; a label stashes away the current liveness
897 in the future liveness environment).
900 i386RegLiveness :: I386Instr -> RegLiveness -> RegLiveness
901 i386RegLiveness instr info@(RL live future@(FL all env)) = case instr of
903 JXX _ lbl -> RL (lookup lbl `unionUniqSets` live) future
904 JMP _ -> RL emptyUniqSet future
905 CALL _ -> RL live future
906 LABEL lbl -> RL live (FL (all `unionUniqSets` live) (addToFM env lbl live))
910 lookup lbl = case lookupFM env lbl of
912 Nothing -> trace ("Missing " ++ (uppShow 80 (pprCLabel (PprForAsm (\_->False) False id) lbl)) ++
913 " in future?") emptyUniqSet
917 @i386PatchRegs@ takes an instruction (possibly with MemoryReg/UnmappedReg registers) and
918 changes all register references according to the supplied environment.
922 i386PatchRegs :: I386Instr -> (Reg -> Reg) -> I386Instr
923 i386PatchRegs instr env = case instr of
924 MOV sz src dst -> patch2 (MOV sz) src dst
925 MOVZX sz src dst -> patch2 (MOVZX sz) src dst
926 MOVSX sz src dst -> patch2 (MOVSX sz) src dst
927 LEA sz src dst -> patch2 (LEA sz) src dst
928 ADD sz src dst -> patch2 (ADD sz) src dst
929 SUB sz src dst -> patch2 (SUB sz) src dst
930 IMUL sz src dst -> patch2 (IMUL sz) src dst
931 IDIV sz src -> patch1 (IDIV sz) src
932 AND sz src dst -> patch2 (AND sz) src dst
933 OR sz src dst -> patch2 (OR sz) src dst
934 XOR sz src dst -> patch2 (XOR sz) src dst
935 NOT sz op -> patch1 (NOT sz) op
936 NEGI sz op -> patch1 (NEGI sz) op
937 SHL sz imm dst -> patch1 (SHL sz imm) dst
938 SAR sz imm dst -> patch1 (SAR sz imm) dst
939 SHR sz imm dst -> patch1 (SHR sz imm) dst
940 TEST sz src dst -> patch2 (TEST sz) src dst
941 CMP sz src dst -> patch2 (CMP sz) src dst
942 PUSH sz op -> patch1 (PUSH sz) op
943 POP sz op -> patch1 (POP sz) op
944 SETCC cond op -> patch1 (SETCC cond) op
945 JMP op -> patch1 JMP op
946 FADD sz src -> FADD sz (patchOp src)
947 FIADD sz asrc -> FIADD sz (lookupAddr asrc)
948 FCOM sz src -> patch1 (FCOM sz) src
949 FDIV sz src -> FDIV sz (patchOp src)
950 --FDIVP sz src -> FDIVP sz (patchOp src)
951 FIDIV sz asrc -> FIDIV sz (lookupAddr asrc)
952 FDIVR sz src -> FDIVR sz (patchOp src)
953 --FDIVRP sz src -> FDIVRP sz (patchOp src)
954 FIDIVR sz asrc -> FIDIVR sz (lookupAddr asrc)
955 FICOM sz asrc -> FICOM sz (lookupAddr asrc)
956 FILD sz asrc dst -> FILD sz (lookupAddr asrc) (env dst)
957 FIST sz adst -> FIST sz (lookupAddr adst)
958 FLD sz src -> patch1 (FLD sz) (patchOp src)
959 FMUL sz src -> FMUL sz (patchOp src)
960 --FMULP sz src -> FMULP sz (patchOp src)
961 FIMUL sz asrc -> FIMUL sz (lookupAddr asrc)
962 FST sz dst -> FST sz (patchOp dst)
963 FSTP sz dst -> FSTP sz (patchOp dst)
964 FSUB sz src -> FSUB sz (patchOp src)
965 --FSUBP sz src -> FSUBP sz (patchOp src)
966 FISUB sz asrc -> FISUB sz (lookupAddr asrc)
967 FSUBR sz src -> FSUBR sz (patchOp src)
968 --FSUBRP sz src -> FSUBRP sz (patchOp src)
969 FISUBR sz asrc -> FISUBR sz (lookupAddr asrc)
970 FCOMP sz src -> FCOMP sz (patchOp src)
974 patch1 insn op = insn (patchOp op)
975 patch2 insn src dst = insn (patchOp src) (patchOp dst)
977 patchOp (OpReg reg) = OpReg (env reg)
978 patchOp (OpImm imm) = OpImm imm
979 patchOp (OpAddr ea) = OpAddr (lookupAddr ea)
981 lookupAddr (Addr base index disp)
982 = Addr (lookupBase base) (lookupIndex index) disp
983 where lookupBase Nothing = Nothing
984 lookupBase (Just r) = Just (env r)
985 lookupIndex Nothing = Nothing
986 lookupIndex (Just (r,i)) = Just (env r, i)
987 lookupAddr (ImmAddr imm off)
992 Sometimes, we want to be able to modify addresses at compile time.
993 (Okay, just for chrCode of a fetch.)
997 #ifdef __GLASGOW_HASKELL__
1000 is13Bits :: Int -> Bool
1003 is13Bits :: Integer -> Bool
1008 is13Bits :: Integral a => a -> Bool
1009 is13Bits x = x >= -4096 && x < 4096
1011 offset :: Addr -> Int -> Maybe Addr
1012 offset (Addr reg index (ImmInt n)) off
1013 = Just (Addr reg index (ImmInt n2))
1016 offset (Addr reg index (ImmInteger n)) off
1017 = Just (Addr reg index (ImmInt (fromInteger n2)))
1018 where n2 = n + toInteger off
1020 offset (ImmAddr imm off1) off2
1021 = Just (ImmAddr imm off3)
1022 where off3 = off1 + off2
1024 offset _ _ = Nothing
1028 If you value your sanity, do not venture below this line.
1032 -- platform.h is generate and tells us what the target architecture is
1033 #include "../../includes/platform.h"
1034 #define STOLEN_X86_REGS 5
1035 #include "../../includes/MachRegs.h"
1036 #include "../../includes/i386-unknown-linuxaout.h"
1038 -- Redefine the literals used for I386 register names in the header
1039 -- files. Gag me with a spoon, eh?
1057 #define CALLER_SAVES_Hp
1058 -- ToDo: rm when we give esp back
1062 baseRegOffset :: MagicId -> Int
1063 baseRegOffset StkOReg = OFFSET_StkO
1064 baseRegOffset (VanillaReg _ ILIT2(1)) = OFFSET_R1
1065 baseRegOffset (VanillaReg _ ILIT2(2)) = OFFSET_R2
1066 baseRegOffset (VanillaReg _ ILIT2(3)) = OFFSET_R3
1067 baseRegOffset (VanillaReg _ ILIT2(4)) = OFFSET_R4
1068 baseRegOffset (VanillaReg _ ILIT2(5)) = OFFSET_R5
1069 baseRegOffset (VanillaReg _ ILIT2(6)) = OFFSET_R6
1070 baseRegOffset (VanillaReg _ ILIT2(7)) = OFFSET_R7
1071 baseRegOffset (VanillaReg _ ILIT2(8)) = OFFSET_R8
1072 baseRegOffset (FloatReg ILIT2(1)) = OFFSET_Flt1
1073 baseRegOffset (FloatReg ILIT2(2)) = OFFSET_Flt2
1074 baseRegOffset (FloatReg ILIT2(3)) = OFFSET_Flt3
1075 baseRegOffset (FloatReg ILIT2(4)) = OFFSET_Flt4
1076 baseRegOffset (DoubleReg ILIT2(1)) = OFFSET_Dbl1
1077 baseRegOffset (DoubleReg ILIT2(2)) = OFFSET_Dbl2
1078 baseRegOffset TagReg = OFFSET_Tag
1079 baseRegOffset RetReg = OFFSET_Ret
1080 baseRegOffset SpA = OFFSET_SpA
1081 baseRegOffset SuA = OFFSET_SuA
1082 baseRegOffset SpB = OFFSET_SpB
1083 baseRegOffset SuB = OFFSET_SuB
1084 baseRegOffset Hp = OFFSET_Hp
1085 baseRegOffset HpLim = OFFSET_HpLim
1086 baseRegOffset LivenessReg = OFFSET_Liveness
1087 --baseRegOffset ActivityReg = OFFSET_Activity
1089 baseRegOffset BaseReg = panic "baseRegOffset:BaseReg"
1090 baseRegOffset StdUpdRetVecReg = panic "baseRegOffset:StgUpdRetVecReg"
1091 baseRegOffset StkStubReg = panic "baseRegOffset:StkStubReg"
1092 baseRegOffset CurCostCentre = panic "baseRegOffset:CurCostCentre"
1093 baseRegOffset VoidReg = panic "baseRegOffset:VoidReg"
1096 callerSaves :: MagicId -> Bool
1097 #ifdef CALLER_SAVES_Base
1098 callerSaves BaseReg = True
1100 #ifdef CALLER_SAVES_StkO
1101 callerSaves StkOReg = True
1103 #ifdef CALLER_SAVES_R1
1104 callerSaves (VanillaReg _ ILIT2(1)) = True
1106 #ifdef CALLER_SAVES_R2
1107 callerSaves (VanillaReg _ ILIT2(2)) = True
1109 #ifdef CALLER_SAVES_R3
1110 callerSaves (VanillaReg _ ILIT2(3)) = True
1112 #ifdef CALLER_SAVES_R4
1113 callerSaves (VanillaReg _ ILIT2(4)) = True
1115 #ifdef CALLER_SAVES_R5
1116 callerSaves (VanillaReg _ ILIT2(5)) = True
1118 #ifdef CALLER_SAVES_R6
1119 callerSaves (VanillaReg _ ILIT2(6)) = True
1121 #ifdef CALLER_SAVES_R7
1122 callerSaves (VanillaReg _ ILIT2(7)) = True
1124 #ifdef CALLER_SAVES_R8
1125 callerSaves (VanillaReg _ ILIT2(8)) = True
1127 #ifdef CALLER_SAVES_FltReg1
1128 callerSaves (FloatReg ILIT2(1)) = True
1130 #ifdef CALLER_SAVES_FltReg2
1131 callerSaves (FloatReg ILIT2(2)) = True
1133 #ifdef CALLER_SAVES_FltReg3
1134 callerSaves (FloatReg ILIT2(3)) = True
1136 #ifdef CALLER_SAVES_FltReg4
1137 callerSaves (FloatReg ILIT2(4)) = True
1139 #ifdef CALLER_SAVES_DblReg1
1140 callerSaves (DoubleReg ILIT2(1)) = True
1142 #ifdef CALLER_SAVES_DblReg2
1143 callerSaves (DoubleReg ILIT2(2)) = True
1145 #ifdef CALLER_SAVES_Tag
1146 callerSaves TagReg = True
1148 #ifdef CALLER_SAVES_Ret
1149 callerSaves RetReg = True
1151 #ifdef CALLER_SAVES_SpA
1152 callerSaves SpA = True
1154 #ifdef CALLER_SAVES_SuA
1155 callerSaves SuA = True
1157 #ifdef CALLER_SAVES_SpB
1158 callerSaves SpB = True
1160 #ifdef CALLER_SAVES_SuB
1161 callerSaves SuB = True
1163 #ifdef CALLER_SAVES_Hp
1164 callerSaves Hp = True
1166 #ifdef CALLER_SAVES_HpLim
1167 callerSaves HpLim = True
1169 #ifdef CALLER_SAVES_Liveness
1170 callerSaves LivenessReg = True
1172 #ifdef CALLER_SAVES_Activity
1173 --callerSaves ActivityReg = True
1175 #ifdef CALLER_SAVES_StdUpdRetVec
1176 callerSaves StdUpdRetVecReg = True
1178 #ifdef CALLER_SAVES_StkStub
1179 callerSaves StkStubReg = True
1181 callerSaves _ = False
1183 stgRegMap :: MagicId -> Maybe Reg
1186 stgRegMap BaseReg = Just (FixedReg ILIT(REG_Base))
1189 stgRegMap StkOReg = Just (FixedReg ILIT(REG_StkOReg))
1192 stgRegMap (VanillaReg _ ILIT2(1)) = Just (FixedReg ILIT(REG_R1))
1195 stgRegMap (VanillaReg _ ILIT2(2)) = Just (FixedReg ILIT(REG_R2))
1198 stgRegMap (VanillaReg _ ILIT2(3)) = Just (FixedReg ILIT(REG_R3))
1201 stgRegMap (VanillaReg _ ILIT2(4)) = Just (FixedReg ILIT(REG_R4))
1204 stgRegMap (VanillaReg _ ILIT2(5)) = Just (FixedReg ILIT(REG_R5))
1207 stgRegMap (VanillaReg _ ILIT2(6)) = Just (FixedReg ILIT(REG_R6))
1210 stgRegMap (VanillaReg _ ILIT2(7)) = Just (FixedReg ILIT(REG_R7))
1213 stgRegMap (VanillaReg _ ILIT2(8)) = Just (FixedReg ILIT(REG_R8))
1216 stgRegMap (FloatReg ILIT2(1)) = Just (FixedReg ILIT(REG_Flt1))
1219 stgRegMap (FloatReg ILIT2(2)) = Just (FixedReg ILIT(REG_Flt2))
1222 stgRegMap (FloatReg ILIT2(3)) = Just (FixedReg ILIT(REG_Flt3))
1225 stgRegMap (FloatReg ILIT2(4)) = Just (FixedReg ILIT(REG_Flt4))
1228 stgRegMap (DoubleReg ILIT2(1)) = Just (FixedReg ILIT(REG_Dbl1))
1231 stgRegMap (DoubleReg ILIT2(2)) = Just (FixedReg ILIT(REG_Dbl2))
1234 stgRegMap TagReg = Just (FixedReg ILIT(REG_TagReg))
1237 stgRegMap RetReg = Just (FixedReg ILIT(REG_Ret))
1240 stgRegMap SpA = Just (FixedReg ILIT(REG_SpA))
1243 stgRegMap SuA = Just (FixedReg ILIT(REG_SuA))
1246 stgRegMap SpB = Just (FixedReg ILIT(REG_SpB))
1249 stgRegMap SuB = Just (FixedReg ILIT(REG_SuB))
1252 stgRegMap Hp = Just (FixedReg ILIT(REG_Hp))
1255 stgRegMap HpLim = Just (FixedReg ILIT(REG_HpLim))
1258 stgRegMap LivenessReg = Just (FixedReg ILIT(REG_Liveness))
1261 --stgRegMap ActivityReg = Just (FixedReg ILIT(REG_Activity))
1263 #ifdef REG_StdUpdRetVec
1264 stgRegMap StdUpdRetVecReg = Just (FixedReg ILIT(REG_StdUpdRetVec))
1267 stgRegMap StkStubReg = Just (FixedReg ILIT(REG_StkStub))
1270 stgRegMap _ = Nothing
1274 Here is the list of registers we can use in register allocation.
1277 freeReg :: FAST_INT -> FAST_BOOL
1279 --freeReg ILIT(esp) = _FALSE_ -- %esp is our stack pointer.
1282 freeReg ILIT(REG_Base) = _FALSE_
1285 freeReg ILIT(REG_StkO) = _FALSE_
1288 freeReg ILIT(REG_R1) = _FALSE_
1291 freeReg ILIT(REG_R2) = _FALSE_
1294 freeReg ILIT(REG_R3) = _FALSE_
1297 freeReg ILIT(REG_R4) = _FALSE_
1300 freeReg ILIT(REG_R5) = _FALSE_
1303 freeReg ILIT(REG_R6) = _FALSE_
1306 freeReg ILIT(REG_R7) = _FALSE_
1309 freeReg ILIT(REG_R8) = _FALSE_
1312 freeReg ILIT(REG_Flt1) = _FALSE_
1315 freeReg ILIT(REG_Flt2) = _FALSE_
1318 freeReg ILIT(REG_Flt3) = _FALSE_
1321 freeReg ILIT(REG_Flt4) = _FALSE_
1324 freeReg ILIT(REG_Dbl1) = _FALSE_
1327 freeReg ILIT(REG_Dbl2) = _FALSE_
1330 freeReg ILIT(REG_Tag) = _FALSE_
1333 freeReg ILIT(REG_Ret) = _FALSE_
1336 freeReg ILIT(REG_SpA) = _FALSE_
1339 freeReg ILIT(REG_SuA) = _FALSE_
1342 freeReg ILIT(REG_SpB) = _FALSE_
1345 freeReg ILIT(REG_SuB) = _FALSE_
1348 freeReg ILIT(REG_Hp) = _FALSE_
1351 freeReg ILIT(REG_HpLim) = _FALSE_
1354 freeReg ILIT(REG_Liveness) = _FALSE_
1357 --freeReg ILIT(REG_Activity) = _FALSE_
1359 #ifdef REG_StdUpdRetVec
1360 freeReg ILIT(REG_StdUpdRetVec) = _FALSE_
1363 freeReg ILIT(REG_StkStub) = _FALSE_
1367 | n _EQ_ (ILIT(REG_Dbl1) _ADD_ ILIT(1)) = _FALSE_
1370 | n _EQ_ (ILIT(REG_Dbl2) _ADD_ ILIT(1)) = _FALSE_
1373 | otherwise = _TRUE_
1375 reservedRegs :: [Int]
1377 --reservedRegs = [NCG_Reserved_I1, NCG_Reserved_I2,
1378 -- NCG_Reserved_F1, NCG_Reserved_F2,
1379 -- NCG_Reserved_D1, NCG_Reserved_D2]