Mercurial > lcfOS
diff 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 |
line wrap: on
line diff
--- a/python/target/arminstructions.py Mon Feb 17 20:41:30 2014 +0100 +++ b/python/target/arminstructions.py Wed Feb 19 22:32:15 2014 +0100 @@ -10,6 +10,55 @@ def u32(x): return struct.pack('<I', x) + +def val2bit(v, bits): + b = [] + for i in range(bits): + b.append(bool((1<<i) & v)) + #b.reverse() + return b + + +def bit_range(b, e): + getter = lambda s: s[b:e] + def setter(s, v): + s[b:e] = v + return property(getter, setter) + +class ArmToken: + def __init__(self): + self.bit_value = 0 + + def set_bit(self, i, value): + value = bool(value) + assert i in range(0, 16) + mask = 1 << i + if value: + self.bit_value |= mask + else: + self.bit_value &= (~mask) + + def __getitem__(self, key): + return False + + def __setitem__(self, key, value): + if type(key) is int: + self.set_bit(key, value) + elif type(key) is slice: + assert key.step is None + bits = key.stop - key.start + value_bits = val2bit(value, bits) + for i in range(key.start, key.stop): + self.set_bit(i, value_bits[i - key.start]) + else: + raise KeyError() + + rd = bit_range(0, 3) + + def encode(self): + return u16(self.bit_value) + + # Operands: class ArmRegister(Register): @@ -440,11 +489,16 @@ return cls(im.dst[0], im.src[0], im.src[1]) def encode(self): - rd = self.rd.num + at = ArmToken() + at.rd = self.rd.num rn = self.rn.num rm = self.rm.num - h = (self.opcode << 9) | (rm << 6) | (rn << 3) | rd - return u16(h) + at[3:6] = rn + at[6:9] = rm + at[9:16] = self.opcode + #h = (self.opcode << 9) | (rm << 6) | (rn << 3) | rd + #return u16(h) + return at.encode() def __repr__(self): return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.rm) @@ -476,11 +530,15 @@ return cls(im.dst[0], im.src[0]) def encode(self): - Rd = self.rd.num & 0x7 + at = ArmToken() + at.rd = self.rd.num & 0x7 D = (self.rd.num >> 3) & 0x1 Rm = self.rm.num opcode = 0b01000110 - return u16((opcode << 8) | (D << 7) |(Rm << 3) | Rd) + at[8:16] = opcode + at[3:7] = Rm + at[7] = D + return at.encode() # u16((opcode << 8) | (D << 7) |(Rm << 3) | Rd) def __repr__(self): return '{} {}, {}'.format(self.mnemonic, self.rd, self.rm) @@ -501,11 +559,14 @@ return cls(im.src[0], im.dst[0]) def encode(self): + at = ArmToken() rn = self.rn.num - rdm = self.rdm.num + at.rd = self.rdm.num opcode = 0b0100001101 - h = (opcode << 6) | (rn << 3) | rdm - return u16(h) + #h = (opcode << 6) | (rn << 3) | rdm + at[6:16] = opcode + at[3:6] = rn + return at.encode() def __repr__(self): return '{} {}, {}'.format(self.mnemonic, self.rn, self.rdm) @@ -526,10 +587,12 @@ return cls(im.src[0], im.src[1]) def encode(self): - rdn = self.rdn.num + at = ArmToken() + at.rd = self.rdn.num rm = self.rm.num - h = (self.opcode << 6) | (rm << 3) | rdn - return u16(h) + at[3:6] = rm + at[6:16] = self.opcode + return at.encode() def __repr__(self): return '{} {}, {}'.format(self.mnemonic, self.rdn, self.rm) @@ -636,7 +699,7 @@ return [(self.target.name, 'bl_imm11_imm10')] -class cond_base_ins_short(jumpBase_ins): +class cond_base_ins(jumpBase_ins): def encode(self): imm8 = wrap_negative(self.offset >> 1, 8) h = (0b1101 << 12) | (self.cond << 8) | imm8 @@ -646,7 +709,7 @@ return [(self.target.name, 'rel8')] -class cond_base_ins(jumpBase_ins): +class cond_base_ins_long(jumpBase_ins): """ Encoding T3 """ def encode(self): j1 = 1 # TODO: what do these mean?