tests/tcg: i386: add SSE tests
[qemu/ar7.git] / tests / tcg / i386 / test-avx.py
blob6eb455a8b4d857517dd16288aa60dff14367f452
1 #! /usr/bin/env python3
3 # Generate test-avx.h from x86.csv
5 import csv
6 import sys
7 from fnmatch import fnmatch
9 archs = [
10 # TODO: MMX?
11 "SSE", "SSE2", "SSE3", "SSSE3", "SSE4_1", "SSE4_2",
14 ignore = set(["FISTTP",
15 "LDMXCSR", "VLDMXCSR", "STMXCSR", "VSTMXCSR"])
17 imask = {
18 'vBLENDPD': 0xff,
19 'vBLENDPS': 0x0f,
20 'CMP[PS][SD]': 0x07,
21 'VCMP[PS][SD]': 0x1f,
22 'vDPPD': 0x33,
23 'vDPPS': 0xff,
24 'vEXTRACTPS': 0x03,
25 'vINSERTPS': 0xff,
26 'MPSADBW': 0x7,
27 'VMPSADBW': 0x3f,
28 'vPALIGNR': 0x3f,
29 'vPBLENDW': 0xff,
30 'vPCMP[EI]STR*': 0x0f,
31 'vPEXTRB': 0x0f,
32 'vPEXTRW': 0x07,
33 'vPEXTRD': 0x03,
34 'vPEXTRQ': 0x01,
35 'vPINSRB': 0x0f,
36 'vPINSRW': 0x07,
37 'vPINSRD': 0x03,
38 'vPINSRQ': 0x01,
39 'vPSHUF[DW]': 0xff,
40 'vPSHUF[LH]W': 0xff,
41 'vPS[LR][AL][WDQ]': 0x3f,
42 'vPS[RL]LDQ': 0x1f,
43 'vROUND[PS][SD]': 0x7,
44 'vSHUFPD': 0x0f,
45 'vSHUFPS': 0xff,
46 'vAESKEYGENASSIST': 0,
47 'VEXTRACT[FI]128': 0x01,
48 'VINSERT[FI]128': 0x01,
49 'VPBLENDD': 0xff,
50 'VPERM2[FI]128': 0x33,
51 'VPERMPD': 0xff,
52 'VPERMQ': 0xff,
53 'VPERMILPS': 0xff,
54 'VPERMILPD': 0x0f,
57 def strip_comments(x):
58 for l in x:
59 if l != '' and l[0] != '#':
60 yield l
62 def reg_w(w):
63 if w == 8:
64 return 'al'
65 elif w == 16:
66 return 'ax'
67 elif w == 32:
68 return 'eax'
69 elif w == 64:
70 return 'rax'
71 raise Exception("bad reg_w %d" % w)
73 def mem_w(w):
74 if w == 8:
75 t = "BYTE"
76 elif w == 16:
77 t = "WORD"
78 elif w == 32:
79 t = "DWORD"
80 elif w == 64:
81 t = "QWORD"
82 elif w == 128:
83 t = "XMMWORD"
84 elif w == 256:
85 t = "YMMWORD"
86 else:
87 raise Exception()
89 return t + " PTR 16[rdx]"
91 class XMMArg():
92 isxmm = True
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)
96 self.reg = reg
97 self.mw = mw
98 self.ismem = mw != 0
99 def regstr(self, n):
100 if n < 0:
101 return mem_w(self.mw)
102 else:
103 return "%smm%d" % (self.reg, n)
105 class MMArg():
106 isxmm = True
107 ismem = False # TODO
108 def regstr(self, n):
109 return "mm%d" % (n & 7)
111 def match(op, pattern):
112 if pattern[0] == 'v':
113 return fnmatch(op, pattern[1:]) or fnmatch(op, 'V'+pattern[1:])
114 return fnmatch(op, pattern)
116 class ArgVSIB():
117 isxmm = True
118 ismem = False
119 def __init__(self, reg, w):
120 if w not in [32, 64]:
121 raise Exception("Bad vsib width: %s" % w)
122 self.w = w
123 self.reg = reg
124 def regstr(self, n):
125 reg = "%smm%d" % (self.reg, n >> 2)
126 return "[rsi + %s * %d]" % (reg, 1 << (n & 3))
128 class ArgImm8u():
129 isxmm = False
130 ismem = False
131 def __init__(self, op):
132 for k, v in imask.items():
133 if match(op, k):
134 self.mask = imask[k];
135 return
136 raise Exception("Unknown immediate")
137 def vals(self):
138 mask = self.mask
139 yield 0
140 n = 0
141 while n != mask:
142 n += 1
143 while (n & ~mask) != 0:
144 n += (n & ~mask)
145 yield n
147 class ArgRM():
148 isxmm = False
149 def __init__(self, rw, mw):
150 if rw not in [8, 16, 32, 64]:
151 raise Exception("Bad r/w width: %s" % w)
152 if mw not in [0, 8, 16, 32, 64]:
153 raise Exception("Bad r/w width: %s" % w)
154 self.rw = rw
155 self.mw = mw
156 self.ismem = mw != 0
157 def regstr(self, n):
158 if n < 0:
159 return mem_w(self.mw)
160 else:
161 return reg_w(self.rw)
163 class ArgMem():
164 isxmm = False
165 ismem = True
166 def __init__(self, w):
167 if w not in [8, 16, 32, 64, 128, 256]:
168 raise Exception("Bad mem width: %s" % w)
169 self.w = w
170 def regstr(self, n):
171 return mem_w(self.w)
173 def ArgGenerator(arg, op):
174 if arg[:3] == 'xmm' or arg[:3] == "ymm":
175 if "/" in arg:
176 r, m = arg.split('/')
177 if (m[0] != 'm'):
178 raise Exception("Expected /m: %s", arg)
179 return XMMArg(arg[0], int(m[1:]));
180 else:
181 return XMMArg(arg[0], 0);
182 elif arg[:2] == 'mm':
183 return MMArg();
184 elif arg[:4] == 'imm8':
185 return ArgImm8u(op);
186 elif arg == '<XMM0>':
187 return None
188 elif arg[0] == 'r':
189 if '/m' in arg:
190 r, m = arg.split('/')
191 if (m[0] != 'm'):
192 raise Exception("Expected /m: %s", arg)
193 mw = int(m[1:])
194 if r == 'r':
195 rw = mw
196 else:
197 rw = int(r[1:])
198 return ArgRM(rw, mw)
200 return ArgRM(int(arg[1:]), 0);
201 elif arg[0] == 'm':
202 return ArgMem(int(arg[1:]))
203 elif arg[:2] == 'vm':
204 return ArgVSIB(arg[-1], int(arg[2:-1]))
205 else:
206 raise Exception("Unrecognised arg: %s", arg)
208 class InsnGenerator:
209 def __init__(self, op, args):
210 self.op = op
211 if op[-2:] in ["PS", "PD", "SS", "SD"]:
212 if op[-1] == 'S':
213 self.optype = 'F32'
214 else:
215 self.optype = 'F64'
216 else:
217 self.optype = 'I'
219 try:
220 self.args = list(ArgGenerator(a, op) for a in args)
221 if len(self.args) > 0 and self.args[-1] is None:
222 self.args = self.args[:-1]
223 except Exception as e:
224 raise Exception("Bad arg %s: %s" % (op, e))
226 def gen(self):
227 regs = (10, 11, 12)
228 dest = 9
230 nreg = len(self.args)
231 if nreg == 0:
232 yield self.op
233 return
234 if isinstance(self.args[-1], ArgImm8u):
235 nreg -= 1
236 immarg = self.args[-1]
237 else:
238 immarg = None
239 memarg = -1
240 for n, arg in enumerate(self.args):
241 if arg.ismem:
242 memarg = n
244 if (self.op.startswith("VGATHER") or self.op.startswith("VPGATHER")):
245 if "GATHERD" in self.op:
246 ireg = 13 << 2
247 else:
248 ireg = 14 << 2
249 regset = [
250 (dest, ireg | 0, regs[0]),
251 (dest, ireg | 1, regs[0]),
252 (dest, ireg | 2, regs[0]),
253 (dest, ireg | 3, regs[0]),
255 if memarg >= 0:
256 raise Exception("vsib with memory: %s" % self.op)
257 elif nreg == 1:
258 regset = [(regs[0],)]
259 if memarg == 0:
260 regset += [(-1,)]
261 elif nreg == 2:
262 regset = [
263 (regs[0], regs[1]),
264 (regs[0], regs[0]),
266 if memarg == 0:
267 regset += [(-1, regs[0])]
268 elif memarg == 1:
269 regset += [(dest, -1)]
270 elif nreg == 3:
271 regset = [
272 (dest, regs[0], regs[1]),
273 (dest, regs[0], regs[0]),
274 (regs[0], regs[0], regs[1]),
275 (regs[0], regs[1], regs[0]),
276 (regs[0], regs[0], regs[0]),
278 if memarg == 2:
279 regset += [
280 (dest, regs[0], -1),
281 (regs[0], regs[0], -1),
283 elif memarg > 0:
284 raise Exception("Memarg %d" % memarg)
285 elif nreg == 4:
286 regset = [
287 (dest, regs[0], regs[1], regs[2]),
288 (dest, regs[0], regs[0], regs[1]),
289 (dest, regs[0], regs[1], regs[0]),
290 (dest, regs[1], regs[0], regs[0]),
291 (dest, regs[0], regs[0], regs[0]),
292 (regs[0], regs[0], regs[1], regs[2]),
293 (regs[0], regs[1], regs[0], regs[2]),
294 (regs[0], regs[1], regs[2], regs[0]),
295 (regs[0], regs[0], regs[0], regs[1]),
296 (regs[0], regs[0], regs[1], regs[0]),
297 (regs[0], regs[1], regs[0], regs[0]),
298 (regs[0], regs[0], regs[0], regs[0]),
300 if memarg == 2:
301 regset += [
302 (dest, regs[0], -1, regs[1]),
303 (dest, regs[0], -1, regs[0]),
304 (regs[0], regs[0], -1, regs[1]),
305 (regs[0], regs[1], -1, regs[0]),
306 (regs[0], regs[0], -1, regs[0]),
308 elif memarg > 0:
309 raise Exception("Memarg4 %d" % memarg)
310 else:
311 raise Exception("Too many regs: %s(%d)" % (self.op, nreg))
313 for regv in regset:
314 argstr = []
315 for i in range(nreg):
316 arg = self.args[i]
317 argstr.append(arg.regstr(regv[i]))
318 if immarg is None:
319 yield self.op + ' ' + ','.join(argstr)
320 else:
321 for immval in immarg.vals():
322 yield self.op + ' ' + ','.join(argstr) + ',' + str(immval)
324 def split0(s):
325 if s == '':
326 return []
327 return s.split(',')
329 def main():
330 n = 0
331 if len(sys.argv) != 3:
332 print("Usage: test-avx.py x86.csv test-avx.h")
333 exit(1)
334 csvfile = open(sys.argv[1], 'r', newline='')
335 with open(sys.argv[2], "w") as outf:
336 outf.write("// Generated by test-avx.py. Do not edit.\n")
337 for row in csv.reader(strip_comments(csvfile)):
338 insn = row[0].replace(',', '').split()
339 if insn[0] in ignore:
340 continue
341 cpuid = row[6]
342 if cpuid in archs:
343 g = InsnGenerator(insn[0], insn[1:])
344 for insn in g.gen():
345 outf.write('TEST(%d, "%s", %s)\n' % (n, insn, g.optype))
346 n += 1
347 outf.write("#undef TEST\n")
348 csvfile.close()
350 if __name__ == "__main__":
351 main()