comparison python/target/arminstructions.py @ 341:4d204f6f7d4e devel

Rewrite of assembler parts
author Windel Bouwman
date Fri, 28 Feb 2014 18:07:14 +0100
parents c7cc54c0dfdf
children
comparison
equal deleted inserted replaced
340:c7cc54c0dfdf 341:4d204f6f7d4e
1 import struct 1 import struct
2 from ppci.asmnodes import ASymbol, AInstruction, ANumber, AUnop, ABinop 2 from ppci.asmnodes import ASymbol, AInstruction, ANumber, AUnop, ABinop
3 from .basetarget import Register, Instruction, Target, Label, LabelRef 3 from .basetarget import Register, Instruction, Target, Label, LabelRef
4 from .basetarget import Imm32, Imm8, Imm7, Imm3 4 from .basetarget import Imm32, Imm8, Imm7, Imm3
5 5
6 from .armtokens import ThumbToken, ArmToken 6 from .armtoken import ThumbToken, ArmToken
7 from .armregisters import R0 7 from .armregisters import R0, ArmRegister, SP
8 8
9 def add_rule(rhs, f): 9
10 pass
11 10
12 def u16(h): 11 def u16(h):
13 return struct.pack('<H', h) 12 return struct.pack('<H', h)
14 13
15 def u32(x): 14 def u32(x):
16 return struct.pack('<I', x) 15 return struct.pack('<I', x)
17 16
18 17
19 thumb_assembly_rules = []
20 arm_assembly_rules = [] 18 arm_assembly_rules = []
21 19
22 20
23 # Operands: 21 # Operands:
24 22
53 return y.number 51 return y.number
54 elif type(y) is ASymbol and type(x) is ANumber and y.name.upper() == regname: 52 elif type(y) is ASymbol and type(x) is ANumber and y.name.upper() == regname:
55 return x.number 53 return x.number
56 54
57 55
58 class MemRegXRel:
59 def __init__(self, offset):
60 assert offset % 4 == 0
61 self.offset = offset
62
63 def __repr__(self):
64 return '[{}, #{}]'.format(self.regname, self.offset)
65
66 @classmethod
67 def Create(cls, vop):
68 if type(vop) is AUnop and vop.operation == '[]' and type(vop.arg) is ABinop and vop.arg.op == '+':
69 vop = vop.arg # descent
70 offset = isRegOffset(cls.regname, vop.arg1, vop.arg2)
71 if type(offset) is int:
72 if offset % 4 == 0:
73 offset = vop.arg2.number
74 return cls(offset)
75 elif type(vop) is ASymbol and vop.name.upper() == self.regname:
76 return cls(0)
77
78
79 class MemSpRel(MemRegXRel):
80 regname = 'SP'
81
82
83 class MemR8Rel:
84 def __init__(self, basereg, offset):
85 assert type(basereg) is Reg8Op
86 assert type(offset) is int
87 self.basereg = basereg
88 self.offset = offset
89
90 def __repr__(self):
91 return '[{}, #{}]'.format(self.basereg, self.offset)
92
93 @classmethod
94 def Create(cls, vop):
95 if type(vop) is AUnop and vop.operation == '[]':
96 vop = vop.arg # descent
97 if type(vop) is ABinop:
98 if vop.op == '+' and type(vop.arg1) is ASymbol and type(vop.arg2) is ANumber:
99 offset = vop.arg2.number
100 if offset > 120:
101 return
102 basereg = Reg8Op.Create(vop.arg1)
103 if not basereg:
104 return
105 else:
106 return
107 elif type(vop) is ASymbol:
108 offset = 0
109 basereg = Reg8Op.Create(vop)
110 if not basereg:
111 return
112 else:
113 return
114 return cls(getRegNum(basereg.num), offset)
115
116
117 class RegisterSet:
118 def __init__(self, regs):
119 assert type(regs) is set
120 self.regs = regs
121
122 def __repr__(self):
123 return ','.join([str(r) for r in self.regs])
124
125 @classmethod
126 def Create(cls, vop):
127 assert type(vop) is AUnop and vop.operation == '{}'
128 assert type(vop.arg) is list
129 regs = set()
130 for arg in vop.arg:
131 if type(arg) is ASymbol:
132 reg = ArmRegister.Create(arg)
133 if not reg:
134 return
135 regs.add(reg)
136 elif type(arg) is ABinop and arg.op == '-':
137 reg1 = ArmRegister.Create(arg.arg1)
138 reg2 = ArmRegister.Create(arg.arg2)
139 if not reg1:
140 return
141 if not reg2:
142 return
143 for r in getRegisterRange(reg1, reg2):
144 regs.add(r)
145 else:
146 raise Exception('Cannot be')
147 return cls(regs)
148
149 def registerNumbers(self):
150 return [r.num for r in self.regs]
151
152
153 56
154 # Instructions: 57 # Instructions:
155 58
156 class ArmInstruction(Instruction): 59 class ThumbInstruction(Instruction):
157 pass 60 pass
158 61
159 62
160 allins = [] 63
161 64 class Dcd(ThumbInstruction):
162
163 def instruction(i):
164 allins.append(i)
165 return i
166
167 add_rule(['dcd', 'imm32'], lambda rhs: Dcd(rhs[1]))
168
169 class Dcd(ArmInstruction):
170 mnemonic = 'dcd'
171 operands = (Imm32,)
172 def __init__(self, expr): 65 def __init__(self, expr):
173 if isinstance(expr, Imm32): 66 if isinstance(expr, Imm32):
174 self.expr = expr.imm 67 self.expr = expr.imm
175 self.label = None 68 self.label = None
176 elif isinstance(expr, LabelRef): 69 elif isinstance(expr, LabelRef):
191 84
192 def __repr__(self): 85 def __repr__(self):
193 return 'DCD 0x{0:X}'.format(self.expr) 86 return 'DCD 0x{0:X}'.format(self.expr)
194 87
195 88
196 @instruction 89 class nop_ins(ThumbInstruction):
197 class nop_ins(ArmInstruction):
198 mnemonic = 'nop'
199 operands = tuple()
200
201 def encode(self): 90 def encode(self):
202 return bytes() 91 return bytes()
203 92
204 def __repr__(self): 93 def __repr__(self):
205 return 'NOP' 94 return 'NOP'
206 95
207 96
208 # Memory related 97 # Memory related
209 98
210 class LS_imm5_base(ArmInstruction): 99 class LS_imm5_base(ThumbInstruction):
211 """ ??? Rt, [Rn, imm5] """ 100 """ ??? Rt, [Rn, imm5] """
212 operands = (Reg8Op, MemR8Rel) 101 def __init__(self, rt, rn, imm5):
213 def __init__(self, rt, memop): 102 assert imm5 % 4 == 0
214 assert memop.offset % 4 == 0 103 self.imm5 = imm5 >> 2
215 self.imm5 = memop.offset >> 2 104 self.rn = rn
216 self.rn = memop.basereg.num
217 self.rt = rt 105 self.rt = rt
218 self.memloc = memop 106 assert self.rn.num < 8
219 assert self.rn < 8
220 assert self.rt.num < 8 107 assert self.rt.num < 8
221 108 self.token = ThumbToken()
222 def encode(self): 109
223 Rn = self.rn 110 def encode(self):
111 Rn = self.rn.num
224 Rt = self.rt.num 112 Rt = self.rt.num
225 imm5 = self.imm5 113 imm5 = self.imm5
226 114 self.token[0:3] = Rt
227 h = (self.opcode << 11) | (imm5 << 6) | (Rn << 3) | Rt 115 self.token[3:6] = Rn
228 return u16(h) 116 self.token[6:11] = imm5
229 117 self.token[11:16] = self.opcode
230 118 return self.token.encode()
231 def __repr__(self): 119
232 return '{} {}, {}'.format(self.mnemonic, self.rt, self.memloc) 120 def __repr__(self):
233 121 mnemonic = "???"
234 122 return '{} {}, [{}, {}]'.format(mnemonic, self.rt, self.rn, self.imm5)
235 @instruction 123
124
236 class Str2(LS_imm5_base): 125 class Str2(LS_imm5_base):
237 mnemonic = 'STR'
238 opcode = 0xC 126 opcode = 0xC
239 127
240 @classmethod 128 @classmethod
241 def fromim(cls, im): 129 def fromim(cls, im):
242 mem = MemR8Rel(im.src[0], im.others[0]) 130 return cls(im.src[1], im.src[0], im.others[0])
243 return cls(im.src[1], mem) 131
244 132
245
246 @instruction
247 class Ldr2(LS_imm5_base): 133 class Ldr2(LS_imm5_base):
248 mnemonic = 'LDR'
249 opcode = 0xD 134 opcode = 0xD
250 135
251 @classmethod 136 @classmethod
252 def fromim(cls, im): 137 def fromim(cls, im):
253 mem = MemR8Rel(im.src[0], im.others[0]) 138 return cls(im.dst[0], im.src[0], im.others[0])
254 return cls(im.dst[0], mem) 139
255 140 class ls_sp_base_imm8(ThumbInstruction):
256 class ls_sp_base_imm8(ArmInstruction): 141 def __init__(self, rt, offset):
257 operands = (Reg8Op, MemSpRel)
258 def __init__(self, rt, memop):
259 self.rt = rt 142 self.rt = rt
260 self.offset = memop.offset 143 self.offset = offset
261 144
262 def encode(self): 145 def encode(self):
263 rt = self.rt.num 146 rt = self.rt.num
264 assert rt < 8 147 assert rt < 8
265 imm8 = self.offset >> 2 148 imm8 = self.offset >> 2
266 assert imm8 < 256 149 assert imm8 < 256
267 h = (self.opcode << 8) | (rt << 8) | imm8 150 h = (self.opcode << 8) | (rt << 8) | imm8
268 return u16(h) 151 return u16(h)
269 152
270 def __repr__(self): 153 def __repr__(self):
271 return '{} {}, [sp,#{}]'.format(self.mnemonic, self.rt, self.offset) 154 mnemonic = self.__class__.__name__
155 return '{} {}, [sp,#{}]'.format(mnemonic, self.rt, self.offset)
272 156
273 def align(x, m): 157 def align(x, m):
274 while ((x % m) != 0): 158 while ((x % m) != 0):
275 x = x + 1 159 x = x + 1
276 return x 160 return x
277 161
278 162 def Ldr(*args):
279 @instruction 163 if len(args) == 2 and isinstance(args[0], ArmRegister) \
280 class Ldr3(ArmInstruction): 164 and isinstance(args[1], str):
165 return Ldr3(*args)
166 else:
167 raise Exception()
168
169
170 class Ldr3(ThumbInstruction):
281 """ ldr Rt, LABEL, load value from pc relative position """ 171 """ ldr Rt, LABEL, load value from pc relative position """
282 mnemonic = 'ldr' 172 mnemonic = 'ldr'
283 operands = (Reg8Op, LabelRef)
284 def __init__(self, rt, label): 173 def __init__(self, rt, label):
285 assert isinstance(label, LabelRef)
286 self.rt = rt 174 self.rt = rt
287 self.label = label 175 self.label = label
288 self.offset = 0
289 176
290 @classmethod 177 @classmethod
291 def fromim(cls, im): 178 def fromim(cls, im):
292 return cls(im.dst[0], im.others[0]) 179 return cls(im.dst[0], im.others[0])
293 180
294 def relocations(self): 181 def relocations(self):
295 return [(self.label.name, 'lit_add_8')] 182 return [(self.label, 'lit_add_8')]
296 183
297 def encode(self): 184 def encode(self):
298 rt = self.rt.num 185 rt = self.rt.num
299 assert rt < 8 186 assert rt < 8
300 assert self.offset % 4 == 0 187 imm8 = 0
301 imm8 = self.offset >> 2
302 assert imm8 < 256
303 assert imm8 >= 0
304 h = (0x9 << 11) | (rt << 8) | imm8 188 h = (0x9 << 11) | (rt << 8) | imm8
305 return u16(h) 189 return u16(h)
306 190
307 def __repr__(self): 191 def __repr__(self):
308 return 'LDR {}, {}'.format(self.rt, self.label.name) 192 return 'LDR {}, {}'.format(self.rt, self.label)
309 193
310 194
311 @instruction
312 class Ldr1(ls_sp_base_imm8): 195 class Ldr1(ls_sp_base_imm8):
313 """ ldr Rt, [SP, imm8] """ 196 """ ldr Rt, [SP, imm8] """
314 mnemonic = 'LDR'
315 opcode = 0x98 197 opcode = 0x98
316 198
317 199
318 @instruction
319 class Str1(ls_sp_base_imm8): 200 class Str1(ls_sp_base_imm8):
320 """ str Rt, [SP, imm8] """ 201 """ str Rt, [SP, imm8] """
321 mnemonic = 'STR'
322 opcode = 0x90 202 opcode = 0x90
323 203
324 204
325 @instruction 205 class Mov3(ThumbInstruction):
326 class Mov3(ArmInstruction):
327 """ mov Rd, imm8, move immediate value into register """ 206 """ mov Rd, imm8, move immediate value into register """
328 mnemonic = 'mov'
329 opcode = 4 # 00100 Rd(3) imm8 207 opcode = 4 # 00100 Rd(3) imm8
330 operands = (Reg8Op, Imm8)
331 def __init__(self, rd, imm): 208 def __init__(self, rd, imm):
332 if type(imm) is int: 209 assert imm < 256
333 imm = Imm8(imm) 210 self.imm = imm
334 assert type(imm) is Imm8
335 self.imm = imm.imm
336 assert type(rd) is Reg8Op, str(type(rd))
337 self.rd = rd 211 self.rd = rd
212 self.token = ThumbToken()
338 213
339 @classmethod 214 @classmethod
340 def fromim(cls, im): 215 def fromim(cls, im):
341 return cls(im.dst[0], im.others[0]) 216 return cls(im.dst[0], im.others[0])
342 217
343 def encode(self): 218 def encode(self):
344 rd = self.rd.num 219 rd = self.rd.num
345 opcode = self.opcode 220 self.token[8:11] = rd
346 imm8 = self.imm 221 self.token[0:8] = self.imm
347 h = (opcode << 11) | (rd << 8) | imm8 222 self.token[11:16] = self.opcode
348 return u16(h) 223 return self.token.encode()
349 224
350 def __repr__(self): 225 def __repr__(self):
351 return 'MOV {}, {}'.format(self.rd, self.imm) 226 return 'MOV {}, {}'.format(self.rd, self.imm)
352 227
353 228
354 229
355 # Arithmatics: 230 # Arithmatics:
356 231
357 232
358 233
359 class regregimm3_base(ArmInstruction): 234 class regregimm3_base(ThumbInstruction):
360 operands = (Reg8Op, Reg8Op, Imm3)
361 def __init__(self, rd, rn, imm3): 235 def __init__(self, rd, rn, imm3):
362 self.rd = rd 236 self.rd = rd
363 self.rn = rn 237 self.rn = rn
364 assert type(imm3) is Imm3 238 assert imm3 < 8
365 self.imm3 = imm3 239 self.imm3 = imm3
240 self.token = ThumbToken()
366 241
367 @classmethod 242 @classmethod
368 def fromim(cls, im): 243 def fromim(cls, im):
369 return cls(im.dst[0], im.src[0], im.others[0]) 244 return cls(im.dst[0], im.src[0], im.others[0])
370 245
371 def encode(self): 246 def encode(self):
372 rd = self.rd.num 247 rd = self.rd.num
373 rn = self.rn.num 248 self.token[0:3] = rd
374 imm3 = self.imm3.imm 249 self.token[3:6] = self.rn.num
375 opcode = self.opcode 250 self.token[6:9] = self.imm3
376 h = (self.opcode << 9) | (imm3 << 6) | (rn << 3) | rd 251 self.token[9:16] = self.opcode
377 return u16(h) 252 return self.token.encode()
378 253
379 def __repr__(self): 254 def __repr__(self):
380 return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.imm3.imm) 255 mnemonic = self.__class__.__name__
381 256 return '{} {}, {}, {}'.format(mnemonic, self.rd, self.rn, self.imm3)
382 257
383 add_rule(['add', 'r8', ',', 'r8', ',', 'imm3'], lambda rhs: Add2(rhs[1], rhs[3], rhs[5])) 258
384 259
385 @instruction
386 class Add2(regregimm3_base): 260 class Add2(regregimm3_base):
387 """ add Rd, Rn, imm3 """ 261 """ add Rd, Rn, imm3 """
388 mnemonic = 'add'
389 opcode = 0b0001110 262 opcode = 0b0001110
390 263
391 264
392 @instruction
393 class Sub2(regregimm3_base): 265 class Sub2(regregimm3_base):
394 """ sub Rd, Rn, imm3 """ 266 """ sub Rd, Rn, imm3 """
395 mnemonic = 'sub'
396 opcode = 0b0001111 267 opcode = 0b0001111
397 268
398 269
399 class regregreg_base(ArmInstruction): 270 def Sub(*args):
271 if len(args) == 3 and args[0] is SP and args[1] is SP and \
272 isinstance(args[2], int) and args[2] < 256:
273 return SubSp(args[2])
274 elif len(args) == 3 and isinstance(args[0], ArmRegister) and \
275 isinstance(args[1], ArmRegister) and isinstance(args[2], int) and \
276 args[2] < 8:
277 return Sub2(args[0], args[1], args[2])
278 else:
279 raise Exception()
280
281 class regregreg_base(ThumbInstruction):
400 """ ??? Rd, Rn, Rm """ 282 """ ??? Rd, Rn, Rm """
401 operands = (Reg8Op, Reg8Op, Reg8Op)
402 def __init__(self, rd, rn, rm): 283 def __init__(self, rd, rn, rm):
403 self.rd = rd 284 self.rd = rd
404 self.rn = rn 285 self.rn = rn
405 self.rm = rm 286 self.rm = rm
406 287
414 rn = self.rn.num 295 rn = self.rn.num
415 rm = self.rm.num 296 rm = self.rm.num
416 at[3:6] = rn 297 at[3:6] = rn
417 at[6:9] = rm 298 at[6:9] = rm
418 at[9:16] = self.opcode 299 at[9:16] = self.opcode
419 #h = (self.opcode << 9) | (rm << 6) | (rn << 3) | rd
420 #return u16(h)
421 return at.encode() 300 return at.encode()
422 301
423 def __repr__(self): 302 def __repr__(self):
424 return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.rm) 303 return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.rm)
425 304
426 305
427 @instruction 306 class Add3(regregreg_base):
428 class Add(regregreg_base):
429 mnemonic = 'ADD' 307 mnemonic = 'ADD'
430 opcode = 0b0001100 308 opcode = 0b0001100
431 309
432 310
433 @instruction 311 class Sub3(regregreg_base):
434 class Sub(regregreg_base):
435 mnemonic = 'SUB' 312 mnemonic = 'SUB'
436 opcode = 0b0001101 313 opcode = 0b0001101
437 314
438 315
439 @instruction 316 class Mov2(ThumbInstruction):
440 class Mov2(ArmInstruction):
441 """ mov rd, rm """ 317 """ mov rd, rm """
442 operands = (ArmRegister, ArmRegister)
443 mnemonic = 'MOV' 318 mnemonic = 'MOV'
444 def __init__(self, rd, rm): 319 def __init__(self, rd, rm):
445 self.rd = rd 320 self.rd = rd
446 self.rm = rm 321 self.rm = rm
447 322
456 Rm = self.rm.num 331 Rm = self.rm.num
457 opcode = 0b01000110 332 opcode = 0b01000110
458 at[8:16] = opcode 333 at[8:16] = opcode
459 at[3:7] = Rm 334 at[3:7] = Rm
460 at[7] = D 335 at[7] = D
461 return at.encode() # u16((opcode << 8) | (D << 7) |(Rm << 3) | Rd) 336 return at.encode()
462 337
463 def __repr__(self): 338 def __repr__(self):
464 return '{} {}, {}'.format(self.mnemonic, self.rd, self.rm) 339 return '{} {}, {}'.format(self.mnemonic, self.rd, self.rm)
465 340
466 341
467 @instruction 342 class Mul(ThumbInstruction):
468 class Mul(ArmInstruction):
469 """ mul Rn, Rdm """ 343 """ mul Rn, Rdm """
470 operands = (Reg8Op, Reg8Op)
471 mnemonic = 'MUL' 344 mnemonic = 'MUL'
472 def __init__(self, rn, rdm): 345 def __init__(self, rn, rdm):
473 self.rn = rn 346 self.rn = rn
474 self.rdm = rdm 347 self.rdm = rdm
475 348
490 363
491 def __repr__(self): 364 def __repr__(self):
492 return '{} {}, {}'.format(self.mnemonic, self.rn, self.rdm) 365 return '{} {}, {}'.format(self.mnemonic, self.rn, self.rdm)
493 366
494 367
495 class regreg_base(ArmInstruction): 368 class regreg_base(ThumbInstruction):
496 """ ??? Rdn, Rm """ 369 """ ??? Rdn, Rm """
497 operands = (Reg8Op, Reg8Op)
498 # TODO: integrate with the code gen interface:
499 src = (0, 1)
500 dst = (0,)
501 def __init__(self, rdn, rm): 370 def __init__(self, rdn, rm):
502 self.rdn = rdn 371 self.rdn = rdn
503 self.rm = rm 372 self.rm = rm
504 373
505 @classmethod 374 @classmethod
513 at[3:6] = rm 382 at[3:6] = rm
514 at[6:16] = self.opcode 383 at[6:16] = self.opcode
515 return at.encode() 384 return at.encode()
516 385
517 def __repr__(self): 386 def __repr__(self):
518 return '{} {}, {}'.format(self.mnemonic, self.rdn, self.rm) 387 mnemonic = self.__class__.__name__
519 388 return '{} {}, {}'.format(mnemonic, self.rdn, self.rm)
520 389
521 @instruction 390
522 class movregreg_ins(regreg_base): 391 class movregreg_ins(regreg_base):
523 """ mov Rd, Rm (reg8 operands) """ 392 """ mov Rd, Rm (reg8 operands) """
524 mnemonic = 'mov'
525 opcode = 0 393 opcode = 0
526 394
527 395
528 @instruction
529 class And(regreg_base): 396 class And(regreg_base):
530 mnemonic = 'AND'
531 opcode = 0b0100000000 397 opcode = 0b0100000000
532 398
533 399
534 @instruction
535 class Orr(regreg_base): 400 class Orr(regreg_base):
536 mnemonic = 'ORR'
537 opcode = 0b0100001100 401 opcode = 0b0100001100
538 402
539 403
540 @instruction
541 class Cmp(regreg_base): 404 class Cmp(regreg_base):
542 mnemonic = 'CMP'
543 opcode = 0b0100001010 405 opcode = 0b0100001010
544 406
545 407
546 @instruction
547 class Lsl(regreg_base): 408 class Lsl(regreg_base):
548 mnemonic = 'LSL'
549 opcode = 0b0100000010 409 opcode = 0b0100000010
550 410
551 411
552 @instruction 412 class cmpregimm8_ins(ThumbInstruction):
553 class cmpregimm8_ins(ArmInstruction):
554 """ cmp Rn, imm8 """ 413 """ cmp Rn, imm8 """
555 mnemonic = 'cmp'
556 opcode = 5 # 00101 414 opcode = 5 # 00101
557 operands = (Reg8Op, Imm8)
558 def __init__(self, rn, imm): 415 def __init__(self, rn, imm):
559 self.rn = rn 416 self.rn = rn
560 self.imm = imm 417 self.imm = imm
561 418
562 def encode(self): 419 def encode(self):
563 rn = self.rn.num 420 at = ThumbToken()
564 imm = self.imm.imm 421 at[0:8] = self.imm.imm
565 opcode = self.opcode 422 at[8:11] = self.rn.num
566 h = (opcode << 11) | (rn << 8) | imm 423 at[11:16] = self.opcode
567 return u16(h) 424 return at.encode()
568 425
569 426
570 # Jumping: 427 # Jumping:
571 428
572 def wrap_negative(x, bits): 429 class jumpBase_ins(ThumbInstruction):
573 b = struct.unpack('<I', struct.pack('<i', x))[0]
574 mask = (1 << bits) - 1
575 return b & mask
576
577 class jumpBase_ins(ArmInstruction):
578 operands = (LabelRef,)
579 def __init__(self, target_label): 430 def __init__(self, target_label):
580 assert type(target_label) is LabelRef
581 self.target = target_label 431 self.target = target_label
582 self.offset = 0 432 self.offset = 0
583 433
584 def __repr__(self): 434 def __repr__(self):
585 return '{} {}'.format(self.mnemonic, self.target.name) 435 mnemonic = self.__class__.__name__
586 436 return '{} {}'.format(mnemonic, self.target)
587 437
588 class Imm11Reloc: 438
589 def apply(self, P, S):
590 pass
591
592
593 @instruction
594 class B(jumpBase_ins): 439 class B(jumpBase_ins):
595 mnemonic = 'B' 440 def encode(self):
596 def encode(self): 441 h = (0b11100 << 11) | 0
597 imm11 = wrap_negative(self.offset >> 1, 11) 442 # | 1 # 1 to enable thumb mode
598 h = (0b11100 << 11) | imm11 # | 1 # 1 to enable thumb mode
599 return u16(h) 443 return u16(h)
600 444
601 def relocations(self): 445 def relocations(self):
602 return [(self.target.name, 'wrap_new11')] 446 return [(self.target, 'wrap_new11')]
603 447
604 @instruction
605 class Bl(jumpBase_ins): 448 class Bl(jumpBase_ins):
606 mnemonic = 'BL' 449 def encode(self):
607 def encode(self): 450 imm11 = 0
608 imm32 = wrap_negative(self.offset >> 1, 32) 451 imm10 = 0
609 imm11 = imm32 & 0x7FF
610 imm10 = (imm32 >> 11) & 0x3FF
611 j1 = 1 # TODO: what do these mean? 452 j1 = 1 # TODO: what do these mean?
612 j2 = 1 453 j2 = 1
613 s = (imm32 >> 24) & 0x1 454 s = 0
614 h1 = (0b11110 << 11) | (s << 10) | imm10 455 h1 = (0b11110 << 11) | (s << 10) | imm10
615 h2 = (0b1101 << 12) | (j1 << 13) | (j2 << 11) | imm11 456 h2 = (0b1101 << 12) | (j1 << 13) | (j2 << 11) | imm11
616 return u16(h1) + u16(h2) 457 return u16(h1) + u16(h2)
617 458
618 def relocations(self): 459 def relocations(self):
619 return [(self.target.name, 'bl_imm11_imm10')] 460 return [(self.target, 'bl_imm11_imm10')]
620 461
621 462
622 class cond_base_ins(jumpBase_ins): 463 class cond_base_ins(jumpBase_ins):
623 def encode(self): 464 def encode(self):
624 imm8 = wrap_negative(self.offset >> 1, 8) 465 imm8 = 0
625 h = (0b1101 << 12) | (self.cond << 8) | imm8 466 h = (0b1101 << 12) | (self.cond << 8) | imm8
626 return u16(h) 467 return u16(h)
627 468
628 def relocations(self): 469 def relocations(self):
629 return [(self.target.name, 'rel8')] 470 return [(self.target, 'rel8')]
630 471
631 472
632 class cond_base_ins_long(jumpBase_ins): 473 class cond_base_ins_long(jumpBase_ins):
633 """ Encoding T3 """ 474 """ Encoding T3 """
634 def encode(self): 475 def encode(self):
637 h1 = (0b11110 << 11) | (self.cond << 6) 478 h1 = (0b11110 << 11) | (self.cond << 6)
638 h2 = (0b1101 << 12) | (j1 << 13) | (j2 << 11) 479 h2 = (0b1101 << 12) | (j1 << 13) | (j2 << 11)
639 return u16(h1) + u16(h2) 480 return u16(h1) + u16(h2)
640 481
641 def relocations(self): 482 def relocations(self):
642 return [(self.target.name, 'b_imm11_imm6')] 483 return [(self.target, 'b_imm11_imm6')]
643 484
644 485
645 @instruction
646 class Beq(cond_base_ins): 486 class Beq(cond_base_ins):
647 mnemonic = 'beq'
648 cond = 0 487 cond = 0
649 488
650 489
651 @instruction
652 class Bne(cond_base_ins): 490 class Bne(cond_base_ins):
653 mnemonic = 'bne'
654 cond = 1 491 cond = 1
655 492
656 493
657 @instruction
658 class Blt(cond_base_ins): 494 class Blt(cond_base_ins):
659 mnemonic = 'blt'
660 cond = 0b1011 495 cond = 0b1011
661 496
662 497
663 @instruction
664 class Bgt(cond_base_ins): 498 class Bgt(cond_base_ins):
665 mnemonic = 'bgt'
666 cond = 0b1100 499 cond = 0b1100
667 500
668 501
669 @instruction 502 class Push(ThumbInstruction):
670 class Push(ArmInstruction):
671 operands = (RegisterSet,)
672 mnemonic = 'push'
673
674 def __init__(self, regs): 503 def __init__(self, regs):
675 if type(regs) is set: 504 assert type(regs) is set
676 regs = RegisterSet(regs)
677 assert (type(regs),) == self.operands, (type(regs),)
678 self.regs = regs 505 self.regs = regs
679 506
680 def __repr__(self): 507 def __repr__(self):
681 return '{0} {{{1}}}'.format(self.mnemonic, self.regs) 508 return 'Push {{{}}}'.format(self.regs)
682 509
683 def encode(self): 510 def encode(self):
684 reg_list = 0 511 at = ThumbToken()
685 M = 0 512 for n in register_numbers(self.regs):
686 for n in self.regs.registerNumbers():
687 if n < 8: 513 if n < 8:
688 reg_list |= (1 << n) 514 at[n] = 1
689 elif n == 14: 515 elif n == 14:
690 M = 1 516 at[8] = 1
517 else:
518 raise NotImplementedError('not implemented for {}'.format(n))
519 at[9:16] = 0x5a
520 return at.encode()
521
522
523
524 def register_numbers(regs):
525 for r in regs:
526 yield r.num
527
528 class Pop(ThumbInstruction):
529 def __init__(self, regs):
530 assert type(regs) is set
531 self.regs = regs
532 self.token = ThumbToken()
533
534 def __repr__(self):
535 return 'Pop {{{}}}'.format(self.regs)
536
537 def encode(self):
538 for n in register_numbers(self.regs):
539 if n < 8:
540 self.token[n] = 1
541 elif n == 15:
542 self.token[8] = 1
691 else: 543 else:
692 raise NotImplementedError('not implemented for this register') 544 raise NotImplementedError('not implemented for this register')
693 h = (0x5a << 9) | (M << 8) | reg_list 545 self.token[9:16] = 0x5E
694 return u16(h) 546 return self.token.encode()
695 547
696 548
697 add_rule(['pop', 'reg_list'], lambda rhs: Pop(rhs[1])) 549
698 550 class Yield(ThumbInstruction):
699 @instruction
700 class Pop(ArmInstruction):
701 operands = (RegisterSet,)
702 mnemonic = 'pop'
703
704 def __init__(self, regs):
705 if type(regs) is set:
706 regs = RegisterSet(regs)
707 assert (type(regs),) == self.operands, (type(regs),)
708 self.regs = regs
709
710 def __repr__(self):
711 return '{0} {{{1}}}'.format(self.mnemonic, self.regs)
712
713 def encode(self):
714 reg_list = 0
715 P = 0
716 for n in self.regs.registerNumbers():
717 if n < 8:
718 reg_list |= (1 << n)
719 elif n == 15:
720 P = 1
721 else:
722 raise NotImplementedError('not implemented for this register')
723 h = (0x5E << 9) | (P << 8) | reg_list
724 return u16(h)
725
726
727 @instruction
728 class Yield(ArmInstruction):
729 operands = ()
730 mnemonic = 'yield'
731
732 def encode(self): 551 def encode(self):
733 return u16(0xbf10) 552 return u16(0xbf10)
734 553
735 # misc: 554 # misc:
736 555
737 # add/sub SP: 556 # add/sub SP:
738 class addspsp_base(ArmInstruction): 557 class addspsp_base(ThumbInstruction):
739 operands = (RegSpOp, RegSpOp, Imm7) 558 def __init__(self, imm7):
740 def __init__(self, _sp, _sp2, imm7): 559 self.imm7 = imm7
741 self.imm7 = imm7.imm
742 assert self.imm7 % 4 == 0 560 assert self.imm7 % 4 == 0
743 self.imm7 >>= 2 561 self.imm7 >>= 2
744 562
745 def encode(self): 563 def encode(self):
746 return u16((self.opcode << 7) |self.imm7) 564 return u16((self.opcode << 7) | self.imm7)
747 565
748 def __repr__(self): 566 def __repr__(self):
749 return '{} sp, sp, {}'.format(self.mnemonic, self.imm7 << 2) 567 mnemonic = self.__class__.__name__
750 568 return '{} sp, sp, {}'.format(mnemonic, self.imm7 << 2)
751 569
752 @instruction 570
753 class AddSp(addspsp_base): 571 class AddSp(addspsp_base):
754 mnemonic = 'add'
755 opcode = 0b101100000 572 opcode = 0b101100000
756 573
757 574
758 @instruction
759 class SubSp(addspsp_base): 575 class SubSp(addspsp_base):
760 mnemonic = 'sub'
761 opcode = 0b101100001 576 opcode = 0b101100001