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()