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) branch_table_base: Rc<InstructionFormat>, 17 pub(crate) branch_table_entry: Rc<InstructionFormat>, 18 pub(crate) call: Rc<InstructionFormat>, 19 pub(crate) call_indirect: Rc<InstructionFormat>, 20 pub(crate) cond_trap: Rc<InstructionFormat>, 21 pub(crate) copy_special: Rc<InstructionFormat>, 22 pub(crate) copy_to_ssa: Rc<InstructionFormat>, 23 pub(crate) float_compare: Rc<InstructionFormat>, 24 pub(crate) float_cond: Rc<InstructionFormat>, 25 pub(crate) float_cond_trap: Rc<InstructionFormat>, 26 pub(crate) func_addr: Rc<InstructionFormat>, 27 pub(crate) heap_addr: Rc<InstructionFormat>, 28 pub(crate) indirect_jump: Rc<InstructionFormat>, 29 pub(crate) int_compare: Rc<InstructionFormat>, 30 pub(crate) int_compare_imm: Rc<InstructionFormat>, 31 pub(crate) int_cond: Rc<InstructionFormat>, 32 pub(crate) int_cond_trap: Rc<InstructionFormat>, 33 pub(crate) int_select: Rc<InstructionFormat>, 34 pub(crate) jump: Rc<InstructionFormat>, 35 pub(crate) load: Rc<InstructionFormat>, 36 pub(crate) load_complex: Rc<InstructionFormat>, 37 pub(crate) load_no_offset: Rc<InstructionFormat>, 38 pub(crate) multiary: Rc<InstructionFormat>, 39 pub(crate) nullary: Rc<InstructionFormat>, 40 pub(crate) reg_fill: Rc<InstructionFormat>, 41 pub(crate) reg_move: Rc<InstructionFormat>, 42 pub(crate) reg_spill: Rc<InstructionFormat>, 43 pub(crate) shuffle: Rc<InstructionFormat>, 44 pub(crate) stack_load: Rc<InstructionFormat>, 45 pub(crate) stack_store: Rc<InstructionFormat>, 46 pub(crate) store: Rc<InstructionFormat>, 47 pub(crate) store_complex: Rc<InstructionFormat>, 48 pub(crate) store_no_offset: Rc<InstructionFormat>, 49 pub(crate) table_addr: Rc<InstructionFormat>, 50 pub(crate) ternary: Rc<InstructionFormat>, 51 pub(crate) ternary_imm8: Rc<InstructionFormat>, 52 pub(crate) trap: Rc<InstructionFormat>, 53 pub(crate) unary: Rc<InstructionFormat>, 54 pub(crate) unary_bool: Rc<InstructionFormat>, 55 pub(crate) unary_const: Rc<InstructionFormat>, 56 pub(crate) unary_global_value: Rc<InstructionFormat>, 57 pub(crate) unary_ieee32: Rc<InstructionFormat>, 58 pub(crate) unary_ieee64: Rc<InstructionFormat>, 59 pub(crate) unary_imm: Rc<InstructionFormat>, 60 } 61 62 impl Formats { new(imm: &Immediates, entities: &EntityRefs) -> Self63 pub fn new(imm: &Immediates, entities: &EntityRefs) -> Self { 64 Self { 65 unary: Builder::new("Unary").value().build(), 66 67 unary_imm: Builder::new("UnaryImm").imm(&imm.imm64).build(), 68 69 unary_ieee32: Builder::new("UnaryIeee32").imm(&imm.ieee32).build(), 70 71 unary_ieee64: Builder::new("UnaryIeee64").imm(&imm.ieee64).build(), 72 73 unary_bool: Builder::new("UnaryBool").imm(&imm.boolean).build(), 74 75 unary_const: Builder::new("UnaryConst").imm(&imm.pool_constant).build(), 76 77 unary_global_value: Builder::new("UnaryGlobalValue") 78 .imm(&entities.global_value) 79 .build(), 80 81 binary: Builder::new("Binary").value().value().build(), 82 83 binary_imm8: Builder::new("BinaryImm8").value().imm(&imm.uimm8).build(), 84 85 binary_imm64: Builder::new("BinaryImm64").value().imm(&imm.imm64).build(), 86 87 // The select instructions are controlled by the second VALUE operand. 88 // The first VALUE operand is the controlling flag which has a derived type. 89 // The fma instruction has the same constraint on all inputs. 90 ternary: Builder::new("Ternary") 91 .value() 92 .value() 93 .value() 94 .typevar_operand(1) 95 .build(), 96 97 ternary_imm8: Builder::new("TernaryImm8") 98 .value() 99 .imm(&imm.uimm8) 100 .value() 101 .build(), 102 103 // Catch-all for instructions with many outputs and inputs and no immediate 104 // operands. 105 multiary: Builder::new("MultiAry").varargs().build(), 106 107 nullary: Builder::new("NullAry").build(), 108 109 shuffle: Builder::new("Shuffle") 110 .value() 111 .value() 112 .imm_with_name("mask", &imm.uimm128) 113 .build(), 114 115 int_compare: Builder::new("IntCompare") 116 .imm(&imm.intcc) 117 .value() 118 .value() 119 .build(), 120 121 int_compare_imm: Builder::new("IntCompareImm") 122 .imm(&imm.intcc) 123 .value() 124 .imm(&imm.imm64) 125 .build(), 126 127 int_cond: Builder::new("IntCond").imm(&imm.intcc).value().build(), 128 129 float_compare: Builder::new("FloatCompare") 130 .imm(&imm.floatcc) 131 .value() 132 .value() 133 .build(), 134 135 float_cond: Builder::new("FloatCond").imm(&imm.floatcc).value().build(), 136 137 int_select: Builder::new("IntSelect") 138 .imm(&imm.intcc) 139 .value() 140 .value() 141 .value() 142 .build(), 143 144 jump: Builder::new("Jump").imm(&entities.block).varargs().build(), 145 146 branch: Builder::new("Branch") 147 .value() 148 .imm(&entities.block) 149 .varargs() 150 .build(), 151 152 branch_int: Builder::new("BranchInt") 153 .imm(&imm.intcc) 154 .value() 155 .imm(&entities.block) 156 .varargs() 157 .build(), 158 159 branch_float: Builder::new("BranchFloat") 160 .imm(&imm.floatcc) 161 .value() 162 .imm(&entities.block) 163 .varargs() 164 .build(), 165 166 branch_icmp: Builder::new("BranchIcmp") 167 .imm(&imm.intcc) 168 .value() 169 .value() 170 .imm(&entities.block) 171 .varargs() 172 .build(), 173 174 branch_table: Builder::new("BranchTable") 175 .value() 176 .imm(&entities.block) 177 .imm(&entities.jump_table) 178 .build(), 179 180 branch_table_entry: Builder::new("BranchTableEntry") 181 .value() 182 .value() 183 .imm(&imm.uimm8) 184 .imm(&entities.jump_table) 185 .build(), 186 187 branch_table_base: Builder::new("BranchTableBase") 188 .imm(&entities.jump_table) 189 .build(), 190 191 indirect_jump: Builder::new("IndirectJump") 192 .value() 193 .imm(&entities.jump_table) 194 .build(), 195 196 call: Builder::new("Call") 197 .imm(&entities.func_ref) 198 .varargs() 199 .build(), 200 201 call_indirect: Builder::new("CallIndirect") 202 .imm(&entities.sig_ref) 203 .value() 204 .varargs() 205 .build(), 206 207 func_addr: Builder::new("FuncAddr").imm(&entities.func_ref).build(), 208 209 atomic_rmw: Builder::new("AtomicRmw") 210 .imm(&imm.memflags) 211 .imm(&imm.atomic_rmw_op) 212 .value() 213 .value() 214 .build(), 215 216 atomic_cas: Builder::new("AtomicCas") 217 .imm(&imm.memflags) 218 .value() 219 .value() 220 .value() 221 .typevar_operand(2) 222 .build(), 223 224 load: Builder::new("Load") 225 .imm(&imm.memflags) 226 .value() 227 .imm(&imm.offset32) 228 .build(), 229 230 load_complex: Builder::new("LoadComplex") 231 .imm(&imm.memflags) 232 .varargs() 233 .imm(&imm.offset32) 234 .build(), 235 236 load_no_offset: Builder::new("LoadNoOffset") 237 .imm(&imm.memflags) 238 .value() 239 .build(), 240 241 store: Builder::new("Store") 242 .imm(&imm.memflags) 243 .value() 244 .value() 245 .imm(&imm.offset32) 246 .build(), 247 248 store_complex: Builder::new("StoreComplex") 249 .imm(&imm.memflags) 250 .value() 251 .varargs() 252 .imm(&imm.offset32) 253 .build(), 254 255 store_no_offset: Builder::new("StoreNoOffset") 256 .imm(&imm.memflags) 257 .value() 258 .value() 259 .build(), 260 261 stack_load: Builder::new("StackLoad") 262 .imm(&entities.stack_slot) 263 .imm(&imm.offset32) 264 .build(), 265 266 stack_store: Builder::new("StackStore") 267 .value() 268 .imm(&entities.stack_slot) 269 .imm(&imm.offset32) 270 .build(), 271 272 // Accessing a WebAssembly heap. 273 heap_addr: Builder::new("HeapAddr") 274 .imm(&entities.heap) 275 .value() 276 .imm(&imm.uimm32) 277 .build(), 278 279 // Accessing a WebAssembly table. 280 table_addr: Builder::new("TableAddr") 281 .imm(&entities.table) 282 .value() 283 .imm(&imm.offset32) 284 .build(), 285 286 reg_move: Builder::new("RegMove") 287 .value() 288 .imm_with_name("src", &imm.regunit) 289 .imm_with_name("dst", &imm.regunit) 290 .build(), 291 292 copy_special: Builder::new("CopySpecial") 293 .imm_with_name("src", &imm.regunit) 294 .imm_with_name("dst", &imm.regunit) 295 .build(), 296 297 copy_to_ssa: Builder::new("CopyToSsa") 298 .imm_with_name("src", &imm.regunit) 299 .build(), 300 301 reg_spill: Builder::new("RegSpill") 302 .value() 303 .imm_with_name("src", &imm.regunit) 304 .imm_with_name("dst", &entities.stack_slot) 305 .build(), 306 307 reg_fill: Builder::new("RegFill") 308 .value() 309 .imm_with_name("src", &entities.stack_slot) 310 .imm_with_name("dst", &imm.regunit) 311 .build(), 312 313 trap: Builder::new("Trap").imm(&imm.trapcode).build(), 314 315 cond_trap: Builder::new("CondTrap").value().imm(&imm.trapcode).build(), 316 317 int_cond_trap: Builder::new("IntCondTrap") 318 .imm(&imm.intcc) 319 .value() 320 .imm(&imm.trapcode) 321 .build(), 322 323 float_cond_trap: Builder::new("FloatCondTrap") 324 .imm(&imm.floatcc) 325 .value() 326 .imm(&imm.trapcode) 327 .build(), 328 } 329 } 330 } 331