annotate python/codegenarm.py @ 272:e64bae57cda8

refactor ir
author Windel Bouwman
date Sat, 31 Aug 2013 17:58:54 +0200
parents cdc76d183bcc
children ea93e0a7a31e
rev   line source
255
7416c923a02a Added more logging
Windel Bouwman
parents: 250
diff changeset
1 import logging
211
99164160fb0b Added another missing file
Windel Bouwman
parents:
diff changeset
2 import ir
249
e41e4109addd Added current position arrow
Windel Bouwman
parents: 243
diff changeset
3 from target import Label, Comment, Alignment, LabelRef, Imm32, DebugInfo
218
494828a7adf1 added some sort of cache to assembler
Windel Bouwman
parents: 212
diff changeset
4 import cortexm3 as arm
211
99164160fb0b Added another missing file
Windel Bouwman
parents:
diff changeset
5 from ppci import CompilerError
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
6 import flowgraph
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
7 import registerallocator
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
8 from instructionselector import InstructionSelector
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
9 import irmach
262
ed14e077124c Added conditional branch instructions
Windel Bouwman
parents: 261
diff changeset
10
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
11 class ArmInstructionSelector(InstructionSelector):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
12 """ Instruction selector for the arm architecture """
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
13 def munchExpr(self, e):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
14 if isinstance(e, ir.Alloc):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
15 return 0
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
16 elif isinstance(e, ir.Binop) and e.operation == '+':
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
17 a = self.munchExpr(e.value1)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
18 b = self.munchExpr(e.value2)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
19 d = self.newTmp()
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
20 self.emit('add %d0, %s0, %s1', dst=[d], src=[a, b])
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
21 return d
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
22 elif isinstance(e, ir.Binop) and e.operation == '-':
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
23 a = self.munchExpr(e.value1)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
24 b = self.munchExpr(e.value2)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
25 d = self.newTmp()
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
26 self.emit('sub %d0, %s0, %s1', dst=[d], src=[a, b])
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
27 return d
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
28 elif isinstance(e, ir.Binop) and e.operation == '|':
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
29 a = self.munchExpr(e.value1)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
30 b = self.munchExpr(e.value2)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
31 d = self.newTmp()
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
32 self.emit('or %d0, %s0, %s1', dst=[d], src=[a, b])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
33 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
34 elif isinstance(e, ir.Binop) and e.operation == '<<':
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
35 a = self.munchExpr(e.value1)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
36 b = self.munchExpr(e.value2)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
37 d = self.newTmp()
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
38 self.emit('lsl %d0, %s0, %s1', dst=[d], src=[a, b])
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
39 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
40 elif isinstance(e, ir.Binop) and e.operation == '*':
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
41 a = self.munchExpr(e.value1)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
42 b = self.munchExpr(e.value2)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
43 d = self.newTmp()
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
44 self.emit('mul %d0, %s0, %s1', dst=[d], src=[a, b])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
45 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
46 elif isinstance(e, ir.Const):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
47 d = self.newTmp()
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
48 if e.value < 256:
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
49 self.emit('ldr %d0, {}'.format(e.value), dst=[d])
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
50 else:
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
51 self.emit('ldrpcrel TODO', dst=[d])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
52 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
53 elif isinstance(e, ir.Mem):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
54 # Load from memory
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
55 loc = self.munchExpr(e.e)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
56 d = self.newTmp()
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
57 self.emit('ldr %d0, [%s0]', src=[loc], dst=[d])
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
58 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
59 elif isinstance(e, ir.Temp):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
60 return self.getTempReg(e)
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
61 elif isinstance(e, ir.Call):
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
62 args = [self.munchExpr(a) for a in e.arguments]
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
63 self.emit('add sp, sp, 22')
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
64 # TODO: save frame
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
65 for a in args:
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
66 self.emit('push %s0', src=[a])
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
67 self.emit('bl {}'.format(e.f.name))
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
68 self.emit('sub sp, sp, 22')
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
69 else:
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
70 raise NotImplementedError('Expr --> {}'.format(e))
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
71
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
72 def munchStm(self, s):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
73 if isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
74 memloc = self.munchExpr(s.dst.e)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
75 val = self.munchExpr(s.src)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
76 self.emit('str [%s0], %s1')
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
77 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
78 val = self.munchExpr(s.src)
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
79 dreg = self.getTempReg(s.dst)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
80 self.emit('mov %d0, %s0', dst=[dreg], src=[val])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
81 elif isinstance(s, ir.Jump):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
82 tgt = self.targets[s.target]
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
83 self.emit('jmp {}'.format(s), jumps=[tgt])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
84 elif isinstance(s, ir.CJump):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
85 a = self.munchExpr(s.a)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
86 b = self.munchExpr(s.b)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
87 self.emit('cmp %s0, %s1', src=[a, b])
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
88 ntgt = self.targets[s.lab_no]
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
89 ytgt = self.targets[s.lab_yes]
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
90 jmp_ins = self.makeIns('jmp {}'.format(s.lab_no), jumps=[ntgt])
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
91 # Explicitely add fallthrough:
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
92 self.emit('jeq {}'.format(s.lab_yes), jumps=[ytgt, jmp_ins])
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
93 self.emit2(jmp_ins)
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
94 else:
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
95 raise NotImplementedError('--> {}'.format(s))
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
96
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
97
211
99164160fb0b Added another missing file
Windel Bouwman
parents:
diff changeset
98 class ArmCodeGenerator:
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
99 def __init__(self, outs):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
100 # TODO: schedule traces in better order.
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
101 # This is optional!
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
102 self.ins_sel = ArmInstructionSelector()
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
103 self.outs = outs
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
104 self.outs.getSection('code').address = 0x08000000
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
105 self.outs.getSection('data').address = 0x20000000
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
106
270
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
107 def useUnused(self, inslist):
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
108 # Use unused temporaries at the end of the list
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
109 defTemps = []
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
110 useTemps = []
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
111 for i in inslist:
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
112 for d in iter(i.dst):
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
113 defTemps.append(d)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
114 for s in iter(i.src):
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
115 useTemps.append(s)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
116 defTemps = set(defTemps)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
117 useTemps = set(useTemps)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
118 unUsed = defTemps - useTemps
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
119 #print('Unused:', unUsed)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
120 for uu in unUsed:
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
121 inslist.append(irmach.AbstractInstruction('use %s0', src=[uu]))
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
122 #print(useTemps)
270
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
123
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
124 def generate(self, ircode, cfg_file=None, ig_file=None):
270
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
125 ir2 = self.ins_sel.munchProgram(ircode)
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
126 self.useUnused(ir2)
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
127 cfg = flowgraph.FlowGraph(ir2)
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
128 if cfg_file:
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
129 cfg.to_dot(cfg_file)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
130 ig = registerallocator.InterferenceGraph(cfg)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
131 if ig_file:
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
132 ig.to_dot(ig_file)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
133
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
134 regs = ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7']
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
135 ra = registerallocator.RegisterAllocator()
270
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
136 regMap = ra.registerAllocate(ig, regs)
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
137 #print(regMap)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
138 # Use allocated registers:
270
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
139 for i in ir2:
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
140 i.src = tuple(regMap[t] for t in i.src)
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
141 i.dst = tuple(regMap[t] for t in i.dst)
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
142 #print(i)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
143 return ir2
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
144
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
145
270
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
146