%
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
-% $Id: AbsCSyn.lhs,v 1.41 2001/12/05 17:35:12 sewardj Exp $
+% $Id: AbsCSyn.lhs,v 1.42 2001/12/06 11:50:07 sewardj Exp $
%
\section[AbstractC]{Abstract C: the last stop before machine code}
| CMem PrimRep -- A value :: PrimRep, in memory, at the
CAddrMode -- specified address
+
+ | CBytesPerWord -- Word size, in bytes, on this platform
\end{code}
Various C macros for values which are dependent on the back-end layout.
isDynamicTarget, isCasmTarget, defaultCCallConv )
import StgSyn ( StgOp(..) )
import SMRep ( arrPtrsHdrSize, arrWordsHdrSize, fixedHdrSize )
-import Constants ( wORD_SIZE )
import Maybes ( Maybe012(..) )
import Outputable
import Panic ( panic )
-- Assumes no volatiles
mkHalfWord_HIADDR res arg
-# if WORDS_BIGENDIAN
- = CMachOpStmt (Just1 res) MO_Nat_And [arg, CLit (mkMachWord halfword_mask)] Nothing
-# else
- = CMachOpStmt (Just1 res) MO_Nat_Shr [arg, CLit (mkMachWord halfword_shift)] Nothing
-# endif
- where
- (halfword_mask, halfword_shift)
- | wORD_SIZE == 4 = (65535, 16)
- | wORD_SIZE == 8 = (4294967295::Integer, 32)
+ = mkTemp IntRep `thenFlt` \ t_hw_shift ->
+ mkTemp WordRep `thenFlt` \ t_hw_mask1 ->
+ mkTemp WordRep `thenFlt` \ t_hw_mask2 ->
+ let a_hw_shift
+ = CMachOpStmt (Just1 t_hw_shift)
+ MO_Nat_Shl [CBytesPerWord, CLit (mkMachInt 2)] Nothing
+ a_hw_mask1
+ = CMachOpStmt (Just1 t_hw_mask1)
+ MO_Nat_Shl [CLit (mkMachWord 1), t_hw_shift] Nothing
+ a_hw_mask2
+ = CMachOpStmt (Just1 t_hw_mask2)
+ MO_Nat_Sub [t_hw_mask1, CLit (mkMachWord 1)] Nothing
+ final
+# if WORDS_BIGENDIAN
+ = CSequential [ a_hw_shift, a_hw_mask1, a_hw_mask2,
+ CMachOpStmt (Just1 res) MO_Nat_And [arg, t_hw_mask2] Nothing
+ ]
+# else
+ = CSequential [ a_hw_shift,
+ CMachOpStmt (Just1 res) MO_Nat_Shr [arg, t_hw_shift] Nothing
+ ]
+# endif
+ in
+ returnFlt final
mkTemp :: PrimRep -> FlatM CAddrMode
(returnFlt . CSequential) [
CAssign w (mkDerefOff WordRep arg fixedHdrSize),
CMachOpStmt (Just1 w)
- MO_NatU_Mul [w, CLit (mkMachInt (toInteger wORD_SIZE))] (Just vols),
+ MO_NatU_Mul [w, CBytesPerWord] (Just vols),
CAssign res w
]
-- #define dataToTagzh(r,a) r=(GET_TAG(((StgClosure *)a)->header.info))
dscCOpStmt [res] DataToTagOp [arg] vols
= mkTemps [PtrRep, WordRep] `thenFlt` \ [t_infoptr, t_theword] ->
+ mkHalfWord_HIADDR res t_theword `thenFlt` \ select_ops ->
(returnFlt . CSequential) [
CAssign t_infoptr (mkDerefOff PtrRep arg 0),
CAssign t_theword (mkDerefOff WordRep t_infoptr (-1)),
- mkHalfWord_HIADDR res t_theword
+ select_ops
]
mixedPtrLocn, mixedTypeLocn
)
-import Constants ( mIN_UPD_SIZE, wORD_SIZE )
+import Constants ( mIN_UPD_SIZE )
import ForeignCall ( CCallSpec(..), CCallTarget(..), playSafe, ccallConvAttribute )
import CLabel ( externallyVisibleCLabel,
needsCDecl, pprCLabel,
-- * (scaleRep*) (
-- ((char*)baseAmode) + offw*bytes_per_word + indexAmode*bytes_per_scaleRep
-- )
- = let offb = parens (int offw <> char '*' <> int wORD_SIZE)
+ = let offb = parens (int offw <> char '*' <> text "sizeof(void*)")
indb = parens (parens (pprAmode indexAmode)
<> char '*' <> int (getPrimRepArrayElemSize scaleRep))
baseb = text "(char*)" <> parens (pprAmode baseAmode)
amode has kind2.
\begin{code}
+ppr_amode CBytesPerWord
+ = text "(sizeof(void*))"
+
ppr_amode (CMem rep addr)
= let txt_rep = pprPrimKind rep
in hcat [ char '*', parens (txt_rep <> char '*'), parens (ppr_amode addr) ]
MO_Nat_Ne -> StInt (if x /= y then 1 else 0)
MO_NatS_Lt -> StInt (if x < y then 1 else 0)
MO_NatS_Le -> StInt (if x <= y then 1 else 0)
+ MO_Nat_Shl | y >= 0 && y < 32 -> do_shl x y
other -> StMachOp mop args
+ where
+ do_shl :: Integer -> Integer -> StixExpr
+ do_shl v 0 = StInt v
+ do_shl v n | n > 0 = do_shl (v*2) (n-1)
\end{code}
When possible, shift the constants to the right-hand side, so that we
import MachOp ( MachOp(..) )
import PrimRep ( PrimRep(..), getPrimRepSizeInBytes )
import UniqSupply ( returnUs, thenUs, getUniqueUs, UniqSM )
-import Constants ( mIN_INTLIKE, mIN_CHARLIKE, uF_UPDATEE, bLOCK_SIZE,
+import Constants ( wORD_SIZE,
+ mIN_INTLIKE, mIN_CHARLIKE, uF_UPDATEE, bLOCK_SIZE,
rESERVED_STACK_WORDS )
import CLabel ( mkIntlikeClosureLabel, mkCharlikeClosureLabel,
mkMAP_FROZEN_infoLabel, mkEMPTY_MVAR_infoLabel,
amodeToStix (CVal rr pk) = StInd pk (amodeToStix (CAddr rr))
+amodeToStix CBytesPerWord
+ = StInt (toInteger wORD_SIZE)
+
amodeToStix (CMem pk addr) = StInd pk (amodeToStix addr)
amodeToStix (CAddr (SpRel off))