module GHC.CmmToAsm.X86.Cond ( Cond(..), condToUnsigned, maybeFlipCond, maybeInvertCond ) where import GHC.Prelude data Cond = ALWAYS -- What's really used? ToDo | EQQ -- je/jz -> zf=1 | GE -- jge -> sf=of | GEU -- ae -> cf=0 | GTT -- jg -> zf=0 && sf=of | GU -- ja -> cf=0 && zf=0 | LE -- jle -> zf=1 || sf/=of | LEU -- jbe -> cf=1 || zf=1 | LTT -- jl -> sf/=of | LU -- jb -> cf=1 | NE -- jne -> zf=0 | NEG -- js -> sf=1 | POS -- jns -> sf=0 | CARRY -- jc -> cf=1 | OFLO -- jo -> of=1 | PARITY -- jp -> pf=1 | NOTPARITY -- jnp -> pf=0 deriving Eq condToUnsigned :: Cond -> Cond condToUnsigned GTT = GU condToUnsigned LTT = LU condToUnsigned GE = GEU condToUnsigned LE = LEU condToUnsigned x = x -- | @maybeFlipCond c@ returns @Just c'@ if it is possible to flip the -- arguments to the conditional @c@, and the new condition should be @c'@. maybeFlipCond :: Cond -> Maybe Cond maybeFlipCond cond = case cond of EQQ -> Just EQQ NE -> Just NE LU -> Just GU GU -> Just LU LEU -> Just GEU GEU -> Just LEU LTT -> Just GTT GTT -> Just LTT LE -> Just GE GE -> Just LE _other -> Nothing -- | If we apply @maybeInvertCond@ to the condition of a jump we turn -- jumps taken into jumps not taken and vice versa. -- -- Careful! If the used comparison and the conditional jump -- don't match the above behaviour will NOT hold. -- When used for FP comparisons this does not consider unordered -- numbers. -- Also inverting twice might return a synonym for the original condition. maybeInvertCond :: Cond -> Maybe Cond maybeInvertCond cond = case cond of ALWAYS -> Nothing EQQ -> Just NE NE -> Just EQQ NEG -> Just POS POS -> Just NEG GEU -> Just LU LU -> Just GEU GE -> Just LTT LTT -> Just GE GTT -> Just LE LE -> Just GTT GU -> Just LEU LEU -> Just GU --GEU "==" NOTCARRY, they are synonyms --at the assembly level CARRY -> Just GEU OFLO -> Nothing PARITY -> Just NOTPARITY NOTPARITY -> Just PARITY