use mgen in amd64/isel.c
[qbe.git] / tools / vatest.py
blob1a1f19913221d5a6af9c242ca62eb567b9d2272f
1 # generate variadic calls to test the
2 # abi implementation
4 from random import seed, randint, uniform
5 from struct import unpack
7 I, D = 'd', 'g'
9 formats = [
10 # list of formats to test
11 [I],
12 [D],
13 [I,D],
14 [D,D],
15 [I,I,I,I],
16 [D,D,D,D],
17 [I,D,I,D],
18 [D,D,I,I],
19 [I,I,D,D],
20 [],
23 generate = [
24 # numbers of fixed integer and
25 # floating point arguments to
26 # test
27 (0, 0), (1, 0), (0, 1), (4, 0),
28 (0, 6), (5, 7), (10, 10), (9, 0),
31 def mkargs(nargs, type, name):
32 args = map(
33 lambda n: ''.join([type, name, str(n), ', ']),
34 range(nargs)
36 return ''.join(args)
38 def mkfstr(fmt):
39 fstr = map(
40 lambda x: {I: '%d ', D: '%g '}[x],
41 fmt
43 return '"' + ''.join(fstr) + '\\n"'
45 def randargs(fmt):
46 ra = {
47 I: lambda: '{}'.format(randint(-10, 10)),
48 D: lambda: '{0:.4g}'.format(uniform(-10, 10))
50 return list(map(lambda x: ra[x](), fmt))
52 def genssa(qbeprint, qbecall):
53 funcs = [('qbeprint', qbeprint), ('qbecall', qbecall)]
54 for fnum, (nia, nfa) in enumerate(generate):
55 params = "{}{}l %fmt, ...".format(
56 mkargs(nia, 'w ', '%argw'),
57 mkargs(nfa, 'd ', '%argd')
59 for name, code in funcs:
60 print('export function ${}{}({}) {}'
61 .format(name, fnum, params, code)
64 def gendriver():
65 print('# >>> driver')
66 print('# #include <stdarg.h>')
67 print('# #include <stdio.h>')
69 for fnum, (nia, nfa) in enumerate(generate):
70 params = "{}{}char *, ...".format(
71 mkargs(nia, 'int ', 'argw'),
72 mkargs(nfa, 'double ', 'argd')
74 for name in ['qbeprint', 'qbecall']:
75 print('# extern void {}{}({});'
76 .format(name, fnum, params)
79 output = ''
80 print('# int print(char *fmt, va_list *ap) {')
81 print('# return vprintf(fmt, *ap);');
82 print('# }')
83 print('# int main() {')
85 for fnum, (nia, nfa) in enumerate(generate):
86 info = '# ({} int, {} double)'.format(nia, nfa)
87 print('# puts("{}");'.format(info))
88 output += '# {}\n'.format(info)
89 for fmt in formats:
90 ra = randargs(fmt)
91 vaargs = ', '.join(ra)
92 expect = ' '.join(ra)
93 if fmt:
94 vaargs = ', ' + vaargs
95 expect = expect + ' '
96 args = ''.join(
97 ['0, '] * (nia+nfa) +
98 [mkfstr(fmt), vaargs]
100 for name in ['qbeprint', 'qbecall']:
101 print('# {}{}({});'
102 .format(name, fnum, args)
104 output += '# {}\n'.format(expect)
106 print('# }')
107 print('# <<<')
109 print('\n# >>> output\n' + output + '# <<<')
112 qbeprint="""{{
113 @start
114 %fmtdbl =l alloc4 4
115 %fmtint =l alloc4 4
116 %emptys =l alloc4 4
117 storew {}, %fmtint
118 storew {}, %fmtdbl
119 storew 0, %emptys
120 %vp =l alloc8 32
121 %fmt1 =l add 1, %fmt
122 vastart %vp
123 @loop
124 %p =l phi @start %fmt1, @casef %p1, @cased %p1
125 %c =w loadsb %p
126 %p1 =l add 3, %p
127 jnz %c, @loop1, @end
128 @loop1
129 %isg =w ceqw %c, 103
130 jnz %isg, @casef, @cased
131 @casef
132 %dbl =d vaarg %vp
133 %r =w call $printf(l %fmtdbl, ..., d %dbl)
134 jmp @loop
135 @cased
136 %int =w vaarg %vp
137 %r =w call $printf(l %fmtint, ..., w %int)
138 jmp @loop
139 @end
140 %r =w call $puts(l %emptys)
143 """.format(
144 unpack("i", b'%d \x00')[0],
145 unpack("i", b'%g \x00')[0]
148 qbecall="""{
149 @start
150 %vp =l alloc8 32
151 vastart %vp
152 %r =w call $print(l %fmt, l %vp)
158 if __name__ == "__main__":
159 seed(42)
160 genssa(qbeprint, qbecall)
161 gendriver()