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