Mercurial > lcfOS
comparison python/codegenarm.py @ 272:e64bae57cda8
refactor ir
author | Windel Bouwman |
---|---|
date | Sat, 31 Aug 2013 17:58:54 +0200 |
parents | cdc76d183bcc |
children | ea93e0a7a31e |
comparison
equal
deleted
inserted
replaced
271:cf7d5fb7d9c8 | 272:e64bae57cda8 |
---|---|
4 import cortexm3 as arm | 4 import cortexm3 as arm |
5 from ppci import CompilerError | 5 from ppci import CompilerError |
6 import flowgraph | 6 import flowgraph |
7 import registerallocator | 7 import registerallocator |
8 from instructionselector import InstructionSelector | 8 from instructionselector import InstructionSelector |
9 | 9 import irmach |
10 | 10 |
11 class ArmInstructionSelector(InstructionSelector): | 11 class ArmInstructionSelector(InstructionSelector): |
12 """ Instruction selector for the arm architecture """ | 12 """ Instruction selector for the arm architecture """ |
13 def munchExpr(self, e): | 13 def munchExpr(self, e): |
14 if isinstance(e, ir.Alloc): | 14 if isinstance(e, ir.Alloc): |
56 d = self.newTmp() | 56 d = self.newTmp() |
57 self.emit('ldr %d0, [%s0]', src=[loc], dst=[d]) | 57 self.emit('ldr %d0, [%s0]', src=[loc], dst=[d]) |
58 return d | 58 return d |
59 elif isinstance(e, ir.Temp): | 59 elif isinstance(e, ir.Temp): |
60 return self.getTempReg(e) | 60 return self.getTempReg(e) |
61 elif isinstance(e, ir.Call): | |
62 args = [self.munchExpr(a) for a in e.arguments] | |
63 self.emit('add sp, sp, 22') | |
64 # TODO: save frame | |
65 for a in args: | |
66 self.emit('push %s0', src=[a]) | |
67 self.emit('bl {}'.format(e.f.name)) | |
68 self.emit('sub sp, sp, 22') | |
61 else: | 69 else: |
62 raise NotImplementedError('--> {}'.format(e)) | 70 raise NotImplementedError('Expr --> {}'.format(e)) |
63 | 71 |
64 def munchStm(self, s): | 72 def munchStm(self, s): |
65 if isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem): | 73 if isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem): |
66 memloc = self.munchExpr(s.dst.e) | 74 memloc = self.munchExpr(s.dst.e) |
67 val = self.munchExpr(s.src) | 75 val = self.munchExpr(s.src) |
68 self.emit('str [%s0], %s1') | 76 self.emit('str [%s0], %s1') |
69 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp): | 77 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp): |
70 val = self.munchExpr(s.src) | 78 val = self.munchExpr(s.src) |
71 dreg = self.getTempReg(s.dst) | 79 dreg = self.getTempReg(s.dst) |
72 self.emit('mov %d0, %s0', dst=[dreg], src=[val]) | 80 self.emit('mov %d0, %s0', dst=[dreg], src=[val]) |
73 elif isinstance(s, ir.Return): | |
74 #etgt = self.targets[ | |
75 self.emit('jmp exit', jumps=[]) | |
76 elif isinstance(s, ir.Jump): | 81 elif isinstance(s, ir.Jump): |
77 tgt = self.targets[s.target] | 82 tgt = self.targets[s.target] |
78 self.emit('jmp {}'.format(s), jumps=[tgt]) | 83 self.emit('jmp {}'.format(s), jumps=[tgt]) |
79 elif isinstance(s, ir.CJump): | 84 elif isinstance(s, ir.CJump): |
80 a = self.munchExpr(s.a) | 85 a = self.munchExpr(s.a) |
100 self.outs.getSection('data').address = 0x20000000 | 105 self.outs.getSection('data').address = 0x20000000 |
101 | 106 |
102 def useUnused(self, inslist): | 107 def useUnused(self, inslist): |
103 # Use unused temporaries at the end of the list | 108 # Use unused temporaries at the end of the list |
104 defTemps = [] | 109 defTemps = [] |
105 for d in (i.dst for i in inslist): | 110 useTemps = [] |
106 print(d) | 111 for i in inslist: |
107 defTemps.append(d) | 112 for d in iter(i.dst): |
108 useTemps = [d for d in ([i.src] for i in inslist)] | 113 defTemps.append(d) |
109 print(defTemps) | 114 for s in iter(i.src): |
110 print(useTemps) | 115 useTemps.append(s) |
116 defTemps = set(defTemps) | |
117 useTemps = set(useTemps) | |
118 unUsed = defTemps - useTemps | |
119 #print('Unused:', unUsed) | |
120 for uu in unUsed: | |
121 inslist.append(irmach.AbstractInstruction('use %s0', src=[uu])) | |
122 #print(useTemps) | |
111 | 123 |
112 def generate(self, ircode, cfg_file=None, ig_file=None): | 124 def generate(self, ircode, cfg_file=None, ig_file=None): |
113 ir2 = self.ins_sel.munchProgram(ircode) | 125 ir2 = self.ins_sel.munchProgram(ircode) |
114 self.useUnused(ir2) | 126 self.useUnused(ir2) |
115 cfg = flowgraph.FlowGraph(ir2) | 127 cfg = flowgraph.FlowGraph(ir2) |
120 ig.to_dot(ig_file) | 132 ig.to_dot(ig_file) |
121 | 133 |
122 regs = ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7'] | 134 regs = ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7'] |
123 ra = registerallocator.RegisterAllocator() | 135 ra = registerallocator.RegisterAllocator() |
124 regMap = ra.registerAllocate(ig, regs) | 136 regMap = ra.registerAllocate(ig, regs) |
125 print(regMap) | 137 #print(regMap) |
138 # Use allocated registers: | |
126 for i in ir2: | 139 for i in ir2: |
127 i.src = tuple(regMap[t] for t in i.src) | 140 i.src = tuple(regMap[t] for t in i.src) |
128 i.dst = tuple(regMap[t] for t in i.dst) | 141 i.dst = tuple(regMap[t] for t in i.dst) |
129 print(i) | 142 #print(i) |
143 return ir2 | |
130 | 144 |
131 | 145 |
132 | 146 |