269
|
1
|
|
2 import ir
|
|
3 import irmach
|
|
4
|
|
5 def genTemps():
|
|
6 n = 900
|
|
7 while True:
|
|
8 yield 't{}'.format(n)
|
|
9 n = n + 1
|
|
10
|
|
11 class InstructionSelector:
|
|
12 """
|
|
13 Base instruction selector. This class must be overridden by
|
|
14 backends.
|
|
15 """
|
|
16 def newTmp(self):
|
|
17 return self.temps.__next__()
|
|
18
|
|
19 def getTempReg(self, tmp):
|
|
20 if tmp not in self.tempMap:
|
|
21 self.tempMap[tmp] = self.newTmp()
|
|
22 return self.tempMap[tmp]
|
|
23
|
|
24 def munchProgram(self, p):
|
|
25 # Entry point for instruction selection
|
|
26 self.temps = genTemps()
|
|
27 assert isinstance(p, ir.Module)
|
|
28 self.result = []
|
|
29 self.targets = {}
|
|
30 self.tempMap = {} # Mapping from temporaries to infinite register
|
|
31 for f in p.Functions:
|
|
32 # First define labels:
|
|
33 for bb in f.BasicBlocks:
|
|
34 itgt = self.makeIns('{}:'.format(bb.name))
|
|
35 self.targets[bb] = itgt
|
|
36 for bb in f.BasicBlocks:
|
|
37 self.emit2(self.targets[bb])
|
|
38 for i in bb.Instructions:
|
|
39 self.munchStm(i)
|
|
40 bb.machIns = self.result
|
|
41 return self.result
|
|
42
|
|
43 def makeIns(self, *args, **kwargs):
|
|
44 return irmach.AbstractInstruction(*args, **kwargs)
|
|
45
|
|
46 def emit(self, *args, **kwargs):
|
|
47 """ Abstract instruction emitter """
|
|
48 i = self.makeIns(*args, **kwargs)
|
|
49 return self.emit2(i)
|
|
50
|
|
51 def emit2(self, i):
|
|
52 self.result.append(i)
|
|
53 return i
|
|
54
|
|
55 def munchStm(self, s):
|
|
56 raise NotImplementedError()
|
|
57
|
|
58 def munchExpr(self, e):
|
|
59 raise NotImplementedError()
|
|
60
|