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_table: Rc<InstructionFormat>, 12 pub(crate) brif: Rc<InstructionFormat>, 13 pub(crate) call: Rc<InstructionFormat>, 14 pub(crate) call_indirect: Rc<InstructionFormat>, 15 pub(crate) cond_trap: Rc<InstructionFormat>, 16 pub(crate) float_compare: Rc<InstructionFormat>, 17 pub(crate) func_addr: Rc<InstructionFormat>, 18 pub(crate) int_compare: Rc<InstructionFormat>, 19 pub(crate) int_compare_imm: Rc<InstructionFormat>, 20 pub(crate) int_add_trap: Rc<InstructionFormat>, 21 pub(crate) jump: Rc<InstructionFormat>, 22 pub(crate) load: Rc<InstructionFormat>, 23 pub(crate) load_no_offset: Rc<InstructionFormat>, 24 pub(crate) multiary: Rc<InstructionFormat>, 25 pub(crate) nullary: Rc<InstructionFormat>, 26 pub(crate) shuffle: Rc<InstructionFormat>, 27 pub(crate) stack_load: Rc<InstructionFormat>, 28 pub(crate) stack_store: Rc<InstructionFormat>, 29 pub(crate) dynamic_stack_load: Rc<InstructionFormat>, 30 pub(crate) dynamic_stack_store: Rc<InstructionFormat>, 31 pub(crate) store: Rc<InstructionFormat>, 32 pub(crate) store_no_offset: Rc<InstructionFormat>, 33 pub(crate) ternary: Rc<InstructionFormat>, 34 pub(crate) ternary_imm8: Rc<InstructionFormat>, 35 pub(crate) trap: Rc<InstructionFormat>, 36 pub(crate) unary: Rc<InstructionFormat>, 37 pub(crate) unary_const: Rc<InstructionFormat>, 38 pub(crate) unary_global_value: Rc<InstructionFormat>, 39 pub(crate) unary_ieee32: Rc<InstructionFormat>, 40 pub(crate) unary_ieee64: Rc<InstructionFormat>, 41 pub(crate) unary_imm: Rc<InstructionFormat>, 42 } 43 44 impl Formats { 45 pub fn new(imm: &Immediates, entities: &EntityRefs) -> Self { 46 Self { 47 unary: Builder::new("Unary").value().build(), 48 49 unary_imm: Builder::new("UnaryImm").imm(&imm.imm64).build(), 50 51 unary_ieee32: Builder::new("UnaryIeee32").imm(&imm.ieee32).build(), 52 53 unary_ieee64: Builder::new("UnaryIeee64").imm(&imm.ieee64).build(), 54 55 unary_const: Builder::new("UnaryConst").imm(&imm.pool_constant).build(), 56 57 unary_global_value: Builder::new("UnaryGlobalValue") 58 .imm(&entities.global_value) 59 .build(), 60 61 binary: Builder::new("Binary").value().value().build(), 62 63 binary_imm8: Builder::new("BinaryImm8").value().imm(&imm.uimm8).build(), 64 65 binary_imm64: Builder::new("BinaryImm64").value().imm(&imm.imm64).build(), 66 67 // The select instructions are controlled by the second VALUE operand. 68 // The first VALUE operand is the controlling flag which has a derived type. 69 // The fma instruction has the same constraint on all inputs. 70 ternary: Builder::new("Ternary") 71 .value() 72 .value() 73 .value() 74 .typevar_operand(1) 75 .build(), 76 77 ternary_imm8: Builder::new("TernaryImm8") 78 .value() 79 .imm(&imm.uimm8) 80 .value() 81 .build(), 82 83 // Catch-all for instructions with many outputs and inputs and no immediate 84 // operands. 85 multiary: Builder::new("MultiAry").varargs().build(), 86 87 nullary: Builder::new("NullAry").build(), 88 89 shuffle: Builder::new("Shuffle") 90 .value() 91 .value() 92 .imm(&imm.uimm128) 93 .build(), 94 95 int_compare: Builder::new("IntCompare") 96 .imm(&imm.intcc) 97 .value() 98 .value() 99 .build(), 100 101 int_compare_imm: Builder::new("IntCompareImm") 102 .imm(&imm.intcc) 103 .value() 104 .imm(&imm.imm64) 105 .build(), 106 107 float_compare: Builder::new("FloatCompare") 108 .imm(&imm.floatcc) 109 .value() 110 .value() 111 .build(), 112 113 jump: Builder::new("Jump").block().build(), 114 115 brif: Builder::new("Brif").value().block().block().build(), 116 117 branch_table: Builder::new("BranchTable") 118 .value() 119 .imm(&entities.jump_table) 120 .build(), 121 122 call: Builder::new("Call") 123 .imm(&entities.func_ref) 124 .varargs() 125 .build(), 126 127 call_indirect: Builder::new("CallIndirect") 128 .imm(&entities.sig_ref) 129 .value() 130 .varargs() 131 .build(), 132 133 func_addr: Builder::new("FuncAddr").imm(&entities.func_ref).build(), 134 135 atomic_rmw: Builder::new("AtomicRmw") 136 .imm(&imm.memflags) 137 .imm(&imm.atomic_rmw_op) 138 .value() 139 .value() 140 .build(), 141 142 atomic_cas: Builder::new("AtomicCas") 143 .imm(&imm.memflags) 144 .value() 145 .value() 146 .value() 147 .typevar_operand(2) 148 .build(), 149 150 load: Builder::new("Load") 151 .imm(&imm.memflags) 152 .value() 153 .imm(&imm.offset32) 154 .build(), 155 156 load_no_offset: Builder::new("LoadNoOffset") 157 .imm(&imm.memflags) 158 .value() 159 .build(), 160 161 store: Builder::new("Store") 162 .imm(&imm.memflags) 163 .value() 164 .value() 165 .imm(&imm.offset32) 166 .build(), 167 168 store_no_offset: Builder::new("StoreNoOffset") 169 .imm(&imm.memflags) 170 .value() 171 .value() 172 .build(), 173 174 stack_load: Builder::new("StackLoad") 175 .imm(&entities.stack_slot) 176 .imm(&imm.offset32) 177 .build(), 178 179 stack_store: Builder::new("StackStore") 180 .value() 181 .imm(&entities.stack_slot) 182 .imm(&imm.offset32) 183 .build(), 184 185 dynamic_stack_load: Builder::new("DynamicStackLoad") 186 .imm(&entities.dynamic_stack_slot) 187 .build(), 188 189 dynamic_stack_store: Builder::new("DynamicStackStore") 190 .value() 191 .imm(&entities.dynamic_stack_slot) 192 .build(), 193 194 trap: Builder::new("Trap").imm(&imm.trapcode).build(), 195 196 cond_trap: Builder::new("CondTrap").value().imm(&imm.trapcode).build(), 197 198 int_add_trap: Builder::new("IntAddTrap") 199 .value() 200 .value() 201 .imm(&imm.trapcode) 202 .build(), 203 } 204 } 205 } 206