Mercurial > lcfOS
diff 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 |
line wrap: on
line diff
--- a/python/codegenarm.py Sun Sep 29 14:08:15 2013 +0200 +++ b/python/codegenarm.py Sat Oct 12 09:56:23 2013 +0200 @@ -70,11 +70,15 @@ """ self.instructions.insert(0, makeIns('{}:'.format(self.name))) self.instructions.insert(1, makeIns('push {lr, r7}')) - self.instructions.insert(2, makeIns('mov r7, sp')) - self.instructions.insert(3, makeIns('add sp, sp, {}'.format(self.stacksize))) - self.instructions.append(makeIns('sub sp, sp, {}'.format(self.stacksize))) + # Reserve stack space for locals: + self.instructions.insert(2, makeIns('sub sp, sp, {}'.format(self.stacksize))) + # Setup frame pointer: + self.instructions.insert(3, makeIns('mov r7, sp')) + # Stack grows downwards + self.instructions.append(makeIns('add sp, sp, {}'.format(self.stacksize))) self.instructions.append(makeIns('pop {pc,r7}')) # Add constant literals: + self.instructions.append(makeIns('align 4')) # Align at 4 bytes for ln, v in self.constants: self.instructions.append(makeIns('{}:'.format(ln))) self.instructions.append(makeIns('dcd {}'.format(v))) @@ -86,7 +90,8 @@ def munchExpr(self, e): if isinstance(e, ir.Alloc): return 0 - elif isinstance(e, ir.Binop) and e.operation == '+' and isinstance(e.b, ir.Const) and e.b.value < 8: + elif isinstance(e, ir.Binop) and e.operation == '+' and \ + isinstance(e.b, ir.Const) and e.b.value < 8: a = self.munchExpr(e.a) d = self.newTmp() self.emit('add %d0, %s0, {}'.format(e.b.value), dst=[d], src=[a]) @@ -97,7 +102,8 @@ d = self.newTmp() self.emit('add %d0, %s0, %s1', dst=[d], src=[a, b]) return d - elif isinstance(e, ir.Binop) and e.operation == '-' and isinstance(e.b, ir.Const) and e.b.value < 8: + elif isinstance(e, ir.Binop) and e.operation == '-' and \ + isinstance(e.b, ir.Const) and e.b.value < 8: a = self.munchExpr(e.a) d = self.newTmp() self.emit('sub %d0, %s0, {}'.format(e.b.value), dst=[d], src=[a]) @@ -112,22 +118,23 @@ a = self.munchExpr(e.a) b = self.munchExpr(e.b) d = self.newTmp() - self.emit('mov %d0, %s0', src=[a], dst=[d]) - self.emit('orr %d0, %s0', dst=[d], src=[b, d]) + self.move(d, a) + self.emit('orr %s1, %s0', dst=[], src=[b, d]) return d elif isinstance(e, ir.Binop) and e.operation == '<<': a = self.munchExpr(e.a) b = self.munchExpr(e.b) d = self.newTmp() - self.emit('mov %d0, %s0', src=[a], dst=[d]) - self.emit('lsl %d0, %s0', dst=[d], src=[b, d]) # TODO: is d a source variable? + self.move(d, a) + self.emit('lsl %s1, %s0', dst=[], src=[b, d]) # TODO: is d a source variable? return d elif isinstance(e, ir.Binop) and e.operation == '*': a = self.munchExpr(e.a) b = self.munchExpr(e.b) d = self.newTmp() - self.emit('mov %d0, %s0', src=[a], dst=[d]) - self.emit('mul %d0, %s0', dst=[d], src=[b, d]) + self.move(d, a) + # this mul instruction has operands swapped: + self.emit('mul %s0, %d0', dst=[d], src=[b, d]) return d elif isinstance(e, ir.Const) and e.value < 256: d = self.newTmp() @@ -142,7 +149,8 @@ e.e.operation == '+' and isinstance(e.e.b, ir.Const): base = self.munchExpr(e.e.a) d = self.newTmp() - self.emit('ldr %d0, [%s0 + {}]'.format(e.e.b.value), src=[base], dst=[d]) + c = e.e.b.value + self.emit('ldr %d0, [%s0 + {}]'.format(c), src=[base], dst=[d]) return d elif isinstance(e, ir.Mem): # Load from memory @@ -171,9 +179,13 @@ def munchStm(self, s): if isinstance(s, ir.Terminator): pass - 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): + 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.b, ir.Const): + a = self.munchExpr(s.dst.e.a) val = self.munchExpr(s.src) - self.emit('str %s1, [%s0 + {}]'.format(s.dst.e.b.value), src=[s.dst.e.a, val]) + c = s.dst.e.b.value + self.emit('str %s1, [%s0 + {}]'.format(c), src=[a, val]) elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem): memloc = self.munchExpr(s.dst.e) val = self.munchExpr(s.src) @@ -185,7 +197,7 @@ elif isinstance(s, ir.Exp): # Generate expression code and discard the result. x = self.munchExpr(s.e) - self.emit('mov r0, r0', src=[x]) + self.emit('nop', src=[x]) elif isinstance(s, ir.Jump): tgt = self.targets[s.target] self.emit('b {}'.format(s.target.name), jumps=[tgt]) @@ -248,6 +260,10 @@ # another interface? assembler = asm.Assembler(target=arm.armtarget, stream=self.outs) self.outs.selectSection('code') + # assembly glue to make it work: + self.outs.emit(arm.dcd_ins(Imm32(0x20000678))) # initial SP + self.outs.emit(arm.dcd_ins(Imm32(0x08000009))) # reset vector + self.outs.emit(arm.b_ins(LabelRef('main'))) for frame in self.frames: for i in frame.instructions: assembler.assemble_line(str(i))