1 use crate::cdsl::operands::{EnumValues, OperandKind, OperandKindFields}; 2 3 use std::collections::HashMap; 4 5 pub(crate) struct Immediates { 6 /// A 64-bit immediate integer operand. 7 /// 8 /// This type of immediate integer can interact with SSA values with any IntType type. 9 pub imm64: OperandKind, 10 11 /// An unsigned 8-bit immediate integer operand. 12 /// 13 /// This small operand is used to indicate lane indexes in SIMD vectors and immediate bit 14 /// counts on shift instructions. 15 pub uimm8: OperandKind, 16 17 /// An unsigned 128-bit immediate integer operand. 18 /// 19 /// This operand is used to pass entire 128-bit vectors as immediates to instructions like 20 /// const. 21 pub uimm128: OperandKind, 22 23 /// A constant stored in the constant pool. 24 /// 25 /// This operand is used to pass constants to instructions like vconst while storing the 26 /// actual bytes in the constant pool. 27 pub pool_constant: OperandKind, 28 29 /// A 32-bit immediate signed offset. 30 /// 31 /// This is used to represent an immediate address offset in load/store instructions. 32 pub offset32: OperandKind, 33 34 /// A 32-bit immediate floating point operand. 35 /// 36 /// IEEE 754-2008 binary32 interchange format. 37 pub ieee32: OperandKind, 38 39 /// A 64-bit immediate floating point operand. 40 /// 41 /// IEEE 754-2008 binary64 interchange format. 42 pub ieee64: OperandKind, 43 44 /// A condition code for comparing integer values. 45 /// 46 /// This enumerated operand kind is used for the `icmp` instruction and corresponds to the 47 /// condcodes::IntCC` Rust type. 48 pub intcc: OperandKind, 49 50 /// A condition code for comparing floating point values. 51 /// 52 /// This enumerated operand kind is used for the `fcmp` instruction and corresponds to the 53 /// `condcodes::FloatCC` Rust type. 54 pub floatcc: OperandKind, 55 56 /// Flags for memory operations like `load` and `store`. 57 pub memflags: OperandKind, 58 59 /// A trap code indicating the reason for trapping. 60 /// 61 /// The Rust enum type also has a `User(u16)` variant for user-provided trap codes. 62 pub trapcode: OperandKind, 63 64 /// A code indicating the arithmetic operation to perform in an atomic_rmw memory access. 65 pub atomic_rmw_op: OperandKind, 66 } 67 68 fn new_imm( 69 format_field_name: &'static str, 70 rust_type: &'static str, 71 doc: &'static str, 72 ) -> OperandKind { 73 OperandKind::new( 74 format_field_name, 75 rust_type, 76 OperandKindFields::ImmValue, 77 doc, 78 ) 79 } 80 fn new_enum( 81 format_field_name: &'static str, 82 rust_type: &'static str, 83 values: EnumValues, 84 doc: &'static str, 85 ) -> OperandKind { 86 OperandKind::new( 87 format_field_name, 88 rust_type, 89 OperandKindFields::ImmEnum(values), 90 doc, 91 ) 92 } 93 94 impl Immediates { 95 pub fn new() -> Self { 96 Self { 97 imm64: new_imm( 98 "imm", 99 "ir::immediates::Imm64", 100 "A 64-bit immediate integer.", 101 ), 102 uimm8: new_imm( 103 "imm", 104 "ir::immediates::Uimm8", 105 "An 8-bit immediate unsigned integer.", 106 ), 107 uimm128: new_imm( 108 "imm", 109 "ir::Immediate", 110 "A 128-bit immediate unsigned integer.", 111 ), 112 pool_constant: new_imm( 113 "constant_handle", 114 "ir::Constant", 115 "A constant stored in the constant pool.", 116 ), 117 offset32: new_imm( 118 "offset", 119 "ir::immediates::Offset32", 120 "A 32-bit immediate signed offset.", 121 ), 122 ieee32: new_imm( 123 "imm", 124 "ir::immediates::Ieee32", 125 "A 32-bit immediate floating point number.", 126 ), 127 ieee64: new_imm( 128 "imm", 129 "ir::immediates::Ieee64", 130 "A 64-bit immediate floating point number.", 131 ), 132 intcc: { 133 let mut intcc_values = HashMap::new(); 134 intcc_values.insert("eq", "Equal"); 135 intcc_values.insert("ne", "NotEqual"); 136 intcc_values.insert("sge", "SignedGreaterThanOrEqual"); 137 intcc_values.insert("sgt", "SignedGreaterThan"); 138 intcc_values.insert("sle", "SignedLessThanOrEqual"); 139 intcc_values.insert("slt", "SignedLessThan"); 140 intcc_values.insert("uge", "UnsignedGreaterThanOrEqual"); 141 intcc_values.insert("ugt", "UnsignedGreaterThan"); 142 intcc_values.insert("ule", "UnsignedLessThanOrEqual"); 143 intcc_values.insert("ult", "UnsignedLessThan"); 144 new_enum( 145 "cond", 146 "ir::condcodes::IntCC", 147 intcc_values, 148 "An integer comparison condition code.", 149 ) 150 }, 151 152 floatcc: { 153 let mut floatcc_values = HashMap::new(); 154 floatcc_values.insert("ord", "Ordered"); 155 floatcc_values.insert("uno", "Unordered"); 156 floatcc_values.insert("eq", "Equal"); 157 floatcc_values.insert("ne", "NotEqual"); 158 floatcc_values.insert("one", "OrderedNotEqual"); 159 floatcc_values.insert("ueq", "UnorderedOrEqual"); 160 floatcc_values.insert("lt", "LessThan"); 161 floatcc_values.insert("le", "LessThanOrEqual"); 162 floatcc_values.insert("gt", "GreaterThan"); 163 floatcc_values.insert("ge", "GreaterThanOrEqual"); 164 floatcc_values.insert("ult", "UnorderedOrLessThan"); 165 floatcc_values.insert("ule", "UnorderedOrLessThanOrEqual"); 166 floatcc_values.insert("ugt", "UnorderedOrGreaterThan"); 167 floatcc_values.insert("uge", "UnorderedOrGreaterThanOrEqual"); 168 new_enum( 169 "cond", 170 "ir::condcodes::FloatCC", 171 floatcc_values, 172 "A floating point comparison condition code", 173 ) 174 }, 175 176 memflags: new_imm("flags", "ir::MemFlags", "Memory operation flags"), 177 178 trapcode: { 179 let mut trapcode_values = HashMap::new(); 180 trapcode_values.insert("stk_ovf", "StackOverflow"); 181 trapcode_values.insert("heap_oob", "HeapOutOfBounds"); 182 trapcode_values.insert("int_ovf", "IntegerOverflow"); 183 trapcode_values.insert("int_divz", "IntegerDivisionByZero"); 184 trapcode_values.insert("bad_toint", "BadConversionToInteger"); 185 new_enum( 186 "code", 187 "ir::TrapCode", 188 trapcode_values, 189 "A trap reason code.", 190 ) 191 }, 192 atomic_rmw_op: { 193 let mut atomic_rmw_op_values = HashMap::new(); 194 atomic_rmw_op_values.insert("add", "Add"); 195 atomic_rmw_op_values.insert("sub", "Sub"); 196 atomic_rmw_op_values.insert("and", "And"); 197 atomic_rmw_op_values.insert("nand", "Nand"); 198 atomic_rmw_op_values.insert("or", "Or"); 199 atomic_rmw_op_values.insert("xor", "Xor"); 200 atomic_rmw_op_values.insert("xchg", "Xchg"); 201 atomic_rmw_op_values.insert("umin", "Umin"); 202 atomic_rmw_op_values.insert("umax", "Umax"); 203 atomic_rmw_op_values.insert("smin", "Smin"); 204 atomic_rmw_op_values.insert("smax", "Smax"); 205 new_enum( 206 "op", 207 "ir::AtomicRmwOp", 208 atomic_rmw_op_values, 209 "Atomic Read-Modify-Write Ops", 210 ) 211 }, 212 } 213 } 214 } 215