2 % (c) The AQUA Project, Glasgow University, 1993-1998
6 module StixPrim ( primCode, amodeToStix, amodeToStix' ) where
8 #include "HsVersions.h"
14 import AbsCSyn hiding ( spRel )
15 import AbsCUtils ( getAmodeRep, mixedTypeLocn )
16 import SMRep ( fixedHdrSize )
17 import Literal ( Literal(..), word2IntLit )
18 import PrimOp ( PrimOp(..), CCall(..), CCallTarget(..) )
19 import PrimRep ( PrimRep(..), isFloatingRep )
20 import UniqSupply ( returnUs, thenUs, getUniqueUs, UniqSM )
21 import Constants ( mIN_INTLIKE, mIN_CHARLIKE, uF_UPDATEE, bLOCK_SIZE,
22 rESERVED_STACK_WORDS )
23 import CLabel ( mkIntlikeClosureLabel, mkCharlikeClosureLabel,
24 mkMAP_FROZEN_infoLabel, mkForeignLabel )
30 The main honcho here is primCode, which handles the guts of COpStmts.
34 :: [CAddrMode] -- results
36 -> [CAddrMode] -- args
37 -> UniqSM StixTreeList
40 First, the dreaded @ccall@. We can't handle @casm@s.
42 Usually, this compiles to an assignment, but when the left-hand side
43 is empty, we just perform the call and ignore the result.
45 btw Why not let programmer use casm to provide assembly code instead
48 The (MP) integer operations are a true nightmare. Since we don't have
49 a convenient abstract way of allocating temporary variables on the (C)
50 stack, we use the space just below HpLim for the @MP_INT@ structures,
51 and modify our heap check accordingly.
54 -- NB: ordering of clauses somewhere driven by
55 -- the desire to getting sane patt-matching behavior
56 primCode res@[sr,dr] IntegerNegOp arg@[sa,da]
57 = gmpNegate (sr,dr) (sa,da)
59 primCode [res] IntegerCmpOp args@[sa1,da1, sa2,da2]
60 = gmpCompare res (sa1,da1, sa2,da2)
62 primCode [res] IntegerCmpIntOp args@[sa1,da1,ai]
63 = gmpCompareInt res (sa1,da1,ai)
65 primCode [res] Integer2IntOp arg@[sa,da]
66 = gmpInteger2Int res (sa,da)
68 primCode [res] Integer2WordOp arg@[sa,da]
69 = gmpInteger2Word res (sa,da)
71 primCode [res] Int2AddrOp [arg]
72 = simpleCoercion AddrRep res arg
74 primCode [res] Addr2IntOp [arg]
75 = simpleCoercion IntRep res arg
77 primCode [res] Int2WordOp [arg]
78 = simpleCoercion IntRep{-WordRep?-} res arg
80 primCode [res] Word2IntOp [arg]
81 = simpleCoercion IntRep res arg
85 primCode [res] SameMutableArrayOp args
87 compare = StPrim AddrEqOp (map amodeToStix args)
88 assign = StAssign IntRep (amodeToStix res) compare
90 returnUs (\xs -> assign : xs)
92 primCode res@[_] SameMutableByteArrayOp args
93 = primCode res SameMutableArrayOp args
95 primCode res@[_] SameMutVarOp args
96 = primCode res SameMutableArrayOp args
98 primCode res@[_] SameMVarOp args
99 = primCode res SameMutableArrayOp args
102 Freezing an array of pointers is a double assignment. We fix the
103 header of the ``new'' closure because the lhs is probably a better
104 addressing mode for the indirection (most likely, it's a VanillaReg).
108 primCode [lhs] UnsafeFreezeArrayOp [rhs]
110 lhs' = amodeToStix lhs
111 rhs' = amodeToStix rhs
112 header = StInd PtrRep lhs'
113 assign = StAssign PtrRep lhs' rhs'
114 freeze = StAssign PtrRep header mutArrPtrsFrozen_info
116 returnUs (\xs -> assign : freeze : xs)
118 primCode [lhs] UnsafeFreezeByteArrayOp [rhs]
119 = simpleCoercion PtrRep lhs rhs
122 Returning the size of (mutable) byte arrays is just
123 an indexing operation.
126 primCode [lhs] SizeofByteArrayOp [rhs]
128 lhs' = amodeToStix lhs
129 rhs' = amodeToStix rhs
130 sz = StIndex IntRep rhs' fixedHS
131 assign = StAssign IntRep lhs' (StInd IntRep sz)
133 returnUs (\xs -> assign : xs)
135 primCode [lhs] SizeofMutableByteArrayOp [rhs]
137 lhs' = amodeToStix lhs
138 rhs' = amodeToStix rhs
139 sz = StIndex IntRep rhs' fixedHS
140 assign = StAssign IntRep lhs' (StInd IntRep sz)
142 returnUs (\xs -> assign : xs)
146 Most other array primitives translate to simple indexing.
149 primCode lhs@[_] IndexArrayOp args
150 = primCode lhs ReadArrayOp args
152 primCode [lhs] ReadArrayOp [obj, ix]
154 lhs' = amodeToStix lhs
155 obj' = amodeToStix obj
157 base = StIndex IntRep obj' arrPtrsHS
158 assign = StAssign PtrRep lhs' (StInd PtrRep (StIndex PtrRep base ix'))
160 returnUs (\xs -> assign : xs)
162 primCode [] WriteArrayOp [obj, ix, v]
164 obj' = amodeToStix obj
167 base = StIndex IntRep obj' arrPtrsHS
168 assign = StAssign PtrRep (StInd PtrRep (StIndex PtrRep base ix')) v'
170 returnUs (\xs -> assign : xs)
172 primCode [] WriteForeignObjOp [obj, v]
174 obj' = amodeToStix obj
176 obj'' = StIndex AddrRep obj' (StInt 4711) -- fixedHS
177 assign = StAssign AddrRep (StInd AddrRep obj'') v'
179 returnUs (\xs -> assign : xs)
181 -- NB: indexing in "pk" units, *not* in bytes (WDP 95/09)
182 primCode ls IndexByteArrayOp_Char rs = primCode_ReadByteArrayOp Int8Rep ls rs
183 primCode ls IndexByteArrayOp_Int rs = primCode_ReadByteArrayOp IntRep ls rs
184 primCode ls IndexByteArrayOp_Word rs = primCode_ReadByteArrayOp WordRep ls rs
185 primCode ls IndexByteArrayOp_Addr rs = primCode_ReadByteArrayOp AddrRep ls rs
186 primCode ls IndexByteArrayOp_Float rs = primCode_ReadByteArrayOp FloatRep ls rs
187 primCode ls IndexByteArrayOp_Double rs = primCode_ReadByteArrayOp DoubleRep ls rs
188 primCode ls IndexByteArrayOp_StablePtr rs = primCode_ReadByteArrayOp StablePtrRep ls rs
189 primCode ls IndexByteArrayOp_Int64 rs = primCode_ReadByteArrayOp Int64Rep ls rs
190 primCode ls IndexByteArrayOp_Word64 rs = primCode_ReadByteArrayOp Word64Rep ls rs
192 primCode ls ReadByteArrayOp_Char rs = primCode_ReadByteArrayOp Int8Rep ls rs
193 primCode ls ReadByteArrayOp_Int rs = primCode_ReadByteArrayOp IntRep ls rs
194 primCode ls ReadByteArrayOp_Word rs = primCode_ReadByteArrayOp WordRep ls rs
195 primCode ls ReadByteArrayOp_Addr rs = primCode_ReadByteArrayOp AddrRep ls rs
196 primCode ls ReadByteArrayOp_Float rs = primCode_ReadByteArrayOp FloatRep ls rs
197 primCode ls ReadByteArrayOp_Double rs = primCode_ReadByteArrayOp DoubleRep ls rs
198 primCode ls ReadByteArrayOp_StablePtr rs = primCode_ReadByteArrayOp StablePtrRep ls rs
199 primCode ls ReadByteArrayOp_Int64 rs = primCode_ReadByteArrayOp Int64Rep ls rs
200 primCode ls ReadByteArrayOp_Word64 rs = primCode_ReadByteArrayOp Word64Rep ls rs
202 primCode ls ReadOffAddrOp_Char rs = primCode_IndexOffAddrOp Int8Rep ls rs
203 primCode ls ReadOffAddrOp_Int rs = primCode_IndexOffAddrOp IntRep ls rs
204 primCode ls ReadOffAddrOp_Word rs = primCode_IndexOffAddrOp WordRep ls rs
205 primCode ls ReadOffAddrOp_Addr rs = primCode_IndexOffAddrOp AddrRep ls rs
206 primCode ls ReadOffAddrOp_Float rs = primCode_IndexOffAddrOp FloatRep ls rs
207 primCode ls ReadOffAddrOp_Double rs = primCode_IndexOffAddrOp DoubleRep ls rs
208 primCode ls ReadOffAddrOp_StablePtr rs = primCode_IndexOffAddrOp StablePtrRep ls rs
209 primCode ls ReadOffAddrOp_Int64 rs = primCode_IndexOffAddrOp Int64Rep ls rs
210 primCode ls ReadOffAddrOp_Word64 rs = primCode_IndexOffAddrOp Word64Rep ls rs
212 primCode ls IndexOffAddrOp_Char rs = primCode_IndexOffAddrOp Int8Rep ls rs
213 primCode ls IndexOffAddrOp_Int rs = primCode_IndexOffAddrOp IntRep ls rs
214 primCode ls IndexOffAddrOp_Word rs = primCode_IndexOffAddrOp WordRep ls rs
215 primCode ls IndexOffAddrOp_Addr rs = primCode_IndexOffAddrOp AddrRep ls rs
216 primCode ls IndexOffAddrOp_Float rs = primCode_IndexOffAddrOp FloatRep ls rs
217 primCode ls IndexOffAddrOp_Double rs = primCode_IndexOffAddrOp DoubleRep ls rs
218 primCode ls IndexOffAddrOp_StablePtr rs = primCode_IndexOffAddrOp StablePtrRep ls rs
219 primCode ls IndexOffAddrOp_Int64 rs = primCode_IndexOffAddrOp Int64Rep ls rs
220 primCode ls IndexOffAddrOp_Word64 rs = primCode_IndexOffAddrOp Word64Rep ls rs
222 primCode ls IndexOffForeignObjOp_Char rs = primCode_IndexOffForeignObjOp Int8Rep ls rs
223 primCode ls IndexOffForeignObjOp_Int rs = primCode_IndexOffForeignObjOp IntRep ls rs
224 primCode ls IndexOffForeignObjOp_Word rs = primCode_IndexOffForeignObjOp WordRep ls rs
225 primCode ls IndexOffForeignObjOp_Addr rs = primCode_IndexOffForeignObjOp AddrRep ls rs
226 primCode ls IndexOffForeignObjOp_Float rs = primCode_IndexOffForeignObjOp FloatRep ls rs
227 primCode ls IndexOffForeignObjOp_Double rs = primCode_IndexOffForeignObjOp DoubleRep ls rs
228 primCode ls IndexOffForeignObjOp_StablePtr rs = primCode_IndexOffForeignObjOp StablePtrRep ls rs
229 primCode ls IndexOffForeignObjOp_Int64 rs = primCode_IndexOffForeignObjOp Int64Rep ls rs
230 primCode ls IndexOffForeignObjOp_Word64 rs = primCode_IndexOffForeignObjOp Word64Rep ls rs
232 primCode ls WriteOffAddrOp_Char rs = primCode_WriteOffAddrOp Int8Rep ls rs
233 primCode ls WriteOffAddrOp_Int rs = primCode_WriteOffAddrOp IntRep ls rs
234 primCode ls WriteOffAddrOp_Word rs = primCode_WriteOffAddrOp WordRep ls rs
235 primCode ls WriteOffAddrOp_Addr rs = primCode_WriteOffAddrOp AddrRep ls rs
236 primCode ls WriteOffAddrOp_Float rs = primCode_WriteOffAddrOp FloatRep ls rs
237 primCode ls WriteOffAddrOp_Double rs = primCode_WriteOffAddrOp DoubleRep ls rs
238 primCode ls WriteOffAddrOp_StablePtr rs = primCode_WriteOffAddrOp StablePtrRep ls rs
239 primCode ls WriteOffAddrOp_Int64 rs = primCode_WriteOffAddrOp Int64Rep ls rs
240 primCode ls WriteOffAddrOp_Word64 rs = primCode_WriteOffAddrOp Word64Rep ls rs
242 primCode ls WriteByteArrayOp_Char rs = primCode_WriteByteArrayOp Int8Rep ls rs
243 primCode ls WriteByteArrayOp_Int rs = primCode_WriteByteArrayOp IntRep ls rs
244 primCode ls WriteByteArrayOp_Word rs = primCode_WriteByteArrayOp WordRep ls rs
245 primCode ls WriteByteArrayOp_Addr rs = primCode_WriteByteArrayOp AddrRep ls rs
246 primCode ls WriteByteArrayOp_Float rs = primCode_WriteByteArrayOp FloatRep ls rs
247 primCode ls WriteByteArrayOp_Double rs = primCode_WriteByteArrayOp DoubleRep ls rs
248 primCode ls WriteByteArrayOp_StablePtr rs = primCode_WriteByteArrayOp StablePtrRep ls rs
249 primCode ls WriteByteArrayOp_Int64 rs = primCode_WriteByteArrayOp Int64Rep ls rs
250 primCode ls WriteByteArrayOp_Word64 rs = primCode_WriteByteArrayOp Word64Rep ls rs
254 ToDo: saving/restoring of volatile regs around ccalls.
257 primCode lhs (CCallOp (CCall (StaticTarget fn) is_asm may_gc cconv)) rhs
258 | is_asm = error "ERROR: Native code generator can't handle casm"
259 | not may_gc = returnUs (\xs -> ccall : xs)
261 save_thread_state `thenUs` \ save ->
262 load_thread_state `thenUs` \ load ->
263 getUniqueUs `thenUs` \ uniq ->
265 id = StReg (StixTemp uniq IntRep)
267 suspend = StAssign IntRep id
268 (StCall SLIT("suspendThread") cconv IntRep [stgBaseReg])
269 resume = StCall SLIT("resumeThread") cconv VoidRep [id]
271 returnUs (\xs -> save (suspend : ccall : resume : load xs))
274 args = map amodeCodeForCCall rhs
275 amodeCodeForCCall x =
276 let base = amodeToStix' x
278 case getAmodeRep x of
279 ArrayRep -> StIndex PtrRep base arrPtrsHS
280 ByteArrayRep -> StIndex IntRep base arrWordsHS
281 ForeignObjRep -> StInd PtrRep (StIndex PtrRep base fixedHS)
285 [] -> StCall fn cconv VoidRep args
287 let lhs' = amodeToStix lhs
288 pk = case getAmodeRep lhs of
290 DoubleRep -> DoubleRep
293 StAssign pk lhs' (StCall fn cconv pk args)
296 DataToTagOp won't work for 64-bit archs, as it is.
299 primCode [lhs] DataToTagOp [arg]
300 = let lhs' = amodeToStix lhs
301 arg' = amodeToStix arg
302 infoptr = StInd PtrRep arg'
303 word_32 = StInd WordRep (StIndex PtrRep infoptr (StInt (-1)))
304 masked_le32 = StPrim SrlOp [word_32, StInt 16]
305 masked_be32 = StPrim AndOp [word_32, StInt 65535]
306 #ifdef WORDS_BIGENDIAN
311 assign = StAssign IntRep lhs' masked
313 returnUs (\xs -> assign : xs)
316 MutVars are pretty simple.
317 #define writeMutVarzh(a,v) (P_)(((StgMutVar *)(a))->var)=(v)
320 primCode [] WriteMutVarOp [aa,vv]
321 = let aa_s = amodeToStix aa
322 vv_s = amodeToStix vv
323 var_field = StIndex PtrRep aa_s fixedHS
324 assign = StAssign PtrRep (StInd PtrRep var_field) vv_s
326 returnUs (\xs -> assign : xs)
328 primCode [rr] ReadMutVarOp [aa]
329 = let aa_s = amodeToStix aa
330 rr_s = amodeToStix rr
331 var_field = StIndex PtrRep aa_s fixedHS
332 assign = StAssign PtrRep rr_s (StInd PtrRep var_field)
334 returnUs (\xs -> assign : xs)
340 primCode [rr] ForeignObjToAddrOp [fo]
341 = let code = StAssign AddrRep (amodeToStix rr)
343 (StIndex PtrRep (amodeToStix fo) fixedHS))
345 returnUs (\xs -> code : xs)
347 primCode [] TouchOp [_] = returnUs id
350 Now the more mundane operations.
355 lhs' = map amodeToStix lhs
356 rhs' = map amodeToStix' rhs
357 pk = getAmodeRep (head lhs)
359 returnUs (\ xs -> simplePrim pk lhs' op rhs' : xs)
362 Helper fns for some array ops.
365 primCode_ReadByteArrayOp pk [lhs] [obj, ix]
367 lhs' = amodeToStix lhs
368 obj' = amodeToStix obj
370 base = StIndex IntRep obj' arrWordsHS
371 assign = StAssign pk lhs' (StInd pk (StIndex pk base ix'))
373 returnUs (\xs -> assign : xs)
376 primCode_IndexOffAddrOp pk [lhs] [obj, ix]
378 lhs' = amodeToStix lhs
379 obj' = amodeToStix obj
381 assign = StAssign pk lhs' (StInd pk (StIndex pk obj' ix'))
383 returnUs (\xs -> assign : xs)
386 primCode_IndexOffForeignObjOp pk [lhs] [obj, ix]
388 lhs' = amodeToStix lhs
389 obj' = amodeToStix obj
391 obj'' = StIndex AddrRep obj' fixedHS
392 assign = StAssign pk lhs' (StInd pk (StIndex pk obj'' ix'))
394 returnUs (\xs -> assign : xs)
397 primCode_WriteOffAddrOp pk [] [obj, ix, v]
399 obj' = amodeToStix obj
402 assign = StAssign pk (StInd pk (StIndex pk obj' ix')) v'
404 returnUs (\xs -> assign : xs)
407 primCode_WriteByteArrayOp pk [] [obj, ix, v]
409 obj' = amodeToStix obj
412 base = StIndex IntRep obj' arrWordsHS
413 assign = StAssign pk (StInd pk (StIndex pk base ix')) v'
415 returnUs (\xs -> assign : xs)
424 -> UniqSM StixTreeList
426 simpleCoercion pk lhs rhs
427 = returnUs (\xs -> StAssign pk (amodeToStix lhs) (amodeToStix rhs) : xs)
430 Here we try to rewrite primitives into a form the code generator can
431 understand. Any primitives not handled here must be handled at the
432 level of the specific code generator.
436 :: PrimRep -- Rep of first destination
437 -> [StixTree] -- Destinations
443 Now look for something more conventional.
446 simplePrim pk [lhs] op rest = StAssign pk lhs (StPrim op rest)
447 simplePrim pk as op bs = simplePrim_error op
450 = error ("ERROR: primitive operation `"++show op++"'cannot be handled\nby the native-code generator. Workaround: use -fvia-C.\n(Perhaps you should report it as a GHC bug, also.)\n")
453 %---------------------------------------------------------------------
455 Here we generate the Stix code for CAddrModes.
457 When a character is fetched from a mixed type location, we have to do
458 an extra cast. This is reflected in amodeCode', which is for rhs
459 amodes that might possibly need the extra cast.
462 amodeToStix, amodeToStix' :: CAddrMode -> StixTree
464 amodeToStix'{-'-} am@(CVal rr CharRep)
465 | mixedTypeLocn am = StPrim ChrOp [amodeToStix am]
466 | otherwise = amodeToStix am
468 amodeToStix' am = amodeToStix am
471 amodeToStix am@(CVal rr CharRep)
473 = StInd IntRep (amodeToStix (CAddr rr))
475 amodeToStix (CVal rr pk) = StInd pk (amodeToStix (CAddr rr))
477 amodeToStix (CAddr (SpRel off))
478 = StIndex PtrRep stgSp (StInt (toInteger IBOX(off)))
480 amodeToStix (CAddr (HpRel off))
481 = StIndex IntRep stgHp (StInt (toInteger (- IBOX(off))))
483 amodeToStix (CAddr (NodeRel off))
484 = StIndex IntRep stgNode (StInt (toInteger IBOX(off)))
486 amodeToStix (CAddr (CIndex base off pk))
487 = StIndex pk (amodeToStix base) (amodeToStix off)
489 amodeToStix (CReg magic) = StReg (StixMagicId magic)
490 amodeToStix (CTemp uniq pk) = StReg (StixTemp uniq pk)
492 amodeToStix (CLbl lbl _) = StCLbl lbl
494 -- For CharLike and IntLike, we attempt some trivial constant-folding here.
496 amodeToStix (CCharLike (CLit (MachChar c)))
497 = StIndex Int8Rep cHARLIKE_closure (StInt (toInteger off))
499 off = charLikeSize * (c - mIN_CHARLIKE)
501 amodeToStix (CCharLike x)
504 amodeToStix (CIntLike (CLit (MachInt i)))
505 = StIndex Int8Rep iNTLIKE_closure (StInt (toInteger off))
507 off = intLikeSize * (fromInteger (i - mIN_INTLIKE))
509 amodeToStix (CIntLike x)
512 amodeToStix (CLit core)
514 MachChar c -> StInt (toInteger c)
515 MachStr s -> StString s
516 MachAddr a -> StInt a
518 MachWord w -> case word2IntLit core of MachInt iw -> StInt iw
519 MachLitLit s _ -> litLitErr
520 MachLabel l -> StCLbl (mkForeignLabel l False{-ToDo: dynamic-})
521 MachFloat d -> StFloat d
522 MachDouble d -> StDouble d
523 _ -> panic "amodeToStix:core literal"
525 amodeToStix (CMacroExpr _ macro [arg])
527 ENTRY_CODE -> amodeToStix arg
528 ARG_TAG -> amodeToStix arg -- just an integer no. of words
530 #ifdef WORDS_BIGENDIAN
532 [StInd WordRep (StIndex PtrRep (amodeToStix arg)
533 (StInt (toInteger (-1)))),
537 [StInd WordRep (StIndex PtrRep (amodeToStix arg)
538 (StInt (toInteger (-1)))),
542 -> StInd PtrRep (StIndex PtrRep (amodeToStix arg)
543 (StInt (toInteger uF_UPDATEE)))
546 panic "native code generator can't compile lit-lits, use -fvia-C"
549 Sizes of the CharLike and IntLike closures that are arranged as arrays
550 in the data segment. (These are in bytes.)
553 -- The INTLIKE base pointer
555 iNTLIKE_closure :: StixTree
556 iNTLIKE_closure = StCLbl mkIntlikeClosureLabel
560 cHARLIKE_closure :: StixTree
561 cHARLIKE_closure = StCLbl mkCharlikeClosureLabel
563 mutArrPtrsFrozen_info = StCLbl mkMAP_FROZEN_infoLabel
565 -- these are the sizes of charLike and intLike closures, in _bytes_.
566 charLikeSize = (fixedHdrSize + 1) * (fromInteger (sizeOf PtrRep))
567 intLikeSize = (fixedHdrSize + 1) * (fromInteger (sizeOf PtrRep))
573 = getUniqueUs `thenUs` \tso_uq ->
574 let tso = StReg (StixTemp tso_uq ThreadIdRep) in
576 StAssign ThreadIdRep tso stgCurrentTSO :
578 (StInd PtrRep (StPrim IntAddOp
579 [tso, StInt (toInteger (TSO_SP*BYTES_PER_WORD))]))
582 (StInd PtrRep (StPrim IntAddOp
583 [tso, StInt (toInteger (TSO_SU*BYTES_PER_WORD))]))
586 (StInd PtrRep (StPrim IntAddOp
588 StInt (toInteger (BDESCR_FREE * BYTES_PER_WORD))]))
589 (StPrim IntAddOp [stgHp, StInt (toInteger (1 * BYTES_PER_WORD))]) :
594 = getUniqueUs `thenUs` \tso_uq ->
595 let tso = StReg (StixTemp tso_uq ThreadIdRep) in
597 StAssign ThreadIdRep tso stgCurrentTSO :
598 StAssign PtrRep stgSp
599 (StInd PtrRep (StPrim IntAddOp
600 [tso, StInt (toInteger (TSO_SP*BYTES_PER_WORD))])) :
601 StAssign PtrRep stgSu
602 (StInd PtrRep (StPrim IntAddOp
603 [tso, StInt (toInteger (TSO_SU*BYTES_PER_WORD))])) :
604 StAssign PtrRep stgSpLim
605 (StPrim IntAddOp [tso,
606 StInt (toInteger ((TSO_STACK + rESERVED_STACK_WORDS)
607 *BYTES_PER_WORD))]) :
608 StAssign PtrRep stgHp
610 StInd PtrRep (StPrim IntAddOp
612 StInt (toInteger (BDESCR_FREE * BYTES_PER_WORD))]),
613 StInt (toInteger (1 * BYTES_PER_WORD))
615 StAssign PtrRep stgHpLim
617 StInd PtrRep (StPrim IntAddOp
619 StInt (toInteger (BDESCR_START * BYTES_PER_WORD))]),
620 StInt (toInteger (bLOCK_SIZE - (1 * BYTES_PER_WORD)))