[project @ 2001-12-20 15:20:37 by sewardj]
[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               | IMUL64        Reg Reg                   -- 32 x 32 -> 64 signed mul
497                 -- operand1:operand2 := (operand1[31:0] *signed operand2[31:0])
498
499 -- Quotient and remainder.  SEE comment above -- these are not
500 -- real x86 insns; instead they are expanded when printed
501 -- into a sequence of real insns.
502
503               | IQUOT         Size Operand Operand      -- signed quotient
504               | IREM          Size Operand Operand      -- signed remainder
505               | QUOT          Size Operand Operand      -- unsigned quotient
506               | REM           Size Operand Operand      -- unsigned remainder
507
508 -- Simple bit-twiddling.
509
510               | AND           Size Operand Operand
511               | OR            Size Operand Operand
512               | XOR           Size Operand Operand
513               | NOT           Size Operand
514               | NEGI          Size Operand -- NEG instruction (name clash with Cond)
515               | SHL           Size Imm Operand -- Only immediate shifts allowed
516               | SAR           Size Imm Operand -- Only immediate shifts allowed
517               | SHR           Size Imm Operand -- Only immediate shifts allowed
518               | BT            Size Imm Operand
519               | NOP
520
521 -- Float Arithmetic.
522
523 -- Note that we cheat by treating G{ABS,MOV,NEG} of doubles 
524 -- as single instructions right up until we spit them out.
525
526               -- all the 3-operand fake fp insns are src1 src2 dst
527               -- and furthermore are constrained to be fp regs only.
528               -- IMPORTANT: keep is_G_insn up to date with any changes here
529               | GMOV          Reg Reg -- src(fpreg), dst(fpreg)
530               | GLD           Size MachRegsAddr Reg -- src, dst(fpreg)
531               | GST           Size Reg MachRegsAddr -- src(fpreg), dst
532
533               | GLDZ          Reg -- dst(fpreg)
534               | GLD1          Reg -- dst(fpreg)
535
536               | GFTOI         Reg Reg -- src(fpreg), dst(intreg)
537               | GDTOI         Reg Reg -- src(fpreg), dst(intreg)
538
539               | GITOF         Reg Reg -- src(intreg), dst(fpreg)
540               | GITOD         Reg Reg -- src(intreg), dst(fpreg)
541
542               | GADD          Size Reg Reg Reg -- src1, src2, dst
543               | GDIV          Size Reg Reg Reg -- src1, src2, dst
544               | GSUB          Size Reg Reg Reg -- src1, src2, dst
545               | GMUL          Size Reg Reg Reg -- src1, src2, dst
546
547                 -- FP compare.  Cond must be `elem` [EQQ, NE, LE, LTT, GE, GTT]
548                 -- Compare src1 with src2; set the Zero flag iff the numbers are
549                 -- comparable and the comparison is True.  Subsequent code must
550                 -- test the %eflags zero flag regardless of the supplied Cond.
551               | GCMP          Cond Reg Reg -- src1, src2
552
553               | GABS          Size Reg Reg -- src, dst
554               | GNEG          Size Reg Reg -- src, dst
555               | GSQRT         Size Reg Reg -- src, dst
556               | GSIN          Size Reg Reg -- src, dst
557               | GCOS          Size Reg Reg -- src, dst
558               | GTAN          Size Reg Reg -- src, dst
559
560               | GFREE         -- do ffree on all x86 regs; an ugly hack
561 -- Comparison
562
563               | TEST          Size Operand Operand
564               | CMP           Size Operand Operand
565               | SETCC         Cond Operand
566
567 -- Stack Operations.
568
569               | PUSH          Size Operand
570               | POP           Size Operand
571               | PUSHA
572               | POPA
573
574 -- Jumping around.
575
576               | JMP           DestInfo Operand -- possible dests, target
577               | JXX           Cond CLabel -- target
578               | CALL          Imm
579
580 -- Other things.
581
582               | CLTD -- sign extend %eax into %edx:%eax
583
584 data Operand
585   = OpReg  Reg          -- register
586   | OpImm  Imm          -- immediate value
587   | OpAddr MachRegsAddr -- memory reference
588
589
590 i386_insert_ffrees :: [Instr] -> [Instr]
591 i386_insert_ffrees insns
592    | any is_G_instr insns
593    = concatMap ffree_before_nonlocal_transfers insns
594    | otherwise
595    = insns
596
597 ffree_before_nonlocal_transfers insn
598    = case insn of
599         CALL _                                        -> [GFREE, insn]
600         -- Jumps to immediate labels are local
601         JMP _ (OpImm (ImmCLbl clbl)) | isAsmTemp clbl -> [insn]
602         -- If a jump mentions dests, it is a local jump thru
603         -- a case table.
604         JMP (DestInfo _) _                            -> [insn]
605         JMP _ _                                       -> [GFREE, insn]
606         other                                         -> [insn]
607
608
609 -- if you ever add a new FP insn to the fake x86 FP insn set,
610 -- you must update this too
611 is_G_instr :: Instr -> Bool
612 is_G_instr instr
613    = case instr of
614         GMOV _ _ -> True; GLD _ _ _ -> True; GST _ _ _ -> True;
615         GLDZ _ -> True; GLD1 _ -> True;
616         GFTOI _ _ -> True; GDTOI _ _ -> True;
617         GITOF _ _ -> True; GITOD _ _ -> True;
618         GADD _ _ _ _ -> True; GDIV _ _ _ _ -> True
619         GSUB _ _ _ _ -> True; GMUL _ _ _ _ -> True
620         GCMP _ _ _ -> True; GABS _ _ _ -> True
621         GNEG _ _ _ -> True; GSQRT _ _ _ -> True
622         GSIN _ _ _ -> True; GCOS _ _ _ -> True; GTAN _ _ _ -> True;
623         GFREE -> panic "is_G_instr: GFREE (!)"
624         other -> False
625
626 #endif {- i386_TARGET_ARCH -}
627 \end{code}
628
629 \begin{code}
630 #if sparc_TARGET_ARCH
631
632 -- data Instr continues...
633
634 -- Loads and stores.
635
636               | LD            Size MachRegsAddr Reg -- size, src, dst
637               | ST            Size Reg MachRegsAddr -- size, src, dst
638
639 -- Int Arithmetic.
640
641               | ADD           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
642               | SUB           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
643               | UMUL               Bool Reg RI Reg --     cc?, src1, src2, dst
644               | SMUL               Bool Reg RI Reg --     cc?, src1, src2, dst
645               | RDY           Reg       -- move contents of Y register to reg
646
647 -- Simple bit-twiddling.
648
649               | AND           Bool Reg RI Reg -- cc?, src1, src2, dst
650               | ANDN          Bool Reg RI Reg -- cc?, src1, src2, dst
651               | OR            Bool Reg RI Reg -- cc?, src1, src2, dst
652               | ORN           Bool Reg RI Reg -- cc?, src1, src2, dst
653               | XOR           Bool Reg RI Reg -- cc?, src1, src2, dst
654               | XNOR          Bool Reg RI Reg -- cc?, src1, src2, dst
655               | SLL           Reg RI Reg -- src1, src2, dst
656               | SRL           Reg RI Reg -- src1, src2, dst
657               | SRA           Reg RI Reg -- src1, src2, dst
658               | SETHI         Imm Reg -- src, dst
659               | NOP           -- Really SETHI 0, %g0, but worth an alias
660
661 -- Float Arithmetic.
662
663 -- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single instructions
664 -- right up until we spit them out.
665
666               | FABS          Size Reg Reg -- src dst
667               | FADD          Size Reg Reg Reg -- src1, src2, dst
668               | FCMP          Bool Size Reg Reg -- exception?, src1, src2, dst
669               | FDIV          Size Reg Reg Reg -- src1, src2, dst
670               | FMOV          Size Reg Reg -- src, dst
671               | FMUL          Size Reg Reg Reg -- src1, src2, dst
672               | FNEG          Size Reg Reg -- src, dst
673               | FSQRT         Size Reg Reg -- src, dst
674               | FSUB          Size Reg Reg Reg -- src1, src2, dst
675               | FxTOy         Size Size Reg Reg -- src, dst
676
677 -- Jumping around.
678
679               | BI            Cond Bool Imm -- cond, annul?, target
680               | BF            Cond Bool Imm -- cond, annul?, target
681
682               | JMP           DestInfo MachRegsAddr      -- target
683               | CALL          Imm Int Bool -- target, args, terminal
684
685 data RI = RIReg Reg
686         | RIImm Imm
687
688 riZero :: RI -> Bool
689
690 riZero (RIImm (ImmInt 0))           = True
691 riZero (RIImm (ImmInteger 0))       = True
692 riZero (RIReg (RealReg 0))          = True
693 riZero _                            = False
694
695 -- Calculate the effective address which would be used by the
696 -- corresponding fpRel sequence.  fpRel is in MachRegs.lhs,
697 -- alas -- can't have fpRelEA here because of module dependencies.
698 fpRelEA :: Int -> Reg -> Instr
699 fpRelEA n dst
700    = ADD False False fp (RIImm (ImmInt (n * BYTES_PER_WORD))) dst
701
702 -- Code to shift the stack pointer by n words.
703 moveSp :: Int -> Instr
704 moveSp n
705    = ADD False False sp (RIImm (ImmInt (n * BYTES_PER_WORD))) sp
706
707 -- Produce the second-half-of-a-double register given the first half.
708 fPair :: Reg -> Reg
709 fPair (RealReg n) | n >= 32 && n `mod` 2 == 0  = RealReg (n+1)
710 fPair other = pprPanic "fPair(sparc NCG)" (ppr other)
711 #endif {- sparc_TARGET_ARCH -}
712 \end{code}