annotate python/codegenarm.py @ 274:ea93e0a7a31e

Move docs
author Windel Bouwman
date Wed, 04 Sep 2013 17:35:06 +0200
parents e64bae57cda8
children 6f2423df0675
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
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
11
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
12 class ArmFrame(irmach.Frame):
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
13 """
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
14 Arm specific frame for functions.
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
15 """
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
16 pass
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
17
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
18
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
19 class ArmInstructionSelector(InstructionSelector):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
20 """ Instruction selector for the arm architecture """
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
21 def newFrame(self, name):
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
22 return ArmFrame(name)
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
23
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
24 def munchExpr(self, e):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
25 if isinstance(e, ir.Alloc):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
26 return 0
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
27 elif isinstance(e, ir.Binop) and e.operation == '+':
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
28 a = self.munchExpr(e.value1)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
29 b = self.munchExpr(e.value2)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
30 d = self.newTmp()
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
31 self.emit('add %d0, %s0, %s1', dst=[d], src=[a, b])
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
32 return d
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
33 elif isinstance(e, ir.Binop) and e.operation == '-':
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
34 a = self.munchExpr(e.value1)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
35 b = self.munchExpr(e.value2)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
36 d = self.newTmp()
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
37 self.emit('sub %d0, %s0, %s1', dst=[d], src=[a, b])
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
38 return d
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
39 elif isinstance(e, ir.Binop) and e.operation == '|':
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
40 a = self.munchExpr(e.value1)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
41 b = self.munchExpr(e.value2)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
42 d = self.newTmp()
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
43 self.emit('or %d0, %s0, %s1', dst=[d], src=[a, b])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
44 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
45 elif isinstance(e, ir.Binop) and e.operation == '<<':
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
46 a = self.munchExpr(e.value1)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
47 b = self.munchExpr(e.value2)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
48 d = self.newTmp()
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
49 self.emit('lsl %d0, %s0, %s1', dst=[d], src=[a, b])
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
50 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
51 elif isinstance(e, ir.Binop) and e.operation == '*':
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
52 a = self.munchExpr(e.value1)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
53 b = self.munchExpr(e.value2)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
54 d = self.newTmp()
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
55 self.emit('mul %d0, %s0, %s1', dst=[d], src=[a, b])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
56 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
57 elif isinstance(e, ir.Const):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
58 d = self.newTmp()
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
59 if e.value < 256:
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
60 self.emit('ldr %d0, {}'.format(e.value), dst=[d])
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
61 else:
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
62 self.emit('ldrpcrel TODO', dst=[d])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
63 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
64 elif isinstance(e, ir.Mem):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
65 # Load from memory
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
66 loc = self.munchExpr(e.e)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
67 d = self.newTmp()
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
68 self.emit('ldr %d0, [%s0]', src=[loc], dst=[d])
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
69 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
70 elif isinstance(e, ir.Temp):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
71 return self.getTempReg(e)
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
72 elif isinstance(e, ir.Parameter):
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
73 offset = 1337 # TODO: determine offset in frame??
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
74 d = self.newTmp()
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
75 self.emit('ldr %d0, [sp + {}]'.format(offset), dst=[d])
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
76 return d
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
77 elif isinstance(e, ir.Call):
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
78 args = [self.munchExpr(a) for a in e.arguments]
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
79 frame_size = 222 # TODO: determine frame size?
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
80 self.emit('add sp, sp, {}'.format(frame_size))
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
81 # TODO: save frame
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
82 for a in args:
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
83 self.emit('push %s0', src=[a])
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
84 self.emit('bl {}'.format(e.f.name))
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
85 self.emit('sub sp, sp, 22')
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
86 else:
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
87 raise NotImplementedError('Expr --> {}'.format(e))
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
88
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
89 def munchStm(self, s):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
90 if isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
91 memloc = self.munchExpr(s.dst.e)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
92 val = self.munchExpr(s.src)
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
93 self.emit('str [%s0], %s1', src=[memloc, val])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
94 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
95 val = self.munchExpr(s.src)
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
96 dreg = self.getTempReg(s.dst)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
97 self.emit('mov %d0, %s0', dst=[dreg], src=[val])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
98 elif isinstance(s, ir.Jump):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
99 tgt = self.targets[s.target]
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
100 self.emit('jmp %l0', jumps=[tgt])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
101 elif isinstance(s, ir.CJump):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
102 a = self.munchExpr(s.a)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
103 b = self.munchExpr(s.b)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
104 self.emit('cmp %s0, %s1', src=[a, b])
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
105 ntgt = self.targets[s.lab_no]
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
106 ytgt = self.targets[s.lab_yes]
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
107 jmp_ins = self.makeIns('jmp %l0', jumps=[ntgt])
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
108 # Explicitely add fallthrough:
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
109 self.emit('jeq %l0', jumps=[ytgt, jmp_ins])
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
110 self.emit2(jmp_ins)
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
111 elif isinstance(s, ir.Terminator):
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
112 pass
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
113 else:
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
114 raise NotImplementedError('Stmt --> {}'.format(s))
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
115
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
116
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
117 # TODO: this class could be target independent:
211
99164160fb0b Added another missing file
Windel Bouwman
parents:
diff changeset
118 class ArmCodeGenerator:
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
119 def __init__(self, outs):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
120 # TODO: schedule traces in better order.
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
121 # This is optional!
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
122 self.ins_sel = ArmInstructionSelector()
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
123 self.outs = outs
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
124 self.outs.getSection('code').address = 0x08000000
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
125 self.outs.getSection('data').address = 0x20000000
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
126
270
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
127 def useUnused(self, inslist):
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
128 # Use unused temporaries at the end of the list
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
129 defTemps = []
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
130 useTemps = []
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
131 for i in inslist:
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
132 for d in iter(i.dst):
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
133 defTemps.append(d)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
134 for s in iter(i.src):
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
135 useTemps.append(s)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
136 defTemps = set(defTemps)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
137 useTemps = set(useTemps)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
138 unUsed = defTemps - useTemps
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
139 print('Unused:', unUsed)
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
140 for uu in unUsed:
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
141 inslist.append(irmach.AbstractInstruction('use %s0', src=[uu]))
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
142 #print(useTemps)
270
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
143
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
144 def allocFrame(self, f):
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
145 """
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
146 Do register allocation for a single stack frame.
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
147 """
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
148 ilist = f.instructions
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
149 self.useUnused(ilist)
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
150 cfg = flowgraph.FlowGraph(ilist)
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
151 f.cfg = cfg
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
152 ig = registerallocator.InterferenceGraph(cfg)
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
153 f.ig = ig
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
154
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
155 regs = ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7']
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
156 ra = registerallocator.RegisterAllocator()
270
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
157 regMap = ra.registerAllocate(ig, regs)
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
158 #print(regMap)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
159 # Use allocated registers:
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
160 for i in ilist:
270
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
161 i.src = tuple(regMap[t] for t in i.src)
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
162 i.dst = tuple(regMap[t] for t in i.dst)
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
163 #print(i)
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
164
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
165 def generate(self, ircode):
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
166 # Munch program into a bunch of frames. One frame per function.
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
167 # Each frame has a flat list of abstract instructions.
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
168 frames = self.ins_sel.munchProgram(ircode)
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
169 self.frames = frames
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
170 for f in frames:
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
171 self.allocFrame(f)
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
172
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
173 # TODO: Peep-hole here
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
174 # TODO: Materialize assembly
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
175 return frames
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
176
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
177