view 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 source

from target import Register, Instruction, Target
from asmnodes import ASymbol, ANumber
from ppci import CompilerError
import struct, types

def u16(h):
    return struct.pack('<H', h)

armtarget = Target('arm')

class ArmReg(Register):
    def __init__(self, num, name):
        super().__init__(name)
        self.num = num

class ArmImm:
    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

@armtarget.instruction
class ldr_ins(ArmInstruction):
    mnemonic = 'ldr'
    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 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
        imm8 = self.imm
        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):
    operands = ()
    mnemonic = 'yield'
    def encode(self):
        return u16(0xbf10)