Mercurial > lcfOS
diff python/cortexm3.py @ 277:046017431c6a
Started register allocator
author | Windel Bouwman |
---|---|
date | Thu, 26 Sep 2013 21:14:25 +0200 |
parents | 56d37ed4b4d2 |
children | 2ccd57b1d78c |
line wrap: on
line diff
--- a/python/cortexm3.py Mon Sep 16 21:51:17 2013 +0200 +++ b/python/cortexm3.py Thu Sep 26 21:14:25 2013 +0200 @@ -16,18 +16,14 @@ armtarget = Target('arm') -class ArmReg(Register): +class ArmRegister(Register): def __init__(self, num, name): super().__init__(name) self.num = num + def __repr__(self): return self.name -class RegOp: - def __init__(self, num): - assert num < 16 - self.num = num - @classmethod def Create(cls, vop): if type(vop) is ASymbol: @@ -37,41 +33,17 @@ regs[r.name] = r if name in regs: r = regs[name] - return cls(r.num) + if isinstance(r, cls): + return r -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) +class Reg8Op(ArmRegister): + pass + -class Reg16Op: - def __init__(self, num): - assert num < 16 - self.num = num +class Reg16Op(ArmRegister): + pass - @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 < 16: - return cls(r.num) class RegSpOp: @classmethod @@ -128,7 +100,7 @@ class MemR8Rel: def __init__(self, basereg, offset): - assert type(basereg) is ArmReg + assert type(basereg) is Reg8Op self.basereg = basereg self.offset = offset @@ -173,13 +145,13 @@ regs = set() for arg in vop.arg: if type(arg) is ASymbol: - reg = RegOp.Create(arg) + reg = ArmRegister.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) + reg1 = ArmRegister.Create(arg.arg1) + reg2 = ArmRegister.Create(arg.arg2) if not reg1: return if not reg2: @@ -193,32 +165,30 @@ def registerNumbers(self): return [r.num for r in self.regs] +def makeReg(cls, num, name): + r = cls(num, name) + armtarget.registers.append(r) + return r + # 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') -armtarget.registers.append(r5) -r6 = ArmReg(6, 'r6') -armtarget.registers.append(r6) -r7 = ArmReg(7, 'r7') -armtarget.registers.append(r7) +r0 = makeReg(Reg8Op, 0, 'r0') +r1 = makeReg(Reg8Op, 1, 'r1') +r2 = makeReg(Reg8Op, 2, 'r2') +r3 = makeReg(Reg8Op, 3, 'r3') +r4 = makeReg(Reg8Op, 4, 'r4') +r5 = makeReg(Reg8Op, 5, 'r5') +r6 = makeReg(Reg8Op, 6, 'r6') +r7 = makeReg(Reg8Op, 7, '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) +sp = makeReg(ArmRegister, 13, 'sp') +lr = makeReg(ArmRegister, 14, 'lr') +pc = makeReg(ArmRegister, 15, 'pc') +assert isinstance(sp, ArmRegister) +assert isinstance(r3, ArmRegister) +assert ArmRegister.Create(ASymbol('r3')) is r3 +assert ArmRegister.Create(ASymbol('sp')) is sp class ArmInstruction(Instruction): pass @@ -307,11 +277,12 @@ x = x + 1 return x + @armtarget.instruction class ldr_pcrel(ArmInstruction): """ ldr Rt, LABEL, load value from pc relative position """ mnemonic = 'ldr' - operands = (RegOp, LabelRef) + operands = (Reg8Op, LabelRef) def __init__(self, rt, label): assert isinstance(label, LabelRef) self.rt = rt @@ -337,38 +308,40 @@ def __repr__(self): return 'LDR {}, {}'.format(self.rt, self.label.name) + @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 """ mnemonic = 'mov' opcode = 4 # 00100 Rd(3) imm8 - operands = (RegOp, Imm8) + operands = (Reg8Op, Imm8) def __init__(self, rd, imm): self.imm = imm.imm - self.r = rd.num + self.rd = rd def encode(self): - rd = self.r + rd = self.rd.num 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) - - + return 'MOV {}, {}'.format(self.rd, self.imm) @@ -382,6 +355,7 @@ self.rd = rd self.rn = rn self.imm3 = imm3 + def encode(self): rd = self.rd.num rn = self.rn.num @@ -390,6 +364,8 @@ h = (self.opcode << 9) | (imm3 << 6) | (rn << 3) | rd return u16(h) + def __repr__(self): + return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.imm3.imm) @armtarget.instruction class addregregimm3_ins(regregimm3_base): @@ -421,30 +397,35 @@ 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 + @armtarget.instruction class movregreg_ext_ins(ArmInstruction): - operands = (Reg16Op, Reg16Op) + operands = (ArmRegister, ArmRegister) mnemonic = 'MOV' def __init__(self, rd, rm): self.rd = rd self.rm = rm + def encode(self): 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) + def __repr__(self): return '{} {}, {}'.format(self.mnemonic, self.rd, self.rm) @@ -457,50 +438,65 @@ def __init__(self, rn, rdm): self.rn = rn self.rdm = rdm + def encode(self): rn = self.rn.num rdm = self.rdm.num opcode = 0b0100001101 h = (opcode << 6) | (rn << 3) | rdm return u16(h) + def __repr__(self): - return '{} {}, {}'.format(self.mnemonic, self.rdn, self.rm) + return '{} {}, {}'.format(self.mnemonic, self.rn, self.rdm) + class regreg_base(ArmInstruction): """ ??? Rdn, Rm """ operands = (Reg8Op, Reg8Op) + # TODO: integrate with the code gen interface: + src = (0, 1) + dst = (0,) 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 movregreg_ins(regreg_base): + # TODO: match this: + pattern = ir.Move(ir.Temp, ir.Temp) """ mov Rd, Rm """ mnemonic = 'mov' opcode = 0 + @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 lslregs_ins(regreg_base): mnemonic = 'LSL' @@ -511,7 +507,7 @@ """ cmp Rn, imm8 """ mnemonic = 'cmp' opcode = 5 # 00101 - operands = (RegOp, Imm8) + operands = (Reg8Op, Imm8) def __init__(self, rn, imm): self.rn = rn self.imm = imm @@ -522,6 +518,7 @@ h = (opcode << 11) | (rn << 8) | imm return u16(h) + # Jumping: def wrap_negative(x, bits): @@ -653,29 +650,29 @@ # misc: # add/sub SP: -@armtarget.instruction -class addspsp_ins(ArmInstruction): +class addspsp_base(ArmInstruction): operands = (RegSpOp, RegSpOp, Imm7) - mnemonic = 'add' def __init__(self, _sp, _sp2, imm7): self.imm7 = imm7.imm assert self.imm7 % 4 == 0 self.imm7 >>= 2 def encode(self): - return u16((0b101100000 << 7) |self.imm7) + return u16((self.opcode << 7) |self.imm7) + + def __repr__(self): + return '{} sp, sp, {}'.format(self.mnemonic, self.imm7 << 2) @armtarget.instruction -class subspsp_ins(ArmInstruction): - operands = (RegSpOp, RegSpOp, Imm7) +class addspsp_ins(addspsp_base): + mnemonic = 'add' + opcode = 0b101100000 + + +@armtarget.instruction +class subspsp_ins(addspsp_base): mnemonic = 'sub' - def __init__(self, _sp, _sp2, imm7): - self.imm7 = imm7.imm - assert self.imm7 % 4 == 0 - self.imm7 >>= 2 - - def encode(self): - return u16((0b101100001 << 7) |self.imm7) + opcode = 0b101100001 armtarget.check()