Mercurial > lcfOS
comparison python/target/arminstructionselector.py @ 323:e9fe6988497c
Used burg for generating expressions
author | Windel Bouwman |
---|---|
date | Thu, 30 Jan 2014 19:03:24 +0100 |
parents | 44f336460c2a |
children | d1ecc493384e |
comparison
equal
deleted
inserted
replaced
322:44f336460c2a | 323:e9fe6988497c |
---|---|
13 | 13 |
14 # Import BURG spec for arm: | 14 # Import BURG spec for arm: |
15 spec_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'arm.brg') | 15 spec_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'arm.brg') |
16 arm_matcher = pyburg.load_as_module(spec_file) | 16 arm_matcher = pyburg.load_as_module(spec_file) |
17 | 17 |
18 | |
18 class ArmMatcher(arm_matcher.Matcher): | 19 class ArmMatcher(arm_matcher.Matcher): |
19 def __init__(self): | 20 """ Matcher that derives from a burg spec generated matcher """ |
21 def __init__(self, selector): | |
20 super().__init__() | 22 super().__init__() |
21 | 23 self.newTmp = selector.newTmp |
22 def newTmp(self): | 24 self.emit = selector.emit |
23 pass | 25 self.selector = selector |
24 | |
25 def emit(self, *args, **kwargs): | |
26 pass | |
27 | 26 |
28 | 27 |
29 class ArmInstructionSelector(InstructionSelector): | 28 class ArmInstructionSelector(InstructionSelector): |
30 """ Instruction selector for the arm architecture """ | 29 """ Instruction selector for the arm architecture """ |
31 def __init__(self): | 30 def __init__(self): |
32 super().__init__() | 31 super().__init__() |
33 self.matcher = ArmMatcher() | 32 self.matcher = ArmMatcher(self) |
34 | 33 |
35 def munchExpr(self, e): | 34 def munchExpr(self, e): |
36 #t = makeTree(e) | 35 # Use BURG system here: |
37 #print(t) | 36 t = makeTree(e) |
38 #return self.matcher.gen(t) | 37 return self.matcher.gen(t) |
39 | 38 |
40 # TODO: below is obsolete: | 39 def munchCall(self, e): |
41 if isinstance(e, ir.Binop) and e.operation == '+' and \ | 40 """ Generate code for call sequence """ |
42 isinstance(e.b, ir.Const) and e.b.value < 8: | 41 # Move arguments into proper locations: |
43 a = self.munchExpr(e.a) | 42 reguses = [] |
44 d = self.newTmp() | 43 for i, a in enumerate(e.arguments): |
45 c = Imm3(e.b.value) | 44 loc = self.frame.argLoc(i) |
46 self.emit(Add2, others=[c], dst=[d], src=[a]) | 45 m = ir.Move(loc, a) |
47 return d | 46 self.munchStm(m) |
48 elif isinstance(e, ir.Binop) and e.operation == '+': | 47 if isinstance(loc, ir.Temp): |
49 a = self.munchExpr(e.a) | 48 reguses.append(loc) |
50 b = self.munchExpr(e.b) | 49 self.emit(Bl(LabelRef(e.f)), src=reguses, dst=[self.frame.rv]) |
51 d = self.newTmp() | 50 d = self.newTmp() |
52 self.emit(Add, dst=[d], src=[a, b]) | 51 self.move(d, self.frame.rv) |
53 return d | 52 return d |
54 elif isinstance(e, ir.Binop) and e.operation == '-' and \ | |
55 isinstance(e.b, ir.Const) and e.b.value < 8: | |
56 a = self.munchExpr(e.a) | |
57 d = self.newTmp() | |
58 c = Imm3(e.b.value) | |
59 self.emit(Sub2, others=[c], dst=[d], src=[a]) | |
60 return d | |
61 elif isinstance(e, ir.Binop) and e.operation == '-': | |
62 a = self.munchExpr(e.a) | |
63 b = self.munchExpr(e.b) | |
64 d = self.newTmp() | |
65 self.emit(Sub, dst=[d], src=[a, b]) | |
66 return d | |
67 elif isinstance(e, ir.Binop) and e.operation == '|': | |
68 a = self.munchExpr(e.a) | |
69 b = self.munchExpr(e.b) | |
70 d = self.newTmp() | |
71 self.move(d, a) | |
72 self.emit(Orr, dst=[], src=[d, b]) | |
73 return d | |
74 elif isinstance(e, ir.Binop) and e.operation == '<<': | |
75 a = self.munchExpr(e.a) | |
76 b = self.munchExpr(e.b) | |
77 d = self.newTmp() | |
78 self.move(d, a) | |
79 self.emit(Lsl, dst=[], src=[d, b]) # TODO: is d a source variable? | |
80 return d | |
81 elif isinstance(e, ir.Binop) and e.operation == '*': | |
82 a = self.munchExpr(e.a) | |
83 b = self.munchExpr(e.b) | |
84 d = self.newTmp() | |
85 self.move(d, a) | |
86 # this mul instruction has operands swapped: | |
87 self.emit(Mul, dst=[d], src=[b, d]) | |
88 return d | |
89 elif isinstance(e, ir.Const) and e.value < 256: | |
90 d = self.newTmp() | |
91 self.emit(Mov3, others=[Imm8(e.value)], dst=[d]) | |
92 return d | |
93 elif isinstance(e, ir.Const) and e.value < (2**31): | |
94 d = self.newTmp() | |
95 ln = LabelRef(self.frame.addConstant(e.value)) | |
96 self.emit(Ldr3, others=[ln], dst=[d]) | |
97 return d | |
98 elif isinstance(e, ir.Mem) and isinstance(e.e, ir.Binop) and \ | |
99 e.e.operation == '+' and isinstance(e.e.b, ir.Const): | |
100 base = self.munchExpr(e.e.a) | |
101 d = self.newTmp() | |
102 c = e.e.b.value | |
103 self.emit(Ldr2, others=[c], src=[base], dst=[d]) | |
104 return d | |
105 elif isinstance(e, ir.Mem): | |
106 # Load from memory | |
107 base = self.munchExpr(e.e) | |
108 d = self.newTmp() | |
109 self.emit(Ldr2, others=[0], src=[base], dst=[d]) | |
110 return d | |
111 elif isinstance(e, ir.Temp): | |
112 return e | |
113 elif isinstance(e, ir.Call): | |
114 # Move arguments into proper locations: | |
115 reguses = [] | |
116 for i, a in enumerate(e.arguments): | |
117 loc = self.frame.argLoc(i) | |
118 m = ir.Move(loc, a) | |
119 self.munchStm(m) | |
120 if isinstance(loc, ir.Temp): | |
121 reguses.append(loc) | |
122 self.emit(Bl(LabelRef(e.f)), src=reguses, dst=[self.frame.rv]) | |
123 d = self.newTmp() | |
124 self.move(d, self.frame.rv) | |
125 return d | |
126 else: | |
127 raise NotImplementedError('Expr --> {}'.format(e)) | |
128 | 53 |
129 def munchStm(self, s): | 54 def munchStm(self, s): |
130 if isinstance(s, ir.Terminator): | 55 if isinstance(s, ir.Terminator): |
131 pass | 56 pass |
132 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \ | 57 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \ |