diff options
| -rw-r--r-- | compiler/cmm/CmmMachOp.hs | 1 | ||||
| -rw-r--r-- | compiler/cmm/OldCmmUtils.hs | 4 | ||||
| -rw-r--r-- | compiler/cmm/PprC.hs | 1 | ||||
| -rw-r--r-- | compiler/codeGen/CgPrimOp.hs | 8 | ||||
| -rw-r--r-- | compiler/llvmGen/LlvmCodeGen/CodeGen.hs | 1 | ||||
| -rw-r--r-- | compiler/nativeGen/PPC/CodeGen.hs | 1 | ||||
| -rw-r--r-- | compiler/nativeGen/SPARC/CodeGen.hs | 1 | ||||
| -rw-r--r-- | compiler/nativeGen/X86/CodeGen.hs | 38 | ||||
| -rw-r--r-- | compiler/prelude/primops.txt.pp | 4 |
9 files changed, 44 insertions, 15 deletions
diff --git a/compiler/cmm/CmmMachOp.hs b/compiler/cmm/CmmMachOp.hs index 967f3289ff..d88d1043d0 100644 --- a/compiler/cmm/CmmMachOp.hs +++ b/compiler/cmm/CmmMachOp.hs @@ -441,6 +441,7 @@ data CallishMachOp | MO_F32_Sqrt | MO_S_QuotRem Width + | MO_U_QuotRem Width | MO_WriteBarrier | MO_Touch -- Keep variables live (when using interior pointers) diff --git a/compiler/cmm/OldCmmUtils.hs b/compiler/cmm/OldCmmUtils.hs index 3fc6fd441a..efdeeff6ff 100644 --- a/compiler/cmm/OldCmmUtils.hs +++ b/compiler/cmm/OldCmmUtils.hs @@ -105,5 +105,9 @@ expandCallishMachOp (MO_S_QuotRem width) [CmmHinted res_q _, CmmHinted res_r _] = Just [CmmAssign (CmmLocal res_q) (CmmMachOp (MO_S_Quot width) args'), CmmAssign (CmmLocal res_r) (CmmMachOp (MO_S_Rem width) args')] where args' = map hintlessCmm args +expandCallishMachOp (MO_U_QuotRem width) [CmmHinted res_q _, CmmHinted res_r _] args + = Just [CmmAssign (CmmLocal res_q) (CmmMachOp (MO_U_Quot width) args'), + CmmAssign (CmmLocal res_r) (CmmMachOp (MO_U_Rem width) args')] + where args' = map hintlessCmm args expandCallishMachOp _ _ _ = Nothing diff --git a/compiler/cmm/PprC.hs b/compiler/cmm/PprC.hs index d636c41997..f3c762c581 100644 --- a/compiler/cmm/PprC.hs +++ b/compiler/cmm/PprC.hs @@ -664,6 +664,7 @@ pprCallishMachOp_for_C mop (MO_PopCnt w) -> ptext (sLit $ popCntLabel w) MO_S_QuotRem {} -> unsupported + MO_U_QuotRem {} -> unsupported MO_Touch -> unsupported where unsupported = panic ("pprCallishMachOp_for_C: " ++ show mop ++ " not supported!") diff --git a/compiler/codeGen/CgPrimOp.hs b/compiler/codeGen/CgPrimOp.hs index f169c0ce38..9ec99bf4f8 100644 --- a/compiler/codeGen/CgPrimOp.hs +++ b/compiler/codeGen/CgPrimOp.hs @@ -448,6 +448,14 @@ emitPrimOp [res_q, res_r] IntQuotRemOp [arg_x, arg_y] _ CmmHinted arg_y NoHint] CmmMayReturn in stmtC stmt +emitPrimOp [res_q, res_r] WordQuotRemOp [arg_x, arg_y] _ + = let stmt = CmmCall (CmmPrim (MO_U_QuotRem wordWidth)) + [CmmHinted res_q NoHint, + CmmHinted res_r NoHint] + [CmmHinted arg_x NoHint, + CmmHinted arg_y NoHint] + CmmMayReturn + in stmtC stmt emitPrimOp _ op _ _ = pprPanic "emitPrimOp: can't translate PrimOp" (ppr op) diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs index 98fb8eb4e8..78df37346b 100644 --- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs +++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs @@ -475,6 +475,7 @@ cmmPrimOpFunctions env mop (MO_PopCnt w) -> fsLit $ "llvm.ctpop." ++ show (widthToLlvmInt w) MO_S_QuotRem {} -> unsupported + MO_U_QuotRem {} -> unsupported MO_WriteBarrier -> unsupported MO_Touch -> unsupported diff --git a/compiler/nativeGen/PPC/CodeGen.hs b/compiler/nativeGen/PPC/CodeGen.hs index db97a8cc97..169cd0cac4 100644 --- a/compiler/nativeGen/PPC/CodeGen.hs +++ b/compiler/nativeGen/PPC/CodeGen.hs @@ -1148,6 +1148,7 @@ genCCall' gcp target dest_regs argsAndHints MO_PopCnt w -> (fsLit $ popCntLabel w, False) MO_S_QuotRem {} -> unsupported + MO_U_QuotRem {} -> unsupported MO_WriteBarrier -> unsupported MO_Touch -> unsupported unsupported = panic ("outOfLineCmmOp: " ++ show mop diff --git a/compiler/nativeGen/SPARC/CodeGen.hs b/compiler/nativeGen/SPARC/CodeGen.hs index f8e71f4aef..6093751595 100644 --- a/compiler/nativeGen/SPARC/CodeGen.hs +++ b/compiler/nativeGen/SPARC/CodeGen.hs @@ -643,6 +643,7 @@ outOfLineMachOp_table mop MO_PopCnt w -> fsLit $ popCntLabel w MO_S_QuotRem {} -> unsupported + MO_U_QuotRem {} -> unsupported MO_WriteBarrier -> unsupported MO_Touch -> unsupported where unsupported = panic ("outOfLineCmmOp: " ++ show mop diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs index 7900b3ee81..ec6bf59c23 100644 --- a/compiler/nativeGen/X86/CodeGen.hs +++ b/compiler/nativeGen/X86/CodeGen.hs @@ -1841,24 +1841,31 @@ genCCall64 target dest_regs args = -- we only cope with a single result for foreign calls outOfLineCmmOp op (Just res) args - (CmmPrim (MO_S_QuotRem width), [CmmHinted res_q _, CmmHinted res_r _]) -> - case args of - [CmmHinted arg_x _, CmmHinted arg_y _] -> - do let size = intSize width - reg_q = getRegisterReg True (CmmLocal res_q) - reg_r = getRegisterReg True (CmmLocal res_r) - (y_reg, y_code) <- getRegOrMem arg_y - x_code <- getAnyReg arg_x - return $ y_code `appOL` - x_code rax `appOL` - toOL [CLTD size, - IDIV size y_reg, - MOV size (OpReg rax) (OpReg reg_q), - MOV size (OpReg rdx) (OpReg reg_r)] - _ -> panic "genCCall64: Wrong number of arguments for MO_S_QuotRem" + (CmmPrim (MO_S_QuotRem width), _) -> divOp True width dest_regs args + (CmmPrim (MO_U_QuotRem width), _) -> divOp False width dest_regs args _ -> genCCall64' target dest_regs args + where divOp signed width [CmmHinted res_q _, CmmHinted res_r _] + [CmmHinted arg_x _, CmmHinted arg_y _] + = do let size = intSize width + reg_q = getRegisterReg True (CmmLocal res_q) + reg_r = getRegisterReg True (CmmLocal res_r) + widen | signed = CLTD size + | otherwise = XOR size (OpReg rdx) (OpReg rdx) + instr | signed = IDIV + | otherwise = DIV + (y_reg, y_code) <- getRegOrMem arg_y + x_code <- getAnyReg arg_x + return $ y_code `appOL` + x_code rax `appOL` + toOL [widen, + instr size y_reg, + MOV size (OpReg rax) (OpReg reg_q), + MOV size (OpReg rdx) (OpReg reg_r)] + divOp _ _ _ _ + = panic "genCCall64: Wrong number of arguments/results for divOp" + genCCall64' :: CmmCallTarget -- function to call -> [HintedCmmFormal] -- where to put the result -> [HintedCmmActual] -- arguments (of mixed type) @@ -2079,6 +2086,7 @@ outOfLineCmmOp mop res args MO_PopCnt _ -> fsLit "popcnt" MO_S_QuotRem {} -> unsupported + MO_U_QuotRem {} -> unsupported MO_WriteBarrier -> unsupported MO_Touch -> unsupported unsupported = panic ("outOfLineCmmOp: " ++ show mop diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp index 183bd35db4..baedd14411 100644 --- a/compiler/prelude/primops.txt.pp +++ b/compiler/prelude/primops.txt.pp @@ -280,6 +280,10 @@ primop WordQuotOp "quotWord#" Dyadic Word# -> Word# -> Word# primop WordRemOp "remWord#" Dyadic Word# -> Word# -> Word# with can_fail = True +primop WordQuotRemOp "quotRemWord#" GenPrimOp + Word# -> Word# -> (# Word#, Word# #) + with can_fail = True + primop AndOp "and#" Dyadic Word# -> Word# -> Word# with commutable = True |
