annotate python/ppci/target/arm/instructions.py @ 346:3bb7dcfe5529

expanded arm target
author Windel Bouwman
date Fri, 07 Mar 2014 17:05:32 +0100
parents b4882ff0ed06
children 2b02bd286fe9
rev   line source
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
1
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
2 from ..basetarget import Instruction
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
3 from ...bitfun import rotate_left
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
4
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
5 from .token import ArmToken
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
6 from .registers import R0, SP, ArmRegister
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
7
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
8
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
9 def encode_imm32(v):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
10 """ Bundle 32 bit value into 4 bits rotation and 8 bits value
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
11 """
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
12 for i in range(0, 16):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
13 v2 = rotate_left(v, i*2)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
14 if (v2 & 0xFFFFFF00) == 0:
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
15 rotation = i
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
16 val = v2 & 0xFF
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
17 x = (rotation << 8) | val
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
18 return x
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
19 raise Exception("Invalid value {}".format(v))
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
20
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
21 # Instructions:
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
22
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
23 class ArmInstruction(Instruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
24 def __init__(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
25 self.token = ArmToken()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
26
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
27
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
28 class Dcd(ArmInstruction):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
29 def __init__(self, v):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
30 super().__init__()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
31 self.v = v
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
32
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
33 def encode(self):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
34 self.token[0:32] = self.v
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
35 return self.token.encode()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
36
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
37
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
38 def Mov(*args):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
39 if len(args) == 2:
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
40 if isinstance(args[1], int):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
41 return Mov1(*args)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
42 elif isinstance(args[1], ArmRegister):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
43 return Mov2(*args)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
44 raise Exception()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
45
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
46
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
47 class Mov1(ArmInstruction):
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
48 """ Mov Rd, imm16 """
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
49 def __init__(self, reg, imm):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
50 super().__init__()
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
51 assert type(imm) is int
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
52 self.reg = reg
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
53 self.imm = imm
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
54
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
55 def encode(self):
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
56 self.token[0:12] = encode_imm32(self.imm)
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
57 self.token.Rd = self.reg.num
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
58 self.token[16:20] = 0
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
59 self.token[20] = 0 # Set flags
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
60 self.token[21:28] = 0b0011101
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
61 self.token.cond = AL
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
62 return self.token.encode()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
63
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
64 def relocations(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
65 return []
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
66
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
67 def __repr__(self):
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
68 return 'Mov {}, {}'.format(self.reg, self.imm)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
69
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
70
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
71 class Mov2(ArmInstruction):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
72 def __init__(self, rd, rm):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
73 super().__init__()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
74 self.rd = rd
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
75 self.rm = rm
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
76
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
77 def encode(self):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
78 self.token[0:4] = self.rm.num
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
79 self.token[4:12] = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
80 self.token[12:16] = self.rd.num
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
81 self.token[16:20] = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
82 self.token.S = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
83 self.token[21:28] = 0xD
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
84 self.token.cond = AL
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
85 return self.token.encode()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
86
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
87
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
88 def Add(*args):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
89 if len(args) == 3 and isinstance(args[0], ArmRegister) and \
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
90 isinstance(args[1], ArmRegister):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
91 if isinstance(args[2], ArmRegister):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
92 return Add1(args[0], args[1], args[2])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
93 elif isinstance(args[2], int):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
94 return Add2(args[0], args[1], args[2])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
95 raise Exception()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
96
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
97 def Sub(*args):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
98 if len(args) == 3 and isinstance(args[0], ArmRegister) and \
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
99 isinstance(args[1], ArmRegister):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
100 if isinstance(args[2], ArmRegister):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
101 return Sub1(args[0], args[1], args[2])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
102 elif isinstance(args[2], int):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
103 return Sub2(args[0], args[1], args[2])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
104 raise Exception()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
105
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
106 def Mul(*args):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
107 return Mul1(args[0], args[1], args[2])
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
108
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
109
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
110 class Mul(ArmInstruction):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
111 def __init__(self, rd, rn, rm):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
112 super().__init__()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
113 self.rd = rd
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
114 self.rn = rn
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
115 self.rm = rm
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
116
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
117 def encode(self):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
118 self.token[0:4] = self.rn.num
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
119 self.token[4:8] = 0b1001
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
120 self.token[8:12] = self.rm.num
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
121 self.token[16:20] = self.rd.num
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
122 self.token.S = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
123 self.token.cond = AL
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
124 return self.token.encode()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
125
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
126
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
127 class OpRegRegReg(ArmInstruction):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
128 """ add rd, rn, rm """
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
129 def __init__(self, rd, rn, rm, shift=0):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
130 super().__init__()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
131 self.rd = rd
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
132 self.rn = rn
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
133 self.rm = rm
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
134
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
135 def encode(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
136 self.token[0:4] = self.rm.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
137 self.token[4] = 0
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
138 self.token[5:7] = 0
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
139 self.token[7:12] = 0 # Shift
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
140 self.token.Rd = self.rd.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
141 self.token.Rn = self.rn.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
142 self.token.S = 0 # Set flags
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
143 self.token[21:28] = self.opcode
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
144 self.token.cond = 0xE # Always!
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
145 return self.token.encode()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
146
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
147 def __repr__(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
148 return 'add {}, {}, {}'.format(self.rd, self.rn, self.rm)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
149
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
150
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
151 class Add1(OpRegRegReg):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
152 opcode = 0b0000100
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
153
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
154
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
155 class Sub1(OpRegRegReg):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
156 opcode = 0b0000010
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
157
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
158
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
159 class Orr1(OpRegRegReg):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
160 opcode = 0b0001100
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
161
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
162
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
163 class OpRegRegImm(ArmInstruction):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
164 """ add rd, rn, imm12 """
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
165 def __init__(self, rd, rn, imm):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
166 super().__init__()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
167 self.rd = rd
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
168 self.rn = rn
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
169 self.imm2 = encode_imm32(imm)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
170 self.imm = imm
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
171
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
172 def encode(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
173 self.token[0:12] = self.imm2
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
174 self.token.Rd = self.rd.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
175 self.token.Rn = self.rn.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
176 self.token.S = 0 # Set flags
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
177 self.token[21:28] = self.opcode
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
178 self.token.cond = 0xE # Always!
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
179 return self.token.encode()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
180
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
181 def __repr__(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
182 return 'add {}, {}, {}'.format(self.rd, self.rn, self.imm)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
183
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
184
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
185 class Add2(OpRegRegImm):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
186 opcode = 0b0010100
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
187
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
188
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
189 class Sub2(OpRegRegImm):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
190 opcode = 0b0010010
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
191
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
192
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
193
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
194 # Branches:
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
195
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
196 class BranchBaseRoot(ArmInstruction):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
197 def __init__(self, target):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
198 super().__init__()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
199 self.target = target
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
200
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
201 def encode(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
202 self.token.cond = self.cond
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
203 self.token[24:28] = self.opcode
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
204 return self.token.encode()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
205
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
206 def relocations(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
207 return [(self.target, 'b_imm24')]
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
208
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
209
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
210 EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL = range(15)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
211
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
212 class BranchBase(BranchBaseRoot):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
213 opcode = 0b1010
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
214
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
215 class BranchLinkBase(BranchBaseRoot):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
216 opcode = 0b1011
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
217
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
218 class Bl(BranchLinkBase):
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
219 cond = AL
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
220
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
221 class B(BranchBase):
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
222 cond = AL
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
223
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
224 class Beq(BranchBase):
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
225 cond = EQ
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
226
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
227 class Bgt(BranchBase):
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
228 cond = GT
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
229
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
230 class Ble(BranchBase):
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
231 cond = LE
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
232
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
233 class Blt(BranchBase):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
234 cond = LT
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
235
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
236
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
237 # Memory:
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
238
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
239 def reg_list_to_mask(reg_list):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
240 mask = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
241 for reg in reg_list:
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
242 mask |= (1 << reg.num)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
243 return mask
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
244
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
245
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
246 class Push(ArmInstruction):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
247 def __init__(self, register_set):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
248 super().__init__()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
249 self.reg_list = register_set
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
250
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
251 def encode(self):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
252 self.token.cond = AL
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
253 self.token[16:28] = 0b100100101101
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
254 reg_list = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
255 self.token[0:16] = reg_list_to_mask(self.reg_list)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
256 return self.token.encode()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
257
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
258 class Pop(ArmInstruction):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
259 def __init__(self, register_set):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
260 super().__init__()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
261 self.reg_list = register_set
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
262
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
263 def encode(self):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
264 self.token.cond = AL
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
265 self.token[16:28] = 0b100010111101
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
266 self.token[0:16] = reg_list_to_mask(self.reg_list)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
267 return self.token.encode()
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
268
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
269
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
270 def Ldr(*args):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
271 if len(args) == 3 and isinstance(args[1], ArmRegister):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
272 return Ldr1(*args)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
273 elif len(args) == 2 and isinstance(args[1], ArmRegister):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
274 return Ldr1(args[0], args[1], 0)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
275 raise Exception()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
276
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
277 def Str(*args):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
278 if len(args) == 3 and isinstance(args[1], ArmRegister):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
279 return Str1(*args)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
280 elif len(args) == 2 and isinstance(args[1], ArmRegister):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
281 return Str1(args[0], args[1], 0)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
282 raise Exception()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
283
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
284
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
285 class LdrStrBase(ArmInstruction):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
286 def __init__(self, rt, rn, offset):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
287 super().__init__()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
288 self.rt = rt
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
289 self.rn = rn
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
290 self.offset = offset
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
291
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
292 def encode(self):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
293 self.token.cond = AL
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
294 self.token.Rn = self.rn.num
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
295 self.token[25:28] = self.opcode
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
296 self.token[20] = self.bit20
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
297 self.token[12:16] = self.rt.num
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
298 self.token[24] = 1 # Index
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
299 if self.offset >= 0:
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
300 self.token[23] = 1 # U == 1 'add'
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
301 self.token[0:12] = self.offset
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
302 else:
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
303 self.token[23] = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
304 self.token[0:12] = -self.offset
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
305 return self.token.encode()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
306
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
307
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
308 class Str1(LdrStrBase):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
309 opcode = 0b010
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
310 bit20 = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
311
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
312
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
313 class Ldr1(LdrStrBase):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
314 opcode = 0b010
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
315 bit20 = 1
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
316
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
317
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
318 class Ldr3(ArmInstruction):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
319 """ Load PC relative constant value """
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
320 def __init__(self, rt, label):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
321 self.rt = rt
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
322 self.label = label
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
323