comparison python/ppci/target/thumb/instructions.py @ 342:86b02c98a717 devel

Moved target directory
author Windel Bouwman
date Sat, 01 Mar 2014 15:40:31 +0100
parents python/target/arminstructions.py@4d204f6f7d4e
children 3bb7dcfe5529
comparison
equal deleted inserted replaced
341:4d204f6f7d4e 342:86b02c98a717
1 from ..basetarget import Register, Instruction, Target, Label
2 from ..basetarget import Imm32, Imm8, Imm7, Imm3
3 from ..token import u16, u32
4 from .armtoken import ThumbToken
5 from ..arm.registers import R0, ArmRegister, SP
6
7
8 # Instructions:
9
10 class ThumbInstruction(Instruction):
11 pass
12
13
14 class Dcd(ThumbInstruction):
15 def __init__(self, expr):
16 if isinstance(expr, Imm32):
17 self.expr = expr.imm
18 self.label = None
19 elif isinstance(expr, int):
20 self.expr = expr
21 self.label = None
22 else:
23 raise NotImplementedError()
24
25 def encode(self):
26 return u32(self.expr)
27
28 def relocations(self):
29 return []
30
31 def __repr__(self):
32 return 'DCD 0x{0:X}'.format(self.expr)
33
34
35 class nop_ins(ThumbInstruction):
36 def encode(self):
37 return bytes()
38
39 def __repr__(self):
40 return 'NOP'
41
42
43 # Memory related
44
45 class LS_imm5_base(ThumbInstruction):
46 """ ??? Rt, [Rn, imm5] """
47 def __init__(self, rt, rn, imm5):
48 assert imm5 % 4 == 0
49 self.imm5 = imm5 >> 2
50 self.rn = rn
51 self.rt = rt
52 assert self.rn.num < 8
53 assert self.rt.num < 8
54 self.token = ThumbToken()
55
56 def encode(self):
57 Rn = self.rn.num
58 Rt = self.rt.num
59 imm5 = self.imm5
60 self.token[0:3] = Rt
61 self.token[3:6] = Rn
62 self.token[6:11] = imm5
63 self.token[11:16] = self.opcode
64 return self.token.encode()
65
66 def __repr__(self):
67 mnemonic = "???"
68 return '{} {}, [{}, {}]'.format(mnemonic, self.rt, self.rn, self.imm5)
69
70
71 class Str2(LS_imm5_base):
72 opcode = 0xC
73
74 @classmethod
75 def fromim(cls, im):
76 return cls(im.src[1], im.src[0], im.others[0])
77
78
79 class Ldr2(LS_imm5_base):
80 opcode = 0xD
81
82 @classmethod
83 def fromim(cls, im):
84 return cls(im.dst[0], im.src[0], im.others[0])
85
86 class ls_sp_base_imm8(ThumbInstruction):
87 def __init__(self, rt, offset):
88 self.rt = rt
89 self.offset = offset
90
91 def encode(self):
92 rt = self.rt.num
93 assert rt < 8
94 imm8 = self.offset >> 2
95 assert imm8 < 256
96 h = (self.opcode << 8) | (rt << 8) | imm8
97 return u16(h)
98
99 def __repr__(self):
100 mnemonic = self.__class__.__name__
101 return '{} {}, [sp,#{}]'.format(mnemonic, self.rt, self.offset)
102
103 def align(x, m):
104 while ((x % m) != 0):
105 x = x + 1
106 return x
107
108 def Ldr(*args):
109 if len(args) == 2 and isinstance(args[0], ArmRegister) \
110 and isinstance(args[1], str):
111 return Ldr3(*args)
112 else:
113 raise Exception()
114
115
116 class Ldr3(ThumbInstruction):
117 """ ldr Rt, LABEL, load value from pc relative position """
118 mnemonic = 'ldr'
119 def __init__(self, rt, label):
120 self.rt = rt
121 self.label = label
122
123 @classmethod
124 def fromim(cls, im):
125 return cls(im.dst[0], im.others[0])
126
127 def relocations(self):
128 return [(self.label, 'lit_add_8')]
129
130 def encode(self):
131 rt = self.rt.num
132 assert rt < 8
133 imm8 = 0
134 h = (0x9 << 11) | (rt << 8) | imm8
135 return u16(h)
136
137 def __repr__(self):
138 return 'LDR {}, {}'.format(self.rt, self.label)
139
140
141 class Ldr1(ls_sp_base_imm8):
142 """ ldr Rt, [SP, imm8] """
143 opcode = 0x98
144
145
146 class Str1(ls_sp_base_imm8):
147 """ str Rt, [SP, imm8] """
148 opcode = 0x90
149
150
151 class Mov3(ThumbInstruction):
152 """ mov Rd, imm8, move immediate value into register """
153 opcode = 4 # 00100 Rd(3) imm8
154 def __init__(self, rd, imm):
155 assert imm < 256
156 self.imm = imm
157 self.rd = rd
158 self.token = ThumbToken()
159
160 @classmethod
161 def fromim(cls, im):
162 return cls(im.dst[0], im.others[0])
163
164 def encode(self):
165 rd = self.rd.num
166 self.token[8:11] = rd
167 self.token[0:8] = self.imm
168 self.token[11:16] = self.opcode
169 return self.token.encode()
170
171 def __repr__(self):
172 return 'MOV {}, {}'.format(self.rd, self.imm)
173
174
175
176 # Arithmatics:
177
178
179
180 class regregimm3_base(ThumbInstruction):
181 def __init__(self, rd, rn, imm3):
182 self.rd = rd
183 self.rn = rn
184 assert imm3 < 8
185 self.imm3 = imm3
186 self.token = ThumbToken()
187
188 @classmethod
189 def fromim(cls, im):
190 return cls(im.dst[0], im.src[0], im.others[0])
191
192 def encode(self):
193 rd = self.rd.num
194 self.token[0:3] = rd
195 self.token[3:6] = self.rn.num
196 self.token[6:9] = self.imm3
197 self.token[9:16] = self.opcode
198 return self.token.encode()
199
200 def __repr__(self):
201 mnemonic = self.__class__.__name__
202 return '{} {}, {}, {}'.format(mnemonic, self.rd, self.rn, self.imm3)
203
204
205
206 class Add2(regregimm3_base):
207 """ add Rd, Rn, imm3 """
208 opcode = 0b0001110
209
210
211 class Sub2(regregimm3_base):
212 """ sub Rd, Rn, imm3 """
213 opcode = 0b0001111
214
215
216 def Sub(*args):
217 if len(args) == 3 and args[0] is SP and args[1] is SP and \
218 isinstance(args[2], int) and args[2] < 256:
219 return SubSp(args[2])
220 elif len(args) == 3 and isinstance(args[0], ArmRegister) and \
221 isinstance(args[1], ArmRegister) and isinstance(args[2], int) and \
222 args[2] < 8:
223 return Sub2(args[0], args[1], args[2])
224 else:
225 raise Exception()
226
227
228 def Add(*args):
229 if len(args) == 3 and args[0] is SP and args[1] is SP and \
230 isinstance(args[2], int) and args[2] < 256:
231 return AddSp(args[2])
232 elif len(args) == 3 and isinstance(args[0], ArmRegister) and \
233 isinstance(args[1], ArmRegister) and isinstance(args[2], int) and \
234 args[2] < 8:
235 return Add2(args[0], args[1], args[2])
236 else:
237 raise Exception()
238
239
240 class regregreg_base(ThumbInstruction):
241 """ ??? Rd, Rn, Rm """
242 def __init__(self, rd, rn, rm):
243 self.rd = rd
244 self.rn = rn
245 self.rm = rm
246
247 @classmethod
248 def fromim(cls, im):
249 return cls(im.dst[0], im.src[0], im.src[1])
250
251 def encode(self):
252 at = ThumbToken()
253 at.rd = self.rd.num
254 rn = self.rn.num
255 rm = self.rm.num
256 at[3:6] = rn
257 at[6:9] = rm
258 at[9:16] = self.opcode
259 return at.encode()
260
261 def __repr__(self):
262 return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.rm)
263
264
265 class Add3(regregreg_base):
266 mnemonic = 'ADD'
267 opcode = 0b0001100
268
269
270 class Sub3(regregreg_base):
271 mnemonic = 'SUB'
272 opcode = 0b0001101
273
274
275 class Mov2(ThumbInstruction):
276 """ mov rd, rm """
277 mnemonic = 'MOV'
278 def __init__(self, rd, rm):
279 self.rd = rd
280 self.rm = rm
281
282 @classmethod
283 def fromim(cls, im):
284 return cls(im.dst[0], im.src[0])
285
286 def encode(self):
287 at = ThumbToken()
288 at.rd = self.rd.num & 0x7
289 D = (self.rd.num >> 3) & 0x1
290 Rm = self.rm.num
291 opcode = 0b01000110
292 at[8:16] = opcode
293 at[3:7] = Rm
294 at[7] = D
295 return at.encode()
296
297 def __repr__(self):
298 return '{} {}, {}'.format(self.mnemonic, self.rd, self.rm)
299
300
301 class Mul(ThumbInstruction):
302 """ mul Rn, Rdm """
303 mnemonic = 'MUL'
304 def __init__(self, rn, rdm):
305 self.rn = rn
306 self.rdm = rdm
307
308 @classmethod
309 def fromim(cls, im):
310 assert im.src[1] is im.dst[0]
311 return cls(im.src[0], im.dst[0])
312
313 def encode(self):
314 at = ThumbToken()
315 rn = self.rn.num
316 at.rd = self.rdm.num
317 opcode = 0b0100001101
318 #h = (opcode << 6) | (rn << 3) | rdm
319 at[6:16] = opcode
320 at[3:6] = rn
321 return at.encode()
322
323 def __repr__(self):
324 return '{} {}, {}'.format(self.mnemonic, self.rn, self.rdm)
325
326
327 class regreg_base(ThumbInstruction):
328 """ ??? Rdn, Rm """
329 def __init__(self, rdn, rm):
330 self.rdn = rdn
331 self.rm = rm
332
333 @classmethod
334 def fromim(cls, im):
335 return cls(im.src[0], im.src[1])
336
337 def encode(self):
338 at = ThumbToken()
339 at.rd = self.rdn.num
340 rm = self.rm.num
341 at[3:6] = rm
342 at[6:16] = self.opcode
343 return at.encode()
344
345 def __repr__(self):
346 mnemonic = self.__class__.__name__
347 return '{} {}, {}'.format(mnemonic, self.rdn, self.rm)
348
349
350 class movregreg_ins(regreg_base):
351 """ mov Rd, Rm (reg8 operands) """
352 opcode = 0
353
354
355 class And(regreg_base):
356 opcode = 0b0100000000
357
358
359 class Orr(regreg_base):
360 opcode = 0b0100001100
361
362
363 class Cmp(regreg_base):
364 opcode = 0b0100001010
365
366
367 class Lsl(regreg_base):
368 opcode = 0b0100000010
369
370
371 class Cmp2(ThumbInstruction):
372 """ cmp Rn, imm8 """
373 opcode = 5 # 00101
374 def __init__(self, rn, imm):
375 self.rn = rn
376 self.imm = imm
377
378 def encode(self):
379 at = ThumbToken()
380 at[0:8] = self.imm
381 at[8:11] = self.rn.num
382 at[11:16] = self.opcode
383 return at.encode()
384
385
386 # Jumping:
387
388 class jumpBase_ins(ThumbInstruction):
389 def __init__(self, target_label):
390 assert type(target_label) is str
391 self.target = target_label
392 self.offset = 0
393
394 def __repr__(self):
395 mnemonic = self.__class__.__name__
396 return '{} {}'.format(mnemonic, self.target)
397
398
399 class B(jumpBase_ins):
400 def encode(self):
401 h = (0b11100 << 11) | 0
402 # | 1 # 1 to enable thumb mode
403 return u16(h)
404
405 def relocations(self):
406 return [(self.target, 'wrap_new11')]
407
408 class Bl(jumpBase_ins):
409 def encode(self):
410 imm11 = 0
411 imm10 = 0
412 j1 = 1 # TODO: what do these mean?
413 j2 = 1
414 s = 0
415 h1 = (0b11110 << 11) | (s << 10) | imm10
416 h2 = (0b1101 << 12) | (j1 << 13) | (j2 << 11) | imm11
417 return u16(h1) + u16(h2)
418
419 def relocations(self):
420 return [(self.target, 'bl_imm11_imm10')]
421
422
423 class cond_base_ins(jumpBase_ins):
424 def encode(self):
425 imm8 = 0
426 h = (0b1101 << 12) | (self.cond << 8) | imm8
427 return u16(h)
428
429 def relocations(self):
430 return [(self.target, 'rel8')]
431
432
433 class cond_base_ins_long(jumpBase_ins):
434 """ Encoding T3 """
435 def encode(self):
436 j1 = 1 # TODO: what do these mean?
437 j2 = 1
438 h1 = (0b11110 << 11) | (self.cond << 6)
439 h2 = (0b1101 << 12) | (j1 << 13) | (j2 << 11)
440 return u16(h1) + u16(h2)
441
442 def relocations(self):
443 return [(self.target, 'b_imm11_imm6')]
444
445
446 class Beq(cond_base_ins):
447 cond = 0
448
449
450 class Bne(cond_base_ins):
451 cond = 1
452
453
454 class Blt(cond_base_ins):
455 cond = 0b1011
456
457
458 class Bgt(cond_base_ins):
459 cond = 0b1100
460
461
462 class Push(ThumbInstruction):
463 def __init__(self, regs):
464 assert type(regs) is set
465 self.regs = regs
466
467 def __repr__(self):
468 return 'Push {{{}}}'.format(self.regs)
469
470 def encode(self):
471 at = ThumbToken()
472 for n in register_numbers(self.regs):
473 if n < 8:
474 at[n] = 1
475 elif n == 14:
476 at[8] = 1
477 else:
478 raise NotImplementedError('not implemented for {}'.format(n))
479 at[9:16] = 0x5a
480 return at.encode()
481
482
483
484 def register_numbers(regs):
485 for r in regs:
486 yield r.num
487
488 class Pop(ThumbInstruction):
489 def __init__(self, regs):
490 assert type(regs) is set
491 self.regs = regs
492 self.token = ThumbToken()
493
494 def __repr__(self):
495 return 'Pop {{{}}}'.format(self.regs)
496
497 def encode(self):
498 for n in register_numbers(self.regs):
499 if n < 8:
500 self.token[n] = 1
501 elif n == 15:
502 self.token[8] = 1
503 else:
504 raise NotImplementedError('not implemented for this register')
505 self.token[9:16] = 0x5E
506 return self.token.encode()
507
508
509
510 class Yield(ThumbInstruction):
511 def encode(self):
512 return u16(0xbf10)
513
514 # misc:
515
516 # add/sub SP:
517 class addspsp_base(ThumbInstruction):
518 def __init__(self, imm7):
519 self.imm7 = imm7
520 assert self.imm7 % 4 == 0
521 self.imm7 >>= 2
522
523 def encode(self):
524 return u16((self.opcode << 7) | self.imm7)
525
526 def __repr__(self):
527 mnemonic = self.__class__.__name__
528 return '{} sp, sp, {}'.format(mnemonic, self.imm7 << 2)
529
530
531 class AddSp(addspsp_base):
532 opcode = 0b101100000
533
534
535 class SubSp(addspsp_base):
536 opcode = 0b101100001