cranelift_assembler_x64_meta/
instructions.rs1mod abs;
4mod add;
5mod align;
6mod and;
7mod atomic;
8mod avg;
9mod bitmanip;
10mod cmov;
11mod cmp;
12mod cvt;
13mod div;
14mod fma;
15mod jmp;
16mod lanes;
17mod max;
18mod min;
19mod misc;
20mod mov;
21mod mul;
22mod neg;
23mod nop;
24mod or;
25mod pack;
26mod pma;
27mod recip;
28mod round;
29mod setcc;
30mod shift;
31mod sqrt;
32mod stack;
33mod sub;
34mod unpack;
35mod xor;
36
37use crate::dsl::{Feature, Inst, Mutability, OperandKind};
38use std::collections::HashMap;
39
40#[must_use]
41pub fn list() -> Vec<Inst> {
42 let mut all = vec![];
43 all.extend(abs::list());
44 all.extend(add::list());
45 all.extend(align::list());
46 all.extend(and::list());
47 all.extend(atomic::list());
48 all.extend(avg::list());
49 all.extend(bitmanip::list());
50 all.extend(cmov::list());
51 all.extend(cmp::list());
52 all.extend(cvt::list());
53 all.extend(div::list());
54 all.extend(fma::list());
55 all.extend(jmp::list());
56 all.extend(lanes::list());
57 all.extend(max::list());
58 all.extend(min::list());
59 all.extend(misc::list());
60 all.extend(mov::list());
61 all.extend(mul::list());
62 all.extend(neg::list());
63 all.extend(nop::list());
64 all.extend(or::list());
65 all.extend(pack::list());
66 all.extend(pma::list());
67 all.extend(recip::list());
68 all.extend(round::list());
69 all.extend(setcc::list());
70 all.extend(shift::list());
71 all.extend(sqrt::list());
72 all.extend(stack::list());
73 all.extend(sub::list());
74 all.extend(unpack::list());
75 all.extend(xor::list());
76
77 check_avx_alternates(&mut all);
78
79 all
80}
81
82fn check_avx_alternates(all: &mut [Inst]) {
89 let name_to_index: HashMap<String, usize> = all
90 .iter()
91 .enumerate()
92 .map(|(index, inst)| (inst.name().clone(), index))
93 .collect();
94 for inst in all.iter().filter(|inst| inst.alternate.is_some()) {
95 assert!(
96 inst.features.is_sse(),
97 "expected an SSE instruction: {inst}"
98 );
99 let alternate = inst.alternate.as_ref().unwrap();
100 assert_eq!(alternate.feature, Feature::avx);
101 let avx_index = name_to_index.get(&alternate.name).expect(&format!(
102 "invalid alternate name: {} (did you use the full `<mnemonic>_<format>` form?)",
103 alternate.name
104 ));
105 check_sse_matches_avx(inst, &all[*avx_index]);
106 }
107}
108
109fn check_sse_matches_avx(sse_inst: &Inst, avx_inst: &Inst) {
120 use crate::dsl::{Mutability::*, OperandKind::*};
121
122 debug_assert_eq!(
123 &format!("v{}", sse_inst.mnemonic),
124 &avx_inst.mnemonic,
125 "an alternate AVX instruction should have a 'v' prefix: {avx_inst}"
126 );
127
128 if sse_inst.encoding.opcode() != avx_inst.encoding.opcode() {
129 panic!("alternate instructions should have the same opcode:\n{sse_inst}\n{avx_inst}");
130 }
131
132 match (list_ops(sse_inst).as_slice(), list_ops(avx_inst).as_slice()) {
133 (
140 [
141 (ReadWrite | Write, Reg(_)),
142 (Read, Reg(_) | RegMem(_) | Mem(_)),
143 ],
144 [
145 (Write, Reg(_)),
146 (Read, Reg(_)),
147 (Read, Reg(_) | RegMem(_) | Mem(_)),
148 ],
149 ) => {}
150 (
151 [(ReadWrite, Reg(_)), (Read, RegMem(_)), (Read, Imm(_))],
152 [
153 (Write, Reg(_)),
154 (Read, Reg(_)),
155 (Read, RegMem(_)),
156 (Read, Imm(_)),
157 ],
158 ) => {}
159 (
160 [(ReadWrite, Reg(_)), (Read, Imm(_))],
161 [(Write, Reg(_)), (Read, Reg(_)), (Read, Imm(_))],
162 ) => {}
163 (
165 [
166 (Write, Reg(_) | RegMem(_) | Mem(_)),
167 (Read, Reg(_) | RegMem(_) | Mem(_)),
168 ],
169 [
170 (Write, Reg(_) | RegMem(_) | Mem(_)),
171 (Read, Reg(_) | RegMem(_) | Mem(_)),
172 ],
173 ) => {}
174 (
175 [
176 (Write, Reg(_) | RegMem(_)),
177 (Read, Reg(_) | RegMem(_)),
178 (Read, Imm(_)),
179 ],
180 [
181 (Write, Reg(_) | RegMem(_)),
182 (Read, Reg(_) | RegMem(_)),
183 (Read, Imm(_)),
184 ],
185 ) => {}
186 ([(Read, Reg(_)), (Read, RegMem(_))], [(Read, Reg(_)), (Read, RegMem(_))]) => {}
187 _ => panic!(
190 "unmatched formats for SSE-to-AVX alternate:\n{sse_inst}\n{avx_inst}. {:?}, {:?}",
191 list_ops(sse_inst),
192 list_ops(avx_inst)
193 ),
194 }
195}
196
197fn list_ops(inst: &Inst) -> Vec<(Mutability, OperandKind)> {
199 inst.format
200 .operands
201 .iter()
202 .map(|o| (o.mutability, o.location.kind()))
203 .collect()
204}