comparison python/ppci/target/arm/frame.py @ 346:3bb7dcfe5529

expanded arm target
author Windel Bouwman
date Fri, 07 Mar 2014 17:05:32 +0100
parents
children b8ad45b3a573
comparison
equal deleted inserted replaced
345:b4882ff0ed06 346:3bb7dcfe5529
1 from ... import ir
2 from ..basetarget import Label, Alignment
3 from ...irmach import AbstractInstruction, Frame
4 from .instructions import Dcd, Add, Sub, Push, Pop, Mov
5 from .registers import R0, R1, R2, R3, R4, R5, R6, R7, R8, R11, LR, PC, SP
6
7
8 class ArmFrame(Frame):
9 """ Arm specific frame for functions. """
10 def __init__(self, name):
11 # We use r7 as frame pointer.
12 super().__init__(name)
13 self.regs = [R0, R1, R2, R3, R4, R5, R6, R7, R8]
14 self.rv = ir.Temp('special_RV')
15 self.p1 = ir.Temp('special_P1')
16 self.p2 = ir.Temp('special_P2')
17 self.p3 = ir.Temp('special_P3')
18 self.p4 = ir.Temp('special_P4')
19 self.fp = ir.Temp('special_FP')
20 # Pre-colored registers:
21 self.tempMap = {}
22 self.tempMap[self.rv] = R0
23 self.tempMap[self.p1] = R1
24 self.tempMap[self.p2] = R2
25 self.tempMap[self.p3] = R3
26 self.tempMap[self.p4] = R4
27 self.tempMap[self.fp] = R11
28 self.locVars = {}
29 self.parMap = {}
30 # Literal pool:
31 self.constants = []
32
33 def argLoc(self, pos):
34 """
35 Gets the function parameter location in IR-code format.
36 """
37 if pos == 0:
38 return self.p1
39 elif pos == 1:
40 return self.p2
41 elif pos == 2:
42 return self.p3
43 elif pos == 3:
44 return self.p4
45 else:
46 raise NotImplementedError('No more than 4 parameters implemented')
47
48 def allocVar(self, lvar):
49 if lvar not in self.locVars:
50 self.locVars[lvar] = self.stacksize
51 self.stacksize = self.stacksize + 4
52 return self.locVars[lvar]
53
54 def addConstant(self, value):
55 lab_name = '{}_literal_{}'.format(self.name, len(self.constants))
56 self.constants.append((lab_name, value))
57 return lab_name
58
59 def prologue(self):
60 """ Returns prologue instruction sequence """
61 pre = [
62 Label(self.name), # Label indication function
63 Push({LR, R11})
64 ]
65 if self.stacksize > 0:
66 pre.append(Sub(SP, SP, self.stacksize)) # Reserve stack space
67 pre += [
68 Mov(R11, SP) # Setup frame pointer
69 ]
70 return pre
71
72 def epilogue(self):
73 """ Return epilogue sequence for a frame. Adjust frame pointer and add constant pool """
74 post = []
75 if self.stacksize > 0:
76 post.append(Add(SP, SP, self.stacksize))
77 post += [
78 Pop({PC, R11}),
79 Alignment(4) # Align at 4 bytes
80 ]
81 # Add constant literals:
82 for ln, v in self.constants:
83 post.extend([Label(ln), Dcd(v)])
84 return post
85
86 def EntryExitGlue3(self):
87 """
88 Add code for the prologue and the epilogue. Add a label, the
89 return instruction and the stack pointer adjustment for the frame.
90 """
91 for index, ins in enumerate(self.prologue()):
92 self.instructions.insert(index, AbstractInstruction(ins))
93
94 # Postfix code:
95 for ins in self.epilogue():
96 self.instructions.append(AbstractInstruction(ins))