Mercurial > lcfOS
annotate python/target/arminstructionselector.py @ 336:d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
author | Windel Bouwman |
---|---|
date | Wed, 19 Feb 2014 22:32:15 +0100 |
parents | e9fe6988497c |
children | 4d204f6f7d4e |
rev | line source |
---|---|
322 | 1 import os |
336
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
323
diff
changeset
|
2 from ppci import ir, same_dir |
301 | 3 from ppci.irmach import AbstractInstruction as makeIns |
322 | 4 from ppci.ir2tree import makeTree |
5 import pyburg | |
292 | 6 from .basetarget import Label, Comment, Alignment, LabelRef, DebugInfo, Nop |
7 from .instructionselector import InstructionSelector | |
305 | 8 from .arminstructions import Orr, Lsl, Str2, Ldr2, Ldr3 |
9 from .arminstructions import B, Bl, Bgt, Blt, Beq, Bne | |
292 | 10 from .arminstructions import Mov2, Mov3 |
300 | 11 from .arminstructions import Add, Sub, Cmp, Sub2, Add2, Mul |
292 | 12 from .basetarget import Imm8, Imm7, Imm3 |
13 | |
322 | 14 # Import BURG spec for arm: |
336
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
323
diff
changeset
|
15 spec_file = same_dir(__file__, 'arm.brg') |
322 | 16 arm_matcher = pyburg.load_as_module(spec_file) |
17 | |
323 | 18 |
322 | 19 class ArmMatcher(arm_matcher.Matcher): |
323 | 20 """ Matcher that derives from a burg spec generated matcher """ |
21 def __init__(self, selector): | |
322 | 22 super().__init__() |
323 | 23 self.newTmp = selector.newTmp |
24 self.emit = selector.emit | |
25 self.selector = selector | |
322 | 26 |
292 | 27 |
28 class ArmInstructionSelector(InstructionSelector): | |
29 """ Instruction selector for the arm architecture """ | |
322 | 30 def __init__(self): |
31 super().__init__() | |
323 | 32 self.matcher = ArmMatcher(self) |
322 | 33 |
292 | 34 def munchExpr(self, e): |
323 | 35 # Use BURG system here: |
36 t = makeTree(e) | |
37 return self.matcher.gen(t) | |
322 | 38 |
323 | 39 def munchCall(self, e): |
40 """ Generate code for call sequence """ | |
41 # Move arguments into proper locations: | |
42 reguses = [] | |
43 for i, a in enumerate(e.arguments): | |
44 loc = self.frame.argLoc(i) | |
45 m = ir.Move(loc, a) | |
46 self.munchStm(m) | |
47 if isinstance(loc, ir.Temp): | |
48 reguses.append(loc) | |
49 self.emit(Bl(LabelRef(e.f)), src=reguses, dst=[self.frame.rv]) | |
50 d = self.newTmp() | |
51 self.move(d, self.frame.rv) | |
52 return d | |
292 | 53 |
54 def munchStm(self, s): | |
55 if isinstance(s, ir.Terminator): | |
56 pass | |
57 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \ | |
58 isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and \ | |
59 isinstance(s.dst.e.b, ir.Const): | |
60 a = self.munchExpr(s.dst.e.a) | |
61 val = self.munchExpr(s.src) | |
62 c = s.dst.e.b.value | |
63 self.emit(Str2, others=[c], src=[a, val]) | |
64 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem): | |
65 memloc = self.munchExpr(s.dst.e) | |
66 val = self.munchExpr(s.src) | |
67 self.emit(Str2, others=[0], src=[memloc, val]) | |
68 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp): | |
69 val = self.munchExpr(s.src) | |
70 dreg = s.dst | |
71 self.move(dreg, val) | |
72 elif isinstance(s, ir.Exp): | |
73 # Generate expression code and discard the result. | |
74 x = self.munchExpr(s.e) | |
75 self.emit(Nop(), src=[x]) | |
76 elif isinstance(s, ir.Jump): | |
77 tgt = self.targets[s.target] | |
336
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
323
diff
changeset
|
78 self.emit(B(LabelRef(ir.label_name(s.target))), jumps=[tgt]) |
292 | 79 elif isinstance(s, ir.CJump): |
80 a = self.munchExpr(s.a) | |
81 b = self.munchExpr(s.b) | |
82 self.emit(Cmp, src=[a, b]) | |
83 ntgt = self.targets[s.lab_no] | |
84 ytgt = self.targets[s.lab_yes] | |
336
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
323
diff
changeset
|
85 jmp_ins = makeIns(B(LabelRef(ir.label_name(s.lab_no))), jumps=[ntgt]) |
305 | 86 opnames = {'<': Blt, '>':Bgt, '==':Beq, '!=':Bne} |
336
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
323
diff
changeset
|
87 op = opnames[s.cond](LabelRef(ir.label_name(s.lab_yes))) |
292 | 88 self.emit(op, jumps=[ytgt, jmp_ins]) # Explicitely add fallthrough |
89 self.emit2(jmp_ins) | |
90 else: | |
91 raise NotImplementedError('Stmt --> {}'.format(s)) | |
92 | |
93 def move(self, dst, src): | |
318 | 94 self.emit(Mov2, src=[src], dst=[dst], ismove=True) |