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