1 #! /usr/bin/env python3
3 # Generate test-avx.h from x86.csv
7 from fnmatch
import fnmatch
10 "SSE", "SSE2", "SSE3", "SSSE3", "SSE4_1", "SSE4_2",
11 "AES", "AVX", "AVX2", "AES+AVX", "VAES+AVX",
15 ignore
= set(["FISTTP",
16 "LDMXCSR", "VLDMXCSR", "STMXCSR", "VSTMXCSR"])
32 'vPCMP[EI]STR*': 0x0f,
43 'vPS[LR][AL][WDQ]': 0x3f,
45 'vROUND[PS][SD]': 0x7,
48 'vAESKEYGENASSIST': 0xff,
49 'VEXTRACT[FI]128': 0x01,
50 'VINSERT[FI]128': 0x01,
52 'VPERM2[FI]128': 0x33,
59 def strip_comments(x
):
61 if l
!= '' and l
[0] != '#':
73 raise Exception("bad reg_w %d" % w
)
91 return t
+ " PTR 32[rdx]"
95 def __init__(self
, reg
, mw
):
96 if mw
not in [0, 8, 16, 32, 64, 128, 256]:
97 raise Exception("Bad /m width: %s" % w
)
103 return mem_w(self
.mw
)
105 return "%smm%d" % (self
.reg
, n
)
109 def __init__(self
, mw
):
110 if mw
not in [0, 32, 64]:
111 raise Exception("Bad mem width: %s" % mw
)
115 return "mm%d" % (n
& 7)
117 def match(op
, pattern
):
118 if pattern
[0] == 'v':
119 return fnmatch(op
, pattern
[1:]) or fnmatch(op
, 'V'+pattern
[1:])
120 return fnmatch(op
, pattern
)
125 def __init__(self
, reg
, w
):
126 if w
not in [32, 64]:
127 raise Exception("Bad vsib width: %s" % w
)
131 reg
= "%smm%d" % (self
.reg
, n
>> 2)
132 return "[rsi + %s * %d]" % (reg
, 1 << (n
& 3))
137 def __init__(self
, op
):
138 for k
, v
in imask
.items():
140 self
.mask
= imask
[k
];
142 raise Exception("Unknown immediate")
149 while (n
& ~mask
) != 0:
155 def __init__(self
, rw
, mw
):
156 if rw
not in [8, 16, 32, 64]:
157 raise Exception("Bad r/w width: %s" % w
)
158 if mw
not in [0, 8, 16, 32, 64]:
159 raise Exception("Bad r/w width: %s" % w
)
165 return mem_w(self
.mw
)
167 return reg_w(self
.rw
)
172 def __init__(self
, w
):
173 if w
not in [8, 16, 32, 64, 128, 256]:
174 raise Exception("Bad mem width: %s" % w
)
179 class SkipInstruction(Exception):
182 def ArgGenerator(arg
, op
):
183 if arg
[:3] == 'xmm' or arg
[:3] == "ymm":
185 r
, m
= arg
.split('/')
187 raise Exception("Expected /m: %s", arg
)
188 return XMMArg(arg
[0], int(m
[1:]));
190 return XMMArg(arg
[0], 0);
191 elif arg
[:2] == 'mm':
193 r
, m
= arg
.split('/')
195 raise Exception("Expected /m: %s", arg
)
196 return MMArg(int(m
[1:]));
199 elif arg
[:4] == 'imm8':
201 elif arg
== '<XMM0>':
205 r
, m
= arg
.split('/')
207 raise Exception("Expected /m: %s", arg
)
215 return ArgRM(int(arg
[1:]), 0);
217 return ArgMem(int(arg
[1:]))
218 elif arg
[:2] == 'vm':
219 return ArgVSIB(arg
[-1], int(arg
[2:-1]))
221 raise Exception("Unrecognised arg: %s", arg
)
224 def __init__(self
, op
, args
):
226 if op
[-2:] in ["PH", "PS", "PD", "SS", "SD"]:
237 self
.args
= list(ArgGenerator(a
, op
) for a
in args
)
238 if not any((x
.isxmm
for x
in self
.args
)):
239 raise SkipInstruction
240 if len(self
.args
) > 0 and self
.args
[-1] is None:
241 self
.args
= self
.args
[:-1]
242 except SkipInstruction
:
244 except Exception as e
:
245 raise Exception("Bad arg %s: %s" % (op
, e
))
251 nreg
= len(self
.args
)
255 if isinstance(self
.args
[-1], ArgImm8u
):
257 immarg
= self
.args
[-1]
261 for n
, arg
in enumerate(self
.args
):
265 if (self
.op
.startswith("VGATHER") or self
.op
.startswith("VPGATHER")):
266 if "GATHERD" in self
.op
:
271 (dest
, ireg |
0, regs
[0]),
272 (dest
, ireg |
1, regs
[0]),
273 (dest
, ireg |
2, regs
[0]),
274 (dest
, ireg |
3, regs
[0]),
277 raise Exception("vsib with memory: %s" % self
.op
)
279 regset
= [(regs
[0],)]
288 regset
+= [(-1, regs
[0])]
290 regset
+= [(dest
, -1)]
293 (dest
, regs
[0], regs
[1]),
294 (dest
, regs
[0], regs
[0]),
295 (regs
[0], regs
[0], regs
[1]),
296 (regs
[0], regs
[1], regs
[0]),
297 (regs
[0], regs
[0], regs
[0]),
302 (regs
[0], regs
[0], -1),
305 raise Exception("Memarg %d" % memarg
)
308 (dest
, regs
[0], regs
[1], regs
[2]),
309 (dest
, regs
[0], regs
[0], regs
[1]),
310 (dest
, regs
[0], regs
[1], regs
[0]),
311 (dest
, regs
[1], regs
[0], regs
[0]),
312 (dest
, regs
[0], regs
[0], regs
[0]),
313 (regs
[0], regs
[0], regs
[1], regs
[2]),
314 (regs
[0], regs
[1], regs
[0], regs
[2]),
315 (regs
[0], regs
[1], regs
[2], regs
[0]),
316 (regs
[0], regs
[0], regs
[0], regs
[1]),
317 (regs
[0], regs
[0], regs
[1], regs
[0]),
318 (regs
[0], regs
[1], regs
[0], regs
[0]),
319 (regs
[0], regs
[0], regs
[0], regs
[0]),
323 (dest
, regs
[0], -1, regs
[1]),
324 (dest
, regs
[0], -1, regs
[0]),
325 (regs
[0], regs
[0], -1, regs
[1]),
326 (regs
[0], regs
[1], -1, regs
[0]),
327 (regs
[0], regs
[0], -1, regs
[0]),
330 raise Exception("Memarg4 %d" % memarg
)
332 raise Exception("Too many regs: %s(%d)" % (self
.op
, nreg
))
336 for i
in range(nreg
):
338 argstr
.append(arg
.regstr(regv
[i
]))
340 yield self
.op
+ ' ' + ','.join(argstr
)
342 for immval
in immarg
.vals():
343 yield self
.op
+ ' ' + ','.join(argstr
) + ',' + str(immval
)
352 if len(sys
.argv
) != 3:
353 print("Usage: test-avx.py x86.csv test-avx.h")
355 csvfile
= open(sys
.argv
[1], 'r', newline
='')
356 with
open(sys
.argv
[2], "w") as outf
:
357 outf
.write("// Generated by test-avx.py. Do not edit.\n")
358 for row
in csv
.reader(strip_comments(csvfile
)):
359 insn
= row
[0].replace(',', '').split()
360 if insn
[0] in ignore
:
365 g
= InsnGenerator(insn
[0], insn
[1:])
367 outf
.write('TEST(%d, "%s", %s)\n' % (n
, insn
, g
.optype
))
369 except SkipInstruction
:
371 outf
.write("#undef TEST\n")
374 if __name__
== "__main__":