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