1 use crate::cdsl::formats::{InstructionFormat, InstructionFormatBuilder as Builder}; 2 use crate::shared::{entities::EntityRefs, immediates::Immediates}; 3 use std::rc::Rc; 4 5 pub(crate) struct Formats { 6 pub(crate) atomic_cas: Rc<InstructionFormat>, 7 pub(crate) atomic_rmw: Rc<InstructionFormat>, 8 pub(crate) binary: Rc<InstructionFormat>, 9 pub(crate) binary_imm8: Rc<InstructionFormat>, 10 pub(crate) binary_imm64: Rc<InstructionFormat>, 11 pub(crate) branch: Rc<InstructionFormat>, 12 pub(crate) branch_float: Rc<InstructionFormat>, 13 pub(crate) branch_icmp: Rc<InstructionFormat>, 14 pub(crate) branch_int: Rc<InstructionFormat>, 15 pub(crate) branch_table: Rc<InstructionFormat>, 16 pub(crate) call: Rc<InstructionFormat>, 17 pub(crate) call_indirect: Rc<InstructionFormat>, 18 pub(crate) cond_trap: Rc<InstructionFormat>, 19 pub(crate) float_compare: Rc<InstructionFormat>, 20 pub(crate) float_cond: Rc<InstructionFormat>, 21 pub(crate) float_cond_trap: Rc<InstructionFormat>, 22 pub(crate) func_addr: Rc<InstructionFormat>, 23 pub(crate) heap_addr: Rc<InstructionFormat>, 24 pub(crate) int_compare: Rc<InstructionFormat>, 25 pub(crate) int_compare_imm: Rc<InstructionFormat>, 26 pub(crate) int_cond: Rc<InstructionFormat>, 27 pub(crate) int_cond_trap: Rc<InstructionFormat>, 28 pub(crate) int_select: Rc<InstructionFormat>, 29 pub(crate) jump: Rc<InstructionFormat>, 30 pub(crate) load: Rc<InstructionFormat>, 31 pub(crate) load_no_offset: Rc<InstructionFormat>, 32 pub(crate) multiary: Rc<InstructionFormat>, 33 pub(crate) nullary: Rc<InstructionFormat>, 34 pub(crate) shuffle: Rc<InstructionFormat>, 35 pub(crate) stack_load: Rc<InstructionFormat>, 36 pub(crate) stack_store: Rc<InstructionFormat>, 37 pub(crate) store: Rc<InstructionFormat>, 38 pub(crate) store_no_offset: Rc<InstructionFormat>, 39 pub(crate) table_addr: Rc<InstructionFormat>, 40 pub(crate) ternary: Rc<InstructionFormat>, 41 pub(crate) ternary_imm8: Rc<InstructionFormat>, 42 pub(crate) trap: Rc<InstructionFormat>, 43 pub(crate) unary: Rc<InstructionFormat>, 44 pub(crate) unary_bool: Rc<InstructionFormat>, 45 pub(crate) unary_const: Rc<InstructionFormat>, 46 pub(crate) unary_global_value: Rc<InstructionFormat>, 47 pub(crate) unary_ieee32: Rc<InstructionFormat>, 48 pub(crate) unary_ieee64: Rc<InstructionFormat>, 49 pub(crate) unary_imm: Rc<InstructionFormat>, 50 } 51 52 impl Formats { 53 pub fn new(imm: &Immediates, entities: &EntityRefs) -> Self { 54 Self { 55 unary: Builder::new("Unary").value().build(), 56 57 unary_imm: Builder::new("UnaryImm").imm(&imm.imm64).build(), 58 59 unary_ieee32: Builder::new("UnaryIeee32").imm(&imm.ieee32).build(), 60 61 unary_ieee64: Builder::new("UnaryIeee64").imm(&imm.ieee64).build(), 62 63 unary_bool: Builder::new("UnaryBool").imm(&imm.boolean).build(), 64 65 unary_const: Builder::new("UnaryConst").imm(&imm.pool_constant).build(), 66 67 unary_global_value: Builder::new("UnaryGlobalValue") 68 .imm(&entities.global_value) 69 .build(), 70 71 binary: Builder::new("Binary").value().value().build(), 72 73 binary_imm8: Builder::new("BinaryImm8").value().imm(&imm.uimm8).build(), 74 75 binary_imm64: Builder::new("BinaryImm64").value().imm(&imm.imm64).build(), 76 77 // The select instructions are controlled by the second VALUE operand. 78 // The first VALUE operand is the controlling flag which has a derived type. 79 // The fma instruction has the same constraint on all inputs. 80 ternary: Builder::new("Ternary") 81 .value() 82 .value() 83 .value() 84 .typevar_operand(1) 85 .build(), 86 87 ternary_imm8: Builder::new("TernaryImm8") 88 .value() 89 .imm(&imm.uimm8) 90 .value() 91 .build(), 92 93 // Catch-all for instructions with many outputs and inputs and no immediate 94 // operands. 95 multiary: Builder::new("MultiAry").varargs().build(), 96 97 nullary: Builder::new("NullAry").build(), 98 99 shuffle: Builder::new("Shuffle") 100 .value() 101 .value() 102 .imm(&imm.uimm128) 103 .build(), 104 105 int_compare: Builder::new("IntCompare") 106 .imm(&imm.intcc) 107 .value() 108 .value() 109 .build(), 110 111 int_compare_imm: Builder::new("IntCompareImm") 112 .imm(&imm.intcc) 113 .value() 114 .imm(&imm.imm64) 115 .build(), 116 117 int_cond: Builder::new("IntCond").imm(&imm.intcc).value().build(), 118 119 float_compare: Builder::new("FloatCompare") 120 .imm(&imm.floatcc) 121 .value() 122 .value() 123 .build(), 124 125 float_cond: Builder::new("FloatCond").imm(&imm.floatcc).value().build(), 126 127 int_select: Builder::new("IntSelect") 128 .imm(&imm.intcc) 129 .value() 130 .value() 131 .value() 132 .build(), 133 134 jump: Builder::new("Jump").imm(&entities.block).varargs().build(), 135 136 branch: Builder::new("Branch") 137 .value() 138 .imm(&entities.block) 139 .varargs() 140 .build(), 141 142 branch_int: Builder::new("BranchInt") 143 .imm(&imm.intcc) 144 .value() 145 .imm(&entities.block) 146 .varargs() 147 .build(), 148 149 branch_float: Builder::new("BranchFloat") 150 .imm(&imm.floatcc) 151 .value() 152 .imm(&entities.block) 153 .varargs() 154 .build(), 155 156 branch_icmp: Builder::new("BranchIcmp") 157 .imm(&imm.intcc) 158 .value() 159 .value() 160 .imm(&entities.block) 161 .varargs() 162 .build(), 163 164 branch_table: Builder::new("BranchTable") 165 .value() 166 .imm(&entities.block) 167 .imm(&entities.jump_table) 168 .build(), 169 170 call: Builder::new("Call") 171 .imm(&entities.func_ref) 172 .varargs() 173 .build(), 174 175 call_indirect: Builder::new("CallIndirect") 176 .imm(&entities.sig_ref) 177 .value() 178 .varargs() 179 .build(), 180 181 func_addr: Builder::new("FuncAddr").imm(&entities.func_ref).build(), 182 183 atomic_rmw: Builder::new("AtomicRmw") 184 .imm(&imm.memflags) 185 .imm(&imm.atomic_rmw_op) 186 .value() 187 .value() 188 .build(), 189 190 atomic_cas: Builder::new("AtomicCas") 191 .imm(&imm.memflags) 192 .value() 193 .value() 194 .value() 195 .typevar_operand(2) 196 .build(), 197 198 load: Builder::new("Load") 199 .imm(&imm.memflags) 200 .value() 201 .imm(&imm.offset32) 202 .build(), 203 204 load_no_offset: Builder::new("LoadNoOffset") 205 .imm(&imm.memflags) 206 .value() 207 .build(), 208 209 store: Builder::new("Store") 210 .imm(&imm.memflags) 211 .value() 212 .value() 213 .imm(&imm.offset32) 214 .build(), 215 216 store_no_offset: Builder::new("StoreNoOffset") 217 .imm(&imm.memflags) 218 .value() 219 .value() 220 .build(), 221 222 stack_load: Builder::new("StackLoad") 223 .imm(&entities.stack_slot) 224 .imm(&imm.offset32) 225 .build(), 226 227 stack_store: Builder::new("StackStore") 228 .value() 229 .imm(&entities.stack_slot) 230 .imm(&imm.offset32) 231 .build(), 232 233 // Accessing a WebAssembly heap. 234 heap_addr: Builder::new("HeapAddr") 235 .imm(&entities.heap) 236 .value() 237 .imm(&imm.uimm32) 238 .build(), 239 240 // Accessing a WebAssembly table. 241 table_addr: Builder::new("TableAddr") 242 .imm(&entities.table) 243 .value() 244 .imm(&imm.offset32) 245 .build(), 246 247 trap: Builder::new("Trap").imm(&imm.trapcode).build(), 248 249 cond_trap: Builder::new("CondTrap").value().imm(&imm.trapcode).build(), 250 251 int_cond_trap: Builder::new("IntCondTrap") 252 .imm(&imm.intcc) 253 .value() 254 .imm(&imm.trapcode) 255 .build(), 256 257 float_cond_trap: Builder::new("FloatCondTrap") 258 .imm(&imm.floatcc) 259 .value() 260 .imm(&imm.trapcode) 261 .build(), 262 } 263 } 264 } 265