[project @ 1998-12-02 13:17:09 by simonm]
[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         sizeOf, primRepToSize,
12
13         eXTRA_STK_ARGS_HERE,
14
15         volatileSaves, volatileRestores,
16
17         targetMaxDouble, targetMaxInt, targetMinDouble, targetMinInt,
18
19         underscorePrefix,
20         fmtAsmLbl,
21         cvtLitLit,
22         exactLog2,
23
24         Instr(..),  IF_ARCH_i386(Operand(..) COMMA,)
25         Cond(..),
26         Size(..)
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
35 #endif
36     ) where
37
38 #include "HsVersions.h"
39 --#include "config.h"
40
41 import AbsCSyn          ( MagicId(..) ) 
42 import AbsCUtils        ( magicIdPrimRep )
43 import CLabel           ( CLabel )
44 import Const            ( mkMachInt, Literal(..) )
45 import MachRegs         ( stgReg, callerSaves, RegLoc(..),
46                           Imm(..), Reg(..), 
47                           MachRegsAddr(..)
48                         )
49 import PrimRep          ( PrimRep(..) )
50 import SMRep            ( SMRep(..) )
51 import Stix             ( StixTree(..), StixReg(..), CodeSegment )
52 import Util             ( panic )
53 import Char             ( isDigit )
54 import GlaExts          ( word2Int#, int2Word#, shiftRL#, and#, (/=#) )
55 \end{code}
56
57 \begin{code}
58 underscorePrefix :: Bool   -- leading underscore on assembler labels?
59
60 #ifdef LEADING_UNDERSCORE
61 underscorePrefix = True
62 #else
63 underscorePrefix = False
64 #endif
65
66 ---------------------------
67 fmtAsmLbl :: String -> String  -- for formatting labels
68
69 fmtAsmLbl s
70   =  IF_ARCH_alpha(
71      {- The alpha assembler likes temporary labels to look like $L123
72         instead of L123.  (Don't toss the L, because then Lf28
73         turns into $f28.)
74      -}
75      '$' : s
76      ,{-otherwise-}
77      s
78      )
79
80 ---------------------------
81 cvtLitLit :: String -> String
82
83 --
84 -- Rather than relying on guessing, use FILE_SIZE to compute the
85 -- _iob offsets.
86 --
87 cvtLitLit "stdin"  = IF_ARCH_alpha("_iob+0" {-probably OK...-}
88                     ,IF_ARCH_i386("_IO_stdin_"
89                     ,IF_ARCH_sparc("__iob+0x0"{-probably OK...-}
90                     ,)))
91
92 cvtLitLit "stdout" = IF_ARCH_alpha("_iob+"++show (``FILE_SIZE''::Int)
93                     ,IF_ARCH_i386("_IO_stdout_"
94                     ,IF_ARCH_sparc("__iob+"++show (``FILE_SIZE''::Int)
95                     ,)))
96 cvtLitLit "stderr" = IF_ARCH_alpha("_iob+"++show (2*(``FILE_SIZE''::Int))
97                     ,IF_ARCH_i386("_IO_stderr_"
98                     ,IF_ARCH_sparc("__iob+"++show (2*(``FILE_SIZE''::Int))
99                     ,)))
100 {-
101 cvtLitLit "stdout" = IF_ARCH_alpha("_iob+56"{-dodgy *at best*...-}
102                     ,IF_ARCH_i386("_IO_stdout_"
103                     ,IF_ARCH_sparc("__iob+0x10"{-dodgy *at best*...-}
104                     ,)))
105 cvtLitLit "stderr" = IF_ARCH_alpha("_iob+112"{-dodgy *at best*...-}
106                     ,IF_ARCH_i386("_IO_stderr_"
107                     ,IF_ARCH_sparc("__iob+0x20"{-dodgy *at best*...-}
108                     ,)))
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 Size of a @PrimRep@, in bytes.
133
134 \begin{code}
135 sizeOf :: PrimRep -> Integer{-in bytes-}
136     -- the result is an Integer only because it's more convenient
137
138 sizeOf pr = case (primRepToSize pr) of
139   IF_ARCH_alpha({B -> 1; BU -> 1; {-W -> 2; WU -> 2; L -> 4; SF -> 4;-} _ -> 8},)
140   IF_ARCH_sparc({B -> 1; BU -> 1; {-HW -> 2; HWU -> 2;-} W -> 4; {-D -> 8;-} F -> 4; DF -> 8},)
141   IF_ARCH_i386( {B -> 1; {-S -> 2;-} L -> 4; F -> 4; DF -> 8 },)
142 \end{code}
143
144 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
145
146 Now the volatile saves and restores.  We add the basic guys to the
147 list of ``user'' registers provided.  Note that there are more basic
148 registers on the restore list, because some are reloaded from
149 constants.
150
151 (@volatileRestores@ used only for wrapper-hungry PrimOps.)
152
153 \begin{code}
154 volatileSaves, volatileRestores :: [MagicId] -> [StixTree]
155
156 save_cands    = [BaseReg,Sp,Su,SpLim,Hp,HpLim]
157 restore_cands = save_cands
158
159 volatileSaves vols
160   = map save ((filter callerSaves) (save_cands ++ vols))
161   where
162     save x = StAssign (magicIdPrimRep x) loc reg
163       where
164         reg = StReg (StixMagicId x)
165         loc = case stgReg x of
166                 Save loc -> loc
167                 Always _ -> panic "volatileSaves"
168
169 volatileRestores vols
170   = map restore ((filter callerSaves) (restore_cands ++ vols))
171   where
172     restore x = StAssign (magicIdPrimRep x) reg loc
173       where
174         reg = StReg (StixMagicId x)
175         loc = case stgReg x of
176                 Save loc -> loc
177                 Always _ -> panic "volatileRestores"
178 \end{code}
179
180 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
181
182 Obviously slightly weedy
183 (Note that the floating point values aren't terribly important.)
184 ToDo: Fix!(JSM)
185 \begin{code}
186 targetMinDouble = MachDouble (-1.7976931348623157e+308)
187 targetMaxDouble = MachDouble (1.7976931348623157e+308)
188 targetMinInt = mkMachInt (-2147483648)
189 targetMaxInt = mkMachInt 2147483647
190 \end{code}
191
192 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
193
194 This algorithm for determining the $\log_2$ of exact powers of 2 comes
195 from GCC.  It requires bit manipulation primitives, and we use GHC
196 extensions.  Tough.
197
198 \begin{code}
199 w2i x = word2Int# x
200 i2w x = int2Word# x
201
202 exactLog2 :: Integer -> Maybe Integer
203 exactLog2 x
204   = if (x <= 0 || x >= 2147483648) then
205        Nothing
206     else
207        case (fromInteger x) of { I# x# ->
208        if (w2i ((i2w x#) `and#` (i2w (0# -# x#))) /=# x#) then
209           Nothing
210        else
211           Just (toInteger (I# (pow2 x#)))
212        }
213   where
214     shiftr x y = shiftRL# x y
215
216     pow2 x# | x# ==# 1# = 0#
217             | otherwise = 1# +# pow2 (w2i (i2w x# `shiftr` 1#))
218 \end{code}
219
220 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
221
222 \begin{code}
223 data Cond
224 #if alpha_TARGET_ARCH
225   = ALWAYS      -- For BI (same as BR)
226   | EQQ         -- For CMP and BI (NB: "EQ" is a 1.3 Prelude name)
227   | GE          -- For BI only
228   | GTT         -- For BI only (NB: "GT" is a 1.3 Prelude name)
229   | LE          -- For CMP and BI
230   | LTT         -- For CMP and BI (NB: "LT" is a 1.3 Prelude name)
231   | NE          -- For BI only
232   | NEVER       -- For BI (null instruction)
233   | ULE         -- For CMP only
234   | ULT         -- For CMP only
235 #endif
236 #if i386_TARGET_ARCH
237   = ALWAYS      -- What's really used? ToDo
238   | EQQ
239   | GE
240   | GEU
241   | GTT
242   | GU
243   | LE
244   | LEU
245   | LTT
246   | LU
247   | NE
248   | NEG
249   | POS
250 #endif
251 #if sparc_TARGET_ARCH
252   = ALWAYS      -- What's really used? ToDo
253   | EQQ
254   | GE
255   | GEU
256   | GTT
257   | GU
258   | LE
259   | LEU
260   | LTT
261   | LU
262   | NE
263   | NEG
264   | NEVER
265   | POS
266   | VC
267   | VS
268 #endif
269 \end{code}
270
271 \begin{code}
272 data Size
273 #if alpha_TARGET_ARCH
274     = B     -- byte
275     | BU
276 --  | W     -- word (2 bytes): UNUSED
277 --  | WU    -- : UNUSED
278 --  | L     -- longword (4 bytes): UNUSED
279     | Q     -- quadword (8 bytes)
280 --  | FF    -- VAX F-style floating pt: UNUSED
281 --  | GF    -- VAX G-style floating pt: UNUSED
282 --  | DF    -- VAX D-style floating pt: UNUSED
283 --  | SF    -- IEEE single-precision floating pt: UNUSED
284     | TF    -- IEEE double-precision floating pt
285 #endif
286 #if i386_TARGET_ARCH
287     = B     -- byte (lower)
288 --  | HB    -- higher byte **UNUSED**
289 --  | S     -- : UNUSED
290     | L
291     | F     -- IEEE single-precision floating pt
292     | DF    -- IEEE single-precision floating pt
293 #endif
294 #if sparc_TARGET_ARCH
295     = B     -- byte (signed)
296     | BU    -- byte (unsigned)
297 --  | HW    -- halfword, 2 bytes (signed): UNUSED
298 --  | HWU   -- halfword, 2 bytes (unsigned): UNUSED
299     | W     -- word, 4 bytes
300 --  | D     -- doubleword, 8 bytes: UNUSED
301     | F     -- IEEE single-precision floating pt
302     | DF    -- IEEE single-precision floating pt
303 #endif
304
305 primRepToSize :: PrimRep -> Size
306
307 primRepToSize PtrRep        = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
308 primRepToSize CodePtrRep    = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
309 primRepToSize DataPtrRep    = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
310 primRepToSize RetRep        = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
311 primRepToSize CostCentreRep = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
312 primRepToSize CharRep       = IF_ARCH_alpha( BU, IF_ARCH_i386( L, IF_ARCH_sparc( BU,)))
313 primRepToSize IntRep        = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
314 primRepToSize WordRep       = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
315 primRepToSize AddrRep       = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
316 primRepToSize FloatRep      = IF_ARCH_alpha( TF, IF_ARCH_i386( F, IF_ARCH_sparc( F ,)))
317 primRepToSize DoubleRep     = IF_ARCH_alpha( TF, IF_ARCH_i386( DF,IF_ARCH_sparc( DF,)))
318 primRepToSize ArrayRep      = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
319 primRepToSize ByteArrayRep  = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
320 primRepToSize WeakPtrRep    = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
321 primRepToSize ForeignObjRep  = IF_ARCH_alpha( Q, IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
322 primRepToSize StablePtrRep  = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
323 \end{code}
324
325 %************************************************************************
326 %*                                                                      *
327 \subsection{Machine's assembly language}
328 %*                                                                      *
329 %************************************************************************
330
331 We have a few common ``instructions'' (nearly all the pseudo-ops) but
332 mostly all of @Instr@ is machine-specific.
333
334 \begin{code}
335 data Instr
336   = COMMENT FAST_STRING         -- comment pseudo-op
337   | SEGMENT CodeSegment         -- {data,text} segment pseudo-op
338   | LABEL   CLabel              -- global label pseudo-op
339   | ASCII   Bool                -- True <=> needs backslash conversion
340             String              -- the literal string
341   | DATA    Size
342             [Imm]
343 \end{code}
344
345 \begin{code}
346 #if alpha_TARGET_ARCH
347
348 -- data Instr continues...
349
350 -- Loads and stores.
351
352               | LD            Size Reg MachRegsAddr -- size, dst, src
353               | LDA           Reg MachRegsAddr      -- dst, src
354               | LDAH          Reg MachRegsAddr      -- dst, src
355               | LDGP          Reg MachRegsAddr      -- dst, src
356               | LDI           Size Reg Imm     -- size, dst, src
357               | ST            Size Reg MachRegsAddr -- size, src, dst
358
359 -- Int Arithmetic.
360
361               | CLR           Reg                   -- dst
362               | ABS           Size RI Reg           -- size, src, dst
363               | NEG           Size Bool RI Reg      -- size, overflow, src, dst
364               | ADD           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
365               | SADD          Size Size Reg RI Reg  -- size, scale, src, src, dst
366               | SUB           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
367               | SSUB          Size Size Reg RI Reg  -- size, scale, src, src, dst
368               | MUL           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
369               | DIV           Size Bool Reg RI Reg  -- size, unsigned, src, src, dst
370               | REM           Size Bool Reg RI Reg  -- size, unsigned, src, src, dst
371
372 -- Simple bit-twiddling.
373
374               | NOT           RI Reg
375               | AND           Reg RI Reg
376               | ANDNOT        Reg RI Reg
377               | OR            Reg RI Reg
378               | ORNOT         Reg RI Reg
379               | XOR           Reg RI Reg
380               | XORNOT        Reg RI Reg
381               | SLL           Reg RI Reg
382               | SRL           Reg RI Reg
383               | SRA           Reg RI Reg
384
385               | ZAP           Reg RI Reg
386               | ZAPNOT        Reg RI Reg
387
388               | NOP
389
390 -- Comparison
391
392               | CMP           Cond Reg RI Reg
393
394 -- Float Arithmetic.
395
396               | FCLR          Reg
397               | FABS          Reg Reg
398               | FNEG          Size Reg Reg
399               | FADD          Size Reg Reg Reg
400               | FDIV          Size Reg Reg Reg
401               | FMUL          Size Reg Reg Reg
402               | FSUB          Size Reg Reg Reg
403               | CVTxy         Size Size Reg Reg
404               | FCMP          Size Cond Reg Reg Reg
405               | FMOV          Reg Reg
406
407 -- Jumping around.
408
409               | BI            Cond Reg Imm
410               | BF            Cond Reg Imm
411               | BR            Imm
412               | JMP           Reg MachRegsAddr Int
413               | BSR           Imm Int
414               | JSR           Reg MachRegsAddr Int
415
416 -- Alpha-specific pseudo-ops.
417
418               | FUNBEGIN CLabel
419               | FUNEND CLabel
420
421 data RI
422   = RIReg Reg
423   | RIImm Imm
424
425 #endif {- alpha_TARGET_ARCH -}
426 \end{code}
427
428 \begin{code}
429 #if i386_TARGET_ARCH
430
431 -- data Instr continues...
432
433 -- Moves.
434
435               | MOV           Size Operand Operand
436               | MOVZX         Size Operand Operand -- size is the size of operand 2
437               | MOVSX         Size Operand Operand -- size is the size of operand 2
438
439 -- Load effective address (also a very useful three-operand add instruction :-)
440
441               | LEA           Size Operand Operand
442
443 -- Int Arithmetic.
444
445               | ADD           Size Operand Operand
446               | SUB           Size Operand Operand
447
448 -- Multiplication (signed and unsigned), Division (signed and unsigned),
449 -- result in %eax, %edx.
450
451               | IMUL          Size Operand Operand
452               | IDIV          Size Operand
453
454 -- Simple bit-twiddling.
455
456               | AND           Size Operand Operand
457               | OR            Size Operand Operand
458               | XOR           Size Operand Operand
459               | NOT           Size Operand
460               | NEGI          Size Operand -- NEG instruction (name clash with Cond)
461               | SHL           Size Operand Operand -- 1st operand must be an Imm or CL
462               | SAR           Size Operand Operand -- 1st operand must be an Imm or CL
463               | SHR           Size Operand Operand -- 1st operand must be an Imm or CL
464               | NOP
465
466 -- Float Arithmetic. -- ToDo for 386
467
468 -- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single instructions
469 -- right up until we spit them out.
470
471               | SAHF          -- stores ah into flags
472               | FABS
473               | FADD          Size Operand -- src
474               | FADDP
475               | FIADD         Size MachRegsAddr -- src
476               | FCHS
477               | FCOM          Size Operand -- src
478               | FCOS
479               | FDIV          Size Operand -- src
480               | FDIVP
481               | FIDIV         Size MachRegsAddr -- src
482               | FDIVR         Size Operand -- src
483               | FDIVRP
484               | FIDIVR        Size MachRegsAddr -- src
485               | FICOM         Size MachRegsAddr -- src
486               | FILD          Size MachRegsAddr Reg -- src, dst
487               | FIST          Size MachRegsAddr -- dst
488               | FLD           Size Operand -- src
489               | FLD1
490               | FLDZ
491               | FMUL          Size Operand -- src
492               | FMULP
493               | FIMUL         Size MachRegsAddr -- src
494               | FRNDINT
495               | FSIN
496               | FSQRT
497               | FST           Size Operand -- dst
498               | FSTP          Size Operand -- dst
499               | FSUB          Size Operand -- src
500               | FSUBP
501               | FISUB         Size MachRegsAddr -- src
502               | FSUBR         Size Operand -- src
503               | FSUBRP
504               | FISUBR        Size MachRegsAddr -- src
505               | FTST
506               | FCOMP         Size Operand -- src
507               | FUCOMPP
508               | FXCH
509               | FNSTSW
510               | FNOP
511
512 -- Comparison
513
514               | TEST          Size Operand Operand
515               | CMP           Size Operand Operand
516               | SETCC         Cond Operand
517
518 -- Stack Operations.
519
520               | PUSH          Size Operand
521               | POP           Size Operand
522
523 -- Jumping around.
524
525               | JMP           Operand -- target
526               | JXX           Cond CLabel -- target
527               | CALL          Imm
528
529 -- Other things.
530
531               | CLTD -- sign extend %eax into %edx:%eax
532
533 data Operand
534   = OpReg  Reg          -- register
535   | OpImm  Imm          -- immediate value
536   | OpAddr MachRegsAddr -- memory reference
537
538 #endif {- i386_TARGET_ARCH -}
539 \end{code}
540
541 \begin{code}
542 #if sparc_TARGET_ARCH
543
544 -- data Instr continues...
545
546 -- Loads and stores.
547
548               | LD            Size MachRegsAddr Reg -- size, src, dst
549               | ST            Size Reg MachRegsAddr -- size, src, dst
550
551 -- Int Arithmetic.
552
553               | ADD           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
554               | SUB           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
555
556 -- Simple bit-twiddling.
557
558               | AND           Bool Reg RI Reg -- cc?, src1, src2, dst
559               | ANDN          Bool Reg RI Reg -- cc?, src1, src2, dst
560               | OR            Bool Reg RI Reg -- cc?, src1, src2, dst
561               | ORN           Bool Reg RI Reg -- cc?, src1, src2, dst
562               | XOR           Bool Reg RI Reg -- cc?, src1, src2, dst
563               | XNOR          Bool Reg RI Reg -- cc?, src1, src2, dst
564               | SLL           Reg RI Reg -- src1, src2, dst
565               | SRL           Reg RI Reg -- src1, src2, dst
566               | SRA           Reg RI Reg -- src1, src2, dst
567               | SETHI         Imm Reg -- src, dst
568               | NOP           -- Really SETHI 0, %g0, but worth an alias
569
570 -- Float Arithmetic.
571
572 -- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single instructions
573 -- right up until we spit them out.
574
575               | FABS          Size Reg Reg -- src dst
576               | FADD          Size Reg Reg Reg -- src1, src2, dst
577               | FCMP          Bool Size Reg Reg -- exception?, src1, src2, dst
578               | FDIV          Size Reg Reg Reg -- src1, src2, dst
579               | FMOV          Size Reg Reg -- src, dst
580               | FMUL          Size Reg Reg Reg -- src1, src2, dst
581               | FNEG          Size Reg Reg -- src, dst
582               | FSQRT         Size Reg Reg -- src, dst
583               | FSUB          Size Reg Reg Reg -- src1, src2, dst
584               | FxTOy         Size Size Reg Reg -- src, dst
585
586 -- Jumping around.
587
588               | BI            Cond Bool Imm -- cond, annul?, target
589               | BF            Cond Bool Imm -- cond, annul?, target
590
591               | JMP           MachRegsAddr      -- target
592               | CALL          Imm Int Bool -- target, args, terminal
593
594 data RI = RIReg Reg
595         | RIImm Imm
596
597 riZero :: RI -> Bool
598
599 riZero (RIImm (ImmInt 0))           = True
600 riZero (RIImm (ImmInteger 0))       = True
601 riZero (RIReg (FixedReg ILIT(0)))   = True
602 riZero _                            = False
603
604 #endif {- sparc_TARGET_ARCH -}
605 \end{code}