Mercurial > lcfOS
diff python/codegenarm.py @ 219:1fa3e0050b49
Expanded ad hoc code generator
author | Windel Bouwman |
---|---|
date | Sat, 06 Jul 2013 12:38:09 +0200 |
parents | 494828a7adf1 |
children | c3f1ce8b638f |
line wrap: on
line diff
--- a/python/codegenarm.py Fri Jul 05 15:30:22 2013 +0200 +++ b/python/codegenarm.py Sat Jul 06 12:38:09 2013 +0200 @@ -4,7 +4,10 @@ from ppci import CompilerError class ArmCodeGenerator: - """ Simple code generator """ + """ + Simple code generator + Ad hoc implementation + """ def __init__(self, out): self.outs = out @@ -21,8 +24,14 @@ # TODO: use initial value: self.emit(arm.dcd_ins(0)) + self.imms = [] # list with immediates relative to PC. self.outs.selectSection('code') for f in ircode.Functions: + # Add global variable addresses to immediate list: + for gvar in ircode.Variables: + pass #self.imms.append(( + + self.stack_frame = [] self.emit(ALabel(f.name)) # Save some registers: self.emit(arm.push_ins(arm.RegisterSet({arm.r4, arm.r5, arm.r6,arm.r7,arm.lr}))) @@ -31,27 +40,67 @@ for ins in bb.Instructions: self.generateInstruction(ins) + self.outs.align(4) + while self.imms: + l, v = self.imms.pop() + self.emit(ALabel(l)) + self.emit(arm.dcd_ins(v)) + self.outs.align(4) + + def getStack(self, v): + off = self.stack_frame.index(v) + return off * 4 + def addStack(self, v): + self.stack_frame.append(v) + return self.getStack(v) + def getGlobal(self, r, g): + _global_address = g.name + '__global' + self.emit(arm.ldr_pcrel(r, ALabel(_global_address))) + def generateInstruction(self, ins): if type(ins) is ir.Branch: - self.emit(arm.jmp_ins(ins.target)) - elif type(ins) is ir.ImmLoad and ins.value < 255: - self.emit(arm.mov_ins(arm.r0, arm.Imm8(ins.value))) - # determine stack frame.. - self.emit(arm.mov_ins(arm.r1, arm.Imm8(9))) - #self.emit(arm. - elif type(ins) is ir.ImmLoad and ins.value < (2**32): - print(ins) + tgt = ALabel(ins.target.name) + self.emit(arm.jmp_ins(tgt)) + elif type(ins) is ir.ImmLoad: + lname = ins.target.name + '_ivalue' + self.emit(arm.ldr_pcrel(arm.r0, ALabel(lname))) + self.imms.append((lname, ins.value)) + self.emit(arm.str_sprel(arm.r0, self.addStack(ins.target))) elif type(ins) is ir.Store: - print(ins) - elif type(ins) is ir.Return: - self.emit(arm.pop_ins(arm.RegisterSet({arm.r5, arm.r6, arm.pc}))) + # Load value in r0: + self.emit(arm.ldr_sprel(arm.r0, self.getStack(ins.value))) + # store in memory: + self.getGlobal(arm.r1, ins.location) + self.emit(arm.storeimm5_ins(arm.r0, arm.MemoryOp(arm.r1, 0))) elif type(ins) is ir.Load: - print(ins) + self.getGlobal(arm.r0, ins.location) + self.emit(arm.loadimm5_ins(arm.r0, arm.MemoryOp(arm.r0, 0))) + # Store value on stack: + self.emit(arm.str_sprel(arm.r0, self.addStack(ins.value))) elif type(ins) is ir.BinaryOperator: - print(ins) + # Load operands: + self.emit(arm.ldr_sprel(arm.r0, self.getStack(ins.value1))) + self.emit(arm.ldr_sprel(arm.r1, self.getStack(ins.value2))) + # do operation: + if ins.operation == '+': + self.emit(arm.addregs_ins(arm.r0, arm.r0, arm.r1)) + else: + print('operation not implemented', ins.operation) + # Store value back: + self.emit(arm.str_sprel(arm.r0, self.addStack(ins.result))) + elif type(ins) is ir.Return: + self.emit(arm.pop_ins(arm.RegisterSet({arm.r4, arm.r5, arm.r6, arm.r7, arm.pc}))) elif type(ins) is ir.ConditionalBranch: - print(ins) + self.emit(arm.ldr_sprel(arm.r0, self.getStack(ins.a))) + self.emit(arm.ldr_sprel(arm.r1, self.getStack(ins.b))) self.emit(arm.cmp_ins(arm.r1, arm.r0)) + tgt_yes = ALabel(ins.lab1.name) + if ins.cond == '==': + self.emit(arm.beq_ins(tgt_yes)) + else: + print('TODO', ins.cond) + tgt_no = ALabel(ins.lab2.name) + self.emit(arm.jmp_ins(tgt_no)) else: raise CompilerError('IR "{}" not covered'.format(ins))