annotate python/ppci/target/arm/frame.py @ 365:98ff43cfdd36

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