157
|
1 import ppci
|
158
|
2 import ir
|
|
3
|
180
|
4 class X86CodeGenSimple:
|
191
|
5 """
|
|
6 Inefficient code generation, assume stack machine
|
|
7 backend
|
|
8 """
|
157
|
9 def __init__(self, diag):
|
|
10 self.diag = diag
|
|
11
|
158
|
12 def emit(self, i):
|
|
13 self.asm.append(i)
|
|
14
|
171
|
15 def genBin(self, ir):
|
158
|
16 self.asm = []
|
171
|
17 self.genModule(ir)
|
|
18 return self.asm
|
157
|
19
|
171
|
20 def genModule(self, ir):
|
174
|
21 for f in ir.Functions:
|
|
22 self.genFunction(f)
|
158
|
23 def genFunction(self, f):
|
|
24 self.emit('global {0}'.format(f.name))
|
180
|
25 self.emit('{0}:'.format(f.name))
|
|
26 self.emit('jmp {0}'.format(f.entry.name))
|
158
|
27 for bb in f.BasicBlocks:
|
|
28 self.genBB(bb)
|
|
29 def genBB(self, bb):
|
180
|
30 self.emit('{0}:'.format(bb.name))
|
158
|
31 for i in bb.Instructions:
|
|
32 self.genIns(i)
|
|
33 def genIns(self, i):
|
|
34 if type(i) is ir.BinaryOperator:
|
171
|
35 ops = {'+':'add', '-':'sub', '*':'mul'}
|
|
36 if i.operation in ops:
|
180
|
37 i.result.reg = 'rax'
|
|
38 i.value1.reg = 'rbx'
|
|
39 i.value2.reg = 'rbx'
|
|
40 self.emit('mov {0}, {1}'.format(i.result.reg, i.value1.reg))
|
|
41 self.emit('{0} {1}, {2}'.format(ops[i.operation], i.result.reg, i.value2.reg))
|
171
|
42 else:
|
|
43 raise NotImplementedError('op {0}'.format(i.operation))
|
|
44 elif type(i) is ir.Load:
|
180
|
45 self.emit('mov {0}, [{1}]'.format(i.value, i.location))
|
171
|
46 elif type(i) is ir.Return:
|
158
|
47 self.emit('ret')
|
171
|
48 elif type(i) is ir.Call:
|
160
|
49 self.emit('call')
|
171
|
50 elif type(i) is ir.ImmLoad:
|
180
|
51 self.emit('mov {0}, {1}'.format(i.target, i.value))
|
171
|
52 elif type(i) is ir.Store:
|
180
|
53 self.emit('mov [{0}], {1}'.format(i.location, i.value))
|
171
|
54 elif type(i) is ir.ConditionalBranch:
|
180
|
55 self.emit('cmp {0}, {1}'.format(i.a, i.b))
|
171
|
56 jmps = {'>':'jg', '<':'jl', '==':'je'}
|
|
57 if i.cond in jmps:
|
|
58 j = jmps[i.cond]
|
180
|
59 self.emit('{0} {1}'.format(j, i.lab1.name))
|
171
|
60 else:
|
|
61 raise NotImplementedError('condition {0}'.format(i.cond))
|
180
|
62 self.emit('jmp {0}'.format(i.lab2.name))
|
171
|
63 elif type(i) is ir.Branch:
|
180
|
64 self.emit('jmp {0}'.format(i.target.name))
|
174
|
65 elif type(i) is ir.Alloc:
|
|
66 pass
|
158
|
67 else:
|
171
|
68 raise NotImplementedError('{0}'.format(i))
|
158
|
69
|