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