annotate python/codegenarm.py @ 280:02385f62f250

Rework from str interface to Instruction interface
author Windel Bouwman
date Sat, 02 Nov 2013 10:03:26 +0100
parents 2ccd57b1d78c
children
rev   line source
255
7416c923a02a Added more logging
Windel Bouwman
parents: 250
diff changeset
1 import logging
211
99164160fb0b Added another missing file
Windel Bouwman
parents:
diff changeset
2 import ir
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
3 from target import Label, Comment, Alignment, LabelRef, Imm32, DebugInfo, Nop
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
4 from target import Imm3
218
494828a7adf1 added some sort of cache to assembler
Windel Bouwman
parents: 212
diff changeset
5 import cortexm3 as arm
211
99164160fb0b Added another missing file
Windel Bouwman
parents:
diff changeset
6 from ppci import CompilerError
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
7 import registerallocator
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
8 from instructionselector import InstructionSelector
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
9 import irmach
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
10 from irmach import AbstractInstruction as makeIns
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
11 import canon
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
12 import transform
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
13 import asm
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
14
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
15 class ArmFrame(irmach.Frame):
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
16 """
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
17 Arm specific frame for functions.
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
18 """
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
19 def __init__(self, name):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
20 # We use r7 as frame pointer.
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
21 super().__init__(name)
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
22 self.regs = [arm.r0, arm.r1, arm.r2, arm.r3, arm.r4, arm.r5, arm.r6]
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
23 self.rv = ir.Temp('special_RV')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
24 self.p1 = ir.Temp('special_P1')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
25 self.p2 = ir.Temp('special_P2')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
26 self.p3 = ir.Temp('special_P3')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
27 self.p4 = ir.Temp('special_P4')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
28 self.fp = ir.Temp('special_FP')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
29 # Pre-colored registers:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
30 self.tempMap = {}
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
31 self.tempMap[self.rv] = arm.r0
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
32 self.tempMap[self.p1] = arm.r1
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
33 self.tempMap[self.p2] = arm.r2
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
34 self.tempMap[self.p3] = arm.r3
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
35 self.tempMap[self.p4] = arm.r4
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
36 self.tempMap[self.fp] = arm.r7
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
37 self.locVars = {}
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
38 self.parMap = {}
276
Windel Bouwman
parents: 275
diff changeset
39 # Literal pool:
Windel Bouwman
parents: 275
diff changeset
40 self.constants = []
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
41
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
42 def argLoc(self, pos):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
43 """
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
44 Gets the function parameter location in IR-code format.
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
45 """
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
46 if pos == 0:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
47 return self.p1
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
48 elif pos == 1:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
49 return self.p2
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
50 elif pos == 2:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
51 return self.p3
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
52 elif pos == 3:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
53 return self.p4
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
54 else:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
55 raise NotImplementedError('No more than 4 parameters implemented')
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
56
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
57 def allocVar(self, lvar):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
58 if lvar not in self.locVars:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
59 self.locVars[lvar] = self.stacksize
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
60 self.stacksize = self.stacksize + 4
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
61 return self.locVars[lvar]
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
62
276
Windel Bouwman
parents: 275
diff changeset
63 def addConstant(self, value):
Windel Bouwman
parents: 275
diff changeset
64 lab_name = '{}_literal_{}'.format(self.name, len(self.constants))
Windel Bouwman
parents: 275
diff changeset
65 self.constants.append((lab_name, value))
Windel Bouwman
parents: 275
diff changeset
66 return lab_name
Windel Bouwman
parents: 275
diff changeset
67
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
68 def EntryExitGlue3(self):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
69 """
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
70 Add code for the prologue and the epilogue. Add a label, the
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
71 return instruction and the stack pointer adjustment for the frame.
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
72 """
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
73 self.instructions.insert(0, makeIns(arm.Label(self.name)))
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
74 self.instructions.insert(1, makeIns(arm.push_ins(arm.RegisterSet({arm.lr, arm.r7}))))
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
75 # Reserve stack space for locals:
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
76 self.instructions.insert(2, makeIns(arm.subspsp_ins(arm.sp, arm.sp, arm.Imm7(self.stacksize))))
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
77 # Setup frame pointer:
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
78 self.instructions.insert(3, makeIns(arm.movregreg_ext_ins(arm.r7, arm.sp)))
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
79 # Stack grows downwards
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
80 self.instructions.append(makeIns(arm.addspsp_ins(arm.sp, arm.sp, arm.Imm7(self.stacksize))))
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
81 self.instructions.append(makeIns(arm.pop_ins(arm.RegisterSet({arm.pc, arm.r7}))))
276
Windel Bouwman
parents: 275
diff changeset
82 # Add constant literals:
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
83 self.instructions.append(makeIns(Alignment(4))) # Align at 4 bytes
276
Windel Bouwman
parents: 275
diff changeset
84 for ln, v in self.constants:
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
85 self.instructions.append(makeIns(arm.Label(ln)))
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
86 self.instructions.append(makeIns(arm.dcd_ins(v)))
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
87
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
88
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
89 class ArmInstructionSelector(InstructionSelector):
276
Windel Bouwman
parents: 275
diff changeset
90
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
91 """ Instruction selector for the arm architecture """
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
92 def munchExpr(self, e):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
93 if isinstance(e, ir.Alloc):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
94 return 0
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
95 elif isinstance(e, ir.Binop) and e.operation == '+' and \
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
96 isinstance(e.b, ir.Const) and e.b.value < 8:
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
97 a = self.munchExpr(e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
98 d = self.newTmp()
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
99 c = Imm3(e.b.value)
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
100 self.emit(arm.addregregimm3_ins, others=[c], dst=[d], src=[a])
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
101 return d
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
102 elif isinstance(e, ir.Binop) and e.operation == '+':
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
103 a = self.munchExpr(e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
104 b = self.munchExpr(e.b)
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
105 d = self.newTmp()
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
106 self.emit(arm.addregs_ins, dst=[d], src=[a, b])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
107 return d
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
108 elif isinstance(e, ir.Binop) and e.operation == '-' and \
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
109 isinstance(e.b, ir.Const) and e.b.value < 8:
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
110 a = self.munchExpr(e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
111 d = self.newTmp()
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
112 c = Imm3(e.b.value)
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
113 self.emit(arm.subregregimm3_ins, others=[c], dst=[d], src=[a])
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
114 return d
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
115 elif isinstance(e, ir.Binop) and e.operation == '-':
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
116 a = self.munchExpr(e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
117 b = self.munchExpr(e.b)
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
118 d = self.newTmp()
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
119 self.emit(arm.subregs_ins, dst=[d], src=[a, b])
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
120 return d
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
121 elif isinstance(e, ir.Binop) and e.operation == '|':
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
122 a = self.munchExpr(e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
123 b = self.munchExpr(e.b)
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
124 d = self.newTmp()
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
125 self.move(d, a)
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
126 self.emit(arm.orrregs_ins, dst=[], src=[b, d])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
127 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
128 elif isinstance(e, ir.Binop) and e.operation == '<<':
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
129 a = self.munchExpr(e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
130 b = self.munchExpr(e.b)
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
131 d = self.newTmp()
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
132 self.move(d, a)
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
133 self.emit(arm.lslregs_ins, dst=[], src=[b, d]) # TODO: is d a source variable?
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
134 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
135 elif isinstance(e, ir.Binop) and e.operation == '*':
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
136 a = self.munchExpr(e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
137 b = self.munchExpr(e.b)
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
138 d = self.newTmp()
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
139 self.move(d, a)
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
140 # this mul instruction has operands swapped:
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
141 self.emit(arm.mulregreg_ins, dst=[d], src=[b, d])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
142 return d
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
143 elif isinstance(e, ir.Const) and e.value < 256:
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
144 d = self.newTmp()
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
145 self.emit(arm.mov_imm8_ins, others=[arm.Imm8(e.value)], dst=[d])
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
146 return d
276
Windel Bouwman
parents: 275
diff changeset
147 elif isinstance(e, ir.Const) and e.value < (2**31):
Windel Bouwman
parents: 275
diff changeset
148 d = self.newTmp()
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
149 ln = LabelRef(self.frame.addConstant(e.value))
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
150 self.emit(arm.ldr_pcrel, others=[ln], dst=[d])
276
Windel Bouwman
parents: 275
diff changeset
151 return d
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
152 elif isinstance(e, ir.Mem) and isinstance(e.e, ir.Binop) and \
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
153 e.e.operation == '+' and isinstance(e.e.b, ir.Const):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
154 base = self.munchExpr(e.e.a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
155 d = self.newTmp()
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
156 c = e.e.b.value
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
157 self.emit(arm.loadimm5_ins, others=[c], src=[base], dst=[d])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
158 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
159 elif isinstance(e, ir.Mem):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
160 # Load from memory
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
161 base = self.munchExpr(e.e)
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
162 d = self.newTmp()
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
163 self.emit(arm.loadimm5_ins, others=[0], src=[base], dst=[d])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
164 return d
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
165 elif isinstance(e, ir.Temp):
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
166 return e
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
167 elif isinstance(e, ir.Call):
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
168 # Move arguments into proper locations:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
169 reguses = []
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
170 for i, a in enumerate(e.arguments):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
171 loc = self.frame.argLoc(i)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
172 m = ir.Move(loc, a)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
173 self.munchStm(m)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
174 if isinstance(loc, ir.Temp):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
175 reguses.append(loc)
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
176 self.emit(arm.bl_ins(LabelRef(e.f.name)), src=reguses, dst=[self.frame.rv])
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
177 d = self.newTmp()
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
178 self.move(d, self.frame.rv)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
179 return d
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
180 else:
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 270
diff changeset
181 raise NotImplementedError('Expr --> {}'.format(e))
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
182
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
183 def munchStm(self, s):
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
184 if isinstance(s, ir.Terminator):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
185 pass
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
186 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
187 isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and \
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
188 isinstance(s.dst.e.b, ir.Const):
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
189 a = self.munchExpr(s.dst.e.a)
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
190 val = self.munchExpr(s.src)
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
191 c = s.dst.e.b.value
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
192 self.emit(arm.storeimm5_ins, others=[c], src=[a, val])
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
193 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem):
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
194 memloc = self.munchExpr(s.dst.e)
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
195 val = self.munchExpr(s.src)
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
196 self.emit(arm.storeimm5_ins, others=[0], src=[memloc, val])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
197 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp):
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
198 val = self.munchExpr(s.src)
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
199 dreg = s.dst
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
200 self.move(dreg, val)
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
201 elif isinstance(s, ir.Exp):
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
202 # Generate expression code and discard the result.
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
203 x = self.munchExpr(s.e)
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
204 self.emit(Nop(), src=[x])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
205 elif isinstance(s, ir.Jump):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
206 tgt = self.targets[s.target]
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
207 self.emit(arm.b_ins(LabelRef(s.target.name)), jumps=[tgt])
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
208 elif isinstance(s, ir.CJump):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
209 a = self.munchExpr(s.a)
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
210 b = self.munchExpr(s.b)
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
211 self.emit(arm.cmp_ins, src=[a, b])
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
212 ntgt = self.targets[s.lab_no]
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
213 ytgt = self.targets[s.lab_yes]
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
214 jmp_ins = makeIns(arm.b_ins(LabelRef(s.lab_no.name)), jumps=[ntgt])
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
215 opnames = {'<': arm.blt_ins, '>':arm.bgt_ins, '==':arm.beq_ins}
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
216 op = opnames[s.cond](LabelRef(s.lab_yes.name))
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
217 self.emit(op, jumps=[ytgt, jmp_ins]) # Explicitely add fallthrough
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
218 self.emit2(jmp_ins)
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
219 else:
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
220 raise NotImplementedError('Stmt --> {}'.format(s))
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
221
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
222 def move(self, dst, src):
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
223 self.emit(arm.movregreg_ext_ins, src=[src], dst=[dst])
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
224
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
225
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
226 # TODO: this class could be target independent:
211
99164160fb0b Added another missing file
Windel Bouwman
parents:
diff changeset
227 class ArmCodeGenerator:
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
228 def __init__(self, outs):
269
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
229 # TODO: schedule traces in better order.
5f8c04a8d26b Towards better modularity
Windel Bouwman
parents: 268
diff changeset
230 # This is optional!
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
231 self.ins_sel = ArmInstructionSelector()
277
046017431c6a Started register allocator
Windel Bouwman
parents: 276
diff changeset
232 self.ra = registerallocator.RegisterAllocator()
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
233 self.outs = outs
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
234 self.outs.getSection('code').address = 0x08000000
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
235 self.outs.getSection('data').address = 0x20000000
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
236
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
237 def generateFunc(self, irfunc):
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
238 """ Generate code for one function into a frame """
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
239 # Cleanup function:
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
240 transform.removeEmptyBlocks(irfunc)
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
241
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
242 # Create a frame for this function:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
243 frame = ArmFrame(irfunc.name)
277
046017431c6a Started register allocator
Windel Bouwman
parents: 276
diff changeset
244
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
245 # Canonicalize the intermediate language:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
246 canon.make(irfunc, frame)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
247 self.ins_sel.munchFunction(irfunc, frame)
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
248
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
249 # Do register allocation:
277
046017431c6a Started register allocator
Windel Bouwman
parents: 276
diff changeset
250 self.ra.allocFrame(frame)
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
251 # TODO: Peep-hole here?
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
252
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
253 # Can we materialize here??
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
254
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
255 # Add label and return and stack adjustment:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
256 frame.EntryExitGlue3()
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
257
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
258 # Materialize assembly
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
259 # Materialize the register allocated instructions into a stream of
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
260 # real instructions.
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
261 frame.lower_to(self.outs)
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
262 return frame
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
263
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
264 def generate(self, ircode):
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
265 self.outs.selectSection('code')
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
266 # assembly glue to make it work:
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
267 # TODO: this must be in source code, not in compiler
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
268 self.outs.emit(arm.dcd_ins(Imm32(0x20000678))) # initial SP
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
269 self.outs.emit(arm.dcd_ins(Imm32(0x08000009))) # reset vector
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
270 self.outs.emit(arm.b_ins(LabelRef('main')))
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
271
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
272 # Munch program into a bunch of frames. One frame per function.
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
273 # Each frame has a flat list of abstract instructions.
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
274 # Generate code for all functions:
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
275 self.frames = [self.generateFunc(func) for func in ircode.Functions]
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 272
diff changeset
276
276
Windel Bouwman
parents: 275
diff changeset
277 # TODO: fixup references, do this in another way?
Windel Bouwman
parents: 275
diff changeset
278 self.outs.backpatch()
Windel Bouwman
parents: 275
diff changeset
279 self.outs.backpatch()
275
6f2423df0675 Fixed serve arm-as
Windel Bouwman
parents: 274
diff changeset
280 return self.frames
268
5ec7580976d9 Op naar tree-IR
Windel Bouwman
parents: 262
diff changeset
281