| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- # generate variadic calls to test the
- # abi implementation
- from random import seed, randint, uniform
- from struct import unpack
- I, D = 'd', 'g'
- formats = [
- # list of formats to test
- [I],
- [D],
- [I,D],
- [D,D],
- [I,I,I,I],
- [D,D,D,D],
- [I,D,I,D],
- [D,D,I,I],
- [I,I,D,D],
- [],
- ]
- generate = [
- # numbers of fixed integer and
- # floating point arguments to
- # test
- (0, 0), (1, 0), (0, 1), (4, 0),
- (0, 6), (5, 7), (10, 10), (9, 0),
- ]
- def mkargs(nargs, type, name):
- args = map(
- lambda n: ''.join([type, name, str(n), ', ']),
- range(nargs)
- )
- return ''.join(args)
- def mkfstr(fmt):
- fstr = map(
- lambda x: {I: '%d ', D: '%g '}[x],
- fmt
- )
- return '"' + ''.join(fstr) + '\\n"'
- def randargs(fmt):
- ra = {
- I: lambda: '{}'.format(randint(-10, 10)),
- D: lambda: '{0:.4g}'.format(uniform(-10, 10))
- }
- return list(map(lambda x: ra[x](), fmt))
- def genssa(qbeprint, qbecall):
- funcs = [('qbeprint', qbeprint), ('qbecall', qbecall)]
- for fnum, (nia, nfa) in enumerate(generate):
- params = "{}{}l %fmt, ...".format(
- mkargs(nia, 'w ', '%argw'),
- mkargs(nfa, 'd ', '%argd')
- )
- for name, code in funcs:
- print('export function ${}{}({}) {}'
- .format(name, fnum, params, code)
- )
- def gendriver():
- print('# >>> driver')
- print('# #include <stdarg.h>')
- print('# #include <stdio.h>')
- for fnum, (nia, nfa) in enumerate(generate):
- params = "{}{}char *, ...".format(
- mkargs(nia, 'int ', 'argw'),
- mkargs(nfa, 'double ', 'argd')
- )
- for name in ['qbeprint', 'qbecall']:
- print('# extern void {}{}({});'
- .format(name, fnum, params)
- )
- output = ''
- print('# int print(char *fmt, va_list *ap) {')
- print('# return vprintf(fmt, *ap);');
- print('# }')
- print('# int main() {')
- for fnum, (nia, nfa) in enumerate(generate):
- info = '# ({} int, {} double)'.format(nia, nfa)
- print('# puts("{}");'.format(info))
- output += '# {}\n'.format(info)
- for fmt in formats:
- ra = randargs(fmt)
- vaargs = ', '.join(ra)
- expect = ' '.join(ra)
- if fmt:
- vaargs = ', ' + vaargs
- expect = expect + ' '
- args = ''.join(
- ['0, '] * (nia+nfa) +
- [mkfstr(fmt), vaargs]
- )
- for name in ['qbeprint', 'qbecall']:
- print('# {}{}({});'
- .format(name, fnum, args)
- )
- output += '# {}\n'.format(expect)
- print('# }')
- print('# <<<')
- print('\n# >>> output\n' + output + '# <<<')
- qbeprint="""{{
- @start
- %fmtdbl =l alloc4 4
- %fmtint =l alloc4 4
- %emptys =l alloc4 4
- storew {}, %fmtint
- storew {}, %fmtdbl
- storew 0, %emptys
- %vp =l alloc8 32
- %fmt1 =l add 1, %fmt
- vastart %vp
- @loop
- %p =l phi @start %fmt1, @casef %p1, @cased %p1
- %c =w loadsb %p
- %p1 =l add 3, %p
- jnz %c, @loop1, @end
- @loop1
- %isg =w ceqw %c, 103
- jnz %isg, @casef, @cased
- @casef
- %dbl =d vaarg %vp
- %r =w call $printf(l %fmtdbl, ..., d %dbl)
- jmp @loop
- @cased
- %int =w vaarg %vp
- %r =w call $printf(l %fmtint, ..., w %int)
- jmp @loop
- @end
- %r =w call $puts(l %emptys)
- ret
- }}
- """.format(
- unpack("i", b'%d \x00')[0],
- unpack("i", b'%g \x00')[0]
- )
- qbecall="""{
- @start
- %vp =l alloc8 32
- vastart %vp
- %r =w call $print(l %fmt, l %vp)
- ret
- }
- """
- if __name__ == "__main__":
- seed(42)
- genssa(qbeprint, qbecall)
- gendriver()
|