module GHC.CmmToAsm.AArch64.Cond where import GHC.Prelude hiding (EQ) -- https://developer.arm.com/documentation/den0024/a/the-a64-instruction-set/data-processing-instructions/conditional-instructions -- TODO: This appears to go a bit overboard? Maybe we should stick with what LLVM -- settled on for fcmp? -- false: always yields false, regardless of operands. -- oeq: yields true if both operands are not a QNAN and op1 is equal to op2. -- ogt: yields true if both operands are not a QNAN and op1 is greater than op2. -- oge: yields true if both operands are not a QNAN and op1 is greater than or equal to op2. -- olt: yields true if both operands are not a QNAN and op1 is less than op2. -- ole: yields true if both operands are not a QNAN and op1 is less than or equal to op2. -- one: yields true if both operands are not a QNAN and op1 is not equal to op2. -- ord: yields true if both operands are not a QNAN. -- ueq: yields true if either operand is a QNAN or op1 is equal to op2. -- ugt: yields true if either operand is a QNAN or op1 is greater than op2. -- uge: yields true if either operand is a QNAN or op1 is greater than or equal to op2. -- ult: yields true if either operand is a QNAN or op1 is less than op2. -- ule: yields true if either operand is a QNAN or op1 is less than or equal to op2. -- une: yields true if either operand is a QNAN or op1 is not equal to op2. -- uno: yields true if either operand is a QNAN. -- true: always yields true, regardless of operands. -- -- LLVMs icmp knows about: -- eq: yields true if the operands are equal, false otherwise. No sign interpretation is necessary or performed. -- ne: yields true if the operands are unequal, false otherwise. No sign interpretation is necessary or performed. -- ugt: interprets the operands as unsigned values and yields true if op1 is greater than op2. -- uge: interprets the operands as unsigned values and yields true if op1 is greater than or equal to op2. -- ult: interprets the operands as unsigned values and yields true if op1 is less than op2. -- ule: interprets the operands as unsigned values and yields true if op1 is less than or equal to op2. -- sgt: interprets the operands as signed values and yields true if op1 is greater than op2. -- sge: interprets the operands as signed values and yields true if op1 is greater than or equal to op2. -- slt: interprets the operands as signed values and yields true if op1 is less than op2. -- sle: interprets the operands as signed values and yields true if op1 is less than or equal to op2. data Cond = ALWAYS -- b.al | EQ -- b.eq | NE -- b.ne -- signed | SLT -- b.lt | SLE -- b.le | SGE -- b.ge | SGT -- b.gt -- unsigned | ULT -- b.lo | ULE -- b.ls | UGE -- b.hs | UGT -- b.hi -- ordered | OLT -- b.mi | OLE -- b.ls | OGE -- b.ge | OGT -- b.gt -- unordered | UOLT -- b.lt | UOLE -- b.le | UOGE -- b.pl | UOGT -- b.hi -- others -- NEVER -- b.nv -- I removed never. According to the ARM spec: -- > The Condition code NV exists only to provide a valid disassembly of -- > the 0b1111 encoding, otherwise its behavior is identical to AL. -- This can only lead to disaster. Better to not have it than someone -- using it assuming it actually means never. | VS -- oVerflow set | VC -- oVerflow clear deriving Cond -> Cond -> Bool (Cond -> Cond -> Bool) -> (Cond -> Cond -> Bool) -> Eq Cond forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: Cond -> Cond -> Bool == :: Cond -> Cond -> Bool $c/= :: Cond -> Cond -> Bool /= :: Cond -> Cond -> Bool Eq