use num_enum::{FromPrimitive, IntoPrimitive, TryFromPrimitive, TryFromPrimitiveError};
use std::num::NonZero;
#[derive(Debug, Copy, Clone, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
#[non_exhaustive]
pub enum AttrKind {
Alignment = 1,
AlwaysInline = 2,
ByVal = 3,
InlineHint = 4,
InReg = 5,
MinSize = 6,
Naked = 7,
Nest = 8,
NoAlias = 9,
NoBuiltin = 10,
NoCapture = 11,
NoDuplicate = 12,
NoImplicitFloat = 13,
NoInline = 14,
NonLazyBind = 15,
NoRedZone = 16,
NoReturn = 17,
NoUnwind = 18,
OptimizeForSize = 19,
ReadNone = 20,
ReadOnly = 21,
Returned = 22,
ReturnsTwice = 23,
SExt = 24,
StackAlignment = 25,
StackProtect = 26,
StackProtectReq = 27,
StackProtectStrong = 28,
StructRet = 29,
SanitizeAddress = 30,
SanitizeThread = 31,
SanitizeMemory = 32,
UwTable = 33,
ZExt = 34,
Builtin = 35,
Cold = 36,
OptimizeNone = 37,
InAlloca = 38,
NonNull = 39,
JumpTable = 40,
Dereferenceable = 41,
DereferenceableOrNull = 42,
Convergent = 43,
Safestack = 44,
ArgMemOnly = 45,
SwiftSelf = 46,
SwiftError = 47,
NoRecurse = 48,
InaccessibleMemOnly = 49,
InaccessibleMemOrArgMemOnly = 50,
AllocSize = 51,
WriteOnly = 52,
Speculatable = 53,
StrictFp = 54,
SanitizeHwAddress = 55,
NoCfCheck = 56,
OptForFuzzing = 57,
ShadowCallStack = 58,
SpeculativeLoadHardening = 59,
ImmArg = 60,
WillReturn = 61,
Nofree = 62,
Nosync = 63,
SanitizeMemtag = 64,
Preallocated = 65,
NoMerge = 66,
NullPointerIsValid = 67,
NoUndef = 68,
ByRef = 69,
MustProgress = 70,
NoCallback = 71,
Hot = 72,
NoProfile = 73,
VscaleRange = 74,
SwiftAsync = 75,
NoSanitizeCoverage = 76,
Elementtype = 77,
DisableSanitizerInstrumentation = 78,
NoSanitizeBounds = 79,
AllocAlign = 80,
AllocatedPointer = 81,
AllocKind = 82,
PresplitCoroutine = 83,
FnRetThunkExtern = 84,
SkipProfile = 85,
Memory = 86,
NoFpClass = 87,
OptimizeForDebugging = 88,
Writable = 89,
CoroOnlyDestroyWhenComplete = 90,
DeadOnUnwind = 91,
Range = 92,
SanitizeNumericalStability = 93,
Initializes = 94,
HybridPatchable = 95,
SanitizeRealtime = 96,
SanitizeRealtimeBlocking = 97,
CoroElideSafe = 98,
NoExt = 99,
NoDivergenceSource = 100,
SanitizeType = 101,
Captures = 102,
DeadOnReturn = 103,
SanitizeAllocToken = 104,
NoCreateUndefOrPoison = 105,
DenormalFpEnv = 106,
NoOutline = 107,
Flatten = 108,
StringAttribute = !0,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum CastOpcode {
Trunc = 0,
ZExt = 1,
SExt = 2,
FpToUi = 3,
FpToSi = 4,
UiToFp = 5,
SiToFp = 6,
FpTrunc = 7,
FpExt = 8,
PtrToInt = 9,
IntToPtr = 10,
Bitcast = 11,
Addrspace = 12,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
#[non_exhaustive]
pub enum Linkage {
External = 0,
#[deprecated]
WeakAnyOld = 1,
Appending = 2,
Internal = 3,
#[deprecated]
LinkOnceAnyOld = 4,
#[deprecated]
DllImport = 5,
#[deprecated]
DllExport = 6,
ExternWeak = 7,
Common = 8,
Private = 9,
#[deprecated]
WeakOdrOld = 10,
#[deprecated]
LinkOnceOdrOld = 11,
AvailableExternally = 12,
#[deprecated]
LinkerPrivate = 13,
#[deprecated]
LinkerPrivateWeak = 14,
#[deprecated]
LinkOnceOdrAutoHide = 15,
WeakAny = 16,
WeakOdr = 17,
LinkOnceAny = 18,
LinkOnceOdr = 19,
}
impl Linkage {
#[allow(deprecated)]
#[must_use]
pub fn is_private(self) -> bool {
matches!(
self,
Self::Private | Self::Internal | Self::LinkerPrivate | Self::LinkerPrivateWeak
)
}
}
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum DllStorageClass {
#[default]
Default = 0,
Import = 1,
Export = 2,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
#[non_exhaustive]
pub enum CallConv {
C = 0,
Fast = 8,
Cold = 9,
Ghc = 10,
HiPE = 11,
AnyReg = 13,
PreserveMost = 14,
PreserveAll = 15,
Swift = 16,
CxxFastTls = 17,
Tail = 18,
CfGuardCheck = 19,
SwiftTail = 20,
PreserveNone = 21,
X86StdCall = 64,
X86FastCall = 65,
ArmApcs = 66,
ArmAapcs = 67,
ArmAapcsVfp = 68,
Msp430Intr = 69,
X86ThisCall = 70,
PtxKernel = 71,
PtxDevice = 72,
SpirFunc = 75,
SpirKernel = 76,
IntelOclBi = 77,
X8664SysV = 78,
Win64 = 79,
X86VectorCall = 80,
#[deprecated]
DummyHhvm = 81,
DummyHhvmC = 82,
X86Intr = 83,
AvrIntr = 84,
AvrSignal = 85,
AvrBuiltin = 86,
AmdGpuVs = 87,
AmdGpuGs = 88,
AmdGpuPs = 89,
AmdGpuCs = 90,
AmdGpuKernel = 91,
X86RegCall = 92,
AmdGpuHs = 93,
Msp430Builtin = 94,
AmdGpuLs = 95,
AmdGpuEs = 96,
AArch64VectorCall = 97,
AArch64SveVectorCall = 98,
WasmEmscriptenInvoke = 99,
AmdGpuGfx = 100,
M68kIntr = 101,
AArch64SmeAbiSupportRoutinesPreserveMostFromX0 = 102,
AArch64SmeAbiSupportRoutinesPreserveMostFromX2 = 103,
AmdGpuCsChain = 104,
AmdGpuCsChainPreserve = 105,
M68kRtd = 106,
Graal = 107,
Arm64ecThunkX64 = 108,
Arm64ecThunkNative = 109,
RiscVVectorCall = 110,
AArch64SmeAbiSupportRoutinesPreserveMostFromX1 = 111,
RiscVVlsCall32 = 112,
RiscVVlsCall64 = 113,
RiscVVlsCall128 = 114,
RiscVVlsCall256 = 115,
RiscVVlsCall512 = 116,
RiscVVlsCall1024 = 117,
RiscVVlsCall2048 = 118,
RiscVVlsCall4096 = 119,
RiscVVlsCall8192 = 120,
RiscVVlsCall16384 = 121,
RiscVVlsCall32768 = 122,
RiscVVlsCall65536 = 123,
AmdGpuGfxWholeWave = 124,
CHERIoTCompartmentCall = 125,
CHERIoTCompartmentCallee = 126,
CHERIoTLibraryCall = 127,
}
impl CallConv {
#[must_use]
pub fn from_call_flags(ccinfo_flags: u64) -> Option<Self> {
let id = u8::try_from((ccinfo_flags & 0x7ff) >> 1).ok()?;
Self::try_from_primitive(id).ok()
}
#[must_use]
pub fn from_invoke_flags(ccinfo_flags: u64) -> Option<Self> {
let id = u8::try_from(ccinfo_flags & 0x3ff).ok()?;
Self::try_from_primitive(id).ok()
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum BinOpcode {
Add = 0,
Sub = 1,
Mul = 2,
UDiv = 3,
SDiv = 4,
URem = 5,
SRem = 6,
Shl = 7,
LShr = 8,
AShr = 9,
And = 10,
Or = 11,
Xor = 12,
}
#[derive(Debug, Clone, Copy)]
pub enum BinOpcodeFlags {
Add(OverflowFlags),
Sub(OverflowFlags),
Mul(OverflowFlags),
UDiv { exact: bool },
SDiv { exact: bool },
URem,
SRem,
Shl(OverflowFlags),
LShr { exact: bool },
AShr { exact: bool },
And,
Or,
Xor,
}
impl BinOpcode {
#[must_use]
pub fn with_flags(self, flags: u8) -> BinOpcodeFlags {
match self {
Self::Add => BinOpcodeFlags::Add(OverflowFlags::from_bits_truncate(flags)),
Self::Sub => BinOpcodeFlags::Sub(OverflowFlags::from_bits_truncate(flags)),
Self::Mul => BinOpcodeFlags::Mul(OverflowFlags::from_bits_truncate(flags)),
Self::UDiv => BinOpcodeFlags::UDiv { exact: flags != 0 },
Self::SDiv => BinOpcodeFlags::SDiv { exact: flags != 0 },
Self::URem => BinOpcodeFlags::URem,
Self::SRem => BinOpcodeFlags::SRem,
Self::Shl => BinOpcodeFlags::Shl(OverflowFlags::from_bits_truncate(flags)),
Self::LShr => BinOpcodeFlags::LShr { exact: flags != 0 },
Self::AShr => BinOpcodeFlags::AShr { exact: flags != 0 },
Self::And => BinOpcodeFlags::And,
Self::Or => BinOpcodeFlags::Or,
Self::Xor => BinOpcodeFlags::Xor,
}
}
}
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum AtomicOrdering {
#[default]
NotAtomic = 0,
Unordered = 1,
Monotonic = 2,
Acquire = 3,
Release = 4,
AcqRel = 5,
SeqCst = 6,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default, TryFromPrimitive)]
#[repr(u8)]
pub enum ComdatSelectionKind {
#[default]
Any = 1,
ExactMatch = 2,
Largest = 3,
NoDuplicates = 4,
SameSize = 5,
}
#[derive(Debug, Copy, Clone, TryFromPrimitive)]
#[repr(u8)]
#[non_exhaustive]
pub enum RmwOperation {
Xchg = 0,
Add = 1,
Sub = 2,
And = 3,
Nand = 4,
Or = 5,
Xor = 6,
Max = 7,
Min = 8,
UMax = 9,
UMin = 10,
FAdd = 11,
FSub = 12,
FMax = 13,
FMin = 14,
UIncWrap = 15,
UDecWrap = 16,
USubCond = 17,
USubSat = 18,
}
#[derive(Debug, Copy, Clone, TryFromPrimitive)]
#[repr(u8)]
#[non_exhaustive]
pub enum UnaryOpcode {
Fneg = 0,
}
bitflags::bitflags! {
#[derive(Debug, Copy, Clone, Default)]
pub struct InlineAsmFlags: u8 {
const SideEffect = 1 << 0;
const AlignStack = 1 << 1;
const AsmDialectIntel = 1 << 2;
const Unwind = 1 << 3;
}
}
bitflags::bitflags! {
#[derive(Debug, Copy, Clone, Default)]
pub struct OverflowFlags: u8 {
const NoUnsignedWrap = 1 << 0;
const NoSignedWrap = 1 << 1;
}
}
pub type OverflowingBinaryOperatorOptionalFlags = OverflowFlags;
pub type TruncInstOptionalFlags = OverflowFlags;
bitflags::bitflags! {
#[derive(Debug, Copy, Clone, Default)]
pub struct FastMathFlags: u8 {
const UnsafeAlgebra = 1 << 0;
const NoNans = 1 << 1;
const NoInfs = 1 << 2;
const NoSignedZeros = 1 << 3;
const AllowReciprocal = 1 << 4;
const AllowContract = 1 << 5;
const ApproxFunc = 1 << 6;
const AllowReassoc = 1 << 7;
}
}
bitflags::bitflags! {
#[derive(Debug, Copy, Clone, Default)]
pub struct GEPFlags: u8 {
const Inbounds = 1 << 0;
const Nusw = 1 << 1;
const Nuw = 1 << 2;
}
}
bitflags::bitflags! {
#[derive(Debug, Copy, Clone, Default)]
pub struct CallMarkersFlags: u32 {
const Tail = 1 << 0;
const Cconv = 1 << 1;
const MustTail = 1 << 14;
const ExplicitType = 1 << 15;
const NoTail = 1 << 16;
const Fmf = 1 << 17;
}
}
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum Visibility {
#[default]
Default = 0,
Hidden = 1,
Protected = 2,
}
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum ThreadLocalMode {
#[default]
NotThreadLocal = 0,
GeneralDynamic = 1,
LocalDynamic = 2,
InitialExec = 3,
LocalExec = 4,
}
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum UnnamedAddr {
#[default]
None = 0,
Global = 1,
Local = 2,
}
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum PreemptionSpecifier {
#[default]
DsoPreemptable = 0,
DsoLocal = 1,
}
bitflags::bitflags! {
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct FCmpPredicate: u8 {
const Equal = 1 << 0;
const Less = 1 << 1;
const Greater = 1 << 2;
const Unordered = 1 << 3;
const FALSE = 0;
const OEQ = Self::Equal.bits();
const OGT = Self::Greater.bits();
const OGE = Self::Greater.bits() | Self::Equal.bits();
const OLT = Self::Less.bits();
const OLE = Self::Less.bits() | Self::Equal.bits();
const ONE = Self::Less.bits() | Self::Greater.bits();
const ORD = Self::Less.bits() | Self::Greater.bits() | Self::Equal.bits();
const UNO = Self::Unordered.bits();
const UEQ = Self::Unordered.bits() | Self::Equal.bits();
const UGT = Self::Unordered.bits() | Self::Greater.bits();
const UGE = Self::Unordered.bits() | Self::Greater.bits() | Self::Equal.bits();
const ULT = Self::Unordered.bits() | Self::Less.bits();
const ULE = Self::Unordered.bits() | Self::Less.bits() | Self::Equal.bits();
const UNE = Self::Unordered.bits() | Self::Less.bits() | Self::Greater.bits();
const TRUE = Self::Unordered.bits() | Self::Less.bits() | Self::Greater.bits() | Self::Equal.bits();
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum ICmpPredicate {
Eq = 32,
Ne = 33,
Ugt = 34,
Uge = 35,
Ult = 36,
Ule = 37,
Sgt = 38,
Sge = 39,
Slt = 40,
Sle = 41,
}
impl ICmpPredicate {
#[must_use]
pub fn is_unsigned(self) -> bool {
matches!(self, Self::Ugt | Self::Uge | Self::Ult | Self::Ule)
}
#[must_use]
pub fn is_signed(self) -> bool {
matches!(self, Self::Sgt | Self::Sge | Self::Slt | Self::Sle)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum CmpPredicate {
FCmp(FCmpPredicate),
ICmp(ICmpPredicate),
}
impl CmpPredicate {
#[must_use]
pub fn as_fp(self) -> Option<FCmpPredicate> {
match self {
Self::FCmp(p) => Some(p),
Self::ICmp(_) => None,
}
}
#[must_use]
pub fn as_int(self) -> Option<ICmpPredicate> {
match self {
Self::FCmp(_) => None,
Self::ICmp(p) => Some(p),
}
}
}
impl TryFrom<u8> for CmpPredicate {
type Error = TryFromPrimitiveError<ICmpPredicate>;
fn try_from(value: u8) -> Result<Self, Self::Error> {
if value <= 15 {
Ok(Self::FCmp(FCmpPredicate::from_bits_truncate(value)))
} else {
ICmpPredicate::try_from_primitive(value).map(Self::ICmp)
}
}
}
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum DebugEmissionKind {
#[default]
NoDebug = 0,
FullDebug = 1,
LineTablesOnly = 2,
DebugDirectivesOnly = 3,
}
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum DebugNameTableKind {
#[default]
Default = 0,
Gnu = 1,
None = 2,
Apple = 3,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[repr(transparent)]
pub struct Alignment(NonZero<u8>);
impl Alignment {
#[must_use]
pub fn from_encoded(encoded: u8) -> Option<Self> {
NonZero::new(encoded).map(Self)
}
#[must_use]
pub fn ilog2(self) -> u8 {
self.0.get() - 1
}
#[must_use]
pub fn bytes(self) -> usize {
1usize << self.ilog2()
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, FromPrimitive, IntoPrimitive)]
#[repr(u8)]
pub enum AddressSpace {
Generic = 0,
Global = 1,
Region = 2,
Local = 3,
Constant = 4,
Private = 5,
Constant32Bit = 6,
Flat = 7,
#[num_enum(catch_all)]
Other(u8),
}
#[allow(clippy::derivable_impls)]
impl Default for AddressSpace {
fn default() -> Self {
Self::Generic
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
#[non_exhaustive]
pub enum FuncletPad {
CleanupPad = 0,
CatchPad = 1,
}