+genMachOp_slow _ _ _ _ = panic "genMachOp: More then 2 expressions in MachOp!"
+
+
+-- | Handle CmmLoad expression.
+genLoad :: LlvmEnv -> CmmExpr -> CmmType -> UniqSM ExprData
+
+-- First we try to detect a few common cases and produce better code for
+-- these then the default case. We are mostly trying to detect Cmm code
+-- like I32[Sp + n] and use 'getelementptr' operations instead of the
+-- generic case that uses casts and pointer arithmetic
+genLoad env e@(CmmReg (CmmGlobal r)) ty
+ = genLoad_fast env e r 0 ty
+
+genLoad env e@(CmmRegOff (CmmGlobal r) n) ty
+ = genLoad_fast env e r n ty
+
+genLoad env e@(CmmMachOp (MO_Add _) [
+ (CmmReg (CmmGlobal r)),
+ (CmmLit (CmmInt n _))])
+ ty
+ = genLoad_fast env e r (fromInteger n) ty
+
+genLoad env e@(CmmMachOp (MO_Sub _) [
+ (CmmReg (CmmGlobal r)),
+ (CmmLit (CmmInt n _))])
+ ty
+ = genLoad_fast env e r (negate $ fromInteger n) ty
+
+-- generic case
+genLoad env e ty = genLoad_slow env e ty
+
+-- | Handle CmmLoad expression.
+-- This is a special case for loading from a global register pointer
+-- offset such as I32[Sp+8].
+genLoad_fast :: LlvmEnv -> CmmExpr -> GlobalReg -> Int -> CmmType
+ -> UniqSM ExprData
+genLoad_fast env e r n ty =
+ let gr = lmGlobalRegVar r
+ grt = (pLower . getVarType) gr
+ ty' = cmmToLlvmType ty
+ (ix,rem) = n `divMod` ((llvmWidthInBits . pLower) grt `div` 8)
+ in case isPointer grt && rem == 0 of
+ True -> do
+ (gv, s1) <- doExpr grt $ Load gr
+ (ptr, s2) <- doExpr grt $ GetElemPtr True gv [toI32 ix]
+ -- We might need a different pointer type, so check
+ case grt == ty' of
+ -- were fine
+ True -> do
+ (var, s3) <- doExpr ty' $ Load ptr
+ return (env, var, unitOL s1 `snocOL` s2 `snocOL` s3,
+ [])
+
+ -- cast to pointer type needed
+ False -> do
+ let pty = pLift ty'
+ (ptr', s3) <- doExpr pty $ Cast LM_Bitcast ptr pty
+ (var, s4) <- doExpr ty' $ Load ptr'
+ return (env, var, unitOL s1 `snocOL` s2 `snocOL` s3
+ `snocOL` s4, [])
+
+ -- If its a bit type then we use the slow method since
+ -- we can't avoid casting anyway.
+ False -> genLoad_slow env e ty
+
+
+-- | Handle Cmm load expression.
+-- Generic case. Uses casts and pointer arithmetic if needed.
+genLoad_slow :: LlvmEnv -> CmmExpr -> CmmType -> UniqSM ExprData
+genLoad_slow env e ty = do