Mercurial > lcfOS
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)) |