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