[project @ 2001-12-21 17:03:18 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     deriving Eq  -- to make an assertion work
241 \end{code}
242
243 \begin{code}
244 data Size
245 #if alpha_TARGET_ARCH
246     = B     -- byte
247     | Bu
248 --  | W     -- word (2 bytes): UNUSED
249 --  | Wu    -- : UNUSED
250     | L     -- longword (4 bytes)
251     | Q     -- quadword (8 bytes)
252 --  | FF    -- VAX F-style floating pt: UNUSED
253 --  | GF    -- VAX G-style floating pt: UNUSED
254 --  | DF    -- VAX D-style floating pt: UNUSED
255 --  | SF    -- IEEE single-precision floating pt: UNUSED
256     | TF    -- IEEE double-precision floating pt
257 #endif
258 #if i386_TARGET_ARCH
259     = B     -- byte (signed)
260     | Bu    -- byte (unsigned)
261     | W     -- word (signed)
262     | Wu    -- word (unsigned)
263     | L     -- longword (signed)
264     | Lu    -- longword (unsigned)
265     | F     -- IEEE single-precision floating pt
266     | DF    -- IEEE single-precision floating pt
267     | F80   -- Intel 80-bit internal FP format; only used for spilling
268 #endif
269 #if sparc_TARGET_ARCH
270     = B     -- byte (signed)
271     | Bu    -- byte (unsigned)
272     | H     -- halfword (signed, 2 bytes)
273     | Hu    -- halfword (unsigned, 2 bytes)
274     | W     -- word (4 bytes)
275     | F     -- IEEE single-precision floating pt
276     | DF    -- IEEE single-precision floating pt
277 #endif
278
279 primRepToSize :: PrimRep -> Size
280
281 primRepToSize PtrRep        = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
282 primRepToSize CodePtrRep    = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
283 primRepToSize DataPtrRep    = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
284 primRepToSize RetRep        = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
285 primRepToSize CostCentreRep = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
286 primRepToSize CharRep       = IF_ARCH_alpha(L,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
287
288 primRepToSize Int8Rep       = IF_ARCH_alpha(B,  IF_ARCH_i386(B,  IF_ARCH_sparc(B,  )))
289 primRepToSize Int16Rep      = IF_ARCH_alpha(err,IF_ARCH_i386(W,  IF_ARCH_sparc(H,  )))
290     where err = primRepToSize_fail "Int16Rep"
291 primRepToSize Int32Rep      = IF_ARCH_alpha(L,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
292 primRepToSize Word8Rep      = IF_ARCH_alpha(Bu, IF_ARCH_i386(Bu, IF_ARCH_sparc(Bu, )))
293 primRepToSize Word16Rep     = IF_ARCH_alpha(err,IF_ARCH_i386(Wu, IF_ARCH_sparc(Hu, )))
294     where err = primRepToSize_fail "Word16Rep"
295 primRepToSize Word32Rep     = IF_ARCH_alpha(L,  IF_ARCH_i386(Lu, IF_ARCH_sparc(W,  )))
296
297 primRepToSize IntRep        = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
298 primRepToSize WordRep       = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
299 primRepToSize AddrRep       = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
300 primRepToSize FloatRep      = IF_ARCH_alpha(TF, IF_ARCH_i386(F,  IF_ARCH_sparc(F,  )))
301 primRepToSize DoubleRep     = IF_ARCH_alpha(TF, IF_ARCH_i386(DF, IF_ARCH_sparc(DF, )))
302 primRepToSize ArrayRep      = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
303 primRepToSize ByteArrayRep  = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
304 primRepToSize PrimPtrRep    = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
305 primRepToSize WeakPtrRep    = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
306 primRepToSize ForeignObjRep = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
307 primRepToSize BCORep        = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
308 primRepToSize StablePtrRep  = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
309 primRepToSize StableNameRep = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
310 primRepToSize ThreadIdRep   = IF_ARCH_alpha(Q,  IF_ARCH_i386(L,  IF_ARCH_sparc(W,  )))
311
312 primRepToSize Word64Rep     = primRepToSize_fail "Word64Rep"
313 primRepToSize Int64Rep      = primRepToSize_fail "Int64Rep"
314 primRepToSize other         = primRepToSize_fail (showSDoc (ppr other))
315
316 primRepToSize_fail str
317    = error ("ERROR: MachMisc.primRepToSize: cannot handle `" ++ str ++ "'.\n\t" 
318             ++ "Workaround: use -fvia-C.\n\t" 
319             ++ "Perhaps you should report it as a GHC bug,\n\t" 
320             ++ "to glasgow-haskell-bugs@haskell.org.")
321
322 \end{code}
323
324 %************************************************************************
325 %*                                                                      *
326 \subsection{Machine's assembly language}
327 %*                                                                      *
328 %************************************************************************
329
330 We have a few common ``instructions'' (nearly all the pseudo-ops) but
331 mostly all of @Instr@ is machine-specific.
332
333 \begin{code}
334 data Instr
335   = COMMENT FAST_STRING         -- comment pseudo-op
336   | SEGMENT CodeSegment         -- {data,text} segment pseudo-op
337   | LABEL   CLabel              -- global label pseudo-op
338   | ASCII   Bool                -- True <=> needs backslash conversion
339             String              -- the literal string
340   | DATA    Size
341             [Imm]
342   | DELTA   Int                 -- specify current stack offset for
343                                 -- benefit of subsequent passes
344 \end{code}
345
346 \begin{code}
347 #if alpha_TARGET_ARCH
348
349 -- data Instr continues...
350
351 -- Loads and stores.
352
353               | LD            Size Reg MachRegsAddr -- size, dst, src
354               | LDA           Reg MachRegsAddr      -- dst, src
355               | LDAH          Reg MachRegsAddr      -- dst, src
356               | LDGP          Reg MachRegsAddr      -- dst, src
357               | LDI           Size Reg Imm     -- size, dst, src
358               | ST            Size Reg MachRegsAddr -- size, src, dst
359
360 -- Int Arithmetic.
361
362               | CLR           Reg                   -- dst
363               | ABS           Size RI Reg           -- size, src, dst
364               | NEG           Size Bool RI Reg      -- size, overflow, src, dst
365               | ADD           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
366               | SADD          Size Size Reg RI Reg  -- size, scale, src, src, dst
367               | SUB           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
368               | SSUB          Size Size Reg RI Reg  -- size, scale, src, src, dst
369               | MUL           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
370               | DIV           Size Bool Reg RI Reg  -- size, unsigned, src, src, dst
371               | REM           Size Bool Reg RI Reg  -- size, unsigned, src, src, dst
372
373 -- Simple bit-twiddling.
374
375               | NOT           RI Reg
376               | AND           Reg RI Reg
377               | ANDNOT        Reg RI Reg
378               | OR            Reg RI Reg
379               | ORNOT         Reg RI Reg
380               | XOR           Reg RI Reg
381               | XORNOT        Reg RI Reg
382               | SLL           Reg RI Reg
383               | SRL           Reg RI Reg
384               | SRA           Reg RI Reg
385
386               | ZAP           Reg RI Reg
387               | ZAPNOT        Reg RI Reg
388
389               | NOP
390
391 -- Comparison
392
393               | CMP           Cond Reg RI Reg
394
395 -- Float Arithmetic.
396
397               | FCLR          Reg
398               | FABS          Reg Reg
399               | FNEG          Size Reg Reg
400               | FADD          Size Reg Reg Reg
401               | FDIV          Size Reg Reg Reg
402               | FMUL          Size Reg Reg Reg
403               | FSUB          Size Reg Reg Reg
404               | CVTxy         Size Size Reg Reg
405               | FCMP          Size Cond Reg Reg Reg
406               | FMOV          Reg Reg
407
408 -- Jumping around.
409
410               | BI            Cond Reg Imm
411               | BF            Cond Reg Imm
412               | BR            Imm
413               | JMP           Reg MachRegsAddr Int
414               | BSR           Imm Int
415               | JSR           Reg MachRegsAddr Int
416
417 -- Alpha-specific pseudo-ops.
418
419               | FUNBEGIN CLabel
420               | FUNEND CLabel
421
422 data RI
423   = RIReg Reg
424   | RIImm Imm
425
426 #endif {- alpha_TARGET_ARCH -}
427 \end{code}
428
429 Intel, in their infinite wisdom, selected a stack model for floating
430 point registers on x86.  That might have made sense back in 1979 --
431 nowadays we can see it for the nonsense it really is.  A stack model
432 fits poorly with the existing nativeGen infrastructure, which assumes
433 flat integer and FP register sets.  Prior to this commit, nativeGen
434 could not generate correct x86 FP code -- to do so would have meant
435 somehow working the register-stack paradigm into the register
436 allocator and spiller, which sounds very difficult.
437   
438 We have decided to cheat, and go for a simple fix which requires no
439 infrastructure modifications, at the expense of generating ropey but
440 correct FP code.  All notions of the x86 FP stack and its insns have
441 been removed.  Instead, we pretend (to the instruction selector and
442 register allocator) that x86 has six floating point registers, %fake0
443 .. %fake5, which can be used in the usual flat manner.  We further
444 claim that x86 has floating point instructions very similar to SPARC
445 and Alpha, that is, a simple 3-operand register-register arrangement.
446 Code generation and register allocation proceed on this basis.
447   
448 When we come to print out the final assembly, our convenient fiction
449 is converted to dismal reality.  Each fake instruction is
450 independently converted to a series of real x86 instructions.
451 %fake0 .. %fake5 are mapped to %st(0) .. %st(5).  To do reg-reg
452 arithmetic operations, the two operands are pushed onto the top of the
453 FP stack, the operation done, and the result copied back into the
454 relevant register.  There are only six %fake registers because 2 are
455 needed for the translation, and x86 has 8 in total.
456
457 The translation is inefficient but is simple and it works.  A cleverer
458 translation would handle a sequence of insns, simulating the FP stack
459 contents, would not impose a fixed mapping from %fake to %st regs, and
460 hopefully could avoid most of the redundant reg-reg moves of the
461 current translation.
462
463 We might as well make use of whatever unique FP facilities Intel have
464 chosen to bless us with (let's not be churlish, after all).
465 Hence GLDZ and GLD1.  Bwahahahahahahaha!
466
467 LATER (10 Nov 2000): idiv gives problems with the register spiller,
468 because the spiller is simpleminded and because idiv has fixed uses of
469 %eax and %edx.  Rather than make the spiller cleverer, we do away with
470 idiv, and instead have iquot and irem fake (integer) insns, which have
471 no operand register constraints -- ie, they behave like add, sub, mul.
472 The printer-outer transforms them to a sequence of real insns which does
473 the Right Thing (tm).  As with the FP stuff, this gives ropey code, 
474 but we don't care, since it doesn't get used much.  We hope.
475
476 \begin{code}
477 #if i386_TARGET_ARCH
478
479 -- data Instr continues...
480
481 -- Moves.
482
483               | MOV           Size Operand Operand
484               | MOVZxL        Size Operand Operand -- size is the size of operand 1
485               | MOVSxL        Size Operand Operand -- size is the size of operand 1
486
487 -- Load effective address (also a very useful three-operand add instruction :-)
488
489               | LEA           Size Operand Operand
490
491 -- Int Arithmetic.
492
493               | ADD           Size Operand Operand
494               | SUB           Size Operand Operand
495               | IMUL          Size Operand Operand      -- signed int mul
496               | MUL           Size Operand Operand      -- unsigned int mul
497               | IMUL64        Reg Reg                   -- 32 x 32 -> 64 signed mul
498                 -- operand1:operand2 := (operand1[31:0] *signed operand2[31:0])
499
500 -- Quotient and remainder.  SEE comment above -- these are not
501 -- real x86 insns; instead they are expanded when printed
502 -- into a sequence of real insns.
503
504               | IQUOT         Size Operand Operand      -- signed quotient
505               | IREM          Size Operand Operand      -- signed remainder
506               | QUOT          Size Operand Operand      -- unsigned quotient
507               | REM           Size Operand Operand      -- unsigned remainder
508
509 -- Simple bit-twiddling.
510
511               | AND           Size Operand Operand
512               | OR            Size Operand Operand
513               | XOR           Size Operand Operand
514               | NOT           Size Operand
515               | NEGI          Size Operand -- NEG instruction (name clash with Cond)
516               | SHL           Size Imm Operand -- Only immediate shifts allowed
517               | SAR           Size Imm Operand -- Only immediate shifts allowed
518               | SHR           Size Imm Operand -- Only immediate shifts allowed
519               | BT            Size Imm Operand
520               | NOP
521
522 -- Float Arithmetic.
523
524 -- Note that we cheat by treating G{ABS,MOV,NEG} of doubles 
525 -- as single instructions right up until we spit them out.
526
527               -- all the 3-operand fake fp insns are src1 src2 dst
528               -- and furthermore are constrained to be fp regs only.
529               -- IMPORTANT: keep is_G_insn up to date with any changes here
530               | GMOV          Reg Reg -- src(fpreg), dst(fpreg)
531               | GLD           Size MachRegsAddr Reg -- src, dst(fpreg)
532               | GST           Size Reg MachRegsAddr -- src(fpreg), dst
533
534               | GLDZ          Reg -- dst(fpreg)
535               | GLD1          Reg -- dst(fpreg)
536
537               | GFTOI         Reg Reg -- src(fpreg), dst(intreg)
538               | GDTOI         Reg Reg -- src(fpreg), dst(intreg)
539
540               | GITOF         Reg Reg -- src(intreg), dst(fpreg)
541               | GITOD         Reg Reg -- src(intreg), dst(fpreg)
542
543               | GADD          Size Reg Reg Reg -- src1, src2, dst
544               | GDIV          Size Reg Reg Reg -- src1, src2, dst
545               | GSUB          Size Reg Reg Reg -- src1, src2, dst
546               | GMUL          Size Reg Reg Reg -- src1, src2, dst
547
548                 -- FP compare.  Cond must be `elem` [EQQ, NE, LE, LTT, GE, GTT]
549                 -- Compare src1 with src2; set the Zero flag iff the numbers are
550                 -- comparable and the comparison is True.  Subsequent code must
551                 -- test the %eflags zero flag regardless of the supplied Cond.
552               | GCMP          Cond Reg Reg -- src1, src2
553
554               | GABS          Size Reg Reg -- src, dst
555               | GNEG          Size Reg Reg -- src, dst
556               | GSQRT         Size Reg Reg -- src, dst
557               | GSIN          Size Reg Reg -- src, dst
558               | GCOS          Size Reg Reg -- src, dst
559               | GTAN          Size Reg Reg -- src, dst
560
561               | GFREE         -- do ffree on all x86 regs; an ugly hack
562 -- Comparison
563
564               | TEST          Size Operand Operand
565               | CMP           Size Operand Operand
566               | SETCC         Cond Operand
567
568 -- Stack Operations.
569
570               | PUSH          Size Operand
571               | POP           Size Operand
572               | PUSHA
573               | POPA
574
575 -- Jumping around.
576
577               | JMP           DestInfo Operand -- possible dests, target
578               | JXX           Cond CLabel -- target
579               | CALL          Imm
580
581 -- Other things.
582
583               | CLTD -- sign extend %eax into %edx:%eax
584
585 data Operand
586   = OpReg  Reg          -- register
587   | OpImm  Imm          -- immediate value
588   | OpAddr MachRegsAddr -- memory reference
589
590
591 i386_insert_ffrees :: [Instr] -> [Instr]
592 i386_insert_ffrees insns
593    | any is_G_instr insns
594    = concatMap ffree_before_nonlocal_transfers insns
595    | otherwise
596    = insns
597
598 ffree_before_nonlocal_transfers insn
599    = case insn of
600         CALL _                                        -> [GFREE, insn]
601         -- Jumps to immediate labels are local
602         JMP _ (OpImm (ImmCLbl clbl)) | isAsmTemp clbl -> [insn]
603         -- If a jump mentions dests, it is a local jump thru
604         -- a case table.
605         JMP (DestInfo _) _                            -> [insn]
606         JMP _ _                                       -> [GFREE, insn]
607         other                                         -> [insn]
608
609
610 -- if you ever add a new FP insn to the fake x86 FP insn set,
611 -- you must update this too
612 is_G_instr :: Instr -> Bool
613 is_G_instr instr
614    = case instr of
615         GMOV _ _ -> True; GLD _ _ _ -> True; GST _ _ _ -> True;
616         GLDZ _ -> True; GLD1 _ -> True;
617         GFTOI _ _ -> True; GDTOI _ _ -> True;
618         GITOF _ _ -> True; GITOD _ _ -> True;
619         GADD _ _ _ _ -> True; GDIV _ _ _ _ -> True
620         GSUB _ _ _ _ -> True; GMUL _ _ _ _ -> True
621         GCMP _ _ _ -> True; GABS _ _ _ -> True
622         GNEG _ _ _ -> True; GSQRT _ _ _ -> True
623         GSIN _ _ _ -> True; GCOS _ _ _ -> True; GTAN _ _ _ -> True;
624         GFREE -> panic "is_G_instr: GFREE (!)"
625         other -> False
626
627 #endif {- i386_TARGET_ARCH -}
628 \end{code}
629
630 \begin{code}
631 #if sparc_TARGET_ARCH
632
633 -- data Instr continues...
634
635 -- Loads and stores.
636
637               | LD            Size MachRegsAddr Reg -- size, src, dst
638               | ST            Size Reg MachRegsAddr -- size, src, dst
639
640 -- Int Arithmetic.
641
642               | ADD           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
643               | SUB           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
644               | UMUL               Bool Reg RI Reg --     cc?, src1, src2, dst
645               | SMUL               Bool Reg RI Reg --     cc?, src1, src2, dst
646               | RDY           Reg       -- move contents of Y register to reg
647
648 -- Simple bit-twiddling.
649
650               | AND           Bool Reg RI Reg -- cc?, src1, src2, dst
651               | ANDN          Bool Reg RI Reg -- cc?, src1, src2, dst
652               | OR            Bool Reg RI Reg -- cc?, src1, src2, dst
653               | ORN           Bool Reg RI Reg -- cc?, src1, src2, dst
654               | XOR           Bool Reg RI Reg -- cc?, src1, src2, dst
655               | XNOR          Bool Reg RI Reg -- cc?, src1, src2, dst
656               | SLL           Reg RI Reg -- src1, src2, dst
657               | SRL           Reg RI Reg -- src1, src2, dst
658               | SRA           Reg RI Reg -- src1, src2, dst
659               | SETHI         Imm Reg -- src, dst
660               | NOP           -- Really SETHI 0, %g0, but worth an alias
661
662 -- Float Arithmetic.
663
664 -- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single instructions
665 -- right up until we spit them out.
666
667               | FABS          Size Reg Reg -- src dst
668               | FADD          Size Reg Reg Reg -- src1, src2, dst
669               | FCMP          Bool Size Reg Reg -- exception?, src1, src2, dst
670               | FDIV          Size Reg Reg Reg -- src1, src2, dst
671               | FMOV          Size Reg Reg -- src, dst
672               | FMUL          Size Reg Reg Reg -- src1, src2, dst
673               | FNEG          Size Reg Reg -- src, dst
674               | FSQRT         Size Reg Reg -- src, dst
675               | FSUB          Size Reg Reg Reg -- src1, src2, dst
676               | FxTOy         Size Size Reg Reg -- src, dst
677
678 -- Jumping around.
679
680               | BI            Cond Bool Imm -- cond, annul?, target
681               | BF            Cond Bool Imm -- cond, annul?, target
682
683               | JMP           DestInfo MachRegsAddr      -- target
684               | CALL          Imm Int Bool -- target, args, terminal
685
686 data RI = RIReg Reg
687         | RIImm Imm
688
689 riZero :: RI -> Bool
690
691 riZero (RIImm (ImmInt 0))           = True
692 riZero (RIImm (ImmInteger 0))       = True
693 riZero (RIReg (RealReg 0))          = True
694 riZero _                            = False
695
696 -- Calculate the effective address which would be used by the
697 -- corresponding fpRel sequence.  fpRel is in MachRegs.lhs,
698 -- alas -- can't have fpRelEA here because of module dependencies.
699 fpRelEA :: Int -> Reg -> Instr
700 fpRelEA n dst
701    = ADD False False fp (RIImm (ImmInt (n * BYTES_PER_WORD))) dst
702
703 -- Code to shift the stack pointer by n words.
704 moveSp :: Int -> Instr
705 moveSp n
706    = ADD False False sp (RIImm (ImmInt (n * BYTES_PER_WORD))) sp
707
708 -- Produce the second-half-of-a-double register given the first half.
709 fPair :: Reg -> Reg
710 fPair (RealReg n) | n >= 32 && n `mod` 2 == 0  = RealReg (n+1)
711 fPair other = pprPanic "fPair(sparc NCG)" (ppr other)
712 #endif {- sparc_TARGET_ARCH -}
713 \end{code}