[project @ 2002-04-29 14:03:38 by simonmar]
[ghc-hetmet.git] / ghc / compiler / nativeGen / MachMisc.lhs
1 %
2 % (c) The AQUA Project, Glasgow University, 1993-1998
3 %
4 \section[MachMisc]{Description of various machine-specific things}
5
6 \begin{code}
7 #include "nativeGen/NCG.h"
8
9 module MachMisc (
10
11         primRepToSize,
12
13         eXTRA_STK_ARGS_HERE,
14
15         volatileSaves, volatileRestores,
16
17         targetMaxDouble, targetMaxInt, targetMinDouble, targetMinInt,
18
19         underscorePrefix,
20         fmtAsmLbl,
21         exactLog2,
22
23         Instr(..),  IF_ARCH_i386(Operand(..) COMMA,)
24         Cond(..),
25         Size(..),
26         IF_ARCH_i386(i386_insert_ffrees COMMA,) 
27
28 #if alpha_TARGET_ARCH
29         , RI(..)
30 #endif
31 #if i386_TARGET_ARCH
32 #endif
33 #if sparc_TARGET_ARCH
34         RI(..), riZero, fpRelEA, moveSp, fPair
35 #endif
36     ) where
37
38 #include "HsVersions.h"
39 #include "../includes/config.h"
40
41 import AbsCSyn          ( MagicId(..) ) 
42 import AbsCUtils        ( magicIdPrimRep )
43 import CLabel           ( CLabel, isAsmTemp )
44 import Literal          ( mkMachInt, Literal(..) )
45 import MachRegs         ( callerSaves,
46                           get_MagicId_addr, get_MagicId_reg_or_addr,
47                           Imm(..), Reg(..), MachRegsAddr(..)
48 #                         if sparc_TARGET_ARCH
49                           ,fp, sp
50 #                         endif
51                         )
52 import PrimRep          ( PrimRep(..) )
53 import Stix             ( StixStmt(..), StixExpr(..), StixReg(..), 
54                           CodeSegment, DestInfo(..) )
55 import Panic            ( panic )
56 import GlaExts
57 import Outputable       ( pprPanic, ppr, showSDoc )
58 import IOExts           ( trace )
59 import Config           ( cLeadingUnderscore )
60 import FastTypes
61 import FastString
62
63 import Maybe            ( catMaybes )
64 \end{code}
65
66 \begin{code}
67 underscorePrefix :: Bool   -- leading underscore on assembler labels?
68 underscorePrefix = (cLeadingUnderscore == "YES")
69
70 ---------------------------
71 fmtAsmLbl :: String -> String  -- for formatting labels
72
73 fmtAsmLbl s
74   =  IF_ARCH_alpha(
75      {- The alpha assembler likes temporary labels to look like $L123
76         instead of L123.  (Don't toss the L, because then Lf28
77         turns into $f28.)
78      -}
79      '$' : s
80      ,{-otherwise-}
81      '.':'L':s
82      )
83 \end{code}
84
85 % ----------------------------------------------------------------
86
87 We (allegedly) put the first six C-call arguments in registers;
88 where do we start putting the rest of them?
89 \begin{code}
90 eXTRA_STK_ARGS_HERE :: Int
91 eXTRA_STK_ARGS_HERE
92   = IF_ARCH_alpha(0, IF_ARCH_i386(23{-6x4bytes-}, IF_ARCH_sparc(23,???)))
93 \end{code}
94
95 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
96
97 Now the volatile saves and restores.  We add the basic guys to the
98 list of ``user'' registers provided.  Note that there are more basic
99 registers on the restore list, because some are reloaded from
100 constants.
101
102 (@volatileRestores@ used only for wrapper-hungry PrimOps.)
103
104 \begin{code}
105 volatileSaves, volatileRestores :: [MagicId] -> [StixStmt]
106
107 volatileSaves    = volatileSavesOrRestores True
108 volatileRestores = volatileSavesOrRestores False
109
110 save_cands    = [BaseReg,Sp,Su,SpLim,Hp,HpLim]
111 restore_cands = save_cands
112
113 volatileSavesOrRestores do_saves vols
114    = catMaybes (map mkCode vols)
115      where
116         mkCode mid
117            | case mid of { BaseReg -> True; _ -> False } 
118            = panic "volatileSavesOrRestores:BaseReg" 
119            | not (callerSaves mid)
120            = Nothing
121            | otherwise  -- must be callee-saves ...
122            = case get_MagicId_reg_or_addr mid of
123                 -- If stored in BaseReg, we ain't interested
124                 Right baseRegAddr 
125                    -> Nothing
126                 Left (RealReg rrno)
127                    -- OK, it's callee-saves, and in a real reg (rrno).
128                    -- We have to cook up some transfer code.
129                    {- Note that the use of (StixMagicId mid) here is a bit subtle.  
130                       Here, we only create those for MagicIds which are stored in 
131                       a real reg on this arch -- the preceding case on the result 
132                       of get_MagicId_reg_or_addr guarantees this.  Later, when 
133                       selecting insns, that means these assignments are sure to turn 
134                       into real reg-to-mem or mem-to-reg moves, rather than being 
135                       pointless moves from some address in the reg-table 
136                       back to itself.-}
137                    |  do_saves
138                    -> Just (StAssignMem rep addr 
139                                             (StReg (StixMagicId mid)))
140                    |  otherwise
141                    -> Just (StAssignReg rep (StixMagicId mid)
142                                             (StInd rep addr))
143                       where
144                          rep  = magicIdPrimRep mid
145                          addr = get_MagicId_addr mid
146 \end{code}
147
148 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
149
150 Obviously slightly weedy
151 (Note that the floating point values aren't terribly important.)
152 ToDo: Fix!(JSM)
153 \begin{code}
154 targetMinDouble = MachDouble (-1.7976931348623157e+308)
155 targetMaxDouble = MachDouble (1.7976931348623157e+308)
156 targetMinInt = mkMachInt (-2147483648)
157 targetMaxInt = mkMachInt 2147483647
158 \end{code}
159
160 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
161
162 This algorithm for determining the $\log_2$ of exact powers of 2 comes
163 from GCC.  It requires bit manipulation primitives, and we use GHC
164 extensions.  Tough.
165
166 \begin{code}
167 w2i x = word2Int# x
168 i2w x = int2Word# x
169
170 exactLog2 :: Integer -> Maybe Integer
171 exactLog2 x
172   = if (x <= 0 || x >= 2147483648) then
173        Nothing
174     else
175        case iUnbox (fromInteger x) of { x# ->
176        if (w2i ((i2w x#) `and#` (i2w (0# -# x#))) /=# x#) then
177           Nothing
178        else
179           Just (toInteger (iBox (pow2 x#)))
180        }
181   where
182     pow2 x# | x# ==# 1# = 0#
183             | otherwise = 1# +# pow2 (w2i (i2w x# `shiftRL#` 1#))
184 \end{code}
185
186 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
187
188 \begin{code}
189 data Cond
190 #if alpha_TARGET_ARCH
191   = ALWAYS      -- For BI (same as BR)
192   | EQQ         -- For CMP and BI (NB: "EQ" is a 1.3 Prelude name)
193   | GE          -- For BI only
194   | GTT         -- For BI only (NB: "GT" is a 1.3 Prelude name)
195   | LE          -- For CMP and BI
196   | LTT         -- For CMP and BI (NB: "LT" is a 1.3 Prelude name)
197   | NE          -- For BI only
198   | NEVER       -- For BI (null instruction)
199   | ULE         -- For CMP only
200   | ULT         -- For CMP only
201 #endif
202 #if i386_TARGET_ARCH
203   = ALWAYS      -- What's really used? ToDo
204   | EQQ
205   | GE
206   | GEU
207   | GTT
208   | GU
209   | LE
210   | LEU
211   | LTT
212   | LU
213   | NE
214   | NEG
215   | POS
216   | CARRY
217   | OFLO
218 #endif
219 #if sparc_TARGET_ARCH
220   = ALWAYS      -- What's really used? ToDo
221   | EQQ
222   | GE
223   | GEU
224   | GTT
225   | GU
226   | LE
227   | LEU
228   | LTT
229   | LU
230   | NE
231   | NEG
232   | NEVER
233   | POS
234   | VC
235   | VS
236 #endif
237     deriving Eq  -- to make an assertion work
238 \end{code}
239
240 \begin{code}
241 data Size
242 #if alpha_TARGET_ARCH
243     = B     -- byte
244     | Bu
245 --  | W     -- word (2 bytes): UNUSED
246 --  | Wu    -- : UNUSED
247     | L     -- longword (4 bytes)
248     | Q     -- quadword (8 bytes)
249 --  | FF    -- VAX F-style floating pt: UNUSED
250 --  | GF    -- VAX G-style floating pt: UNUSED
251 --  | DF    -- VAX D-style floating pt: UNUSED
252 --  | SF    -- IEEE single-precision floating pt: UNUSED
253     | TF    -- IEEE double-precision floating pt
254 #endif
255 #if i386_TARGET_ARCH
256     = B     -- byte (signed)
257     | Bu    -- byte (unsigned)
258     | W     -- word (signed)
259     | Wu    -- word (unsigned)
260     | L     -- longword (signed)
261     | Lu    -- longword (unsigned)
262     | F     -- IEEE single-precision floating pt
263     | DF    -- IEEE single-precision floating pt
264     | F80   -- Intel 80-bit internal FP format; only used for spilling
265 #endif
266 #if sparc_TARGET_ARCH
267     = B     -- byte (signed)
268     | Bu    -- byte (unsigned)
269     | H     -- halfword (signed, 2 bytes)
270     | Hu    -- halfword (unsigned, 2 bytes)
271     | W     -- word (4 bytes)
272     | F     -- IEEE single-precision floating pt
273     | DF    -- IEEE single-precision floating pt
274 #endif
275
276 primRepToSize :: PrimRep -> Size
277
278 primRepToSize PtrRep        = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
279 primRepToSize CodePtrRep    = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
280 primRepToSize DataPtrRep    = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
281 primRepToSize RetRep        = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
282 primRepToSize CostCentreRep = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
283 primRepToSize CharRep       = IF_ARCH_alpha(L,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
284
285 primRepToSize Int8Rep       = IF_ARCH_alpha(B,  IF_ARCH_i386(B,  IF_ARCH_sparc(B,  )))
286 primRepToSize Int16Rep      = IF_ARCH_alpha(err,IF_ARCH_i386(W,  IF_ARCH_sparc(H,  )))
287     where err = primRepToSize_fail "Int16Rep"
288 primRepToSize Int32Rep      = IF_ARCH_alpha(L,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
289 primRepToSize Word8Rep      = IF_ARCH_alpha(Bu, IF_ARCH_i386(Bu, IF_ARCH_sparc(Bu, )))
290 primRepToSize Word16Rep     = IF_ARCH_alpha(err,IF_ARCH_i386(Wu, IF_ARCH_sparc(Hu, )))
291     where err = primRepToSize_fail "Word16Rep"
292 primRepToSize Word32Rep     = IF_ARCH_alpha(L,  IF_ARCH_i386(Lu, IF_ARCH_sparc(W,  )))
293
294 primRepToSize IntRep        = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
295 primRepToSize WordRep       = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
296 primRepToSize AddrRep       = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
297 primRepToSize FloatRep      = IF_ARCH_alpha(TF, IF_ARCH_i386(F,  IF_ARCH_sparc(F,  )))
298 primRepToSize DoubleRep     = IF_ARCH_alpha(TF, IF_ARCH_i386(DF, IF_ARCH_sparc(DF, )))
299 primRepToSize ArrayRep      = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
300 primRepToSize ByteArrayRep  = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
301 primRepToSize PrimPtrRep    = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
302 primRepToSize WeakPtrRep    = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
303 primRepToSize ForeignObjRep = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
304 primRepToSize BCORep        = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
305 primRepToSize StablePtrRep  = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
306 primRepToSize StableNameRep = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
307 primRepToSize ThreadIdRep   = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
308
309 primRepToSize Word64Rep     = primRepToSize_fail "Word64Rep"
310 primRepToSize Int64Rep      = primRepToSize_fail "Int64Rep"
311 primRepToSize other         = primRepToSize_fail (showSDoc (ppr other))
312
313 primRepToSize_fail str
314    = error ("ERROR: MachMisc.primRepToSize: cannot handle `" ++ str ++ "'.\n\t" 
315             ++ "Workaround: use -fvia-C.\n\t" 
316             ++ "Perhaps you should report it as a GHC bug,\n\t" 
317             ++ "to glasgow-haskell-bugs@haskell.org.")
318
319 \end{code}
320
321 %************************************************************************
322 %*                                                                      *
323 \subsection{Machine's assembly language}
324 %*                                                                      *
325 %************************************************************************
326
327 We have a few common ``instructions'' (nearly all the pseudo-ops) but
328 mostly all of @Instr@ is machine-specific.
329
330 \begin{code}
331 data Instr
332   = COMMENT FastString          -- comment pseudo-op
333   | SEGMENT CodeSegment         -- {data,text} segment pseudo-op
334   | LABEL   CLabel              -- global label pseudo-op
335   | ASCII   Bool                -- True <=> needs backslash conversion
336             String              -- the literal string
337   | DATA    Size
338             [Imm]
339   | DELTA   Int                 -- specify current stack offset for
340                                 -- benefit of subsequent passes
341 \end{code}
342
343 \begin{code}
344 #if alpha_TARGET_ARCH
345
346 -- data Instr continues...
347
348 -- Loads and stores.
349
350               | LD            Size Reg MachRegsAddr -- size, dst, src
351               | LDA           Reg MachRegsAddr      -- dst, src
352               | LDAH          Reg MachRegsAddr      -- dst, src
353               | LDGP          Reg MachRegsAddr      -- dst, src
354               | LDI           Size Reg Imm     -- size, dst, src
355               | ST            Size Reg MachRegsAddr -- size, src, dst
356
357 -- Int Arithmetic.
358
359               | CLR           Reg                   -- dst
360               | ABS           Size RI Reg           -- size, src, dst
361               | NEG           Size Bool RI Reg      -- size, overflow, src, dst
362               | ADD           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
363               | SADD          Size Size Reg RI Reg  -- size, scale, src, src, dst
364               | SUB           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
365               | SSUB          Size Size Reg RI Reg  -- size, scale, src, src, dst
366               | MUL           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
367               | DIV           Size Bool Reg RI Reg  -- size, unsigned, src, src, dst
368               | REM           Size Bool Reg RI Reg  -- size, unsigned, src, src, dst
369
370 -- Simple bit-twiddling.
371
372               | NOT           RI Reg
373               | AND           Reg RI Reg
374               | ANDNOT        Reg RI Reg
375               | OR            Reg RI Reg
376               | ORNOT         Reg RI Reg
377               | XOR           Reg RI Reg
378               | XORNOT        Reg RI Reg
379               | SLL           Reg RI Reg
380               | SRL           Reg RI Reg
381               | SRA           Reg RI Reg
382
383               | ZAP           Reg RI Reg
384               | ZAPNOT        Reg RI Reg
385
386               | NOP
387
388 -- Comparison
389
390               | CMP           Cond Reg RI Reg
391
392 -- Float Arithmetic.
393
394               | FCLR          Reg
395               | FABS          Reg Reg
396               | FNEG          Size Reg Reg
397               | FADD          Size Reg Reg Reg
398               | FDIV          Size Reg Reg Reg
399               | FMUL          Size Reg Reg Reg
400               | FSUB          Size Reg Reg Reg
401               | CVTxy         Size Size Reg Reg
402               | FCMP          Size Cond Reg Reg Reg
403               | FMOV          Reg Reg
404
405 -- Jumping around.
406
407               | BI            Cond Reg Imm
408               | BF            Cond Reg Imm
409               | BR            Imm
410               | JMP           Reg MachRegsAddr Int
411               | BSR           Imm Int
412               | JSR           Reg MachRegsAddr Int
413
414 -- Alpha-specific pseudo-ops.
415
416               | FUNBEGIN CLabel
417               | FUNEND CLabel
418
419 data RI
420   = RIReg Reg
421   | RIImm Imm
422
423 #endif {- alpha_TARGET_ARCH -}
424 \end{code}
425
426 Intel, in their infinite wisdom, selected a stack model for floating
427 point registers on x86.  That might have made sense back in 1979 --
428 nowadays we can see it for the nonsense it really is.  A stack model
429 fits poorly with the existing nativeGen infrastructure, which assumes
430 flat integer and FP register sets.  Prior to this commit, nativeGen
431 could not generate correct x86 FP code -- to do so would have meant
432 somehow working the register-stack paradigm into the register
433 allocator and spiller, which sounds very difficult.
434   
435 We have decided to cheat, and go for a simple fix which requires no
436 infrastructure modifications, at the expense of generating ropey but
437 correct FP code.  All notions of the x86 FP stack and its insns have
438 been removed.  Instead, we pretend (to the instruction selector and
439 register allocator) that x86 has six floating point registers, %fake0
440 .. %fake5, which can be used in the usual flat manner.  We further
441 claim that x86 has floating point instructions very similar to SPARC
442 and Alpha, that is, a simple 3-operand register-register arrangement.
443 Code generation and register allocation proceed on this basis.
444   
445 When we come to print out the final assembly, our convenient fiction
446 is converted to dismal reality.  Each fake instruction is
447 independently converted to a series of real x86 instructions.
448 %fake0 .. %fake5 are mapped to %st(0) .. %st(5).  To do reg-reg
449 arithmetic operations, the two operands are pushed onto the top of the
450 FP stack, the operation done, and the result copied back into the
451 relevant register.  There are only six %fake registers because 2 are
452 needed for the translation, and x86 has 8 in total.
453
454 The translation is inefficient but is simple and it works.  A cleverer
455 translation would handle a sequence of insns, simulating the FP stack
456 contents, would not impose a fixed mapping from %fake to %st regs, and
457 hopefully could avoid most of the redundant reg-reg moves of the
458 current translation.
459
460 We might as well make use of whatever unique FP facilities Intel have
461 chosen to bless us with (let's not be churlish, after all).
462 Hence GLDZ and GLD1.  Bwahahahahahahaha!
463
464 LATER (10 Nov 2000): idiv gives problems with the register spiller,
465 because the spiller is simpleminded and because idiv has fixed uses of
466 %eax and %edx.  Rather than make the spiller cleverer, we do away with
467 idiv, and instead have iquot and irem fake (integer) insns, which have
468 no operand register constraints -- ie, they behave like add, sub, mul.
469 The printer-outer transforms them to a sequence of real insns which does
470 the Right Thing (tm).  As with the FP stuff, this gives ropey code, 
471 but we don't care, since it doesn't get used much.  We hope.
472
473 \begin{code}
474 #if i386_TARGET_ARCH
475
476 -- data Instr continues...
477
478 -- Moves.
479
480               | MOV           Size Operand Operand
481               | MOVZxL        Size Operand Operand -- size is the size of operand 1
482               | MOVSxL        Size Operand Operand -- size is the size of operand 1
483
484 -- Load effective address (also a very useful three-operand add instruction :-)
485
486               | LEA           Size Operand Operand
487
488 -- Int Arithmetic.
489
490               | ADD           Size Operand Operand
491               | SUB           Size Operand Operand
492               | IMUL          Size Operand Operand      -- signed int mul
493               | MUL           Size Operand Operand      -- unsigned int mul
494               | IMUL64        Reg Reg                   -- 32 x 32 -> 64 signed mul
495                 -- operand1:operand2 := (operand1[31:0] *signed operand2[31:0])
496
497 -- Quotient and remainder.  SEE comment above -- these are not
498 -- real x86 insns; instead they are expanded when printed
499 -- into a sequence of real insns.
500
501               | IQUOT         Size Operand Operand      -- signed quotient
502               | IREM          Size Operand Operand      -- signed remainder
503               | QUOT          Size Operand Operand      -- unsigned quotient
504               | REM           Size Operand Operand      -- unsigned remainder
505
506 -- Simple bit-twiddling.
507
508               | AND           Size Operand Operand
509               | OR            Size Operand Operand
510               | XOR           Size Operand Operand
511               | NOT           Size Operand
512               | NEGI          Size Operand -- NEG instruction (name clash with Cond)
513               | SHL           Size Imm Operand -- Only immediate shifts allowed
514               | SAR           Size Imm Operand -- Only immediate shifts allowed
515               | SHR           Size Imm Operand -- Only immediate shifts allowed
516               | BT            Size Imm Operand
517               | NOP
518
519 -- Float Arithmetic.
520
521 -- Note that we cheat by treating G{ABS,MOV,NEG} of doubles 
522 -- as single instructions right up until we spit them out.
523
524               -- all the 3-operand fake fp insns are src1 src2 dst
525               -- and furthermore are constrained to be fp regs only.
526               -- IMPORTANT: keep is_G_insn up to date with any changes here
527               | GMOV          Reg Reg -- src(fpreg), dst(fpreg)
528               | GLD           Size MachRegsAddr Reg -- src, dst(fpreg)
529               | GST           Size Reg MachRegsAddr -- src(fpreg), dst
530
531               | GLDZ          Reg -- dst(fpreg)
532               | GLD1          Reg -- dst(fpreg)
533
534               | GFTOI         Reg Reg -- src(fpreg), dst(intreg)
535               | GDTOI         Reg Reg -- src(fpreg), dst(intreg)
536
537               | GITOF         Reg Reg -- src(intreg), dst(fpreg)
538               | GITOD         Reg Reg -- src(intreg), dst(fpreg)
539
540               | GADD          Size Reg Reg Reg -- src1, src2, dst
541               | GDIV          Size Reg Reg Reg -- src1, src2, dst
542               | GSUB          Size Reg Reg Reg -- src1, src2, dst
543               | GMUL          Size Reg Reg Reg -- src1, src2, dst
544
545                 -- FP compare.  Cond must be `elem` [EQQ, NE, LE, LTT, GE, GTT]
546                 -- Compare src1 with src2; set the Zero flag iff the numbers are
547                 -- comparable and the comparison is True.  Subsequent code must
548                 -- test the %eflags zero flag regardless of the supplied Cond.
549               | GCMP          Cond Reg Reg -- src1, src2
550
551               | GABS          Size Reg Reg -- src, dst
552               | GNEG          Size Reg Reg -- src, dst
553               | GSQRT         Size Reg Reg -- src, dst
554               | GSIN          Size Reg Reg -- src, dst
555               | GCOS          Size Reg Reg -- src, dst
556               | GTAN          Size Reg Reg -- src, dst
557
558               | GFREE         -- do ffree on all x86 regs; an ugly hack
559 -- Comparison
560
561               | TEST          Size Operand Operand
562               | CMP           Size Operand Operand
563               | SETCC         Cond Operand
564
565 -- Stack Operations.
566
567               | PUSH          Size Operand
568               | POP           Size Operand
569               | PUSHA
570               | POPA
571
572 -- Jumping around.
573
574               | JMP           DestInfo Operand -- possible dests, target
575               | JXX           Cond CLabel -- target
576               | CALL          (Either Imm Reg)
577
578 -- Other things.
579
580               | CLTD -- sign extend %eax into %edx:%eax
581
582 data Operand
583   = OpReg  Reg          -- register
584   | OpImm  Imm          -- immediate value
585   | OpAddr MachRegsAddr -- memory reference
586
587
588 i386_insert_ffrees :: [Instr] -> [Instr]
589 i386_insert_ffrees insns
590    | any is_G_instr insns
591    = concatMap ffree_before_nonlocal_transfers insns
592    | otherwise
593    = insns
594
595 ffree_before_nonlocal_transfers insn
596    = case insn of
597         CALL _                                        -> [GFREE, insn]
598         -- Jumps to immediate labels are local
599         JMP _ (OpImm (ImmCLbl clbl)) | isAsmTemp clbl -> [insn]
600         -- If a jump mentions dests, it is a local jump thru
601         -- a case table.
602         JMP (DestInfo _) _                            -> [insn]
603         JMP _ _                                       -> [GFREE, insn]
604         other                                         -> [insn]
605
606
607 -- if you ever add a new FP insn to the fake x86 FP insn set,
608 -- you must update this too
609 is_G_instr :: Instr -> Bool
610 is_G_instr instr
611    = case instr of
612         GMOV _ _ -> True; GLD _ _ _ -> True; GST _ _ _ -> True;
613         GLDZ _ -> True; GLD1 _ -> True;
614         GFTOI _ _ -> True; GDTOI _ _ -> True;
615         GITOF _ _ -> True; GITOD _ _ -> True;
616         GADD _ _ _ _ -> True; GDIV _ _ _ _ -> True
617         GSUB _ _ _ _ -> True; GMUL _ _ _ _ -> True
618         GCMP _ _ _ -> True; GABS _ _ _ -> True
619         GNEG _ _ _ -> True; GSQRT _ _ _ -> True
620         GSIN _ _ _ -> True; GCOS _ _ _ -> True; GTAN _ _ _ -> True;
621         GFREE -> panic "is_G_instr: GFREE (!)"
622         other -> False
623
624 #endif {- i386_TARGET_ARCH -}
625 \end{code}
626
627 \begin{code}
628 #if sparc_TARGET_ARCH
629
630 -- data Instr continues...
631
632 -- Loads and stores.
633
634               | LD            Size MachRegsAddr Reg -- size, src, dst
635               | ST            Size Reg MachRegsAddr -- size, src, dst
636
637 -- Int Arithmetic.
638
639               | ADD           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
640               | SUB           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
641               | UMUL               Bool Reg RI Reg --     cc?, src1, src2, dst
642               | SMUL               Bool Reg RI Reg --     cc?, src1, src2, dst
643               | RDY           Reg       -- move contents of Y register to reg
644
645 -- Simple bit-twiddling.
646
647               | AND           Bool Reg RI Reg -- cc?, src1, src2, dst
648               | ANDN          Bool Reg RI Reg -- cc?, src1, src2, dst
649               | OR            Bool Reg RI Reg -- cc?, src1, src2, dst
650               | ORN           Bool Reg RI Reg -- cc?, src1, src2, dst
651               | XOR           Bool Reg RI Reg -- cc?, src1, src2, dst
652               | XNOR          Bool Reg RI Reg -- cc?, src1, src2, dst
653               | SLL           Reg RI Reg -- src1, src2, dst
654               | SRL           Reg RI Reg -- src1, src2, dst
655               | SRA           Reg RI Reg -- src1, src2, dst
656               | SETHI         Imm Reg -- src, dst
657               | NOP           -- Really SETHI 0, %g0, but worth an alias
658
659 -- Float Arithmetic.
660
661 -- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single instructions
662 -- right up until we spit them out.
663
664               | FABS          Size Reg Reg -- src dst
665               | FADD          Size Reg Reg Reg -- src1, src2, dst
666               | FCMP          Bool Size Reg Reg -- exception?, src1, src2, dst
667               | FDIV          Size Reg Reg Reg -- src1, src2, dst
668               | FMOV          Size Reg Reg -- src, dst
669               | FMUL          Size Reg Reg Reg -- src1, src2, dst
670               | FNEG          Size Reg Reg -- src, dst
671               | FSQRT         Size Reg Reg -- src, dst
672               | FSUB          Size Reg Reg Reg -- src1, src2, dst
673               | FxTOy         Size Size Reg Reg -- src, dst
674
675 -- Jumping around.
676
677               | BI            Cond Bool Imm -- cond, annul?, target
678               | BF            Cond Bool Imm -- cond, annul?, target
679
680               | JMP           DestInfo MachRegsAddr      -- target
681               | CALL          (Either Imm Reg) Int Bool -- target, args, terminal
682
683 data RI = RIReg Reg
684         | RIImm Imm
685
686 riZero :: RI -> Bool
687
688 riZero (RIImm (ImmInt 0))           = True
689 riZero (RIImm (ImmInteger 0))       = True
690 riZero (RIReg (RealReg 0))          = True
691 riZero _                            = False
692
693 -- Calculate the effective address which would be used by the
694 -- corresponding fpRel sequence.  fpRel is in MachRegs.lhs,
695 -- alas -- can't have fpRelEA here because of module dependencies.
696 fpRelEA :: Int -> Reg -> Instr
697 fpRelEA n dst
698    = ADD False False fp (RIImm (ImmInt (n * BYTES_PER_WORD))) dst
699
700 -- Code to shift the stack pointer by n words.
701 moveSp :: Int -> Instr
702 moveSp n
703    = ADD False False sp (RIImm (ImmInt (n * BYTES_PER_WORD))) sp
704
705 -- Produce the second-half-of-a-double register given the first half.
706 fPair :: Reg -> Reg
707 fPair (RealReg n) | n >= 32 && n `mod` 2 == 0  = RealReg (n+1)
708 fPair other = pprPanic "fPair(sparc NCG)" (ppr other)
709 #endif {- sparc_TARGET_ARCH -}
710 \end{code}