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(..) )
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 )
25 import CallConv ( cCallConv )
32 The main honcho here is primCode, which handles the guts of COpStmts.
36 :: [CAddrMode] -- results
38 -> [CAddrMode] -- args
39 -> UniqSM StixTreeList
42 First, the dreaded @ccall@. We can't handle @casm@s.
44 Usually, this compiles to an assignment, but when the left-hand side
45 is empty, we just perform the call and ignore the result.
47 btw Why not let programmer use casm to provide assembly code instead
50 The (MP) integer operations are a true nightmare. Since we don't have
51 a convenient abstract way of allocating temporary variables on the (C)
52 stack, we use the space just below HpLim for the @MP_INT@ structures,
53 and modify our heap check accordingly.
56 -- NB: ordering of clauses somewhere driven by
57 -- the desire to getting sane patt-matching behavior
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
83 primCode [res] AddrToHValueOp [arg]
84 = simpleCoercion PtrRep res arg
88 primCode [res] SameMutableArrayOp args
90 compare = StPrim AddrEqOp (map amodeToStix args)
91 assign = StAssign IntRep (amodeToStix res) compare
93 returnUs (\xs -> assign : xs)
95 primCode res@[_] SameMutableByteArrayOp args
96 = primCode res SameMutableArrayOp args
98 primCode res@[_] SameMutVarOp args
99 = primCode res SameMutableArrayOp args
101 primCode res@[_] SameMVarOp args
102 = primCode res SameMutableArrayOp args
105 Freezing an array of pointers is a double assignment. We fix the
106 header of the ``new'' closure because the lhs is probably a better
107 addressing mode for the indirection (most likely, it's a VanillaReg).
111 primCode [lhs] UnsafeFreezeArrayOp [rhs]
113 lhs' = amodeToStix lhs
114 rhs' = amodeToStix rhs
115 header = StInd PtrRep lhs'
116 assign = StAssign PtrRep lhs' rhs'
117 freeze = StAssign PtrRep header mutArrPtrsFrozen_info
119 returnUs (\xs -> assign : freeze : xs)
121 primCode [lhs] UnsafeFreezeByteArrayOp [rhs]
122 = simpleCoercion PtrRep lhs rhs
125 Returning the size of (mutable) byte arrays is just
126 an indexing operation.
129 primCode [lhs] SizeofByteArrayOp [rhs]
131 lhs' = amodeToStix lhs
132 rhs' = amodeToStix rhs
133 sz = StIndex IntRep rhs' fixedHS
134 assign = StAssign IntRep lhs' (StInd IntRep sz)
136 returnUs (\xs -> assign : xs)
138 primCode [lhs] SizeofMutableByteArrayOp [rhs]
140 lhs' = amodeToStix lhs
141 rhs' = amodeToStix rhs
142 sz = StIndex IntRep rhs' fixedHS
143 assign = StAssign IntRep lhs' (StInd IntRep sz)
145 returnUs (\xs -> assign : xs)
149 Most other array primitives translate to simple indexing.
152 primCode lhs@[_] IndexArrayOp args
153 = primCode lhs ReadArrayOp args
155 primCode [lhs] ReadArrayOp [obj, ix]
157 lhs' = amodeToStix lhs
158 obj' = amodeToStix obj
160 base = StIndex IntRep obj' arrPtrsHS
161 assign = StAssign PtrRep lhs' (StInd PtrRep (StIndex PtrRep base ix'))
163 returnUs (\xs -> assign : xs)
165 primCode [] WriteArrayOp [obj, ix, v]
167 obj' = amodeToStix obj
170 base = StIndex IntRep obj' arrPtrsHS
171 assign = StAssign PtrRep (StInd PtrRep (StIndex PtrRep base ix')) v'
173 returnUs (\xs -> assign : xs)
175 primCode [] WriteForeignObjOp [obj, v]
177 obj' = amodeToStix obj
179 obj'' = StIndex AddrRep obj' (StInt 4711) -- fixedHS
180 assign = StAssign AddrRep (StInd AddrRep obj'') v'
182 returnUs (\xs -> assign : xs)
184 -- NB: indexing in "pk" units, *not* in bytes (WDP 95/09)
185 primCode ls IndexByteArrayOp_Char rs = primCode_ReadByteArrayOp Word8Rep ls rs
186 primCode ls IndexByteArrayOp_WideChar rs = primCode_ReadByteArrayOp CharRep ls rs
187 primCode ls IndexByteArrayOp_Int rs = primCode_ReadByteArrayOp IntRep ls rs
188 primCode ls IndexByteArrayOp_Word rs = primCode_ReadByteArrayOp WordRep ls rs
189 primCode ls IndexByteArrayOp_Addr rs = primCode_ReadByteArrayOp AddrRep ls rs
190 primCode ls IndexByteArrayOp_Float rs = primCode_ReadByteArrayOp FloatRep ls rs
191 primCode ls IndexByteArrayOp_Double rs = primCode_ReadByteArrayOp DoubleRep ls rs
192 primCode ls IndexByteArrayOp_StablePtr rs = primCode_ReadByteArrayOp StablePtrRep ls rs
193 primCode ls IndexByteArrayOp_Int8 rs = primCode_ReadByteArrayOp Int8Rep ls rs
194 primCode ls IndexByteArrayOp_Int16 rs = primCode_ReadByteArrayOp Int16Rep ls rs
195 primCode ls IndexByteArrayOp_Int32 rs = primCode_ReadByteArrayOp Int32Rep ls rs
196 primCode ls IndexByteArrayOp_Int64 rs = primCode_ReadByteArrayOp Int64Rep ls rs
197 primCode ls IndexByteArrayOp_Word8 rs = primCode_ReadByteArrayOp Word8Rep ls rs
198 primCode ls IndexByteArrayOp_Word16 rs = primCode_ReadByteArrayOp Word16Rep ls rs
199 primCode ls IndexByteArrayOp_Word32 rs = primCode_ReadByteArrayOp Word32Rep ls rs
200 primCode ls IndexByteArrayOp_Word64 rs = primCode_ReadByteArrayOp Word64Rep ls rs
202 primCode ls ReadByteArrayOp_Char rs = primCode_ReadByteArrayOp Word8Rep ls rs
203 primCode ls ReadByteArrayOp_WideChar rs = primCode_ReadByteArrayOp CharRep ls rs
204 primCode ls ReadByteArrayOp_Int rs = primCode_ReadByteArrayOp IntRep ls rs
205 primCode ls ReadByteArrayOp_Word rs = primCode_ReadByteArrayOp WordRep ls rs
206 primCode ls ReadByteArrayOp_Addr rs = primCode_ReadByteArrayOp AddrRep ls rs
207 primCode ls ReadByteArrayOp_Float rs = primCode_ReadByteArrayOp FloatRep ls rs
208 primCode ls ReadByteArrayOp_Double rs = primCode_ReadByteArrayOp DoubleRep ls rs
209 primCode ls ReadByteArrayOp_StablePtr rs = primCode_ReadByteArrayOp StablePtrRep ls rs
210 primCode ls ReadByteArrayOp_Int8 rs = primCode_ReadByteArrayOp Int8Rep ls rs
211 primCode ls ReadByteArrayOp_Int16 rs = primCode_ReadByteArrayOp Int16Rep ls rs
212 primCode ls ReadByteArrayOp_Int32 rs = primCode_ReadByteArrayOp Int32Rep ls rs
213 primCode ls ReadByteArrayOp_Int64 rs = primCode_ReadByteArrayOp Int64Rep ls rs
214 primCode ls ReadByteArrayOp_Word8 rs = primCode_ReadByteArrayOp Word8Rep ls rs
215 primCode ls ReadByteArrayOp_Word16 rs = primCode_ReadByteArrayOp Word16Rep ls rs
216 primCode ls ReadByteArrayOp_Word32 rs = primCode_ReadByteArrayOp Word32Rep ls rs
217 primCode ls ReadByteArrayOp_Word64 rs = primCode_ReadByteArrayOp Word64Rep ls rs
219 primCode ls WriteByteArrayOp_Char rs = primCode_WriteByteArrayOp Word8Rep ls rs
220 primCode ls WriteByteArrayOp_WideChar rs = primCode_WriteByteArrayOp CharRep ls rs
221 primCode ls WriteByteArrayOp_Int rs = primCode_WriteByteArrayOp IntRep ls rs
222 primCode ls WriteByteArrayOp_Word rs = primCode_WriteByteArrayOp WordRep ls rs
223 primCode ls WriteByteArrayOp_Addr rs = primCode_WriteByteArrayOp AddrRep ls rs
224 primCode ls WriteByteArrayOp_Float rs = primCode_WriteByteArrayOp FloatRep ls rs
225 primCode ls WriteByteArrayOp_Double rs = primCode_WriteByteArrayOp DoubleRep ls rs
226 primCode ls WriteByteArrayOp_StablePtr rs = primCode_WriteByteArrayOp StablePtrRep ls rs
227 primCode ls WriteByteArrayOp_Int8 rs = primCode_WriteByteArrayOp Int8Rep ls rs
228 primCode ls WriteByteArrayOp_Int16 rs = primCode_WriteByteArrayOp Int16Rep ls rs
229 primCode ls WriteByteArrayOp_Int32 rs = primCode_WriteByteArrayOp Int32Rep ls rs
230 primCode ls WriteByteArrayOp_Int64 rs = primCode_WriteByteArrayOp Int64Rep ls rs
231 primCode ls WriteByteArrayOp_Word8 rs = primCode_WriteByteArrayOp Word8Rep ls rs
232 primCode ls WriteByteArrayOp_Word16 rs = primCode_WriteByteArrayOp Word16Rep ls rs
233 primCode ls WriteByteArrayOp_Word32 rs = primCode_WriteByteArrayOp Word32Rep ls rs
234 primCode ls WriteByteArrayOp_Word64 rs = primCode_WriteByteArrayOp Word64Rep ls rs
236 primCode ls IndexOffAddrOp_Char rs = primCode_IndexOffAddrOp Word8Rep ls rs
237 primCode ls IndexOffAddrOp_WideChar rs = primCode_IndexOffAddrOp CharRep ls rs
238 primCode ls IndexOffAddrOp_Int rs = primCode_IndexOffAddrOp IntRep ls rs
239 primCode ls IndexOffAddrOp_Word rs = primCode_IndexOffAddrOp WordRep ls rs
240 primCode ls IndexOffAddrOp_Addr rs = primCode_IndexOffAddrOp AddrRep ls rs
241 primCode ls IndexOffAddrOp_Float rs = primCode_IndexOffAddrOp FloatRep ls rs
242 primCode ls IndexOffAddrOp_Double rs = primCode_IndexOffAddrOp DoubleRep ls rs
243 primCode ls IndexOffAddrOp_StablePtr rs = primCode_IndexOffAddrOp StablePtrRep ls rs
244 primCode ls IndexOffAddrOp_Int8 rs = primCode_IndexOffAddrOp Int8Rep ls rs
245 primCode ls IndexOffAddrOp_Int16 rs = primCode_IndexOffAddrOp Int16Rep ls rs
246 primCode ls IndexOffAddrOp_Int32 rs = primCode_IndexOffAddrOp Int32Rep ls rs
247 primCode ls IndexOffAddrOp_Int64 rs = primCode_IndexOffAddrOp Int64Rep ls rs
248 primCode ls IndexOffAddrOp_Word8 rs = primCode_IndexOffAddrOp Word8Rep ls rs
249 primCode ls IndexOffAddrOp_Word16 rs = primCode_IndexOffAddrOp Word16Rep ls rs
250 primCode ls IndexOffAddrOp_Word32 rs = primCode_IndexOffAddrOp Word32Rep ls rs
251 primCode ls IndexOffAddrOp_Word64 rs = primCode_IndexOffAddrOp Word64Rep ls rs
253 primCode ls IndexOffForeignObjOp_Char rs = primCode_IndexOffForeignObjOp Word8Rep ls rs
254 primCode ls IndexOffForeignObjOp_WideChar rs = primCode_IndexOffForeignObjOp CharRep ls rs
255 primCode ls IndexOffForeignObjOp_Int rs = primCode_IndexOffForeignObjOp IntRep ls rs
256 primCode ls IndexOffForeignObjOp_Word rs = primCode_IndexOffForeignObjOp WordRep ls rs
257 primCode ls IndexOffForeignObjOp_Addr rs = primCode_IndexOffForeignObjOp AddrRep ls rs
258 primCode ls IndexOffForeignObjOp_Float rs = primCode_IndexOffForeignObjOp FloatRep ls rs
259 primCode ls IndexOffForeignObjOp_Double rs = primCode_IndexOffForeignObjOp DoubleRep ls rs
260 primCode ls IndexOffForeignObjOp_StablePtr rs = primCode_IndexOffForeignObjOp StablePtrRep ls rs
261 primCode ls IndexOffForeignObjOp_Int8 rs = primCode_IndexOffForeignObjOp Int8Rep ls rs
262 primCode ls IndexOffForeignObjOp_Int16 rs = primCode_IndexOffForeignObjOp Int16Rep ls rs
263 primCode ls IndexOffForeignObjOp_Int32 rs = primCode_IndexOffForeignObjOp Int32Rep ls rs
264 primCode ls IndexOffForeignObjOp_Int64 rs = primCode_IndexOffForeignObjOp Int64Rep ls rs
265 primCode ls IndexOffForeignObjOp_Word8 rs = primCode_IndexOffForeignObjOp Word8Rep ls rs
266 primCode ls IndexOffForeignObjOp_Word16 rs = primCode_IndexOffForeignObjOp Word16Rep ls rs
267 primCode ls IndexOffForeignObjOp_Word32 rs = primCode_IndexOffForeignObjOp Word32Rep ls rs
268 primCode ls IndexOffForeignObjOp_Word64 rs = primCode_IndexOffForeignObjOp Word64Rep ls rs
270 primCode ls ReadOffAddrOp_Char rs = primCode_IndexOffAddrOp Word8Rep ls rs
271 primCode ls ReadOffAddrOp_WideChar rs = primCode_IndexOffAddrOp CharRep ls rs
272 primCode ls ReadOffAddrOp_Int rs = primCode_IndexOffAddrOp IntRep ls rs
273 primCode ls ReadOffAddrOp_Word rs = primCode_IndexOffAddrOp WordRep ls rs
274 primCode ls ReadOffAddrOp_Addr rs = primCode_IndexOffAddrOp AddrRep ls rs
275 primCode ls ReadOffAddrOp_Float rs = primCode_IndexOffAddrOp FloatRep ls rs
276 primCode ls ReadOffAddrOp_Double rs = primCode_IndexOffAddrOp DoubleRep ls rs
277 primCode ls ReadOffAddrOp_StablePtr rs = primCode_IndexOffAddrOp StablePtrRep ls rs
278 primCode ls ReadOffAddrOp_Int8 rs = primCode_IndexOffAddrOp Int8Rep ls rs
279 primCode ls ReadOffAddrOp_Int16 rs = primCode_IndexOffAddrOp Int16Rep ls rs
280 primCode ls ReadOffAddrOp_Int32 rs = primCode_IndexOffAddrOp Int32Rep ls rs
281 primCode ls ReadOffAddrOp_Int64 rs = primCode_IndexOffAddrOp Int64Rep ls rs
282 primCode ls ReadOffAddrOp_Word8 rs = primCode_IndexOffAddrOp Word8Rep ls rs
283 primCode ls ReadOffAddrOp_Word16 rs = primCode_IndexOffAddrOp Word16Rep ls rs
284 primCode ls ReadOffAddrOp_Word32 rs = primCode_IndexOffAddrOp Word32Rep ls rs
285 primCode ls ReadOffAddrOp_Word64 rs = primCode_IndexOffAddrOp Word64Rep ls rs
287 primCode ls WriteOffAddrOp_Char rs = primCode_WriteOffAddrOp Word8Rep ls rs
288 primCode ls WriteOffAddrOp_WideChar rs = primCode_WriteOffAddrOp CharRep ls rs
289 primCode ls WriteOffAddrOp_Int rs = primCode_WriteOffAddrOp IntRep ls rs
290 primCode ls WriteOffAddrOp_Word rs = primCode_WriteOffAddrOp WordRep ls rs
291 primCode ls WriteOffAddrOp_Addr rs = primCode_WriteOffAddrOp AddrRep ls rs
292 primCode ls WriteOffAddrOp_Float rs = primCode_WriteOffAddrOp FloatRep ls rs
293 primCode ls WriteOffAddrOp_Double rs = primCode_WriteOffAddrOp DoubleRep ls rs
294 primCode ls WriteOffAddrOp_StablePtr rs = primCode_WriteOffAddrOp StablePtrRep ls rs
295 primCode ls WriteOffAddrOp_Int8 rs = primCode_WriteOffAddrOp Int8Rep ls rs
296 primCode ls WriteOffAddrOp_Int16 rs = primCode_WriteOffAddrOp Int16Rep ls rs
297 primCode ls WriteOffAddrOp_Int32 rs = primCode_WriteOffAddrOp Int32Rep ls rs
298 primCode ls WriteOffAddrOp_Int64 rs = primCode_WriteOffAddrOp Int64Rep ls rs
299 primCode ls WriteOffAddrOp_Word8 rs = primCode_WriteOffAddrOp Word8Rep ls rs
300 primCode ls WriteOffAddrOp_Word16 rs = primCode_WriteOffAddrOp Word16Rep ls rs
301 primCode ls WriteOffAddrOp_Word32 rs = primCode_WriteOffAddrOp Word32Rep ls rs
302 primCode ls WriteOffAddrOp_Word64 rs = primCode_WriteOffAddrOp Word64Rep ls rs
306 ToDo: saving/restoring of volatile regs around ccalls.
308 JRS, 001113: always do the call of suspendThread and resumeThread as a ccall
309 rather than inheriting the calling convention of the thing which we're really
313 primCode lhs (CCallOp (CCall (StaticTarget fn) is_asm may_gc cconv)) rhs
314 | is_asm = error "ERROR: Native code generator can't handle casm"
315 | not may_gc = returnUs (\xs -> ccall : xs)
317 save_thread_state `thenUs` \ save ->
318 load_thread_state `thenUs` \ load ->
319 getUniqueUs `thenUs` \ uniq ->
321 id = StReg (StixTemp uniq IntRep)
323 suspend = StAssign IntRep id
324 (StCall SLIT("suspendThread") {-no:cconv-} cCallConv
326 resume = StCall SLIT("resumeThread") {-no:cconv-} cCallConv
329 returnUs (\xs -> save (suspend : ccall : resume : load xs))
332 args = map amodeCodeForCCall rhs
333 amodeCodeForCCall x =
334 let base = amodeToStix' x
336 case getAmodeRep x of
337 ArrayRep -> StIndex PtrRep base arrPtrsHS
338 ByteArrayRep -> StIndex IntRep base arrWordsHS
339 ForeignObjRep -> StInd PtrRep (StIndex PtrRep base fixedHS)
343 [] -> StCall fn cconv VoidRep args
345 let lhs' = amodeToStix lhs
346 pk = case getAmodeRep lhs of
348 DoubleRep -> DoubleRep
351 StAssign pk lhs' (StCall fn cconv pk args)
354 DataToTagOp won't work for 64-bit archs, as it is.
357 primCode [lhs] DataToTagOp [arg]
358 = let lhs' = amodeToStix lhs
359 arg' = amodeToStix arg
360 infoptr = StInd PtrRep arg'
361 word_32 = StInd WordRep (StIndex PtrRep infoptr (StInt (-1)))
362 masked_le32 = StPrim SrlOp [word_32, StInt 16]
363 masked_be32 = StPrim AndOp [word_32, StInt 65535]
364 #ifdef WORDS_BIGENDIAN
369 assign = StAssign IntRep lhs' masked
371 returnUs (\xs -> assign : xs)
374 MutVars are pretty simple.
375 #define writeMutVarzh(a,v) (P_)(((StgMutVar *)(a))->var)=(v)
378 primCode [] WriteMutVarOp [aa,vv]
379 = let aa_s = amodeToStix aa
380 vv_s = amodeToStix vv
381 var_field = StIndex PtrRep aa_s fixedHS
382 assign = StAssign PtrRep (StInd PtrRep var_field) vv_s
384 returnUs (\xs -> assign : xs)
386 primCode [rr] ReadMutVarOp [aa]
387 = let aa_s = amodeToStix aa
388 rr_s = amodeToStix rr
389 var_field = StIndex PtrRep aa_s fixedHS
390 assign = StAssign PtrRep rr_s (StInd PtrRep var_field)
392 returnUs (\xs -> assign : xs)
398 primCode [rr] ForeignObjToAddrOp [fo]
399 = let code = StAssign AddrRep (amodeToStix rr)
401 (StIndex PtrRep (amodeToStix fo) fixedHS))
403 returnUs (\xs -> code : xs)
405 primCode [] TouchOp [_] = returnUs id
408 Now the more mundane operations.
413 lhs' = map amodeToStix lhs
414 rhs' = map amodeToStix' rhs
415 pk = getAmodeRep (head lhs)
417 returnUs (\ xs -> simplePrim pk lhs' op rhs' : xs)
420 Helper fns for some array ops.
423 primCode_ReadByteArrayOp pk [lhs] [obj, ix]
425 lhs' = amodeToStix lhs
426 obj' = amodeToStix obj
428 base = StIndex IntRep obj' arrWordsHS
429 assign = StAssign pk lhs' (StInd pk (StIndex pk base ix'))
431 returnUs (\xs -> assign : xs)
434 primCode_IndexOffAddrOp pk [lhs] [obj, ix]
436 lhs' = amodeToStix lhs
437 obj' = amodeToStix obj
439 assign = StAssign pk lhs' (StInd pk (StIndex pk obj' ix'))
441 returnUs (\xs -> assign : xs)
444 primCode_IndexOffForeignObjOp pk [lhs] [obj, ix]
446 lhs' = amodeToStix lhs
447 obj' = amodeToStix obj
449 obj'' = StIndex AddrRep obj' fixedHS
450 assign = StAssign pk lhs' (StInd pk (StIndex pk obj'' ix'))
452 returnUs (\xs -> assign : xs)
455 primCode_WriteOffAddrOp pk [] [obj, ix, v]
457 obj' = amodeToStix obj
460 assign = StAssign pk (StInd pk (StIndex pk obj' ix')) v'
462 returnUs (\xs -> assign : xs)
465 primCode_WriteByteArrayOp pk [] [obj, ix, v]
467 obj' = amodeToStix obj
470 base = StIndex IntRep obj' arrWordsHS
471 assign = StAssign pk (StInd pk (StIndex pk base ix')) v'
473 returnUs (\xs -> assign : xs)
482 -> UniqSM StixTreeList
484 simpleCoercion pk lhs rhs
485 = returnUs (\xs -> StAssign pk (amodeToStix lhs) (amodeToStix rhs) : xs)
488 Here we try to rewrite primitives into a form the code generator can
489 understand. Any primitives not handled here must be handled at the
490 level of the specific code generator.
494 :: PrimRep -- Rep of first destination
495 -> [StixTree] -- Destinations
501 Now look for something more conventional.
504 simplePrim pk [lhs] op rest = StAssign pk lhs (StPrim op rest)
505 simplePrim pk as op bs = simplePrim_error op
508 = 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")
511 %---------------------------------------------------------------------
513 Here we generate the Stix code for CAddrModes.
515 When a character is fetched from a mixed type location, we have to do
516 an extra cast. This is reflected in amodeCode', which is for rhs
517 amodes that might possibly need the extra cast.
520 amodeToStix, amodeToStix' :: CAddrMode -> StixTree
522 amodeToStix'{-'-} am@(CVal rr CharRep)
523 | mixedTypeLocn am = StPrim ChrOp [amodeToStix am]
524 | otherwise = amodeToStix am
526 amodeToStix' am = amodeToStix am
529 amodeToStix am@(CVal rr CharRep)
531 = StInd IntRep (amodeToStix (CAddr rr))
533 amodeToStix (CVal rr pk) = StInd pk (amodeToStix (CAddr rr))
535 amodeToStix (CAddr (SpRel off))
536 = StIndex PtrRep stgSp (StInt (toInteger (iBox off)))
538 amodeToStix (CAddr (HpRel off))
539 = StIndex IntRep stgHp (StInt (toInteger (- (iBox off))))
541 amodeToStix (CAddr (NodeRel off))
542 = StIndex IntRep stgNode (StInt (toInteger (iBox off)))
544 amodeToStix (CAddr (CIndex base off pk))
545 = StIndex pk (amodeToStix base) (amodeToStix off)
547 amodeToStix (CReg magic) = StReg (StixMagicId magic)
548 amodeToStix (CTemp uniq pk) = StReg (StixTemp uniq pk)
550 amodeToStix (CLbl lbl _) = StCLbl lbl
552 -- For CharLike and IntLike, we attempt some trivial constant-folding here.
554 amodeToStix (CCharLike (CLit (MachChar c)))
555 = StIndex Word8Rep cHARLIKE_closure (StInt (toInteger off))
557 off = charLikeSize * (c - mIN_CHARLIKE)
559 amodeToStix (CCharLike x)
562 amodeToStix (CIntLike (CLit (MachInt i)))
563 = StIndex Word8Rep iNTLIKE_closure (StInt (toInteger off))
565 off = intLikeSize * (fromInteger (i - mIN_INTLIKE))
567 amodeToStix (CIntLike x)
570 amodeToStix (CLit core)
572 MachChar c -> StInt (toInteger c)
573 MachStr s -> StString s
574 MachAddr a -> StInt a
576 MachWord w -> case word2IntLit core of MachInt iw -> StInt iw
577 MachLitLit s _ -> litLitErr
578 MachLabel l -> StCLbl (mkForeignLabel l False{-ToDo: dynamic-})
579 MachFloat d -> StFloat d
580 MachDouble d -> StDouble d
581 _ -> panic "amodeToStix:core literal"
583 amodeToStix (CMacroExpr _ macro [arg])
585 ENTRY_CODE -> amodeToStix arg
586 ARG_TAG -> amodeToStix arg -- just an integer no. of words
588 #ifdef WORDS_BIGENDIAN
590 [StInd WordRep (StIndex PtrRep (amodeToStix arg)
591 (StInt (toInteger (-1)))),
595 [StInd WordRep (StIndex PtrRep (amodeToStix arg)
596 (StInt (toInteger (-1)))),
600 -> StInd PtrRep (StIndex PtrRep (amodeToStix arg)
601 (StInt (toInteger uF_UPDATEE)))
604 panic "native code generator can't compile lit-lits, use -fvia-C"
607 Sizes of the CharLike and IntLike closures that are arranged as arrays
608 in the data segment. (These are in bytes.)
611 -- The INTLIKE base pointer
613 iNTLIKE_closure :: StixTree
614 iNTLIKE_closure = StCLbl mkIntlikeClosureLabel
618 cHARLIKE_closure :: StixTree
619 cHARLIKE_closure = StCLbl mkCharlikeClosureLabel
621 mutArrPtrsFrozen_info = StCLbl mkMAP_FROZEN_infoLabel
623 -- these are the sizes of charLike and intLike closures, in _bytes_.
624 charLikeSize = (fixedHdrSize + 1) * (sizeOf PtrRep)
625 intLikeSize = (fixedHdrSize + 1) * (sizeOf PtrRep)
631 = getUniqueUs `thenUs` \tso_uq ->
632 let tso = StReg (StixTemp tso_uq ThreadIdRep) in
634 StAssign ThreadIdRep tso stgCurrentTSO :
636 (StInd PtrRep (StPrim IntAddOp
637 [tso, StInt (toInteger (TSO_SP*BYTES_PER_WORD))]))
640 (StInd PtrRep (StPrim IntAddOp
641 [tso, StInt (toInteger (TSO_SU*BYTES_PER_WORD))]))
644 (StInd PtrRep (StPrim IntAddOp
646 StInt (toInteger (BDESCR_FREE * BYTES_PER_WORD))]))
647 (StPrim IntAddOp [stgHp, StInt (toInteger (1 * BYTES_PER_WORD))]) :
652 = getUniqueUs `thenUs` \tso_uq ->
653 let tso = StReg (StixTemp tso_uq ThreadIdRep) in
655 StAssign ThreadIdRep tso stgCurrentTSO :
656 StAssign PtrRep stgSp
657 (StInd PtrRep (StPrim IntAddOp
658 [tso, StInt (toInteger (TSO_SP*BYTES_PER_WORD))])) :
659 StAssign PtrRep stgSu
660 (StInd PtrRep (StPrim IntAddOp
661 [tso, StInt (toInteger (TSO_SU*BYTES_PER_WORD))])) :
662 StAssign PtrRep stgSpLim
663 (StPrim IntAddOp [tso,
664 StInt (toInteger ((TSO_STACK + rESERVED_STACK_WORDS)
665 *BYTES_PER_WORD))]) :
666 StAssign PtrRep stgHp
668 StInd PtrRep (StPrim IntAddOp
670 StInt (toInteger (BDESCR_FREE * BYTES_PER_WORD))]),
671 StInt (toInteger (1 * BYTES_PER_WORD))
673 StAssign PtrRep stgHpLim
675 StInd PtrRep (StPrim IntAddOp
677 StInt (toInteger (BDESCR_START * BYTES_PER_WORD))]),
678 StInt (toInteger (bLOCK_SIZE - (1 * BYTES_PER_WORD)))