diff python/cortexm3.py @ 280:02385f62f250

Rework from str interface to Instruction interface
author Windel Bouwman
date Sat, 02 Nov 2013 10:03:26 +0100
parents 2ccd57b1d78c
children 1c7c1e619be8
line wrap: on
line diff
--- a/python/cortexm3.py	Sat Oct 12 09:56:23 2013 +0200
+++ b/python/cortexm3.py	Sat Nov 02 10:03:26 2013 +0100
@@ -1,6 +1,7 @@
 import struct
 import types
-from target import Register, Instruction, Target, Imm8, Label, Imm3, LabelRef, Imm32, Imm7
+from target import Register, Instruction, Target, Imm8, Label, Imm3, LabelRef
+from target import Imm32, Imm7
 from asmnodes import ASymbol, ANumber, AUnop, ABinop
 from ppci import CompilerError
 import ir
@@ -101,6 +102,7 @@
 class MemR8Rel:
     def __init__(self, basereg, offset):
         assert type(basereg) is Reg8Op
+        assert type(offset) is int
         self.basereg = basereg
         self.offset = offset
 
@@ -185,11 +187,13 @@
 lr = makeReg(ArmRegister, 14, 'lr')
 pc = makeReg(ArmRegister, 15, 'pc')
 
+# Sanity checks:
 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
 
@@ -205,6 +209,9 @@
         elif isinstance(expr, LabelRef):
             self.expr = 0
             self.label = expr
+        elif isinstance(expr, int):
+            self.expr = expr
+            self.label = None
         else:
             raise NotImplementedError()
 
@@ -218,6 +225,7 @@
     def __repr__(self):
         return 'DCD 0x{0:X}'.format(self.expr)
 
+
 @armtarget.instruction
 class nop_ins(ArmInstruction):
     mnemonic = 'nop'
@@ -252,19 +260,32 @@
         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
 
+    @classmethod
+    def fromim(cls, im):
+        mem = MemR8Rel(im.src[0], im.others[0])
+        return cls(im.src[1], mem)
+
+
 @armtarget.instruction
 class loadimm5_ins(LS_imm5_base):
     mnemonic = 'LDR'
     opcode = 0xD
 
+    @classmethod
+    def fromim(cls, im):
+        mem = MemR8Rel(im.src[0], im.others[0])
+        return cls(im.dst[0], mem)
+
 class ls_sp_base_imm8(ArmInstruction):
     operands = (Reg8Op, MemSpRel)
     def __init__(self, rt, memop):
@@ -299,6 +320,10 @@
         self.label = label
         self.offset = 0
 
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.others[0])
+
     def resolve(self, f):
         la = f(self.label.name)
         sa = align(self.address + 2, 4)
@@ -335,15 +360,23 @@
 
 
 @armtarget.instruction
-class mov_ins(ArmInstruction):
+class mov_imm8_ins(ArmInstruction):
     """ mov Rd, imm8, move immediate value into register """
     mnemonic = 'mov'
     opcode = 4 # 00100 Rd(3) imm8
     operands = (Reg8Op, Imm8)
     def __init__(self, rd, imm):
+        if type(imm) is int:
+            imm = Imm8(imm)
+        assert type(imm) is Imm8
         self.imm = imm.imm
+        assert type(rd) is Reg8Op, str(type(rd))
         self.rd = rd
 
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.others[0])
+
     def encode(self):
         rd = self.rd.num
         opcode = self.opcode
@@ -365,8 +398,13 @@
     def __init__(self, rd, rn, imm3):
         self.rd = rd
         self.rn = rn
+        assert type(imm3) is Imm3
         self.imm3 = imm3
 
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.src[0], im.others[0])
+
     def encode(self):
         rd = self.rd.num
         rn = self.rn.num
@@ -399,12 +437,18 @@
         self.rd = rd
         self.rn = rn
         self.rm = rm
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.src[0], im.src[1])
+
     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)
 
@@ -424,12 +468,17 @@
 
 @armtarget.instruction
 class movregreg_ext_ins(ArmInstruction):
+    """ mov rd, rm """
     operands = (ArmRegister, ArmRegister)
     mnemonic = 'MOV'
     def __init__(self, rd, rm):
         self.rd = rd
         self.rm = rm
 
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.src[0])
+
     def encode(self):
         Rd = self.rd.num & 0x7
         D = (self.rd.num >> 3) & 0x1
@@ -450,6 +499,11 @@
         self.rn = rn
         self.rdm = rdm
 
+    @classmethod
+    def fromim(cls, im):
+        assert im.src[1] is im.dst[0]
+        return cls(im.src[0], im.dst[0])
+
     def encode(self):
         rn = self.rn.num
         rdm = self.rdm.num
@@ -471,6 +525,10 @@
         self.rdn = rdn
         self.rm = rm
 
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.src[0], im.src[1])
+
     def encode(self):
         rdn = self.rdn.num
         rm = self.rm.num
@@ -483,9 +541,9 @@
 
 @armtarget.instruction
 class movregreg_ins(regreg_base):
+    """ mov Rd, Rm (reg8 operands) """
     # TODO: match this:
     pattern = ir.Move(ir.Temp, ir.Temp)
-    """ mov Rd, Rm """
     mnemonic = 'mov'
     opcode = 0
 
@@ -548,13 +606,11 @@
         la = f(self.target.name)
         sa = self.address + 4
         self.offset = (la - sa)
-        #if self.offset < 0:
-        #    # TODO: handle negative jump
-        #    self.offset = 0
 
     def __repr__(self):
         return '{} {}'.format(self.mnemonic, self.target.name)
 
+
 @armtarget.instruction
 class b_ins(jumpBase_ins):
     mnemonic = 'B'
@@ -563,6 +619,7 @@
         h = (0b11100 << 11) | imm11 # | 1 # 1 to enable thumb mode
         return u16(h)
 
+
 @armtarget.instruction
 class bl_ins(jumpBase_ins):
     mnemonic = 'BL'
@@ -577,6 +634,7 @@
         h2 = (0b1101 << 12) | (j1 << 13) | (j2 << 11) | imm11
         return u16(h1) + u16(h2)
 
+
 class cond_base_ins(jumpBase_ins):
     def encode(self):
         imm8 = wrap_negative(self.offset >> 1, 8)
@@ -603,7 +661,7 @@
 
 
 @armtarget.instruction
-class blt_ins(cond_base_ins):
+class bgt_ins(cond_base_ins):
     mnemonic = 'bgt'
     cond = 0b1100
 
@@ -630,14 +688,18 @@
         h = (0x5a << 9) | (M << 8) | reg_list
         return u16(h)
 
+
 @armtarget.instruction
 class pop_ins(ArmInstruction):
     operands = (RegisterSet,)
     mnemonic = 'pop'
+
     def __init__(self, regs):
         self.regs = regs
+
     def __repr__(self):
         return '{0} {{{1}}}'.format(self.mnemonic, self.regs)
+
     def encode(self):
         reg_list = 0
         P = 0
@@ -651,10 +713,12 @@
         h = (0x5E << 9) | (P << 8) | reg_list
         return u16(h)
 
+
 @armtarget.instruction
 class yield_ins(ArmInstruction):
     operands = ()
     mnemonic = 'yield'
+
     def encode(self):
         return u16(0xbf10)