Mercurial > lcfOS
diff python/arm_cm3.py @ 206:6c6bf8890d8a
Added push and pop encodings
author | Windel Bouwman |
---|---|
date | Fri, 28 Jun 2013 16:49:38 +0200 |
parents | d77cb5962cc5 |
children | 8b2f20aae086 |
line wrap: on
line diff
--- a/python/arm_cm3.py Sun Jun 23 18:23:18 2013 +0200 +++ b/python/arm_cm3.py Fri Jun 28 16:49:38 2013 +0200 @@ -1,6 +1,6 @@ import struct, types -from target import Register, Instruction, Target -from asmnodes import ASymbol, ANumber +from target import Register, Instruction, Target, Imm8, Label, Imm3 +from asmnodes import ASymbol, ANumber, AUnop, ABinop from ppci import CompilerError import ir @@ -16,14 +16,12 @@ def __init__(self, num, name): super().__init__(name) self.num = num - -class ArmImm: - def __init__(self, i): - self.i = i + def __repr__(self): + return self.name class RegOp: def __init__(self, num): - assert num < 8 + assert num < 16 self.num = num @classmethod @@ -37,44 +35,62 @@ r = regs[name] return cls(r.num) -class Label: - def __init__(self, name): - self.name = name - - @classmethod - def Create(cls, vop): - if type(vop) is ASymbol: - name = vop.name - return cls(name) - -class Imm8: - def __init__(self, imm): - assert imm < 256 - self.imm = imm +def getRegNum(n): + for r in armtarget.registers: + if r.num == n: + return r - @classmethod - 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 - assert type(imm) is int - self.imm = imm - - @classmethod - def Create(cls, vop): - if type(vop) is ANumber and vop.number < 8: - return cls(vop.number) +def getRegisterRange(n1, n2): + regs = [] + if n1.num < n2.num: + for n in range(n1.num, n2.num + 1): + r = getRegNum(n) + assert r + regs.append(r) + return regs class RegisterSet: def __init__(self, regs): - pass + assert type(regs) is set + self.regs = regs + def __repr__(self): + return ','.join([str(r) for r in self.regs]) + @classmethod + def Create(cls, vop): + assert type(vop) is AUnop and vop.operation == '{}' + assert type(vop.arg) is list + regs = set() + for arg in vop.arg: + if type(arg) is ASymbol: + reg = RegOp.Create(arg) + if not reg: + return + regs.add(reg) + elif type(arg) is ABinop and arg.op == '-': + reg1 = RegOp.Create(arg.arg1) + reg2 = RegOp.Create(arg.arg2) + if not reg1: + return + if not reg2: + return + for r in getRegisterRange(reg1, reg2): + regs.add(r) + else: + raise Exception('Cannot be') + return cls(regs) + + def registerNumbers(self): + return [r.num for r in self.regs] # 8 bit registers: r0 = ArmReg(0, 'r0') armtarget.registers.append(r0) +r1 = ArmReg(1, 'r1') +armtarget.registers.append(r1) +r2 = ArmReg(2, 'r2') +armtarget.registers.append(r2) +r3 = ArmReg(3, 'r3') +armtarget.registers.append(r3) r4 = ArmReg(4, 'r4') armtarget.registers.append(r4) r5 = ArmReg(5, 'r5') @@ -83,17 +99,23 @@ armtarget.registers.append(r6) r7 = ArmReg(7, 'r7') armtarget.registers.append(r7) +# Other registers: +# TODO +sp = ArmReg(13, 'sp') +armtarget.registers.append(sp) +lr = ArmReg(14, 'lr') +armtarget.registers.append(lr) +pc = ArmReg(15, 'pc') +armtarget.registers.append(pc) class ArmInstruction(Instruction): pass -@armtarget.instruction class ldr_ins(ArmInstruction): mnemonic = 'ldr' opcode = 1337 irpattern = 'todo' -@armtarget.instruction class dcd_ins(ArmInstruction): mnemonic = 'dcd' def __init__(self, expr): @@ -101,12 +123,6 @@ def encode(self): return u32(self.expr) -class Operand2: - def __init__(self, expr): - if type(expr) is ANumber: - pass - pass - @armtarget.instruction class mov_ins(ArmInstruction): """ mov Rd, imm8, move immediate value into register """ @@ -186,7 +202,7 @@ @armtarget.instruction class jmp_ins(ArmInstruction): - operands = (Label) + operands = (Label,) mnemonic = 'jmp' def __init__(self, target_label): self.target = target_label @@ -198,20 +214,45 @@ @armtarget.instruction class push_ins(ArmInstruction): - operands = (RegisterSet) + operands = (RegisterSet,) mnemonic = 'push' def __init__(self, regs): + print(self.operands) + assert (type(regs),) == self.operands, (type(regs),) self.regs = regs + def __repr__(self): + return '{0} {{{1}}}'.format(self.mnemonic, self.regs) def encode(self): - return u16(0) + reg_list = 0 + M = 0 + for n in self.regs.registerNumbers(): + if n < 8: + reg_list |= (1 << n) + elif n == 14: + M = 1 + else: + raise NotImplementedError('not implemented for this register') + h = (0x5a << 9) | (M << 8) | reg_list + return u16(h) @armtarget.instruction class pop_ins(ArmInstruction): - operands = (RegisterSet) + operands = (RegisterSet,) mnemonic = 'pop' def __init__(self, regs): self.regs = regs def encode(self): + reg_list = 0 + P = 0 + for n in self.regs.registerNumbers(): + if n < 8: + reg_list |= (1 << n) + elif n == 15: + P = 1 + else: + raise NotImplementedError('not implemented for this register') + h = (0x5E << 9) | (P << 8) | reg_list + return u16(h) return u16(0) @armtarget.instruction @@ -221,3 +262,5 @@ def encode(self): return u16(0xbf10) +armtarget.check() +