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