Mercurial > lcfOS
diff python/cortexm3.py @ 219:1fa3e0050b49
Expanded ad hoc code generator
author | Windel Bouwman |
---|---|
date | Sat, 06 Jul 2013 12:38:09 +0200 |
parents | 494828a7adf1 |
children | 85c8105318e7 |
line wrap: on
line diff
--- a/python/cortexm3.py Fri Jul 05 15:30:22 2013 +0200 +++ b/python/cortexm3.py Sat Jul 06 12:38:09 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 +from asmnodes import ASymbol, ANumber, AUnop, ABinop, ALabel from ppci import CompilerError import ir @@ -36,6 +36,23 @@ if name in regs: r = regs[name] return cls(r.num) + +class Reg8Op: + def __init__(self, num): + assert num < 8 + self.num = num + + @classmethod + def Create(cls, vop): + if type(vop) is ASymbol: + name = vop.name + regs = {} + for r in armtarget.registers: + regs[r.name] = r + if name in regs: + r = regs[name] + if r.num < 8: + return cls(r.num) def getRegNum(n): for r in armtarget.registers: @@ -57,6 +74,9 @@ self.basereg = basereg self.offset = offset + def __repr__(self): + return '[{}, #{}]'.format(self.basereg, self.offset) + @classmethod def Create(cls, vop): if type(vop) is AUnop and vop.operation == '[]': @@ -77,7 +97,38 @@ else: return return cls(getRegNum(basereg.num), offset) - pass + +class MemoryOpReg8Imm5: + def __init__(self, basereg, offset): + assert type(basereg) is ArmReg + self.basereg = basereg + self.offset = offset + + def __repr__(self): + return '[{}, #{}]'.format(self.basereg, self.offset) + + @classmethod + def Create(cls, vop): + if type(vop) is AUnop and vop.operation == '[]': + vop = vop.arg # descent + if type(vop) is ABinop: + if vop.op == '+' and type(vop.arg1) is ASymbol and type(vop.arg2) is ANumber: + offset = vop.arg2.number + if offset > 120: + return + basereg = Reg8Op.Create(vop.arg1) + if not basereg: + return + else: + return + elif type(vop) is ASymbol: + offset = 0 + basereg = Reg8Op.Create(vop) + if not basereg: + return + else: + return + return cls(getRegNum(basereg.num), offset) class RegisterSet: def __init__(self, regs): @@ -129,10 +180,6 @@ armtarget.registers.append(r6) r7 = ArmReg(7, 'r7') armtarget.registers.append(r7) -r10 = ArmReg(10, 'r10') -armtarget.registers.append(r10) -r11 = ArmReg(11, 'r11') -armtarget.registers.append(r11) # Other registers: # TODO sp = ArmReg(13, 'sp') @@ -145,54 +192,104 @@ class ArmInstruction(Instruction): pass -class ldr_ins(ArmInstruction): - mnemonic = 'ldr' - opcode = 1337 - irpattern = 'todo' - class dcd_ins(ArmInstruction): mnemonic = 'dcd' def __init__(self, expr): self.expr = expr + def encode(self): return u32(self.expr) -@armtarget.instruction -class storeimm5_ins(ArmInstruction): - """ str Rt, [Rn, imm5], store value into memory """ - mnemonic = 'str' - operands = (RegOp, MemoryOp) + def __repr__(self): + return 'DCD 0x{0:X}'.format(self.expr) + + + +# Memory related + +class LS_imm5_base(ArmInstruction): + """ ??? Rt, [Rn, imm5] """ + operands = (Reg8Op, MemoryOpReg8Imm5) def __init__(self, rt, memop): assert memop.offset % 4 == 0 self.imm5 = memop.offset >> 2 self.rn = memop.basereg.num self.rt = rt.num + self.memloc = memop + assert self.rn < 8 + assert self.rt < 8 def encode(self): Rn = self.rn Rt = self.rt imm5 = self.imm5 - h = (0xC << 11) | (imm5 << 6) | (Rn << 3) | Rt + + h = (self.opcode << 11) | (imm5 << 6) | (Rn << 3) | Rt + return u16(h) + def __repr__(self): + return '{} {}, {}'.format(self.mnemonic, self.rt, self.memloc) + +@armtarget.instruction +class storeimm5_ins(LS_imm5_base): + mnemonic = 'STR' + opcode = 0xC + +@armtarget.instruction +class loadimm5_ins(LS_imm5_base): + mnemonic = 'LDR' + opcode = 0xD + +class ls_sp_base_imm8(ArmInstruction): + operands = (Reg8Op, MemoryOp) + def __init__(self, rt, memop): + self.rt = rt + assert memop.basereg.num == 13 + self.offset = memop.offset + + def encode(self): + rt = self.rt.num + assert rt < 8 + imm8 = self.offset >> 2 + assert imm8 < 256 + h = (self.opcode << 8) | (rt << 8) | imm8 return u16(h) + def __repr__(self): + return '{} {}, [sp,#{}]'.format(self.mnemonic, self.rt, self.offset) + @armtarget.instruction -class loadimm5_ins(ArmInstruction): - """ str Rt, [Rn, imm5], store value into memory """ +class ldr_pcrel(ArmInstruction): + """ ldr Rt, [PC, imm8], store value into memory """ mnemonic = 'ldr' operands = (RegOp, MemoryOp) - def __init__(self, rt, memop): - assert memop.offset % 4 == 0 - self.imm5 = memop.offset >> 2 - self.rn = memop.basereg.num - self.rt = rt.num + def __init__(self, rt, label): + self.rt = rt + self.label = label + self.offset = 0 def encode(self): - Rn = self.rn - Rt = self.rt - imm5 = self.imm5 - h = (0xD << 11) | (imm5 << 6) | (Rn << 3) | Rt + rt = self.rt.num + assert rt < 8 + imm8 = self.offset >> 2 + assert imm8 < 256 + h = (0x9 << 11) | (rt << 8) | imm8 return u16(h) + def __repr__(self): + return 'LDR {}, [pc,#{}]'.format(self.rt, self.offset) + +@armtarget.instruction +class ldr_sprel(ls_sp_base_imm8): + """ ldr Rt, [SP, imm8] """ + mnemonic = 'LDR' + opcode = 0x98 + +@armtarget.instruction +class str_sprel(ls_sp_base_imm8): + """ str Rt, [SP, imm8] """ + mnemonic = 'STR' + opcode = 0x90 + @armtarget.instruction class mov_ins(ArmInstruction): """ mov Rd, imm8, move immediate value into register """ @@ -204,22 +301,19 @@ self.imm = imm.imm self.r = rd.num - @classmethod - def FromIr(cls, ir_ins): - pass - def encode(self): rd = self.r opcode = self.opcode imm8 = self.imm h = (opcode << 11) | (rd << 8) | imm8 return u16(h) + def __repr__(self): + return 'MOV {0}, xx?'.format(self.r) @armtarget.instruction class movregreg_ins(ArmInstruction): """ mov Rd, Rm """ mnemonic = 'mov' - opcode = 8 # 01000 Rd(3) imm8 operands = (RegOp, RegOp) def __init__(self, rd, rm): self.rd = rd @@ -232,9 +326,13 @@ rm = self.rm.num assert rm < 16 opcode = self.opcode - h = (opcode << 11) | (3 << 9) | (D << 7) | (rm << 3) | rd + h = (1 << 14) | (3 << 9) | (D << 7) | (rm << 3) | rd return u16(h) + + +# Arithmatics: + @armtarget.instruction class addregregimm3_ins(ArmInstruction): """ add Rd, Rn, imm3 """ @@ -254,6 +352,61 @@ h = (opcode << 11) | (1 << 10) | (imm3 << 6) | (rn << 3) | rd return u16(h) +class regregreg_base(ArmInstruction): + """ ??? Rd, Rn, Rm """ + operands = (Reg8Op, Reg8Op, Reg8Op) + def __init__(self, rd, rn, rm): + self.rd = rd + self.rn = rn + self.rm = rm + def encode(self): + rd = self.rd.num + rn = self.rn.num + rm = self.rm.num + h = (self.opcode << 9) | (rm << 6) | (rn << 3) | rd + return u16(h) + def __repr__(self): + return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.rm) + +@armtarget.instruction +class addregs_ins(regregreg_base): + mnemonic = 'ADD' + opcode = 0b0001100 + +@armtarget.instruction +class subregs_ins(regregreg_base): + mnemonic = 'SUB' + opcode = 0b0001101 + +class regreg_base(ArmInstruction): + """ ??? Rdn, Rm """ + operands = (Reg8Op, Reg8Op) + def __init__(self, rdn, rm): + self.rdn = rdn + self.rm = rm + def encode(self): + rdn = self.rdn.num + rm = self.rm.num + h = (self.opcode << 6) | (rm << 3) | rdn + return u16(h) + def __repr__(self): + return '{} {}, {}'.format(self.mnemonic, self.rdn, self.rm) + +@armtarget.instruction +class andregs_ins(regreg_base): + mnemonic = 'AND' + opcode = 0b0100000000 + +@armtarget.instruction +class orrregs_ins(regreg_base): + mnemonic = 'ORR' + opcode = 0b0100001100 + +@armtarget.instruction +class cmp_ins(regreg_base): + mnemonic = 'CMP' + opcode = 0b0100001010 + @armtarget.instruction class cmpregimm8_ins(ArmInstruction): """ cmp Rn, imm8 """ @@ -270,34 +423,37 @@ h = (opcode << 11) | (rn << 8) | imm return u16(h) -@armtarget.instruction -class cmp_ins(ArmInstruction): - """ cmp Rn, Rm """ - mnemonic = 'cmp' - operands = (RegOp, RegOp) - def __init__(self, rn, rm): - self.rn = rn - self.rm = rm - def encode(self): - rn = self.rn.num - rm = self.rm.num - assert rn < 8 - assert rm < 8 - opcode = 0x42 - h = (opcode << 8) | (1 << 7) | (rm << 3) | (rn & 0x7) - return u16(h) +# Jumping: @armtarget.instruction class jmp_ins(ArmInstruction): - operands = (Label,) + operands = (ALabel,) mnemonic = 'jmp' def __init__(self, target_label): + assert type(target_label) is ALabel self.target = target_label def fixUp(self): pass def encode(self): - h = 1337 # TODO + h = 0 # TODO return u16(h) + def __repr__(self): + return 'B {0}'.format(self.target.name) + +@armtarget.instruction +class beq_ins(ArmInstruction): + operands = (ALabel,) + mnemonic = 'beq' + def __init__(self, target_label): + assert type(target_label) is ALabel + self.target = target_label + def fixUp(self): + pass + def encode(self): + h = 0 # TODO + return u16(h) + def __repr__(self): + return 'BEQ {0}'.format(self.target.name) @armtarget.instruction class push_ins(ArmInstruction): @@ -341,7 +497,6 @@ raise NotImplementedError('not implemented for this register') h = (0x5E << 9) | (P << 8) | reg_list return u16(h) - return u16(0) @armtarget.instruction class yield_ins(ArmInstruction):