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 \