211
|
1 import ir
|
|
2 from asmnodes import ALabel
|
|
3 import arm_cm3 as arm
|
|
4 from ppci import CompilerError
|
|
5
|
|
6 class ArmCodeGenerator:
|
|
7 """ Simple code generator """
|
|
8 def __init__(self, out):
|
|
9 self.outs = out
|
|
10
|
|
11 def emit(self, item):
|
|
12 self.outs.emit(item)
|
|
13
|
|
14 def generate(self, ircode):
|
|
15 assert isinstance(ircode, ir.Module)
|
|
16 print('ARM code generation')
|
|
17 self.outs.selectSection('data')
|
|
18
|
|
19 for gvar in ircode.Variables:
|
|
20 self.emit(ALabel(gvar.name))
|
|
21 # TODO: use initial value:
|
|
22 self.emit(arm.dcd_ins(0))
|
|
23
|
|
24 self.outs.selectSection('code')
|
|
25 for f in ircode.Functions:
|
|
26 self.emit(ALabel(f.name))
|
|
27 self.emit(arm.push_ins(arm.RegisterSet({arm.r2, arm.r3,arm.lr})))
|
|
28 for bb in f.BasicBlocks:
|
|
29 self.emit(ALabel(bb.name))
|
|
30 for ins in bb.Instructions:
|
|
31 self.generateInstruction(ins)
|
|
32
|
|
33 def generateInstruction(self, ins):
|
|
34 if type(ins) is ir.Branch:
|
|
35 self.emit(arm.jmp_ins(ins.target))
|
|
36 elif type(ins) is ir.ImmLoad and ins.value < 255:
|
|
37 self.emit(arm.mov_ins(arm.r0, arm.Imm8(ins.value)))
|
|
38 elif type(ins) is ir.Store:
|
|
39 print(ins)
|
|
40 elif type(ins) is ir.Return:
|
|
41 self.emit(arm.pop_ins(arm.RegisterSet({arm.r2, arm.r3, arm.pc})))
|
|
42 elif type(ins) is ir.Load:
|
|
43 print(ins)
|
|
44 elif type(ins) is ir.BinaryOperator:
|
|
45 print(ins)
|
|
46 else:
|
|
47 print(ins)
|
|
48 raise CompilerError('IR "{}" not covered'.format(ins))
|
|
49
|
|
50
|