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",
14 ignore
= set(["FISTTP",
15 "LDMXCSR", "VLDMXCSR", "STMXCSR", "VSTMXCSR"])
30 'vPCMP[EI]STR*': 0x0f,
41 'vPS[LR][AL][WDQ]': 0x3f,
43 'vROUND[PS][SD]': 0x7,
46 'vAESKEYGENASSIST': 0xff,
47 'VEXTRACT[FI]128': 0x01,
48 'VINSERT[FI]128': 0x01,
50 'VPERM2[FI]128': 0x33,
57 def strip_comments(x
):
59 if l
!= '' and l
[0] != '#':
71 raise Exception("bad reg_w %d" % w
)
89 return t
+ " PTR 32[rdx]"
93 def __init__(self
, reg
, mw
):
94 if mw
not in [0, 8, 16, 32, 64, 128, 256]:
95 raise Exception("Bad /m width: %s" % w
)
101 return mem_w(self
.mw
)
103 return "%smm%d" % (self
.reg
, n
)
107 def __init__(self
, mw
):
108 if mw
not in [0, 32, 64]:
109 raise Exception("Bad mem width: %s" % mw
)
113 return "mm%d" % (n
& 7)
115 def match(op
, pattern
):
116 if pattern
[0] == 'v':
117 return fnmatch(op
, pattern
[1:]) or fnmatch(op
, 'V'+pattern
[1:])
118 return fnmatch(op
, pattern
)
123 def __init__(self
, reg
, w
):
124 if w
not in [32, 64]:
125 raise Exception("Bad vsib width: %s" % w
)
129 reg
= "%smm%d" % (self
.reg
, n
>> 2)
130 return "[rsi + %s * %d]" % (reg
, 1 << (n
& 3))
135 def __init__(self
, op
):
136 for k
, v
in imask
.items():
138 self
.mask
= imask
[k
];
140 raise Exception("Unknown immediate")
147 while (n
& ~mask
) != 0:
153 def __init__(self
, rw
, mw
):
154 if rw
not in [8, 16, 32, 64]:
155 raise Exception("Bad r/w width: %s" % w
)
156 if mw
not in [0, 8, 16, 32, 64]:
157 raise Exception("Bad r/w width: %s" % w
)
163 return mem_w(self
.mw
)
165 return reg_w(self
.rw
)
170 def __init__(self
, w
):
171 if w
not in [8, 16, 32, 64, 128, 256]:
172 raise Exception("Bad mem width: %s" % w
)
177 class SkipInstruction(Exception):
180 def ArgGenerator(arg
, op
):
181 if arg
[:3] == 'xmm' or arg
[:3] == "ymm":
183 r
, m
= arg
.split('/')
185 raise Exception("Expected /m: %s", arg
)
186 return XMMArg(arg
[0], int(m
[1:]));
188 return XMMArg(arg
[0], 0);
189 elif arg
[:2] == 'mm':
191 r
, m
= arg
.split('/')
193 raise Exception("Expected /m: %s", arg
)
194 return MMArg(int(m
[1:]));
197 elif arg
[:4] == 'imm8':
199 elif arg
== '<XMM0>':
203 r
, m
= arg
.split('/')
205 raise Exception("Expected /m: %s", arg
)
213 return ArgRM(int(arg
[1:]), 0);
215 return ArgMem(int(arg
[1:]))
216 elif arg
[:2] == 'vm':
217 return ArgVSIB(arg
[-1], int(arg
[2:-1]))
219 raise Exception("Unrecognised arg: %s", arg
)
222 def __init__(self
, op
, args
):
224 if op
[-2:] in ["PS", "PD", "SS", "SD"]:
233 self
.args
= list(ArgGenerator(a
, op
) for a
in args
)
234 if not any((x
.isxmm
for x
in self
.args
)):
235 raise SkipInstruction
236 if len(self
.args
) > 0 and self
.args
[-1] is None:
237 self
.args
= self
.args
[:-1]
238 except SkipInstruction
:
240 except Exception as e
:
241 raise Exception("Bad arg %s: %s" % (op
, e
))
247 nreg
= len(self
.args
)
251 if isinstance(self
.args
[-1], ArgImm8u
):
253 immarg
= self
.args
[-1]
257 for n
, arg
in enumerate(self
.args
):
261 if (self
.op
.startswith("VGATHER") or self
.op
.startswith("VPGATHER")):
262 if "GATHERD" in self
.op
:
267 (dest
, ireg |
0, regs
[0]),
268 (dest
, ireg |
1, regs
[0]),
269 (dest
, ireg |
2, regs
[0]),
270 (dest
, ireg |
3, regs
[0]),
273 raise Exception("vsib with memory: %s" % self
.op
)
275 regset
= [(regs
[0],)]
284 regset
+= [(-1, regs
[0])]
286 regset
+= [(dest
, -1)]
289 (dest
, regs
[0], regs
[1]),
290 (dest
, regs
[0], regs
[0]),
291 (regs
[0], regs
[0], regs
[1]),
292 (regs
[0], regs
[1], regs
[0]),
293 (regs
[0], regs
[0], regs
[0]),
298 (regs
[0], regs
[0], -1),
301 raise Exception("Memarg %d" % memarg
)
304 (dest
, regs
[0], regs
[1], regs
[2]),
305 (dest
, regs
[0], regs
[0], regs
[1]),
306 (dest
, regs
[0], regs
[1], regs
[0]),
307 (dest
, regs
[1], regs
[0], regs
[0]),
308 (dest
, regs
[0], regs
[0], regs
[0]),
309 (regs
[0], regs
[0], regs
[1], regs
[2]),
310 (regs
[0], regs
[1], regs
[0], regs
[2]),
311 (regs
[0], regs
[1], regs
[2], regs
[0]),
312 (regs
[0], regs
[0], regs
[0], regs
[1]),
313 (regs
[0], regs
[0], regs
[1], regs
[0]),
314 (regs
[0], regs
[1], regs
[0], regs
[0]),
315 (regs
[0], regs
[0], regs
[0], regs
[0]),
319 (dest
, regs
[0], -1, regs
[1]),
320 (dest
, regs
[0], -1, regs
[0]),
321 (regs
[0], regs
[0], -1, regs
[1]),
322 (regs
[0], regs
[1], -1, regs
[0]),
323 (regs
[0], regs
[0], -1, regs
[0]),
326 raise Exception("Memarg4 %d" % memarg
)
328 raise Exception("Too many regs: %s(%d)" % (self
.op
, nreg
))
332 for i
in range(nreg
):
334 argstr
.append(arg
.regstr(regv
[i
]))
336 yield self
.op
+ ' ' + ','.join(argstr
)
338 for immval
in immarg
.vals():
339 yield self
.op
+ ' ' + ','.join(argstr
) + ',' + str(immval
)
348 if len(sys
.argv
) != 3:
349 print("Usage: test-avx.py x86.csv test-avx.h")
351 csvfile
= open(sys
.argv
[1], 'r', newline
='')
352 with
open(sys
.argv
[2], "w") as outf
:
353 outf
.write("// Generated by test-avx.py. Do not edit.\n")
354 for row
in csv
.reader(strip_comments(csvfile
)):
355 insn
= row
[0].replace(',', '').split()
356 if insn
[0] in ignore
:
361 g
= InsnGenerator(insn
[0], insn
[1:])
363 outf
.write('TEST(%d, "%s", %s)\n' % (n
, insn
, g
.optype
))
365 except SkipInstruction
:
367 outf
.write("#undef TEST\n")
370 if __name__
== "__main__":