157
|
1 import ppci
|
158
|
2 import ir
|
|
3
|
|
4 class AsmLabel:
|
|
5 def __init__(self, lab):
|
|
6 self.lab = lab
|
|
7 def __repr__(self):
|
|
8 return '{0}:'.format(self.lab)
|
|
9
|
|
10 class Op:
|
171
|
11 def __init__(self, op, dst, src):
|
158
|
12 self.op = op
|
171
|
13 self.src = src
|
|
14 self.dst = dst
|
158
|
15 def __repr__(self):
|
171
|
16 return '{0} {1}, {2}'.format(self.op, self.dst, self.src)
|
|
17
|
|
18 class Jmp:
|
|
19 def __init__(self, j, target):
|
|
20 self.j = j
|
|
21 self.target = target
|
|
22 def __repr__(self):
|
|
23 return '{0} {1}'.format(self.j, self.target)
|
157
|
24
|
|
25 class X86CodeGen:
|
|
26 def __init__(self, diag):
|
|
27 self.diag = diag
|
160
|
28 self.regs = ['rax', 'rbx', 'rcx', 'rdx']
|
157
|
29
|
158
|
30 def emit(self, i):
|
|
31 self.asm.append(i)
|
|
32
|
171
|
33 def genBin(self, ir):
|
158
|
34 self.asm = []
|
171
|
35 # Allocate registers:
|
|
36 ir.registerAllocate(self.regs)
|
|
37 self.genModule(ir)
|
|
38 return self.asm
|
157
|
39
|
171
|
40 def genModule(self, ir):
|
|
41 #for f in ir.Functions:
|
|
42 # self.genFunction(f)
|
|
43 for bb in ir.BasicBlocks:
|
|
44 self.genBB(bb)
|
158
|
45 def genFunction(self, f):
|
|
46 self.emit('global {0}'.format(f.name))
|
|
47 self.emit(AsmLabel(f.name))
|
|
48 for bb in f.BasicBlocks:
|
|
49 self.genBB(bb)
|
|
50 def genBB(self, bb):
|
171
|
51 self.emit(AsmLabel(bb.name))
|
158
|
52 for i in bb.Instructions:
|
|
53 self.genIns(i)
|
|
54 def genIns(self, i):
|
|
55 if type(i) is ir.BinaryOperator:
|
171
|
56 ops = {'+':'add', '-':'sub', '*':'mul'}
|
|
57 if i.operation in ops:
|
|
58 self.emit(Op('mov', i.result.reg, i.value1.reg))
|
|
59 self.emit(Op(ops[i.operation], i.result.reg, i.value2.reg))
|
|
60 else:
|
|
61 raise NotImplementedError('op {0}'.format(i.operation))
|
|
62 elif type(i) is ir.Load:
|
|
63 self.emit(Op('mov', i.value, '[{0}]'.format(i.name)))
|
|
64 elif type(i) is ir.Return:
|
158
|
65 self.emit('ret')
|
171
|
66 elif type(i) is ir.Call:
|
160
|
67 self.emit('call')
|
171
|
68 elif type(i) is ir.ImmLoad:
|
|
69 self.emit(Op('mov', i.target, i.value))
|
|
70 elif type(i) is ir.Store:
|
|
71 self.emit(Op('mov', '[{0}]'.format(i.name), i.value))
|
|
72 elif type(i) is ir.ConditionalBranch:
|
|
73 self.emit(Op('cmp', i.a, i.b))
|
|
74 jmps = {'>':'jg', '<':'jl', '==':'je'}
|
|
75 if i.cond in jmps:
|
|
76 j = jmps[i.cond]
|
|
77 self.emit(Jmp(j, i.lab1.name))
|
|
78 else:
|
|
79 raise NotImplementedError('condition {0}'.format(i.cond))
|
|
80 self.emit(Jmp('jmp', i.lab2.name))
|
|
81 elif type(i) is ir.Branch:
|
|
82 self.emit(Jmp('jmp', i.target.name))
|
158
|
83 else:
|
171
|
84 raise NotImplementedError('{0}'.format(i))
|
158
|
85
|