Close input file after done reading
[qbe.git] / tools / vatest.py
blobc9b1bbd29f5aaabdc6f8430fa4e3d9cd20b99b7a
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 format to tests
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),
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 <stdio.h>')
68 for fnum, (nia, nfa) in enumerate(generate):
69 params = "{}{}char *, ...".format(
70 mkargs(nia, 'int ', 'argw'),
71 mkargs(nfa, 'double ', 'argd')
73 for name in ['qbeprint', 'qbecall']:
74 print('# extern void {}{}({});'
75 .format(name, fnum, params)
78 output = ''
79 print('# int main() {')
81 for fnum, (nia, nfa) in enumerate(generate):
82 info = '# ({} int, {} double)'.format(nia, nfa)
83 print('# puts("{}");'.format(info))
84 output += '# {}\n'.format(info)
85 for fmt in formats:
86 ra = randargs(fmt)
87 vaargs = ', '.join(ra)
88 expect = ' '.join(ra)
89 if fmt:
90 vaargs = ', ' + vaargs
91 expect = expect + ' '
92 args = ''.join(
93 ['0, '] * (nia+nfa) +
94 [mkfstr(fmt), vaargs]
96 for name in ['qbeprint', 'qbecall']:
97 print('# {}{}({});'
98 .format(name, fnum, args)
100 output += '# {}\n'.format(expect)
102 print('# }')
103 print('# <<<')
105 print('\n# >>> output\n' + output + '# <<<')
108 qbeprint="""{{
109 @start
110 %fmtdbl =l alloc4 4
111 %fmtint =l alloc4 4
112 %emptys =l alloc4 4
113 storew {}, %fmtint
114 storew {}, %fmtdbl
115 storew 0, %emptys
116 %vp =l alloc8 24
117 %fmt1 =l add 1, %fmt
118 vastart %vp
119 @loop
120 %p =l phi @start %fmt1, @casef %p1, @cased %p1
121 %c =w loadsb %p
122 %p1 =l add 3, %p
123 jnz %c, @loop1, @end
124 @loop1
125 %isg =w ceqw %c, 103
126 jnz %isg, @casef, @cased
127 @casef
128 %dbl =d vaarg %vp
129 call $printf(l %fmtdbl, d %dbl, ...)
130 jmp @loop
131 @cased
132 %int =w vaarg %vp
133 call $printf(l %fmtint, w %int, ...)
134 jmp @loop
135 @end
136 call $puts(l %emptys)
139 """.format(
140 unpack("i", b'%d \x00')[0],
141 unpack("i", b'%g \x00')[0]
144 qbecall="""{
145 @start
146 %vp =l alloc8 24
147 vastart %vp
148 call $vprintf(l %fmt, l %vp)
154 if __name__ == "__main__":
155 seed(42)
156 genssa(qbeprint, qbecall)
157 gendriver()