+
+
+-- Rewrite a narrowing coercion into a pair of shifts.
+narrowingCoercion
+ :: PrimRep -> PrimRep
+ -> CAddrMode -> CAddrMode
+ -> UniqSM StixTreeList
+
+narrowingCoercion pks pkd dst src
+ | szd > szs
+ = panic "StixPrim.narrowingCoercion"
+ | szd == szs
+ = returnUs (\xs -> StAssign pkd dst' src' : xs)
+ | otherwise
+ = returnUs (\xs -> assign : xs)
+ where
+ szs = getPrimRepSizeInBytes pks
+ szd = getPrimRepSizeInBytes pkd
+ src' = amodeToStix src
+ dst' = amodeToStix dst
+ shift_amt = fromIntegral (8 * (szs - szd))
+
+ assign
+ = StAssign pkd dst'
+ (StPrim (if signed then ISraOp else SrlOp)
+ [StPrim SllOp [src', StInt shift_amt],
+ StInt shift_amt])
+ signed
+ = case pkd of
+ Int8Rep -> True; Int16Rep -> True
+ Int32Rep -> True; Int64Rep -> True; IntRep -> True
+ Word8Rep -> False; Word16Rep -> False
+ Word32Rep -> False; Word64Rep -> False; WordRep -> False
+ other -> pprPanic "StixPrim.narrowingCoercion" (ppr pkd)