fix various codegen bugs on arm64
[qbe.git] / tools / abi8.py
blob4616ca5ad7d1bae7a83cab008794f7f74c6c856f
1 #!/usr/bin/python3
3 # support script to create
4 # the abi8.ssa test
6 def ctype(arg):
7 if arg[0] == 'p': return ctype(arg[1:])
8 if arg[0] == ':': return 'S' + arg[1:]
9 return {'w':'int', 'l':'long',
10 's':'float', 'd':'double'}[arg]
12 def cparam(iarg):
13 return ctype(iarg[1]) + ' p' + str(iarg[0])
15 def gencfn(id, args):
16 out = '# extern void qfn' + id + '('
17 out += ', '.join(map(ctype, args)) + ');\n'
18 out += '# void cfn' + id + '('
19 out += ', '.join(map(cparam, enumerate(args)))
20 out += ') {\n'
21 out += '# \tprintf("qbe->c(%d)", ' + id + ');\n'
22 out += '# \t'
23 for (i, arg) in enumerate(args):
24 if arg[0] != 'p': continue
25 ty = arg[1:]
26 if ty[0] == ':':
27 out += 'p' + ty[1:] + '(&'
28 else:
29 out += 'p' + ty + '('
30 out += 'p' + str(i) + '); '
31 out += 'puts("");\n'
32 out += '# \tqfn' + id + '('
33 out += ', '.join('p'+str(i) for i in range(len(args)))
34 out += ');\n'
35 out += '# }\n'
36 return out
38 def qparam(iarg):
39 ty = iarg[1][1:] if iarg[1][0] == 'p' else iarg[1]
40 return ty + ' %p' + str(iarg[0])
42 def genqfn(id, args):
43 out = 'export\nfunction $qfn' + id + '('
44 out += ', '.join(map(qparam, enumerate(args)))
45 out += ') {\n'
46 out += '@start\n'
47 out += '\t%r0 =w call $printf(l $ctoqbestr, w ' + id + ')\n'
48 for (i, arg) in enumerate(args):
49 if arg[0] != 'p': continue
50 ty = arg[1:]
51 if ty[0] == ':':
52 out += '\tcall $p' + ty[1:]
53 out += '(l %p' + str(i) + ')\n'
54 else:
55 out += '\tcall $p' + ty
56 out += '(' + ty + ' %p' + str(i) + ')\n'
57 out += '\t%r1 =w call $puts(l $emptystr)\n'
58 out += '\tret\n'
59 out += '}\n'
60 return out
62 def carg(iarg):
63 i, arg = iarg
64 print = arg[0] == 'p'
65 ty = arg if not print else arg[1:]
66 if ty[0] == ':':
67 if print:
68 return ty + ' $' + ty[1:]
69 else:
70 return ty + ' $z' + ty[1:]
71 if not print:
72 return ty + ' 0'
73 if ty == 'w' or ty == 'l':
74 return ty + ' ' + str(i+1)
75 if ty == 's' or ty == 'd':
76 flt = str(i+1) + '.' + str(i+1)
77 return ty + ' ' + ty + '_' + flt
79 def genmaincall(id, args):
80 out = '\tcall $cfn' + id + '('
81 out += ', '.join(map(carg, enumerate(args)))
82 out += ')\n'
83 return out
85 def gen(tvec):
86 for i, t in enumerate(tvec):
87 print(genqfn(str(i), t), end='')
88 print('')
89 for i, t in enumerate(tvec):
90 print(genmaincall(str(i), t), end='')
91 print('')
92 for i, t in enumerate(tvec):
93 print(gencfn(str(i), t), end='')
95 TVEC = [
96 ['s']*8 + ['ps'],
97 ['pw', 'ps', 'p:fi1'],
98 ['pw', 'p:fi2', 'ps'],
99 ['pw', 'ps', 'p:fi3'],
100 ['p:ss'],
101 ['d']*7 + ['p:ss', 'ps', 'pl'],
102 ['p:lb'],
103 ['w']*7 + ['p:lb'],
104 ['w']*8 + ['p:lb'],
105 [ 'p:big' ],
106 ['w']*8 + ['p:big', 'ps', 'pl'],
109 if __name__ == '__main__':
110 gen(TVEC)