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)