Mercurial > lcfOS
diff python/ppci/target/basetarget.py @ 385:d056b552d3f4
Made better use of layout
author | Windel Bouwman |
---|---|
date | Thu, 01 May 2014 14:03:12 +0200 |
parents | 6df89163e114 |
children | 2a970e7270e2 |
line wrap: on
line diff
--- a/python/ppci/target/basetarget.py Sun Apr 27 17:50:25 2014 +0200 +++ b/python/ppci/target/basetarget.py Thu May 01 14:03:12 2014 +0200 @@ -1,5 +1,7 @@ import types from ppci import CompilerError +from ..bitfun import encode_imm32 +import struct """ Base classes for defining a target @@ -101,6 +103,7 @@ self.asm_keywords = [] self.generate_base_rules() + self.reloc_map = reloc_map # TODO: make this target specific. def generate_base_rules(self): # Base rules for constants: @@ -148,3 +151,134 @@ def add_lowering(self, cls, f): """ Add a function to the table of lowering options for this target """ self.lower_functions[cls] = f + + def add_reloc(self, name, f): + self.reloc_map[name] = f + + + +def align(x, m): + while ((x % m) != 0): + x = x + 1 + return x + +def wrap_negative(x, bits): + b = struct.unpack('<I', struct.pack('<i', x))[0] + mask = (1 << bits) - 1 + return b & mask + + +reloc_map = {} + +def reloc(t): + def f(c): + reloc_map[t] = c + return f + + +@reloc('lit_add_8') +def apply_lit8(reloc, sym_value, section, reloc_value): + assert sym_value % 4 == 0 + offset = (sym_value - (align(reloc_value + 2, 4))) + assert offset in range(0, 1024, 4), str(offset)+str( self.dst.sections) + rel8 = offset >> 2 + section.data[reloc.offset] = rel8 + + +@reloc('wrap_new11') +def apply_wrap_new11(reloc, sym_value, section, reloc_value): + offset = sym_value - (align(reloc_value, 2) + 4) + assert offset in range(-2048, 2046, 2) + imm11 = wrap_negative(offset >> 1, 11) + section.data[reloc.offset] = (imm11 & 0xff) + section.data[reloc.offset + 1] |= (imm11 >> 8) & 0x7 + + +@reloc('rel8') +def apply_rel8(reloc, sym_value, section, reloc_value): + assert sym_value % 2 == 0 + offset = sym_value - (align(reloc_value, 2) + 4) + assert offset in range(-256, 254, 2), str(offset) + str(reloc) + imm8 = wrap_negative(offset >> 1, 8) + section.data[reloc.offset] = imm8 + + +@reloc('bl_imm11_imm10') +def apply_bl_imm11(reloc, sym_value, section, reloc_value): + assert sym_value % 2 == 0 + offset = sym_value - (align(reloc_value, 2) + 4) + assert offset in range(-16777216, 16777214, 2), str(offset) + imm32 = wrap_negative(offset >> 1, 32) + imm11 = imm32 & 0x7FF + imm10 = (imm32 >> 11) & 0x3FF + s = (imm32 >> 24) & 0x1 + section.data[reloc.offset + 2] = imm11 & 0xFF + section.data[reloc.offset + 3] |= (imm11 >> 8) & 0x7 + section.data[reloc.offset] = imm10 & 0xff + section.data[reloc.offset + 1] |= ((imm10 >> 8) & 0x3) | (s << 2) + +@reloc('b_imm11_imm6') +def apply_b_imm11_imm6(reloc, sym_value, section, reloc_value): + assert sym_value % 2 == 0 + offset = sym_value - (align(reloc_value, 2) + 4) + assert offset in range(-1048576, 1048574, 2), str(offset) + imm32 = wrap_negative(offset >> 1, 32) + imm11 = imm32 & 0x7FF + imm6 = (imm32 >> 11) & 0x3F + s = (imm32 >> 24) & 0x1 + section.data[reloc.offset + 2] = imm11 & 0xFF + section.data[reloc.offset + 3] |= (imm11 >> 8) & 0x7 + section.data[reloc.offset] |= imm6 + section.data[reloc.offset + 1] |= (s << 2) + +# ARM reloc!! +# TODO: move to target classes??? +@reloc('b_imm24') +def apply_b_imm24(reloc, sym_value, section, reloc_value): + assert sym_value % 4 == 0 + assert reloc_value % 4 == 0 + offset = (sym_value - (reloc_value + 8)) + rel24 = wrap_negative(offset >> 2, 24) + section.data[reloc.offset+2] = (rel24 >> 16) & 0xFF + section.data[reloc.offset+1] = (rel24 >> 8) & 0xFF + section.data[reloc.offset+0] = rel24 & 0xFF + + +@reloc('ldr_imm12') +def apply_ldr_imm12(reloc, sym_value, section, reloc_value): + assert sym_value % 4 == 0 + assert reloc_value % 4 == 0 + offset = (sym_value - (reloc_value + 8)) + U = 1 + if offset < 0: + offset = -offset + U = 0 + assert offset < 4096, str(sym) + str(section) + str(reloc) + section.data[reloc.offset+2] |= (U << 7) + section.data[reloc.offset+1] |= (offset >> 8) & 0xF + section.data[reloc.offset+0] = offset & 0xFF + +@reloc('adr_imm12') +def apply_adr_imm12(reloc, sym_value, section, reloc_value): + assert sym_value % 4 == 0 + assert reloc_value % 4 == 0 + offset = (sym_value - (reloc_value + 8)) + U = 2 + if offset < 0: + offset = -offset + U = 1 + assert offset < 4096 + offset = encode_imm32(offset) + section.data[reloc.offset+2] |= (U << 6) + section.data[reloc.offset+1] |= (offset >> 8) & 0xF + section.data[reloc.offset+0] = offset & 0xFF + +@reloc('absaddr32') +def apply_absaddr32(reloc, sym_value, section, reloc_value): + assert sym_value % 4 == 0 + assert reloc_value % 4 == 0 + offset = sym_value + section.data[reloc.offset+3] = (offset >> 24) & 0xFF + section.data[reloc.offset+2] = (offset >> 16) & 0xFF + section.data[reloc.offset+1] = (offset >> 8) & 0xFF + section.data[reloc.offset+0] = offset & 0xFF