diff options
Diffstat (limited to 'compiler/GHC/StgToCmm/Prim.hs')
-rw-r--r-- | compiler/GHC/StgToCmm/Prim.hs | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/compiler/GHC/StgToCmm/Prim.hs b/compiler/GHC/StgToCmm/Prim.hs index e17a937a9e..9614689c04 100644 --- a/compiler/GHC/StgToCmm/Prim.hs +++ b/compiler/GHC/StgToCmm/Prim.hs @@ -341,6 +341,12 @@ emitPrimOp cfg primop = EqStablePtrOp -> \args -> opTranslate args (mo_wordEq platform) + CMovOp -> \[cond, x, y] -> + opIntoRegs $ \[res] -> if allowCmov + then emitAssign (CmmLocal res) (cmmCMov platform cond x y) + -- Fall back to using a branch + else emitGenericCMov [res] [cond, x, y] + ReallyUnsafePtrEqualityOp -> \[arg1, arg2] -> opIntoRegs $ \[res] -> emitAssign (CmmLocal res) (CmmMachOp (mo_wordEq platform) [arg1,arg2]) @@ -1735,6 +1741,7 @@ emitPrimOp cfg primop = allowQuotRem2 = stgToCmmAllowQuotRem2 cfg allowExtAdd = stgToCmmAllowExtendedAddSubInstrs cfg allowInt2Mul = stgToCmmAllowIntMul2Instr cfg + allowCmov = stgToCmmAllowCMovInstr cfg data PrimopCmmEmit -- | Out of line fake primop that's actually just a foreign call to other @@ -2024,6 +2031,15 @@ genericIntMul2Op [res_c, res_h, res_l] both_args@[arg_x, arg_y] ] genericIntMul2Op _ _ = panic "genericIntMul2Op" +-- | Emulate cmov by using a branch, urkh +emitGenericCMov :: GenericOp +emitGenericCMov [res] [cond, arg_x, arg_y] + = do true_lbl <- newBlockId + emitAssign (CmmLocal res) arg_x + emit =<< mkCmmIfGoto cond true_lbl + emitAssign (CmmLocal res) arg_y + emitLabel true_lbl +emitGenericCMov _ _ = panic "genericIntMul2Op" ------------------------------------------------------------------------------ -- Helpers for translating various minor variants of array indexing. |