comparison python/x86.py @ 171:3eb9b9e2958d

Improved IR code
author Windel Bouwman
date Wed, 03 Apr 2013 22:20:20 +0200
parents 10330be89bc2
children c1d2b6b9f9a7
comparison
equal deleted inserted replaced
170:4348da5ca307 171:3eb9b9e2958d
6 self.lab = lab 6 self.lab = lab
7 def __repr__(self): 7 def __repr__(self):
8 return '{0}:'.format(self.lab) 8 return '{0}:'.format(self.lab)
9 9
10 class Op: 10 class Op:
11 def __init__(self, op, a, b): 11 def __init__(self, op, dst, src):
12 self.op = op 12 self.op = op
13 self.a = a 13 self.src = src
14 self.b = b 14 self.dst = dst
15 def __repr__(self): 15 def __repr__(self):
16 return '{0} {1}, {2}'.format(self.op, self.a, self.b) 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)
17 24
18 class X86CodeGen: 25 class X86CodeGen:
19 def __init__(self, diag): 26 def __init__(self, diag):
20 self.diag = diag 27 self.diag = diag
21 self.regs = ['rax', 'rbx', 'rcx', 'rdx'] 28 self.regs = ['rax', 'rbx', 'rcx', 'rdx']
22 29
23 def emit(self, i): 30 def emit(self, i):
24 self.asm.append(i) 31 self.asm.append(i)
25 def allocateReg(self, typ):
26 return 'ax'
27 def deallocateReg(self, r):
28 pass
29 32
30 def genBin(self, i): 33 def genBin(self, ir):
31 self.asm = [] 34 self.asm = []
32 self.genModule(i) 35 # Allocate registers:
36 ir.registerAllocate(self.regs)
37 self.genModule(ir)
38 return self.asm
33 39
34 def genModule(self, m): 40 def genModule(self, ir):
35 for g in m.Globals: 41 #for f in ir.Functions:
36 self.emit(AsmLabel(g.name)) 42 # self.genFunction(f)
37 # Ignore types for now .. 43 for bb in ir.BasicBlocks:
38 self.emit('dw 0') 44 self.genBB(bb)
39 for f in m.Functions:
40 self.genFunction(f)
41 def genFunction(self, f): 45 def genFunction(self, f):
42 self.emit('global {0}'.format(f.name)) 46 self.emit('global {0}'.format(f.name))
43 self.emit(AsmLabel(f.name)) 47 self.emit(AsmLabel(f.name))
44 for bb in f.BasicBlocks: 48 for bb in f.BasicBlocks:
45 self.genBB(bb) 49 self.genBB(bb)
46 def genBB(self, bb): 50 def genBB(self, bb):
51 self.emit(AsmLabel(bb.name))
47 for i in bb.Instructions: 52 for i in bb.Instructions:
48 self.genIns(i) 53 self.genIns(i)
49 def genIns(self, i): 54 def genIns(self, i):
50 if type(i) is ir.BinaryOperator: 55 if type(i) is ir.BinaryOperator:
51 if i.operation == 'fadd': 56 ops = {'+':'add', '-':'sub', '*':'mul'}
52 r = 'rax' 57 if i.operation in ops:
53 self.emit(Op('add', r, '11')) 58 self.emit(Op('mov', i.result.reg, i.value1.reg))
54 elif type(i) is ir.LoadInstruction: 59 self.emit(Op(ops[i.operation], i.result.reg, i.value2.reg))
55 r = 'rbx' 60 else:
56 self.emit(Op('mov', r, '{0}'.format(i.value))) 61 raise NotImplementedError('op {0}'.format(i.operation))
57 elif type(i) is ir.RetInstruction: 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:
58 self.emit('ret') 65 self.emit('ret')
59 elif type(i) is ir.CallInstruction: 66 elif type(i) is ir.Call:
60 self.emit('call') 67 self.emit('call')
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))
61 else: 83 else:
62 print('Unknown ins', i) 84 raise NotImplementedError('{0}'.format(i))
63 85