055f9eb474ec27d7db71cdb3a29568f10430f25f
[ghc-hetmet.git] / ghc / compiler / nativeGen / MachMisc.lhs
1 %
2 % (c) The AQUA Project, Glasgow University, 1993-1996
3 %
4 \section[MachMisc]{Description of various machine-specific things}
5
6 \begin{code}
7 #include "HsVersions.h"
8 #include "nativeGen/NCG.h"
9
10 module MachMisc (
11
12         fixedHdrSizeInWords, varHdrSizeInWords,
13         charLikeSize, intLikeSize, mutHS, dataHS,
14         sizeOf, primRepToSize,
15
16         eXTRA_STK_ARGS_HERE,
17
18         volatileSaves, volatileRestores,
19
20         storageMgrInfo, smCAFlist, smOldLim, smOldMutables,
21         smStablePtrTable,
22
23         targetMaxDouble, targetMaxInt, targetMinDouble, targetMinInt,
24
25         underscorePrefix,
26         fmtAsmLbl,
27         cvtLitLit,
28         exactLog2,
29
30         Instr(..),  IF_ARCH_i386(Operand(..) COMMA,)
31         Cond(..),
32         Size(..)
33         
34 #if alpha_TARGET_ARCH
35         , RI(..)
36 #endif
37 #if i386_TARGET_ARCH
38 #endif
39 #if sparc_TARGET_ARCH
40         , RI(..), riZero
41 #endif
42     ) where
43
44 IMP_Ubiq(){-uitous-}
45 IMPORT_DELOOPER(AbsCLoop)               ( fixedHdrSizeInWords, varHdrSizeInWords ) -- paranoia
46 IMPORT_DELOOPER(NcgLoop)                ( underscorePrefix, fmtAsmLbl ) -- paranoia
47 IMPORT_1_3(Char(isDigit))
48
49 import AbsCSyn          ( MagicId(..) ) 
50 import AbsCUtils        ( magicIdPrimRep )
51 import CmdLineOpts      ( opt_SccProfilingOn )
52 import Literal          ( mkMachInt, Literal(..) )
53 import MachRegs         ( stgReg, callerSaves, RegLoc(..),
54                           Imm(..), Reg(..), Addr
55                         )
56 import OrdList          ( OrdList )
57 import PrimRep          ( PrimRep(..) )
58 import SMRep            ( SMRep(..), SMSpecRepKind(..), SMUpdateKind(..) )
59 import Stix             ( StixTree(..), StixReg(..), sStLitLbl,
60                           CodeSegment
61                         )
62 import Util             ( panic )
63 \end{code}
64
65 \begin{code}
66 underscorePrefix :: Bool   -- leading underscore on labels?
67
68 underscorePrefix
69   = IF_ARCH_alpha(False
70     ,{-else-} IF_ARCH_i386(
71         IF_OS_linuxaout(True
72         , IF_OS_freebsd(True
73         , IF_OS_bsdi(True
74         , {-otherwise-} False)))
75      ,{-else-}IF_ARCH_sparc(
76         IF_OS_sunos4(True, {-otherwise-} False)
77      ,)))
78
79 ---------------------------
80 fmtAsmLbl :: String -> String  -- for formatting labels
81
82 fmtAsmLbl s
83   =  IF_ARCH_alpha(
84      {- The alpha assembler likes temporary labels to look like $L123
85         instead of L123.  (Don't toss the L, because then Lf28
86         turns into $f28.)
87      -}
88      '$' : s
89      ,{-otherwise-}
90      s
91      )
92
93 ---------------------------
94 cvtLitLit :: String -> String
95
96 -- ToDo: some kind of *careful* attention needed...
97
98 cvtLitLit "stdin"  = IF_ARCH_alpha("_iob+0" {-probably OK...-}
99                     ,IF_ARCH_i386("_IO_stdin_"
100                     ,IF_ARCH_sparc("__iob+0x0"{-probably OK...-}
101                     ,)))
102 cvtLitLit "stdout" = IF_ARCH_alpha("_iob+56"{-dodgy *at best*...-}
103                     ,IF_ARCH_i386("_IO_stdout_"
104                     ,IF_ARCH_sparc("__iob+0x14"{-dodgy *at best*...-}
105                     ,)))
106 cvtLitLit "stderr" = IF_ARCH_alpha("_iob+112"{-dodgy *at best*...-}
107                     ,IF_ARCH_i386("_IO_stderr_"
108                     ,IF_ARCH_sparc("__iob+0x28"{-dodgy *at best*...-}
109                     ,)))
110 cvtLitLit s
111   | isHex s   = s
112   | otherwise = error ("Native code generator can't handle ``" ++ s ++ "''")
113   where
114     isHex ('0':'x':xs) = all isHexDigit xs
115     isHex _ = False
116     -- Now, where have I seen this before?
117     isHexDigit c = isDigit c || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'
118 \end{code}
119
120 % ----------------------------------------------------------------
121
122 We (allegedly) put the first six C-call arguments in registers;
123 where do we start putting the rest of them?
124 \begin{code}
125 eXTRA_STK_ARGS_HERE :: Int
126 eXTRA_STK_ARGS_HERE
127   = IF_ARCH_alpha(0, IF_ARCH_i386(23{-6x4bytes-}, IF_ARCH_sparc(23,???)))
128 \end{code}
129
130 % ----------------------------------------------------------------
131
132 @fixedHdrSizeInWords@ and @varHdrSizeInWords@: these are not dependent
133 on target architecture.
134 \begin{code}
135 fixedHdrSizeInWords :: Int
136
137 fixedHdrSizeInWords
138   = 1{-info ptr-} + profFHS + parFHS + tickyFHS
139     -- obviously, we aren't taking non-sequential too seriously yet
140   where
141     profFHS  = if opt_SccProfilingOn then 1 else 0
142     parFHS   = {-if PAR or GRAN then 1 else-} 0
143     tickyFHS = {-if ticky ... then 1 else-} 0
144
145 varHdrSizeInWords :: SMRep -> Int{-in words-}
146
147 varHdrSizeInWords sm
148   = case sm of
149     StaticRep _ _          -> 0
150     SpecialisedRep _ _ _ _ -> 0
151     GenericRep _ _ _       -> 0
152     BigTupleRep _          -> 1
153     MuTupleRep _           -> 2 {- (1 + GC_MUT_RESERVED_WORDS) -}
154     DataRep _              -> 1
155     DynamicRep             -> 2
156     BlackHoleRep           -> 0
157     PhantomRep             -> panic "MachMisc.varHdrSizeInWords:phantom"
158 \end{code}
159
160 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
161
162 Static closure sizes:
163 \begin{code}
164 charLikeSize, intLikeSize :: Int
165
166 charLikeSize = blahLikeSize CharLikeRep
167 intLikeSize  = blahLikeSize IntLikeRep
168
169 blahLikeSize blah
170   = fromInteger (sizeOf PtrRep)
171   * (fixedHdrSizeInWords + varHdrSizeInWords blahLikeRep + 1)
172   where
173     blahLikeRep = SpecialisedRep blah 0 1 SMNormalForm
174
175 --------
176 mutHS, dataHS :: StixTree
177
178 mutHS  = blah_hs (MuTupleRep 0)
179 dataHS = blah_hs (DataRep 0)
180
181 blah_hs blah
182   = StInt (toInteger words)
183   where
184     words = fixedHdrSizeInWords + varHdrSizeInWords blah
185 \end{code}
186
187 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
188
189 Size of a @PrimRep@, in bytes.
190
191 \begin{code}
192 sizeOf :: PrimRep -> Integer{-in bytes-}
193     -- the result is an Integer only because it's more convenient
194
195 sizeOf pr = case (primRepToSize pr) of
196   IF_ARCH_alpha({B -> 1; BU -> 1; {-W -> 2; WU -> 2; L -> 4; SF -> 4;-} _ -> 8},)
197   IF_ARCH_sparc({B -> 1; BU -> 1; {-HW -> 2; HWU -> 2;-} W -> 4; {-D -> 8;-} F -> 4; DF -> 8},)
198   IF_ARCH_i386( {B -> 1; {-S -> 2;-} L -> 4; F -> 4; DF -> 8 },)
199 \end{code}
200
201 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
202
203 Now the volatile saves and restores.  We add the basic guys to the
204 list of ``user'' registers provided.  Note that there are more basic
205 registers on the restore list, because some are reloaded from
206 constants.
207
208 (@volatileRestores@ used only for wrapper-hungry PrimOps.)
209
210 \begin{code}
211 volatileSaves, volatileRestores :: [MagicId] -> [StixTree]
212
213 save_cands    = [BaseReg,SpA,SuA,SpB,SuB,Hp,HpLim,RetReg]
214 restore_cands = save_cands ++ [StkStubReg,StdUpdRetVecReg]
215
216 volatileSaves vols
217   = map save ((filter callerSaves) (save_cands ++ vols))
218   where
219     save x = StAssign (magicIdPrimRep x) loc reg
220       where
221         reg = StReg (StixMagicId x)
222         loc = case stgReg x of
223                 Save loc -> loc
224                 Always _ -> panic "volatileSaves"
225
226 volatileRestores vols
227   = map restore ((filter callerSaves) (restore_cands ++ vols))
228   where
229     restore x = StAssign (magicIdPrimRep x) reg loc
230       where
231         reg = StReg (StixMagicId x)
232         loc = case stgReg x of
233                 Save loc -> loc
234                 Always _ -> panic "volatileRestores"
235 \end{code}
236
237 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
238
239 Obviously slightly weedy
240 (Note that the floating point values aren't terribly important.)
241 ToDo: Fix!(JSM)
242 \begin{code}
243 targetMinDouble = MachDouble (-1.7976931348623157e+308)
244 targetMaxDouble = MachDouble (1.7976931348623157e+308)
245 targetMinInt = mkMachInt (-2147483647)
246 targetMaxInt = mkMachInt 2147483647
247 \end{code}
248
249 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
250
251 Storage manager nonsense.  Note that the indices are dependent on
252 the definition of the smInfo structure in SMinterface.lh
253
254 \begin{code}
255 storageMgrInfo, smCAFlist, smOldMutables, smOldLim :: StixTree
256
257 storageMgrInfo   = sStLitLbl SLIT("StorageMgrInfo")
258 smCAFlist        = StInd PtrRep (StIndex PtrRep storageMgrInfo (StInt SM_CAFLIST))
259 smOldMutables    = StInd PtrRep (StIndex PtrRep storageMgrInfo (StInt SM_OLDMUTABLES))
260 smOldLim         = StInd PtrRep (StIndex PtrRep storageMgrInfo (StInt SM_OLDLIM))
261 smStablePtrTable = StInd PtrRep (StIndex PtrRep storageMgrInfo (StInt SM_STABLEPOINTERTABLE))
262 \end{code}
263
264 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
265
266 This algorithm for determining the $\log_2$ of exact powers of 2 comes
267 from GCC.  It requires bit manipulation primitives, and we use GHC
268 extensions.  Tough.
269
270 \begin{code}
271 w2i x = word2Int# x
272 i2w x = int2Word# x
273 i2w_s x = (x::Int#)
274
275 exactLog2 :: Integer -> Maybe Integer
276 exactLog2 x
277   = if (x <= 0 || x >= 2147483648) then
278        Nothing
279     else
280        case (fromInteger x) of { I# x# ->
281        if (w2i ((i2w x#) `and#` (i2w (0# -# x#))) /=# x#) then
282           Nothing
283        else
284           Just (toInteger (I# (pow2 x#)))
285        }
286   where
287     shiftr x y = shiftRA# x y
288
289     pow2 x# | x# ==# 1# = 0#
290             | otherwise = 1# +# pow2 (w2i (i2w x# `shiftr` i2w_s 1#))
291 \end{code}
292
293 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
294
295 \begin{code}
296 data Cond
297 #if alpha_TARGET_ARCH
298   = ALWAYS      -- For BI (same as BR)
299   | EQQ         -- For CMP and BI (NB: "EQ" is a 1.3 Prelude name)
300   | GE          -- For BI only
301   | GTT         -- For BI only (NB: "GT" is a 1.3 Prelude name)
302   | LE          -- For CMP and BI
303   | LTT         -- For CMP and BI (NB: "LT" is a 1.3 Prelude name)
304   | NE          -- For BI only
305   | NEVER       -- For BI (null instruction)
306   | ULE         -- For CMP only
307   | ULT         -- For CMP only
308 #endif
309 #if i386_TARGET_ARCH
310   = ALWAYS      -- What's really used? ToDo
311   | EQQ
312   | GE
313   | GEU
314   | GTT
315   | GU
316   | LE
317   | LEU
318   | LTT
319   | LU
320   | NE
321   | NEG
322   | POS
323 #endif
324 #if sparc_TARGET_ARCH
325   = ALWAYS      -- What's really used? ToDo
326   | EQQ
327   | GE
328   | GEU
329   | GTT
330   | GU
331   | LE
332   | LEU
333   | LTT
334   | LU
335   | NE
336   | NEG
337   | NEVER
338   | POS
339   | VC
340   | VS
341 #endif
342 \end{code}
343
344 \begin{code}
345 data Size
346 #if alpha_TARGET_ARCH
347     = B     -- byte
348     | BU
349 --  | W     -- word (2 bytes): UNUSED
350 --  | WU    -- : UNUSED
351 --  | L     -- longword (4 bytes): UNUSED
352     | Q     -- quadword (8 bytes)
353 --  | FF    -- VAX F-style floating pt: UNUSED
354 --  | GF    -- VAX G-style floating pt: UNUSED
355 --  | DF    -- VAX D-style floating pt: UNUSED
356 --  | SF    -- IEEE single-precision floating pt: UNUSED
357     | TF    -- IEEE double-precision floating pt
358 #endif
359 #if i386_TARGET_ARCH
360     = B     -- byte (lower)
361 --  | HB    -- higher byte **UNUSED**
362 --  | S     -- : UNUSED
363     | L
364     | F     -- IEEE single-precision floating pt
365     | DF    -- IEEE single-precision floating pt
366 #endif
367 #if sparc_TARGET_ARCH
368     = B     -- byte (signed)
369     | BU    -- byte (unsigned)
370 --  | HW    -- halfword, 2 bytes (signed): UNUSED
371 --  | HWU   -- halfword, 2 bytes (unsigned): UNUSED
372     | W     -- word, 4 bytes
373 --  | D     -- doubleword, 8 bytes: UNUSED
374     | F     -- IEEE single-precision floating pt
375     | DF    -- IEEE single-precision floating pt
376 #endif
377
378 primRepToSize :: PrimRep -> Size
379
380 primRepToSize PtrRep        = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
381 primRepToSize CodePtrRep    = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
382 primRepToSize DataPtrRep    = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
383 primRepToSize RetRep        = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
384 primRepToSize CostCentreRep = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
385 primRepToSize CharRep       = IF_ARCH_alpha( BU, IF_ARCH_i386( L, IF_ARCH_sparc( BU,)))
386 primRepToSize IntRep        = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
387 primRepToSize WordRep       = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
388 primRepToSize AddrRep       = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
389 primRepToSize FloatRep      = IF_ARCH_alpha( TF, IF_ARCH_i386( F, IF_ARCH_sparc( F ,)))
390 primRepToSize DoubleRep     = IF_ARCH_alpha( TF, IF_ARCH_i386( DF,IF_ARCH_sparc( DF,)))
391 primRepToSize ArrayRep      = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
392 primRepToSize ByteArrayRep  = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
393 primRepToSize StablePtrRep  = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
394 primRepToSize ForeignObjRep  = IF_ARCH_alpha( Q,         IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
395 \end{code}
396
397 %************************************************************************
398 %*                                                                      *
399 \subsection{Machine's assembly language}
400 %*                                                                      *
401 %************************************************************************
402
403 We have a few common ``instructions'' (nearly all the pseudo-ops) but
404 mostly all of @Instr@ is machine-specific.
405
406 \begin{code}
407 data Instr
408   = COMMENT FAST_STRING         -- comment pseudo-op
409   | SEGMENT CodeSegment         -- {data,text} segment pseudo-op
410   | LABEL   CLabel              -- global label pseudo-op
411   | ASCII   Bool                -- True <=> needs backslash conversion
412             String              -- the literal string
413   | DATA    Size
414             [Imm]
415 \end{code}
416
417 \begin{code}
418 #if alpha_TARGET_ARCH
419
420 -- data Instr continues...
421
422 -- Loads and stores.
423
424               | LD            Size Reg Addr -- size, dst, src
425               | LDA           Reg Addr      -- dst, src
426               | LDAH          Reg Addr      -- dst, src
427               | LDGP          Reg Addr      -- dst, src
428               | LDI           Size Reg Imm  -- size, dst, src
429               | ST            Size Reg Addr -- size, src, dst
430
431 -- Int Arithmetic.
432
433               | CLR           Reg                   -- dst
434               | ABS           Size RI Reg           -- size, src, dst
435               | NEG           Size Bool RI Reg      -- size, overflow, src, dst
436               | ADD           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
437               | SADD          Size Size Reg RI Reg  -- size, scale, src, src, dst
438               | SUB           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
439               | SSUB          Size Size Reg RI Reg  -- size, scale, src, src, dst
440               | MUL           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
441               | DIV           Size Bool Reg RI Reg  -- size, unsigned, src, src, dst
442               | REM           Size Bool Reg RI Reg  -- size, unsigned, src, src, dst
443
444 -- Simple bit-twiddling.
445
446               | NOT           RI Reg
447               | AND           Reg RI Reg
448               | ANDNOT        Reg RI Reg
449               | OR            Reg RI Reg
450               | ORNOT         Reg RI Reg
451               | XOR           Reg RI Reg
452               | XORNOT        Reg RI Reg
453               | SLL           Reg RI Reg
454               | SRL           Reg RI Reg
455               | SRA           Reg RI Reg
456
457               | ZAP           Reg RI Reg
458               | ZAPNOT        Reg RI Reg
459
460               | NOP
461
462 -- Comparison
463
464               | CMP           Cond Reg RI Reg
465
466 -- Float Arithmetic.
467
468               | FCLR          Reg
469               | FABS          Reg Reg
470               | FNEG          Size Reg Reg
471               | FADD          Size Reg Reg Reg
472               | FDIV          Size Reg Reg Reg
473               | FMUL          Size Reg Reg Reg
474               | FSUB          Size Reg Reg Reg
475               | CVTxy         Size Size Reg Reg
476               | FCMP          Size Cond Reg Reg Reg
477               | FMOV          Reg Reg
478
479 -- Jumping around.
480
481               | BI            Cond Reg Imm
482               | BF            Cond Reg Imm
483               | BR            Imm
484               | JMP           Reg Addr Int
485               | BSR           Imm Int
486               | JSR           Reg Addr Int
487
488 -- Alpha-specific pseudo-ops.
489
490               | FUNBEGIN CLabel
491               | FUNEND CLabel
492
493 data RI
494   = RIReg Reg
495   | RIImm Imm
496
497 #endif {- alpha_TARGET_ARCH -}
498 \end{code}
499
500 \begin{code}
501 #if i386_TARGET_ARCH
502
503 -- data Instr continues...
504
505 -- Moves.
506
507               | MOV           Size Operand Operand
508               | MOVZX         Size Operand Operand -- size is the size of operand 2
509               | MOVSX         Size Operand Operand -- size is the size of operand 2
510
511 -- Load effective address (also a very useful three-operand add instruction :-)
512
513               | LEA           Size Operand Operand
514
515 -- Int Arithmetic.
516
517               | ADD           Size Operand Operand
518               | SUB           Size Operand Operand
519
520 -- Multiplication (signed and unsigned), Division (signed and unsigned),
521 -- result in %eax, %edx.
522
523               | IMUL          Size Operand Operand
524               | IDIV          Size Operand
525
526 -- Simple bit-twiddling.
527
528               | AND           Size Operand Operand
529               | OR            Size Operand Operand
530               | XOR           Size Operand Operand
531               | NOT           Size Operand
532               | NEGI          Size Operand -- NEG instruction (name clash with Cond)
533               | SHL           Size Operand Operand -- 1st operand must be an Imm
534               | SAR           Size Operand Operand -- 1st operand must be an Imm
535               | SHR           Size Operand Operand -- 1st operand must be an Imm
536               | NOP
537
538 -- Float Arithmetic. -- ToDo for 386
539
540 -- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single instructions
541 -- right up until we spit them out.
542
543               | SAHF          -- stores ah into flags
544               | FABS
545               | FADD          Size Operand -- src
546               | FADDP
547               | FIADD         Size Addr -- src
548               | FCHS
549               | FCOM          Size Operand -- src
550               | FCOS
551               | FDIV          Size Operand -- src
552               | FDIVP
553               | FIDIV         Size Addr -- src
554               | FDIVR         Size Operand -- src
555               | FDIVRP
556               | FIDIVR        Size Addr -- src
557               | FICOM         Size Addr -- src
558               | FILD          Size Addr Reg -- src, dst
559               | FIST          Size Addr -- dst
560               | FLD           Size Operand -- src
561               | FLD1
562               | FLDZ
563               | FMUL          Size Operand -- src
564               | FMULP
565               | FIMUL         Size Addr -- src
566               | FRNDINT
567               | FSIN
568               | FSQRT
569               | FST           Size Operand -- dst
570               | FSTP          Size Operand -- dst
571               | FSUB          Size Operand -- src
572               | FSUBP
573               | FISUB         Size Addr -- src
574               | FSUBR         Size Operand -- src
575               | FSUBRP
576               | FISUBR        Size Addr -- src
577               | FTST
578               | FCOMP         Size Operand -- src
579               | FUCOMPP
580               | FXCH
581               | FNSTSW
582               | FNOP
583
584 -- Comparison
585
586               | TEST          Size Operand Operand
587               | CMP           Size Operand Operand
588               | SETCC         Cond Operand
589
590 -- Stack Operations.
591
592               | PUSH          Size Operand
593               | POP           Size Operand
594
595 -- Jumping around.
596
597               | JMP           Operand -- target
598               | JXX           Cond CLabel -- target
599               | CALL          Imm
600
601 -- Other things.
602
603               | CLTD -- sign extend %eax into %edx:%eax
604
605 data Operand
606   = OpReg  Reg  -- register
607   | OpImm  Imm  -- immediate value
608   | OpAddr Addr -- memory reference
609
610 #endif {- i386_TARGET_ARCH -}
611 \end{code}
612
613 \begin{code}
614 #if sparc_TARGET_ARCH
615
616 -- data Instr continues...
617
618 -- Loads and stores.
619
620               | LD            Size Addr Reg -- size, src, dst
621               | ST            Size Reg Addr -- size, src, dst
622
623 -- Int Arithmetic.
624
625               | ADD           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
626               | SUB           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
627
628 -- Simple bit-twiddling.
629
630               | AND           Bool Reg RI Reg -- cc?, src1, src2, dst
631               | ANDN          Bool Reg RI Reg -- cc?, src1, src2, dst
632               | OR            Bool Reg RI Reg -- cc?, src1, src2, dst
633               | ORN           Bool Reg RI Reg -- cc?, src1, src2, dst
634               | XOR           Bool Reg RI Reg -- cc?, src1, src2, dst
635               | XNOR          Bool Reg RI Reg -- cc?, src1, src2, dst
636               | SLL           Reg RI Reg -- src1, src2, dst
637               | SRL           Reg RI Reg -- src1, src2, dst
638               | SRA           Reg RI Reg -- src1, src2, dst
639               | SETHI         Imm Reg -- src, dst
640               | NOP           -- Really SETHI 0, %g0, but worth an alias
641
642 -- Float Arithmetic.
643
644 -- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single instructions
645 -- right up until we spit them out.
646
647               | FABS          Size Reg Reg -- src dst
648               | FADD          Size Reg Reg Reg -- src1, src2, dst
649               | FCMP          Bool Size Reg Reg -- exception?, src1, src2, dst
650               | FDIV          Size Reg Reg Reg -- src1, src2, dst
651               | FMOV          Size Reg Reg -- src, dst
652               | FMUL          Size Reg Reg Reg -- src1, src2, dst
653               | FNEG          Size Reg Reg -- src, dst
654               | FSQRT         Size Reg Reg -- src, dst
655               | FSUB          Size Reg Reg Reg -- src1, src2, dst
656               | FxTOy         Size Size Reg Reg -- src, dst
657
658 -- Jumping around.
659
660               | BI            Cond Bool Imm -- cond, annul?, target
661               | BF            Cond Bool Imm -- cond, annul?, target
662
663               | JMP           Addr -- target
664               | CALL          Imm Int Bool -- target, args, terminal
665
666 data RI = RIReg Reg
667         | RIImm Imm
668
669 riZero :: RI -> Bool
670
671 riZero (RIImm (ImmInt 0))           = True
672 riZero (RIImm (ImmInteger 0))       = True
673 riZero (RIReg (FixedReg ILIT(0)))   = True
674 riZero _                            = False
675
676 #endif {- sparc_TARGET_ARCH -}
677 \end{code}