annotate python/codegenarm.py @ 276:56d37ed4b4d2

phaa
author Windel Bouwman
date Mon, 16 Sep 2013 21:51:17 +0200
parents 6f2423df0675
children 046017431c6a
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
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
10 from irmach import makeIns
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
11 import canon
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
12 import asm
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
13
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
14 class ArmFrame(irmach.Frame):
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
15 """
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
16 Arm specific frame for functions.
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
17 """
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
18 def __init__(self, name):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
19 # We use r7 as frame pointer.
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
20 super().__init__(name)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
21 self.regs = ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6']
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
22 self.rv = ir.Temp('special_RV')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
23 self.p1 = ir.Temp('special_P1')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
24 self.p2 = ir.Temp('special_P2')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
25 self.p3 = ir.Temp('special_P3')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
26 self.p4 = ir.Temp('special_P4')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
27 self.fp = ir.Temp('special_FP')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
28 # Pre-colored registers:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
29 self.tempMap = {}
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
30 self.tempMap[self.rv] = 'r0'
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
31 self.tempMap[self.p1] = 'r1'
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
32 self.tempMap[self.p2] = 'r2'
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
33 self.tempMap[self.p3] = 'r3'
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
34 self.tempMap[self.p4] = 'r4'
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
35 self.tempMap[self.fp] = 'r7'
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
36 self.locVars = {}
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
37 self.parMap = {}
276
Windel Bouwman
parents: 275
diff changeset
38 # Literal pool:
Windel Bouwman
parents: 275
diff changeset
39 self.constants = []
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
40
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
41 def argLoc(self, pos):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
42 """
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
43 Gets the function parameter location in IR-code format.
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
44 """
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
45 if pos == 0:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
46 return self.p1
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
47 elif pos == 1:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
48 return self.p2
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
49 elif pos == 2:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
50 return self.p3
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
51 elif pos == 3:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
52 return self.p4
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
53 else:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
54 raise NotImplementedError('No more than 4 parameters implemented')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
55
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
56 def allocVar(self, lvar):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
57 if lvar not in self.locVars:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
58 self.locVars[lvar] = self.stacksize
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
59 self.stacksize = self.stacksize + 4
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
60 return self.locVars[lvar]
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
61
276
Windel Bouwman
parents: 275
diff changeset
62 def addConstant(self, value):
Windel Bouwman
parents: 275
diff changeset
63 lab_name = '{}_literal_{}'.format(self.name, len(self.constants))
Windel Bouwman
parents: 275
diff changeset
64 self.constants.append((lab_name, value))
Windel Bouwman
parents: 275
diff changeset
65 return lab_name
Windel Bouwman
parents: 275
diff changeset
66
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
67 def EntryExitGlue3(self):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
68 """
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
69 Add code for the prologue and the epilogue. Add a label, the
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
70 return instruction and the stack pointer adjustment for the frame.
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
71 """
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
72 self.instructions.insert(0, makeIns('{}:'.format(self.name)))
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
73 self.instructions.insert(1, makeIns('push {lr, r7}'))
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
74 self.instructions.insert(2, makeIns('mov r7, sp'))
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
75 self.instructions.insert(3, makeIns('add sp, sp, {}'.format(self.stacksize)))
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
76 self.instructions.append(makeIns('sub sp, sp, {}'.format(self.stacksize)))
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
77 self.instructions.append(makeIns('pop {pc,r7}'))
276
Windel Bouwman
parents: 275
diff changeset
78 # Add constant literals:
Windel Bouwman
parents: 275
diff changeset
79 for ln, v in self.constants:
Windel Bouwman
parents: 275
diff changeset
80 self.instructions.append(makeIns('{}:'.format(ln)))
Windel Bouwman
parents: 275
diff changeset
81 self.instructions.append(makeIns('dcd {}'.format(v)))
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
82
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
83
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
84 class ArmInstructionSelector(InstructionSelector):
276
Windel Bouwman
parents: 275
diff changeset
85
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
86 """ Instruction selector for the arm architecture """
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
87 def munchExpr(self, e):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
88 if isinstance(e, ir.Alloc):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
89 return 0
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
90 elif isinstance(e, ir.Binop) and e.operation == '+' and isinstance(e.b, ir.Const) and e.b.value < 8:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
91 a = self.munchExpr(e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
92 d = self.newTmp()
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
93 self.emit('add %d0, %s0, {}'.format(e.b.value), dst=[d], src=[a])
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
94 return d
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
95 elif isinstance(e, ir.Binop) and e.operation == '+':
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
96 a = self.munchExpr(e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
97 b = self.munchExpr(e.b)
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
98 d = self.newTmp()
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
99 self.emit('add %d0, %s0, %s1', dst=[d], src=[a, b])
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
100 return d
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
101 elif isinstance(e, ir.Binop) and e.operation == '-' and isinstance(e.b, ir.Const) and e.b.value < 8:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
102 a = self.munchExpr(e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
103 d = self.newTmp()
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
104 self.emit('sub %d0, %s0, {}'.format(e.b.value), dst=[d], src=[a])
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
105 return d
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
106 elif isinstance(e, ir.Binop) and e.operation == '-':
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
107 a = self.munchExpr(e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
108 b = self.munchExpr(e.b)
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
109 d = self.newTmp()
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
110 self.emit('sub %d0, %s0, %s1', dst=[d], src=[a, b])
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
111 return d
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
112 elif isinstance(e, ir.Binop) and e.operation == '|':
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
113 a = self.munchExpr(e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
114 b = self.munchExpr(e.b)
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
115 d = self.newTmp()
276
Windel Bouwman
parents: 275
diff changeset
116 self.emit('mov %d0, %s0', src=[a], dst=[d])
Windel Bouwman
parents: 275
diff changeset
117 self.emit('orr %d0, %s0', dst=[d], src=[b, d])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
118 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
119 elif isinstance(e, ir.Binop) and e.operation == '<<':
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
120 a = self.munchExpr(e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
121 b = self.munchExpr(e.b)
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
122 d = self.newTmp()
276
Windel Bouwman
parents: 275
diff changeset
123 self.emit('mov %d0, %s0', src=[a], dst=[d])
Windel Bouwman
parents: 275
diff changeset
124 self.emit('lsl %d0, %s0', dst=[d], src=[b, d]) # TODO: is d a source variable?
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
125 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
126 elif isinstance(e, ir.Binop) and e.operation == '*':
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
127 a = self.munchExpr(e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
128 b = self.munchExpr(e.b)
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
129 d = self.newTmp()
276
Windel Bouwman
parents: 275
diff changeset
130 self.emit('mov %d0, %s0', src=[a], dst=[d])
Windel Bouwman
parents: 275
diff changeset
131 self.emit('mul %d0, %s0', dst=[d], src=[b, d])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
132 return d
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
133 elif isinstance(e, ir.Const) and e.value < 256:
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
134 d = self.newTmp()
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
135 self.emit('mov %d0, {}'.format(e.value), dst=[d])
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
136 return d
276
Windel Bouwman
parents: 275
diff changeset
137 elif isinstance(e, ir.Const) and e.value < (2**31):
Windel Bouwman
parents: 275
diff changeset
138 d = self.newTmp()
Windel Bouwman
parents: 275
diff changeset
139 ln = self.frame.addConstant(e.value)
Windel Bouwman
parents: 275
diff changeset
140 self.emit('ldr %d0, {}'.format(ln), dst=[d])
Windel Bouwman
parents: 275
diff changeset
141 return d
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
142 elif isinstance(e, ir.Mem) and isinstance(e.e, ir.Binop) and \
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
143 e.e.operation == '+' and isinstance(e.e.b, ir.Const):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
144 base = self.munchExpr(e.e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
145 d = self.newTmp()
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
146 self.emit('ldr %d0, [%s0 + {}]'.format(e.e.b.value), src=[base], dst=[d])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
147 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
148 elif isinstance(e, ir.Mem):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
149 # Load from memory
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
150 base = self.munchExpr(e.e)
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
151 d = self.newTmp()
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
152 self.emit('ldr %d0, [%s0]', src=[base], dst=[d])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
153 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
154 elif isinstance(e, ir.Temp):
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
155 return e
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
156 elif isinstance(e, ir.Call):
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
157 # Move arguments into proper locations:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
158 reguses = []
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
159 for i, a in enumerate(e.arguments):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
160 loc = self.frame.argLoc(i)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
161 m = ir.Move(loc, a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
162 self.munchStm(m)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
163 if isinstance(loc, ir.Temp):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
164 reguses.append(loc)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
165 self.emit('bl {}'.format(e.f.name), src=reguses, dst=[self.frame.rv])
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
166 d = self.newTmp()
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
167 self.move(d, self.frame.rv)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
168 return d
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
169 else:
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
170 raise NotImplementedError('Expr --> {}'.format(e))
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
171
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
172 def munchStm(self, s):
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
173 if isinstance(s, ir.Terminator):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
174 pass
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
175 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and isinstance(s.dst.e.a, ir.Temp) and isinstance(s.dst.e.b, ir.Const):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
176 val = self.munchExpr(s.src)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
177 self.emit('str %s1, [%s0 + {}]'.format(s.dst.e.b.value), src=[s.dst.e.a, val])
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
178 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem):
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
179 memloc = self.munchExpr(s.dst.e)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
180 val = self.munchExpr(s.src)
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
181 self.emit('str %s1, [%s0]', src=[memloc, val])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
182 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
183 val = self.munchExpr(s.src)
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
184 dreg = s.dst
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
185 self.emit('mov %d0, %s0', dst=[dreg], src=[val])
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
186 elif isinstance(s, ir.Exp):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
187 # Generate expression code and discard the result.
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
188 x = self.munchExpr(s.e)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
189 self.emit('mov r0, r0', src=[x])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
190 elif isinstance(s, ir.Jump):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
191 tgt = self.targets[s.target]
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
192 self.emit('b {}'.format(s.target.name), jumps=[tgt])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
193 elif isinstance(s, ir.CJump):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
194 a = self.munchExpr(s.a)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
195 b = self.munchExpr(s.b)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
196 self.emit('cmp %s0, %s1', src=[a, b])
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
197 ntgt = self.targets[s.lab_no]
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
198 ytgt = self.targets[s.lab_yes]
276
Windel Bouwman
parents: 275
diff changeset
199 jmp_ins = makeIns('b {}'.format(s.lab_no.name), jumps=[ntgt])
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
200 # Explicitely add fallthrough:
276
Windel Bouwman
parents: 275
diff changeset
201 self.emit('beq {}'.format(s.lab_yes.name), jumps=[ytgt, jmp_ins])
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
202 self.emit2(jmp_ins)
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
203 else:
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
204 raise NotImplementedError('Stmt --> {}'.format(s))
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
205
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
206
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
207 # TODO: this class could be target independent:
211
99164160fb0b Added another missing file
Windel Bouwman
parents:
diff changeset
208 class ArmCodeGenerator:
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
209 def __init__(self, outs):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
210 # TODO: schedule traces in better order.
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
211 # This is optional!
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
212 self.ins_sel = ArmInstructionSelector()
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
213 self.outs = outs
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
214 self.outs.getSection('code').address = 0x08000000
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
215 self.outs.getSection('data').address = 0x20000000
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
216
270
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
217 def useUnused(self, inslist):
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
218 # Use unused temporaries at the end of the list
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
219 defTemps = []
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
220 useTemps = []
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
221 for i in inslist:
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
222 for d in iter(i.dst):
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
223 defTemps.append(d)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
224 for s in iter(i.src):
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
225 useTemps.append(s)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
226 defTemps = set(defTemps)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
227 useTemps = set(useTemps)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
228 unUsed = defTemps - useTemps
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
229 assert not unUsed
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
230 for uu in unUsed:
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
231 inslist.append(irmach.AbstractInstruction('use %s0', src=[uu]))
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
232 #print(useTemps)
270
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
233
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
234 def allocFrame(self, f):
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
235 """
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
236 Do register allocation for a single stack frame.
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
237 """
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
238 ilist = f.instructions
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
239 self.useUnused(ilist)
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
240 cfg = flowgraph.FlowGraph(ilist)
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
241 f.cfg = cfg
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
242 ig = registerallocator.InterferenceGraph(cfg)
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
243 f.ig = ig
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
244
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
245 ra = registerallocator.RegisterAllocator()
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
246 regMap = ra.registerAllocate(ig, f.regs, f.tempMap)
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
247 # Use allocated registers:
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
248 for i in ilist:
270
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
249 i.src = tuple(regMap[t] for t in i.src)
cdc76d183bcc first register allocator
Windel Bouwman
parents: 269
diff changeset
250 i.dst = tuple(regMap[t] for t in i.dst)
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
251
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
252 def generateFunc(self, irfunc):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
253 # Create a frame for this function:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
254 frame = ArmFrame(irfunc.name)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
255 # Canonicalize the intermediate language:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
256 canon.make(irfunc, frame)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
257 # print('after canonicalize:')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
258 # irfunc.dump()
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
259 self.ins_sel.munchFunction(irfunc, frame)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
260 # print('Selected instructions:')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
261 #for i in frame.instructions:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
262 # print(i)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
263
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
264 # Do register allocation:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
265 self.allocFrame(frame)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
266 # TODO: Peep-hole here?
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
267
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
268 # Add label and return and stack adjustment:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
269 frame.EntryExitGlue3()
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
270 return frame
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
271
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
272 def generate(self, ircode):
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
273 # Munch program into a bunch of frames. One frame per function.
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
274 # Each frame has a flat list of abstract instructions.
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
275 # Generate code for all functions:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
276 self.frames = [self.generateFunc(func) for func in ircode.Functions]
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
277
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
278 # Materialize assembly
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
279 # Reparse the register allocated instructions into a stream of
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
280 # real instructions.
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
281 # TODO: this is ugly via string representations. This could be
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
282 # another interface?
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
283 assembler = asm.Assembler(target=arm.armtarget, stream=self.outs)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
284 self.outs.selectSection('code')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
285 for frame in self.frames:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
286 for i in frame.instructions:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
287 assembler.assemble_line(str(i))
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
288
276
Windel Bouwman
parents: 275
diff changeset
289 # TODO: fixup references, do this in another way?
Windel Bouwman
parents: 275
diff changeset
290 self.outs.backpatch()
Windel Bouwman
parents: 275
diff changeset
291 self.outs.backpatch()
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
292 return self.frames
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
293