Mercurial > lcfOS
comparison python/ppci/target/arm/selector.py @ 346:3bb7dcfe5529
expanded arm target
author | Windel Bouwman |
---|---|
date | Fri, 07 Mar 2014 17:05:32 +0100 |
parents | |
children | 899ae3aea803 |
comparison
equal
deleted
inserted
replaced
345:b4882ff0ed06 | 346:3bb7dcfe5529 |
---|---|
1 from ... import ir, same_dir | |
2 from ppci.irmach import AbstractInstruction as makeIns | |
3 from ppci.ir2tree import makeTree | |
4 from .instructions import Str1, Mov2 | |
5 from .instructions import B, Bl, Blt, Bgt, Beq | |
6 import pyburg | |
7 from ..basetarget import Nop | |
8 from ..instructionselector import InstructionSelector | |
9 | |
10 # Import BURG spec for arm: | |
11 spec_file = same_dir(__file__, 'arm.brg') | |
12 arm_matcher = pyburg.load_as_module(spec_file) | |
13 | |
14 | |
15 class ArmMatcher(arm_matcher.Matcher): | |
16 """ Matcher that derives from a burg spec generated matcher """ | |
17 def __init__(self, selector): | |
18 super().__init__() | |
19 self.newTmp = selector.newTmp | |
20 self.emit = selector.emit | |
21 self.selector = selector | |
22 | |
23 | |
24 class ArmInstructionSelector(InstructionSelector): | |
25 """ Instruction selector for the arm architecture """ | |
26 def __init__(self): | |
27 super().__init__() | |
28 self.matcher = ArmMatcher(self) | |
29 | |
30 def munchExpr(self, e): | |
31 # Use BURG system here: | |
32 t = makeTree(e) | |
33 return self.matcher.gen(t) | |
34 | |
35 def munchCall(self, e): | |
36 """ Generate code for call sequence """ | |
37 # Move arguments into proper locations: | |
38 reguses = [] | |
39 for i, a in enumerate(e.arguments): | |
40 loc = self.frame.argLoc(i) | |
41 m = ir.Move(loc, a) | |
42 self.munchStm(m) | |
43 if isinstance(loc, ir.Temp): | |
44 reguses.append(loc) | |
45 self.emit(Bl(e.f), src=reguses, dst=[self.frame.rv]) | |
46 d = self.newTmp() | |
47 self.move(d, self.frame.rv) | |
48 return d | |
49 | |
50 def munchStm(self, s): | |
51 if isinstance(s, ir.Terminator): | |
52 pass | |
53 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \ | |
54 isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and \ | |
55 isinstance(s.dst.e.b, ir.Const): | |
56 a = self.munchExpr(s.dst.e.a) | |
57 val = self.munchExpr(s.src) | |
58 c = s.dst.e.b.value | |
59 self.emit(Str1, others=[c], src=[a, val]) | |
60 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem): | |
61 memloc = self.munchExpr(s.dst.e) | |
62 val = self.munchExpr(s.src) | |
63 self.emit(Str1, others=[0], src=[memloc, val]) | |
64 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp): | |
65 val = self.munchExpr(s.src) | |
66 dreg = s.dst | |
67 self.move(dreg, val) | |
68 elif isinstance(s, ir.Exp): | |
69 # Generate expression code and discard the result. | |
70 x = self.munchExpr(s.e) | |
71 self.emit(Nop(), src=[x]) | |
72 elif isinstance(s, ir.Jump): | |
73 tgt = self.targets[s.target] | |
74 self.emit(B(ir.label_name(s.target)), jumps=[tgt]) | |
75 elif isinstance(s, ir.CJump): | |
76 a = self.munchExpr(s.a) | |
77 b = self.munchExpr(s.b) | |
78 self.emit(Cmp, src=[a, b]) | |
79 ntgt = self.targets[s.lab_no] | |
80 ytgt = self.targets[s.lab_yes] | |
81 jmp_ins = makeIns(B(ir.label_name(s.lab_no)), jumps=[ntgt]) | |
82 opnames = {'<': Blt, '>':Bgt, '==':Beq, '!=':Bne} | |
83 op = opnames[s.cond](ir.label_name(s.lab_yes)) | |
84 self.emit(op, jumps=[ytgt, jmp_ins]) # Explicitely add fallthrough | |
85 self.emit2(jmp_ins) | |
86 else: | |
87 raise NotImplementedError('Stmt --> {}'.format(s)) | |
88 | |
89 def move(self, dst, src): | |
90 self.emit(Mov2, src=[src], dst=[dst], ismove=True) |