abi8.py (2935B)
1 #!/usr/bin/python3 2 3 # support script to create 4 # the abi8.ssa test 5 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] 11 12 def cparam(iarg): 13 return ctype(iarg[1]) + ' p' + str(iarg[0]) 14 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 37 38 def qparam(iarg): 39 ty = iarg[1][1:] if iarg[1][0] == 'p' else iarg[1] 40 return ty + ' %p' + str(iarg[0]) 41 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 61 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 78 79 def genmaincall(id, args): 80 out = '\tcall $cfn' + id + '(' 81 out += ', '.join(map(carg, enumerate(args))) 82 out += ')\n' 83 return out 84 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='') 94 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'], 107 ] 108 109 if __name__ == '__main__': 110 gen(TVEC)