Mercurial > lcfOS
comparison python/target/arminstructions.py @ 336:d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
author | Windel Bouwman |
---|---|
date | Wed, 19 Feb 2014 22:32:15 +0100 |
parents | 582a1aaa3983 |
children | c7cc54c0dfdf |
comparison
equal
deleted
inserted
replaced
335:582a1aaa3983 | 336:d1ecc493384e |
---|---|
7 def u16(h): | 7 def u16(h): |
8 return struct.pack('<H', h) | 8 return struct.pack('<H', h) |
9 | 9 |
10 def u32(x): | 10 def u32(x): |
11 return struct.pack('<I', x) | 11 return struct.pack('<I', x) |
12 | |
13 | |
14 def val2bit(v, bits): | |
15 b = [] | |
16 for i in range(bits): | |
17 b.append(bool((1<<i) & v)) | |
18 #b.reverse() | |
19 return b | |
20 | |
21 | |
22 def bit_range(b, e): | |
23 getter = lambda s: s[b:e] | |
24 def setter(s, v): | |
25 s[b:e] = v | |
26 return property(getter, setter) | |
27 | |
28 class ArmToken: | |
29 def __init__(self): | |
30 self.bit_value = 0 | |
31 | |
32 def set_bit(self, i, value): | |
33 value = bool(value) | |
34 assert i in range(0, 16) | |
35 mask = 1 << i | |
36 if value: | |
37 self.bit_value |= mask | |
38 else: | |
39 self.bit_value &= (~mask) | |
40 | |
41 def __getitem__(self, key): | |
42 return False | |
43 | |
44 def __setitem__(self, key, value): | |
45 if type(key) is int: | |
46 self.set_bit(key, value) | |
47 elif type(key) is slice: | |
48 assert key.step is None | |
49 bits = key.stop - key.start | |
50 value_bits = val2bit(value, bits) | |
51 for i in range(key.start, key.stop): | |
52 self.set_bit(i, value_bits[i - key.start]) | |
53 else: | |
54 raise KeyError() | |
55 | |
56 rd = bit_range(0, 3) | |
57 | |
58 def encode(self): | |
59 return u16(self.bit_value) | |
60 | |
12 | 61 |
13 # Operands: | 62 # Operands: |
14 | 63 |
15 class ArmRegister(Register): | 64 class ArmRegister(Register): |
16 def __init__(self, num, name): | 65 def __init__(self, num, name): |
438 @classmethod | 487 @classmethod |
439 def fromim(cls, im): | 488 def fromim(cls, im): |
440 return cls(im.dst[0], im.src[0], im.src[1]) | 489 return cls(im.dst[0], im.src[0], im.src[1]) |
441 | 490 |
442 def encode(self): | 491 def encode(self): |
443 rd = self.rd.num | 492 at = ArmToken() |
493 at.rd = self.rd.num | |
444 rn = self.rn.num | 494 rn = self.rn.num |
445 rm = self.rm.num | 495 rm = self.rm.num |
446 h = (self.opcode << 9) | (rm << 6) | (rn << 3) | rd | 496 at[3:6] = rn |
447 return u16(h) | 497 at[6:9] = rm |
498 at[9:16] = self.opcode | |
499 #h = (self.opcode << 9) | (rm << 6) | (rn << 3) | rd | |
500 #return u16(h) | |
501 return at.encode() | |
448 | 502 |
449 def __repr__(self): | 503 def __repr__(self): |
450 return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.rm) | 504 return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.rm) |
451 | 505 |
452 | 506 |
474 @classmethod | 528 @classmethod |
475 def fromim(cls, im): | 529 def fromim(cls, im): |
476 return cls(im.dst[0], im.src[0]) | 530 return cls(im.dst[0], im.src[0]) |
477 | 531 |
478 def encode(self): | 532 def encode(self): |
479 Rd = self.rd.num & 0x7 | 533 at = ArmToken() |
534 at.rd = self.rd.num & 0x7 | |
480 D = (self.rd.num >> 3) & 0x1 | 535 D = (self.rd.num >> 3) & 0x1 |
481 Rm = self.rm.num | 536 Rm = self.rm.num |
482 opcode = 0b01000110 | 537 opcode = 0b01000110 |
483 return u16((opcode << 8) | (D << 7) |(Rm << 3) | Rd) | 538 at[8:16] = opcode |
539 at[3:7] = Rm | |
540 at[7] = D | |
541 return at.encode() # u16((opcode << 8) | (D << 7) |(Rm << 3) | Rd) | |
484 | 542 |
485 def __repr__(self): | 543 def __repr__(self): |
486 return '{} {}, {}'.format(self.mnemonic, self.rd, self.rm) | 544 return '{} {}, {}'.format(self.mnemonic, self.rd, self.rm) |
487 | 545 |
488 | 546 |
499 def fromim(cls, im): | 557 def fromim(cls, im): |
500 assert im.src[1] is im.dst[0] | 558 assert im.src[1] is im.dst[0] |
501 return cls(im.src[0], im.dst[0]) | 559 return cls(im.src[0], im.dst[0]) |
502 | 560 |
503 def encode(self): | 561 def encode(self): |
562 at = ArmToken() | |
504 rn = self.rn.num | 563 rn = self.rn.num |
505 rdm = self.rdm.num | 564 at.rd = self.rdm.num |
506 opcode = 0b0100001101 | 565 opcode = 0b0100001101 |
507 h = (opcode << 6) | (rn << 3) | rdm | 566 #h = (opcode << 6) | (rn << 3) | rdm |
508 return u16(h) | 567 at[6:16] = opcode |
568 at[3:6] = rn | |
569 return at.encode() | |
509 | 570 |
510 def __repr__(self): | 571 def __repr__(self): |
511 return '{} {}, {}'.format(self.mnemonic, self.rn, self.rdm) | 572 return '{} {}, {}'.format(self.mnemonic, self.rn, self.rdm) |
512 | 573 |
513 | 574 |
524 @classmethod | 585 @classmethod |
525 def fromim(cls, im): | 586 def fromim(cls, im): |
526 return cls(im.src[0], im.src[1]) | 587 return cls(im.src[0], im.src[1]) |
527 | 588 |
528 def encode(self): | 589 def encode(self): |
529 rdn = self.rdn.num | 590 at = ArmToken() |
591 at.rd = self.rdn.num | |
530 rm = self.rm.num | 592 rm = self.rm.num |
531 h = (self.opcode << 6) | (rm << 3) | rdn | 593 at[3:6] = rm |
532 return u16(h) | 594 at[6:16] = self.opcode |
595 return at.encode() | |
533 | 596 |
534 def __repr__(self): | 597 def __repr__(self): |
535 return '{} {}, {}'.format(self.mnemonic, self.rdn, self.rm) | 598 return '{} {}, {}'.format(self.mnemonic, self.rdn, self.rm) |
536 | 599 |
537 | 600 |
634 | 697 |
635 def relocations(self): | 698 def relocations(self): |
636 return [(self.target.name, 'bl_imm11_imm10')] | 699 return [(self.target.name, 'bl_imm11_imm10')] |
637 | 700 |
638 | 701 |
639 class cond_base_ins_short(jumpBase_ins): | 702 class cond_base_ins(jumpBase_ins): |
640 def encode(self): | 703 def encode(self): |
641 imm8 = wrap_negative(self.offset >> 1, 8) | 704 imm8 = wrap_negative(self.offset >> 1, 8) |
642 h = (0b1101 << 12) | (self.cond << 8) | imm8 | 705 h = (0b1101 << 12) | (self.cond << 8) | imm8 |
643 return u16(h) | 706 return u16(h) |
644 | 707 |
645 def relocations(self): | 708 def relocations(self): |
646 return [(self.target.name, 'rel8')] | 709 return [(self.target.name, 'rel8')] |
647 | 710 |
648 | 711 |
649 class cond_base_ins(jumpBase_ins): | 712 class cond_base_ins_long(jumpBase_ins): |
650 """ Encoding T3 """ | 713 """ Encoding T3 """ |
651 def encode(self): | 714 def encode(self): |
652 j1 = 1 # TODO: what do these mean? | 715 j1 = 1 # TODO: what do these mean? |
653 j2 = 1 | 716 j2 = 1 |
654 h1 = (0b11110 << 11) | (self.cond << 6) | 717 h1 = (0b11110 << 11) | (self.cond << 6) |