genCall t@(PrimTarget op) [] args
 | Just align <- machOpMemcpyishAlign op = runStmtsDecls $ do
    dflags <- getDynFlags
    let isVolTy = [i1]
        isVolVal = [mkIntLit i1 0]
        argTy | MO_Memset _ <- op = [i8Ptr, i8,    llvmWord dflags, i32] ++ isVolTy
              | otherwise         = [i8Ptr, i8Ptr, llvmWord dflags, i32] ++ isVolTy
        funTy = \name -> LMFunction $ LlvmFunctionDecl name ExternallyVisible
                             CC_Ccc LMVoid FixedArgs (tysToParams argTy) Nothing

    let (_, arg_hints) = foreignTargetHints t
    let args_hints = zip args arg_hints
    argVars       <- arg_varsW args_hints ([], nilOL, [])
    fptr          <- getFunPtrW funTy t
    argVars' <- castVarsW $ zip argVars argTy

    doTrashStmts
    let alignVal = mkIntLit i32 align
        arguments = argVars' ++ (alignVal:isVolVal)
    statement $ Expr $ Call StdCall fptr arguments []

-- We handle MO_U_Mul2 by simply using a 'mul' instruction, but with operands
-- twice the width (we first zero-extend them), e.g., on 64-bit arch we will
-- generate 'mul' on 128-bit operands. Then we only need some plumbing to
-- extract the two 64-bit values out of 128-bit result.
genCall t@(PrimTarget op) [] args
 | Just align <- machOpMemcpyishAlign op = runStmtsDecls $ do
    dflags <- getDynFlags
    let isVolTy = [i1]
        isVolVal = [mkIntLit i1 0]
        argTy | MO_Memset _ <- op = [i8Ptr, i8,    llvmWord dflags, i32] ++ isVolTy
              | otherwise         = [i8Ptr, i8Ptr, llvmWord dflags, i32] ++ isVolTy
        funTy = \name -> LMFunction $ LlvmFunctionDecl name ExternallyVisible
                             CC_Ccc LMVoid FixedArgs (tysToParams argTy) Nothing

    let (_, arg_hints) = foreignTargetHints t
    let args_hints = zip args arg_hints
    argVars       <- arg_varsW args_hints ([], nilOL, [])
    fptr          <- getFunPtrW funTy t
    argVars' <- castVarsW $ zip argVars argTy

    doTrashStmts
    let alignVal = mkIntLit i32 align
        arguments = argVars' ++ (alignVal:isVolVal)
    statement $ Expr $ Call StdCall fptr arguments []

-- We handle MO_U_Mul2 by simply using a 'mul' instruction, but with operands
-- twice the width (we first zero-extend them), e.g., on 64-bit arch we will
-- generate 'mul' on 128-bit operands. Then we only need some plumbing to
-- extract the two 64-bit values out of 128-bit result.
genCall t@(PrimTarget op) [] args
 | Just align <- machOpMemcpyishAlign op = runStmtsDecls $ do
    dflags <- getDynFlags
    let isVolTy = [i1]
        isVolVal = [mkIntLit i1 0]
        argTy | MO_Memset _ <- op = [i8Ptr, i8,    llvmWord dflags, i32] ++ isVolTy
              | otherwise         = [i8Ptr, i8Ptr, llvmWord dflags, i32] ++ isVolTy
        funTy = \name -> LMFunction $ LlvmFunctionDecl name ExternallyVisible
                             CC_Ccc LMVoid FixedArgs (tysToParams argTy) Nothing

    let (_, arg_hints) = foreignTargetHints t
    let args_hints = zip args arg_hints
    argVars       <- arg_varsW args_hints ([], nilOL, [])
    fptr          <- getFunPtrW funTy t
    argVars' <- castVarsW $ zip argVars argTy

    doTrashStmts
    let alignVal = mkIntLit i32 align
        arguments = argVars' ++ (alignVal:isVolVal)
    statement $ Expr $ Call StdCall fptr arguments []

-- We handle MO_U_Mul2 by simply using a 'mul' instruction, but with operands
-- twice the width (we first zero-extend them), e.g., on 64-bit arch we will
-- generate 'mul' on 128-bit operands. Then we only need some plumbing to
-- extract the two 64-bit values out of 128-bit result.