diff python/arm_cm3.py @ 203:ca1ea402f6a1

Added some arm instructions
author Windel Bouwman
date Sat, 15 Jun 2013 19:13:05 +0200
parents f22b431f4113
children d77cb5962cc5
line wrap: on
line diff
--- a/python/arm_cm3.py	Sat Jun 15 10:02:50 2013 +0200
+++ b/python/arm_cm3.py	Sat Jun 15 19:13:05 2013 +0200
@@ -8,25 +8,6 @@
 
 armtarget = Target('arm')
 
-# Add a custom operand mapping method:
-def mapOp(self, operand):
-    if type(operand) is ASymbol:
-        # try to map to register:
-        regs = {}
-        for r in self.registers:
-            regs[r.name] = r
-        if operand.name in regs:
-            reg = regs[operand.name]
-            return reg
-    elif type(operand) is ANumber:
-        return ArmImm(operand.number)
-    raise CompilerError('Cannot map {0}'.format(operand))
-
-armtarget.mapOperand = types.MethodType(mapOp, armtarget)
-
-# Define:
-registers = 'r0,r1,r2,r3,r4,r5'
-
 class ArmReg(Register):
     def __init__(self, num, name):
         super().__init__(name)
@@ -36,9 +17,52 @@
     def __init__(self, i):
         self.i = i
 
+class RegOp:
+    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]
+                return cls(r.num)
+
+class Imm8:
+    def __init__(self, imm):
+        assert imm < 256
+        self.imm = imm
+
+    @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)
+
 # 8 bit registers:
 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)
 
 class ArmInstruction(Instruction):
     pass
@@ -49,15 +73,21 @@
     opcode = 1337
 
 
+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 """
     mnemonic = 'mov'
-    opcode = 4 # 00100
-    operands = (ArmReg, ArmImm)
-    def __init__(self, r, imm):
-        self.imm = imm.i
-        self.r = r.num
+    opcode = 4 # 00100 Rd(3) imm8
+    operands = (RegOp, Imm8)
+    def __init__(self, rd, imm):
+        self.imm = imm.imm
+        self.r = rd.num
     def encode(self):
         rd = self.r
         opcode = self.opcode
@@ -65,6 +95,59 @@
         h = (opcode << 11) | (rd << 8) | imm8
         return u16(h)
         
+@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
+        self.rm = rm
+    def encode(self):
+        rd = self.rd.num
+        D = (rd & 0x8) >> 3
+        assert D < 2
+        rd = rd & 0x7
+        rm = self.rm.num
+        assert rm < 16
+        opcode = self.opcode
+        h = (opcode << 11) | (3 << 9) | (D << 7) | (rm << 3) | rd
+        return u16(h)
+
+@armtarget.instruction
+class addregregimm3_ins(ArmInstruction):
+    """ add Rd, Rn, imm3 """
+    mnemonic = 'add'
+    opcode = 3 # 00011
+    operands = (RegOp, RegOp, Imm3)
+    def __init__(self, rd, rn, imm3):
+        self.rd = rd
+        self.rn = rn
+        self.imm3 = imm3
+    def encode(self):
+        rd = self.rd.num
+        rn = self.rn.num
+        imm3 = self.imm3.imm
+        opcode = self.opcode
+        h = (opcode << 11) | (1 << 10) | (imm3 << 6) | (rn << 3) | rd
+        return u16(h)
+
+@armtarget.instruction
+class cmpregimm8_ins(ArmInstruction):
+    """ cmp Rn, imm8 """
+    mnemonic = 'cmp'
+    opcode = 5 # 00101
+    operands = (RegOp, Imm8)
+    def __init__(self, rn, imm):
+        self.rn = rn
+        self.imm = imm
+    def encode(self):
+        rn = self.rn.num
+        imm = self.imm.imm
+        opcode = self.opcode
+        h = (opcode << 11) | (rn << 8) | imm
+        return u16(h)
 
 @armtarget.instruction
 class yield_ins(ArmInstruction):