Mercurial > lcfOS
diff python/codegenarm.py @ 276:56d37ed4b4d2
phaa
author | Windel Bouwman |
---|---|
date | Mon, 16 Sep 2013 21:51:17 +0200 |
parents | 6f2423df0675 |
children | 046017431c6a |
line wrap: on
line diff
--- a/python/codegenarm.py Sat Sep 14 17:29:10 2013 +0200 +++ b/python/codegenarm.py Mon Sep 16 21:51:17 2013 +0200 @@ -35,6 +35,8 @@ self.tempMap[self.fp] = 'r7' self.locVars = {} self.parMap = {} + # Literal pool: + self.constants = [] def argLoc(self, pos): """ @@ -57,6 +59,11 @@ self.stacksize = self.stacksize + 4 return self.locVars[lvar] + def addConstant(self, value): + lab_name = '{}_literal_{}'.format(self.name, len(self.constants)) + self.constants.append((lab_name, value)) + return lab_name + def EntryExitGlue3(self): """ Add code for the prologue and the epilogue. Add a label, the @@ -68,9 +75,14 @@ self.instructions.insert(3, makeIns('add sp, sp, {}'.format(self.stacksize))) self.instructions.append(makeIns('sub sp, sp, {}'.format(self.stacksize))) self.instructions.append(makeIns('pop {pc,r7}')) + # Add constant literals: + for ln, v in self.constants: + self.instructions.append(makeIns('{}:'.format(ln))) + self.instructions.append(makeIns('dcd {}'.format(v))) class ArmInstructionSelector(InstructionSelector): + """ Instruction selector for the arm architecture """ def munchExpr(self, e): if isinstance(e, ir.Alloc): @@ -101,24 +113,32 @@ a = self.munchExpr(e.a) b = self.munchExpr(e.b) d = self.newTmp() - self.emit('or %d0, %s0, %s1', dst=[d], src=[a, b]) + self.emit('mov %d0, %s0', src=[a], dst=[d]) + self.emit('orr %d0, %s0', dst=[d], 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('lsl %d0, %s0, %s1', dst=[d], src=[a, b]) + 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? 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('mul %d0, %s0, %s1', dst=[d], src=[a, b]) + self.emit('mov %d0, %s0', src=[a], dst=[d]) + self.emit('mul %d0, %s0', dst=[d], src=[b, d]) return d elif isinstance(e, ir.Const) and e.value < 256: d = self.newTmp() self.emit('mov %d0, {}'.format(e.value), dst=[d]) return d + elif isinstance(e, ir.Const) and e.value < (2**31): + d = self.newTmp() + ln = self.frame.addConstant(e.value) + self.emit('ldr %d0, {}'.format(ln), dst=[d]) + return d elif isinstance(e, ir.Mem) and isinstance(e.e, ir.Binop) and \ e.e.operation == '+' and isinstance(e.e.b, ir.Const): base = self.munchExpr(e.e.a) @@ -176,9 +196,9 @@ self.emit('cmp %s0, %s1', src=[a, b]) ntgt = self.targets[s.lab_no] ytgt = self.targets[s.lab_yes] - jmp_ins = makeIns('jmp {}'.format(s.lab_no.name), jumps=[ntgt]) + jmp_ins = makeIns('b {}'.format(s.lab_no.name), jumps=[ntgt]) # Explicitely add fallthrough: - self.emit('jeq %l0', jumps=[ytgt, jmp_ins]) + self.emit('beq {}'.format(s.lab_yes.name), jumps=[ytgt, jmp_ins]) self.emit2(jmp_ins) else: raise NotImplementedError('Stmt --> {}'.format(s)) @@ -266,5 +286,8 @@ for i in frame.instructions: assembler.assemble_line(str(i)) + # TODO: fixup references, do this in another way? + self.outs.backpatch() + self.outs.backpatch() return self.frames