summaryrefslogtreecommitdiff
path: root/ghc/compiler/nativeGen/AsmCodeGen.lhs
diff options
context:
space:
mode:
Diffstat (limited to 'ghc/compiler/nativeGen/AsmCodeGen.lhs')
-rw-r--r--ghc/compiler/nativeGen/AsmCodeGen.lhs150
1 files changed, 37 insertions, 113 deletions
diff --git a/ghc/compiler/nativeGen/AsmCodeGen.lhs b/ghc/compiler/nativeGen/AsmCodeGen.lhs
index 47bc965c8f..da0d83bb7a 100644
--- a/ghc/compiler/nativeGen/AsmCodeGen.lhs
+++ b/ghc/compiler/nativeGen/AsmCodeGen.lhs
@@ -8,19 +8,17 @@
#include "../../includes/GhcConstants.h"
module AsmCodeGen (
-#ifdef __GLASGOW_HASKELL__
writeRealAsm,
-#endif
dumpRealAsm,
-- And, I guess we need these...
AbstractC, GlobalSwitch, SwitchResult,
- SplitUniqSupply, SUniqSM(..)
+ UniqSupply, UniqSM(..)
) where
import AbsCSyn ( AbstractC )
import AbsCStixGen ( genCodeAbstractC )
-import AbsPrel ( PrimKind, PrimOp(..)
+import PrelInfo ( PrimRep, PrimOp(..)
IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
)
@@ -38,14 +36,9 @@ import I386Desc ( mkI386 )
import SparcDesc ( mkSparc )
#endif
import Stix
-import SplitUniq
-import Unique
+import UniqSupply
import Unpretty
import Util
-#if defined(__HBC__)
-import
- Word
-#endif
\end{code}
This is a generic assembly language generator for the Glasgow Haskell
@@ -73,7 +66,7 @@ There are two main components to the code generator.
with a Twig-like system handling each statement in turn.
\item A scheduler turns the tree of assembly language orderings
into a sequence suitable for input to an assembler.
-\end{itemize}
+\end{itemize}
The @codeGenerate@ function returns the final assembly language output
(as a String). We can return a string, because there is only one way
of printing the output suitable for assembler consumption. It also
@@ -86,13 +79,13 @@ instructions. The generic algorithm is heavily inspired by Twig
(ref), but also draws concepts from (ref). The basic idea is to
(dynamically) walk the Abstract C syntax tree, annotating it with
possible code matches. For example, on the Sparc, a possible match
-(with its translation) could be
-@
- :=
- / \
- i r2 => ST r2,[r1]
+(with its translation) could be
+@
+ :=
+ / \
+ i r2 => ST r2,[r1]
|
- r1
+ r1
@
where @r1,r2@ are registers, and @i@ is an indirection. The Twig
bit twiddling algorithm for tree matching has been abandoned. It is
@@ -120,27 +113,20 @@ The flag that needs to be added is -fasm-<platform> where platform is one of
the choices below.
\begin{code}
-
-#ifdef __GLASGOW_HASKELL__
-# if __GLASGOW_HASKELL__ < 23
-# define _FILE _Addr
-# endif
-writeRealAsm :: (GlobalSwitch -> SwitchResult) -> _FILE -> AbstractC -> SplitUniqSupply -> PrimIO ()
+writeRealAsm :: (GlobalSwitch -> SwitchResult) -> _FILE -> AbstractC -> UniqSupply -> PrimIO ()
writeRealAsm flags file absC uniq_supply
= uppAppendFile file 80 (runNCG (code flags absC) uniq_supply)
-#endif
-
-dumpRealAsm :: (GlobalSwitch -> SwitchResult) -> AbstractC -> SplitUniqSupply -> String
+dumpRealAsm :: (GlobalSwitch -> SwitchResult) -> AbstractC -> UniqSupply -> String
dumpRealAsm flags absC uniq_supply = uppShow 80 (runNCG (code flags absC) uniq_supply)
runNCG m uniq_supply = m uniq_supply
code flags absC =
- genCodeAbstractC target absC `thenSUs` \ treelists ->
- let
+ genCodeAbstractC target absC `thenUs` \ treelists ->
+ let
stix = map (map (genericOpt target)) treelists
in
codeGen {-target-} sty stix
@@ -163,7 +149,7 @@ code flags absC =
Just _ {-???"sparc-sun-solaris2"-} -> mkSparc False flags
# endif
#endif
- _ -> error
+ _ -> error
("ERROR:Trying to generate assembly language for an unsupported architecture\n"++
"(or one for which this build is not configured).")
@@ -186,9 +172,9 @@ introduced some new opportunities for constant-folding wrt address manipulations
\begin{code}
-genericOpt
- :: Target
- -> StixTree
+genericOpt
+ :: Target
+ -> StixTree
-> StixTree
\end{code}
@@ -222,11 +208,11 @@ Fold indices together when the types match.
genericOpt target (StIndex pk (StIndex pk' base off) off')
| pk == pk' =
- StIndex pk (genericOpt target base)
+ StIndex pk (genericOpt target base)
(genericOpt target (StPrim IntAddOp [off, off']))
genericOpt target (StIndex pk base off) =
- StIndex pk (genericOpt target base)
+ StIndex pk (genericOpt target base)
(genericOpt target off)
\end{code}
@@ -246,8 +232,8 @@ Replace register leaves with appropriate StixTrees for the given target.
\begin{code}
-genericOpt target leaf@(StReg (StixMagicId id)) =
- case stgReg target id of
+genericOpt target leaf@(StReg (StixMagicId id)) =
+ case stgReg target id of
Always tree -> genericOpt target tree
Save _ -> leaf
@@ -271,7 +257,7 @@ primOpt op arg@[StInt x] =
IntAbsOp -> StInt (abs x)
_ -> StPrim op arg
-primOpt op args@[StInt x, StInt y] =
+primOpt op args@[StInt x, StInt y] =
case op of
CharGtOp -> StInt (if x > y then 1 else 0)
CharGeOp -> StInt (if x >= y then 1 else 0)
@@ -299,18 +285,13 @@ can match for strength reductions. Note that the code generator will
also assume that constants have been shifted to the right when possible.
\begin{code}
-
-primOpt op [x@(StInt _), y] | commutableOp op = primOpt op [y, x]
---OLD:
---primOpt op [x@(StDouble _), y] | commutableOp op = primOpt op [y, x]
-
+primOpt op [x@(StInt _), y] | commutableOp op = primOpt op [y, x]
\end{code}
We can often do something with constants of 0 and 1 ...
\begin{code}
-
-primOpt op args@[x, y@(StInt 0)] =
+primOpt op args@[x, y@(StInt 0)] =
case op of
IntAddOp -> x
IntSubOp -> x
@@ -325,73 +306,40 @@ primOpt op args@[x, y@(StInt 0)] =
ISrlOp -> x
_ -> StPrim op args
-primOpt op args@[x, y@(StInt 1)] =
+primOpt op args@[x, y@(StInt 1)] =
case op of
IntMulOp -> x
IntQuotOp -> x
IntRemOp -> StInt 0
_ -> StPrim op args
-
--- The following code tweaks a bug in early versions of GHC (pre-0.21)
-
-{- OLD: (death to constant folding in ncg)
-primOpt op args@[x, y@(StDouble 0.0)] =
- case op of
- FloatAddOp -> x
- FloatSubOp -> x
- FloatMulOp -> y
- DoubleAddOp -> x
- DoubleSubOp -> x
- DoubleMulOp -> y
- _ -> StPrim op args
-
-primOpt op args@[x, y@(StDouble 1.0)] =
- case op of
- FloatMulOp -> x
- FloatDivOp -> x
- DoubleMulOp -> x
- DoubleDivOp -> x
- _ -> StPrim op args
-
-primOpt op args@[x, y@(StDouble 2.0)] =
- case op of
- FloatMulOp -> StPrim FloatAddOp [x, x]
- DoubleMulOp -> StPrim DoubleAddOp [x, x]
- _ -> StPrim op args
--}
-
\end{code}
Now look for multiplication/division by powers of 2 (integers).
\begin{code}
-
-primOpt op args@[x, y@(StInt n)] =
+primOpt op args@[x, y@(StInt n)] =
case op of
IntMulOp -> case exact_log2 n of
- Nothing -> StPrim op args
+ Nothing -> StPrim op args
Just p -> StPrim SllOp [x, StInt p]
IntQuotOp -> case exact_log2 n of
- Nothing -> StPrim op args
+ Nothing -> StPrim op args
Just p -> StPrim SraOp [x, StInt p]
_ -> StPrim op args
-
\end{code}
Anything else is just too hard.
\begin{code}
-
primOpt op args = StPrim op args
-
\end{code}
-The commutable ops are those for which we will try to move constants to the
-right hand side for strength reduction.
+The commutable ops are those for which we will try to move constants
+to the right hand side for strength reduction.
\begin{code}
-
commutableOp :: PrimOp -> Bool
+
commutableOp CharEqOp = True
commutableOp CharNeOp = True
commutableOp IntAddOp = True
@@ -411,50 +359,26 @@ commutableOp DoubleMulOp = True
commutableOp DoubleEqOp = True
commutableOp DoubleNeOp = True
commutableOp _ = False
-
\end{code}
-This algorithm for determining the $\log_2$ of exact powers of 2 comes from gcc. It
-requires bit manipulation primitives, so we have a ghc version and an hbc version.
-Other Haskell compilers are on their own.
+This algorithm for determining the $\log_2$ of exact powers of 2 comes
+from gcc. It requires bit manipulation primitives, so we have a ghc
+version and an hbc version. Other Haskell compilers are on their own.
\begin{code}
-
-#ifdef __GLASGOW_HASKELL__
-
w2i x = word2Int# x
i2w x = int2Word# x
i2w_s x = (x::Int#)
exact_log2 :: Integer -> Maybe Integer
-exact_log2 x
+exact_log2 x
| x <= 0 || x >= 2147483648 = Nothing
| otherwise = case fromInteger x of
- I# x# -> if (w2i ((i2w x#) `and#` (i2w (0# -# x#))) /=# x#) then Nothing
+ I# x# -> if (w2i ((i2w x#) `and#` (i2w (0# -# x#))) /=# x#) then Nothing
else Just (toInteger (I# (pow2 x#)))
where pow2 x# | x# ==# 1# = 0#
| otherwise = 1# +# pow2 (w2i (i2w x# `shiftr` i2w_s 1#))
-# if __GLASGOW_HASKELL__ >= 23
shiftr x y = shiftRA# x y
-# else
- shiftr x y = shiftR# x y
-# endif
-
-#else {-probably HBC-}
-
-exact_log2 :: Integer -> Maybe Integer
-exact_log2 x
- | x <= 0 || x >= 2147483648 = Nothing
- | otherwise =
- if x' `bitAnd` (-x') /= x' then Nothing
- else Just (toInteger (pow2 x'))
-
- where x' = ((fromInteger x) :: Word)
- pow2 x | x == bit0 = 0 :: Int
- | otherwise = 1 + pow2 (x `bitRsh` 1)
-
-#endif {-probably HBC-}
-
\end{code}