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