comparison python/codegenarm.py @ 279:2ccd57b1d78c

Fix register allocator to do burn2 OK
author Windel Bouwman
date Sat, 12 Oct 2013 09:56:23 +0200
parents 046017431c6a
children 02385f62f250
comparison
equal deleted inserted replaced
278:9fca39eebe50 279:2ccd57b1d78c
68 Add code for the prologue and the epilogue. Add a label, the 68 Add code for the prologue and the epilogue. Add a label, the
69 return instruction and the stack pointer adjustment for the frame. 69 return instruction and the stack pointer adjustment for the frame.
70 """ 70 """
71 self.instructions.insert(0, makeIns('{}:'.format(self.name))) 71 self.instructions.insert(0, makeIns('{}:'.format(self.name)))
72 self.instructions.insert(1, makeIns('push {lr, r7}')) 72 self.instructions.insert(1, makeIns('push {lr, r7}'))
73 self.instructions.insert(2, makeIns('mov r7, sp')) 73 # Reserve stack space for locals:
74 self.instructions.insert(3, makeIns('add sp, sp, {}'.format(self.stacksize))) 74 self.instructions.insert(2, makeIns('sub sp, sp, {}'.format(self.stacksize)))
75 self.instructions.append(makeIns('sub sp, sp, {}'.format(self.stacksize))) 75 # Setup frame pointer:
76 self.instructions.insert(3, makeIns('mov r7, sp'))
77 # Stack grows downwards
78 self.instructions.append(makeIns('add sp, sp, {}'.format(self.stacksize)))
76 self.instructions.append(makeIns('pop {pc,r7}')) 79 self.instructions.append(makeIns('pop {pc,r7}'))
77 # Add constant literals: 80 # Add constant literals:
81 self.instructions.append(makeIns('align 4')) # Align at 4 bytes
78 for ln, v in self.constants: 82 for ln, v in self.constants:
79 self.instructions.append(makeIns('{}:'.format(ln))) 83 self.instructions.append(makeIns('{}:'.format(ln)))
80 self.instructions.append(makeIns('dcd {}'.format(v))) 84 self.instructions.append(makeIns('dcd {}'.format(v)))
81 85
82 86
84 88
85 """ Instruction selector for the arm architecture """ 89 """ Instruction selector for the arm architecture """
86 def munchExpr(self, e): 90 def munchExpr(self, e):
87 if isinstance(e, ir.Alloc): 91 if isinstance(e, ir.Alloc):
88 return 0 92 return 0
89 elif isinstance(e, ir.Binop) and e.operation == '+' and isinstance(e.b, ir.Const) and e.b.value < 8: 93 elif isinstance(e, ir.Binop) and e.operation == '+' and \
94 isinstance(e.b, ir.Const) and e.b.value < 8:
90 a = self.munchExpr(e.a) 95 a = self.munchExpr(e.a)
91 d = self.newTmp() 96 d = self.newTmp()
92 self.emit('add %d0, %s0, {}'.format(e.b.value), dst=[d], src=[a]) 97 self.emit('add %d0, %s0, {}'.format(e.b.value), dst=[d], src=[a])
93 return d 98 return d
94 elif isinstance(e, ir.Binop) and e.operation == '+': 99 elif isinstance(e, ir.Binop) and e.operation == '+':
95 a = self.munchExpr(e.a) 100 a = self.munchExpr(e.a)
96 b = self.munchExpr(e.b) 101 b = self.munchExpr(e.b)
97 d = self.newTmp() 102 d = self.newTmp()
98 self.emit('add %d0, %s0, %s1', dst=[d], src=[a, b]) 103 self.emit('add %d0, %s0, %s1', dst=[d], src=[a, b])
99 return d 104 return d
100 elif isinstance(e, ir.Binop) and e.operation == '-' and isinstance(e.b, ir.Const) and e.b.value < 8: 105 elif isinstance(e, ir.Binop) and e.operation == '-' and \
106 isinstance(e.b, ir.Const) and e.b.value < 8:
101 a = self.munchExpr(e.a) 107 a = self.munchExpr(e.a)
102 d = self.newTmp() 108 d = self.newTmp()
103 self.emit('sub %d0, %s0, {}'.format(e.b.value), dst=[d], src=[a]) 109 self.emit('sub %d0, %s0, {}'.format(e.b.value), dst=[d], src=[a])
104 return d 110 return d
105 elif isinstance(e, ir.Binop) and e.operation == '-': 111 elif isinstance(e, ir.Binop) and e.operation == '-':
110 return d 116 return d
111 elif isinstance(e, ir.Binop) and e.operation == '|': 117 elif isinstance(e, ir.Binop) and e.operation == '|':
112 a = self.munchExpr(e.a) 118 a = self.munchExpr(e.a)
113 b = self.munchExpr(e.b) 119 b = self.munchExpr(e.b)
114 d = self.newTmp() 120 d = self.newTmp()
115 self.emit('mov %d0, %s0', src=[a], dst=[d]) 121 self.move(d, a)
116 self.emit('orr %d0, %s0', dst=[d], src=[b, d]) 122 self.emit('orr %s1, %s0', dst=[], src=[b, d])
117 return d 123 return d
118 elif isinstance(e, ir.Binop) and e.operation == '<<': 124 elif isinstance(e, ir.Binop) and e.operation == '<<':
119 a = self.munchExpr(e.a) 125 a = self.munchExpr(e.a)
120 b = self.munchExpr(e.b) 126 b = self.munchExpr(e.b)
121 d = self.newTmp() 127 d = self.newTmp()
122 self.emit('mov %d0, %s0', src=[a], dst=[d]) 128 self.move(d, a)
123 self.emit('lsl %d0, %s0', dst=[d], src=[b, d]) # TODO: is d a source variable? 129 self.emit('lsl %s1, %s0', dst=[], src=[b, d]) # TODO: is d a source variable?
124 return d 130 return d
125 elif isinstance(e, ir.Binop) and e.operation == '*': 131 elif isinstance(e, ir.Binop) and e.operation == '*':
126 a = self.munchExpr(e.a) 132 a = self.munchExpr(e.a)
127 b = self.munchExpr(e.b) 133 b = self.munchExpr(e.b)
128 d = self.newTmp() 134 d = self.newTmp()
129 self.emit('mov %d0, %s0', src=[a], dst=[d]) 135 self.move(d, a)
130 self.emit('mul %d0, %s0', dst=[d], src=[b, d]) 136 # this mul instruction has operands swapped:
137 self.emit('mul %s0, %d0', dst=[d], src=[b, d])
131 return d 138 return d
132 elif isinstance(e, ir.Const) and e.value < 256: 139 elif isinstance(e, ir.Const) and e.value < 256:
133 d = self.newTmp() 140 d = self.newTmp()
134 self.emit('mov %d0, {}'.format(e.value), dst=[d]) 141 self.emit('mov %d0, {}'.format(e.value), dst=[d])
135 return d 142 return d
140 return d 147 return d
141 elif isinstance(e, ir.Mem) and isinstance(e.e, ir.Binop) and \ 148 elif isinstance(e, ir.Mem) and isinstance(e.e, ir.Binop) and \
142 e.e.operation == '+' and isinstance(e.e.b, ir.Const): 149 e.e.operation == '+' and isinstance(e.e.b, ir.Const):
143 base = self.munchExpr(e.e.a) 150 base = self.munchExpr(e.e.a)
144 d = self.newTmp() 151 d = self.newTmp()
145 self.emit('ldr %d0, [%s0 + {}]'.format(e.e.b.value), src=[base], dst=[d]) 152 c = e.e.b.value
153 self.emit('ldr %d0, [%s0 + {}]'.format(c), src=[base], dst=[d])
146 return d 154 return d
147 elif isinstance(e, ir.Mem): 155 elif isinstance(e, ir.Mem):
148 # Load from memory 156 # Load from memory
149 base = self.munchExpr(e.e) 157 base = self.munchExpr(e.e)
150 d = self.newTmp() 158 d = self.newTmp()
169 raise NotImplementedError('Expr --> {}'.format(e)) 177 raise NotImplementedError('Expr --> {}'.format(e))
170 178
171 def munchStm(self, s): 179 def munchStm(self, s):
172 if isinstance(s, ir.Terminator): 180 if isinstance(s, ir.Terminator):
173 pass 181 pass
174 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): 182 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \
183 isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and \
184 isinstance(s.dst.e.b, ir.Const):
185 a = self.munchExpr(s.dst.e.a)
175 val = self.munchExpr(s.src) 186 val = self.munchExpr(s.src)
176 self.emit('str %s1, [%s0 + {}]'.format(s.dst.e.b.value), src=[s.dst.e.a, val]) 187 c = s.dst.e.b.value
188 self.emit('str %s1, [%s0 + {}]'.format(c), src=[a, val])
177 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem): 189 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem):
178 memloc = self.munchExpr(s.dst.e) 190 memloc = self.munchExpr(s.dst.e)
179 val = self.munchExpr(s.src) 191 val = self.munchExpr(s.src)
180 self.emit('str %s1, [%s0]', src=[memloc, val]) 192 self.emit('str %s1, [%s0]', src=[memloc, val])
181 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp): 193 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp):
183 dreg = s.dst 195 dreg = s.dst
184 self.emit('mov %d0, %s0', dst=[dreg], src=[val]) 196 self.emit('mov %d0, %s0', dst=[dreg], src=[val])
185 elif isinstance(s, ir.Exp): 197 elif isinstance(s, ir.Exp):
186 # Generate expression code and discard the result. 198 # Generate expression code and discard the result.
187 x = self.munchExpr(s.e) 199 x = self.munchExpr(s.e)
188 self.emit('mov r0, r0', src=[x]) 200 self.emit('nop', src=[x])
189 elif isinstance(s, ir.Jump): 201 elif isinstance(s, ir.Jump):
190 tgt = self.targets[s.target] 202 tgt = self.targets[s.target]
191 self.emit('b {}'.format(s.target.name), jumps=[tgt]) 203 self.emit('b {}'.format(s.target.name), jumps=[tgt])
192 elif isinstance(s, ir.CJump): 204 elif isinstance(s, ir.CJump):
193 a = self.munchExpr(s.a) 205 a = self.munchExpr(s.a)
246 # real instructions. 258 # real instructions.
247 # TODO: this is ugly via string representations. This could be 259 # TODO: this is ugly via string representations. This could be
248 # another interface? 260 # another interface?
249 assembler = asm.Assembler(target=arm.armtarget, stream=self.outs) 261 assembler = asm.Assembler(target=arm.armtarget, stream=self.outs)
250 self.outs.selectSection('code') 262 self.outs.selectSection('code')
263 # assembly glue to make it work:
264 self.outs.emit(arm.dcd_ins(Imm32(0x20000678))) # initial SP
265 self.outs.emit(arm.dcd_ins(Imm32(0x08000009))) # reset vector
266 self.outs.emit(arm.b_ins(LabelRef('main')))
251 for frame in self.frames: 267 for frame in self.frames:
252 for i in frame.instructions: 268 for i in frame.instructions:
253 assembler.assemble_line(str(i)) 269 assembler.assemble_line(str(i))
254 270
255 # TODO: fixup references, do this in another way? 271 # TODO: fixup references, do this in another way?