ghc-9.14.1: GHC/CmmToAsm/AArch64/Cond.hs
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 Eq