# HG changeset patch # User Windel Bouwman # Date 1373822961 -7200 # Node ID 83781bd10fdb8e90a6587d16b1bcc9cfcf8a348e # Parent d3dccf12ca88db9d8078f6b35c7b7d569d5ecf04 wip diff -r d3dccf12ca88 -r 83781bd10fdb python/asmnodes.py --- a/python/asmnodes.py Sun Jul 14 12:28:23 2013 +0200 +++ b/python/asmnodes.py Sun Jul 14 19:29:21 2013 +0200 @@ -11,11 +11,6 @@ def __repr__(self): return '{0}:'.format(self.name) -class AComment(ANode): - def __init__(self, name): - self.txt = name - def __repr__(self): - return '; {}'.format(self.txt) class AInstruction(ANode): def __init__(self, mnemonic, operands): diff -r d3dccf12ca88 -r 83781bd10fdb python/codegenarm.py --- a/python/codegenarm.py Sun Jul 14 12:28:23 2013 +0200 +++ b/python/codegenarm.py Sun Jul 14 19:29:21 2013 +0200 @@ -1,5 +1,5 @@ import ir -from asmnodes import ALabel, AComment +from target import Label, Comment import cortexm3 as arm from ppci import CompilerError @@ -37,18 +37,18 @@ pass #self.imms.append(( self.stack_frame = [] - self.emit(ALabel(f.name)) + self.emit(Label(f.name)) # Save some registers: self.emit(arm.push_ins(arm.RegisterSet({arm.r4, arm.r5, arm.r6,arm.r7,arm.lr}))) for bb in f.BasicBlocks: - self.emit(ALabel(bb.name)) + self.emit(Label(bb.name)) for ins in bb.Instructions: self.generateInstruction(ins) self.outs.align(4) while self.imms: l, v = self.imms.pop() - self.emit(ALabel(l)) + self.emit(Label(l)) self.emit(arm.dcd_ins(v)) self.outs.align(4) @@ -65,16 +65,16 @@ def loadStack(self, reg, val): self.emit(arm.ldr_sprel(reg, arm.MemSpRel(self.getStack(val)))) def comment(self, txt): - self.emit(AComment(txt)) + self.emit(Comment(txt)) def generateInstruction(self, ins): self.comment(str(ins)) if type(ins) is ir.Branch: - tgt = ALabel(ins.target.name) + tgt = Label(ins.target.name) self.emit(arm.jmp_ins(tgt)) elif type(ins) is ir.ImmLoad: lname = ins.target.name + '_ivalue' - self.emit(arm.ldr_pcrel(arm.r0, ALabel(lname))) + self.emit(arm.ldr_pcrel(arm.r0, Label(lname))) self.imms.append((lname, ins.value)) self.emit(arm.str_sprel(arm.r0, arm.MemSpRel(self.addStack(ins.target)))) elif type(ins) is ir.Store: diff -r d3dccf12ca88 -r 83781bd10fdb python/cortexm3.py --- a/python/cortexm3.py Sun Jul 14 12:28:23 2013 +0200 +++ b/python/cortexm3.py Sun Jul 14 19:29:21 2013 +0200 @@ -1,6 +1,6 @@ import struct, types from target import Register, Instruction, Target, Imm8, Label, Imm3 -from asmnodes import ASymbol, ANumber, AUnop, ABinop, ALabel +from asmnodes import ASymbol, ANumber, AUnop, ABinop from ppci import CompilerError import ir @@ -36,7 +36,7 @@ if name in regs: r = regs[name] return cls(r.num) - + class Reg8Op: def __init__(self, num): assert num < 8 @@ -269,6 +269,10 @@ self.label = label self.offset = 0 + def resolve(self, f): + la = f(self.label) + self.offset = (la - self.address) + 4 + def encode(self): rt = self.rt.num assert rt < 8 diff -r d3dccf12ca88 -r 83781bd10fdb python/outstream.py --- a/python/outstream.py Sun Jul 14 12:28:23 2013 +0200 +++ b/python/outstream.py Sun Jul 14 19:29:21 2013 +0200 @@ -1,13 +1,11 @@ import binascii -from asmnodes import ALabel, AComment +from target import Instruction, Label + """ The output stream is a stream of instructions that can be output to a file or binary or hexfile. """ -class Alignment: - def __init__(self, a): - self.align = a class OutputStream: def __init__(self): @@ -15,16 +13,26 @@ self.currentSection = None def emit(self, item): + assert isinstance(item, Instruction) self.sections[self.currentSection].append(item) def align(self, alignment): self.emit(Alignment(alignment)) - + def selectSection(self, s): self.currentSection = s if not s in self.sections: self.sections[s] = [] + def getLabelAddress(self, l): + assert isinstance(l, Label) + for s in self.sections.values(): + for i in s: + if type(i) is Label: + if i.name == l.name: + return i.address + return 0 + def backpatch(self): """ Fixup references to other parts in the assembler """ for s in self.sections: @@ -37,12 +45,7 @@ address = 0x0 for i in self.sections[s]: i.address = address - if type(i) in [ALabel, AComment]: - continue - if type(i) is Alignment: - while (address % i.align) != 0: - address += 1 - continue + i.resolve(self.getLabelAddress) bts = i.encode() address += len(bts) @@ -54,17 +57,12 @@ def dumpSection(self, s): print('.section '+s) for i in self.sections[s]: - if type(i) in [ALabel, AComment]: - print(i) - elif type(i) is Alignment: - pass - else: - addr = i.address - insword = i.encode() - assert type(insword) is bytes - insword = binascii.hexlify(bytes(reversed(insword))).decode('ascii') - asm = str(i) - print(' 0x{0:08x} 0x{1} {2}'.format(addr, insword, asm)) + addr = i.address + insword = i.encode() + assert type(insword) is bytes + insword = binascii.hexlify(bytes(reversed(insword))).decode('ascii') + asm = str(i) + print(' 0x{0:08x} 0x{1} {2}'.format(addr, insword, asm)) class TextOutputStream(OutputStream): pass diff -r d3dccf12ca88 -r 83781bd10fdb python/target.py --- a/python/target.py Sun Jul 14 12:28:23 2013 +0200 +++ b/python/target.py Sun Jul 14 19:29:21 2013 +0200 @@ -21,7 +21,7 @@ def Create(cls, vop): if type(vop) is ANumber and vop.number < 256: return cls(vop.number) - + class Imm3: def __init__(self, imm): assert imm < 8 @@ -33,9 +33,21 @@ if type(vop) is ANumber and vop.number < 8: return cls(vop.number) -class Label: +class Instruction: + def encode(self): + raise NotImplementedError('Instruction {0} has no encode yet, TODO'.format(type(self))) + def resolve(self, f): + pass + + +class PseudoInstruction(Instruction): + pass + + +class Label(PseudoInstruction): def __init__(self, name): self.name = name + self.address = 0 @classmethod def Create(cls, vop): @@ -43,13 +55,28 @@ name = vop.name return cls(name) +class Comment(PseudoInstruction): + def __init__(self, txt): + self.txt = txt + def __repr__(self): + return '; {}'.format(self.txt) + +class Alignment(PseudoInstruction): + def __init__(self, a): + self.align = a + def encode(self): + pad = [] + address = self.address + while (address % i.align) != 0: + address += 1 + pad.append(0) + return bytes(pad) + + class Register(Operand): def __init__(self, name): self.name = name -class Instruction: - def encode(self): - raise NotImplementedError('Instruction {0} has no encode yet, TODO'.format(type(self))) class Target: def __init__(self, name, desc=''): diff -r d3dccf12ca88 -r 83781bd10fdb python/testasm.py --- a/python/testasm.py Sun Jul 14 12:28:23 2013 +0200 +++ b/python/testasm.py Sun Jul 14 19:29:21 2013 +0200 @@ -194,6 +194,12 @@ self.feed('str r0, [sp + 4]') self.check('0190') + def testLdrPcRel(self): + self.feed('ldr r1, henkie') + self.feed('dcd 1') + self.feed('henkie: dcd 2') + self.check('04490100000002000000') + def testCmpRegReg(self): self.feed('cmp r0, r1') self.check('8842')