view python/ppci/target/arm/__init__.py @ 362:c05ab629976a

Added CPUID for arm
author Windel Bouwman
date Sat, 15 Mar 2014 10:56:34 +0100
parents b4ac28efcdf4
children c49459768aaa
line wrap: on
line source


from ..basetarget import Target
from ..arm.registers import R0, R1, R2, R3, R4, R5, R6, R7
from ..arm.registers import R8, R9, R10, R11, R12, SP, LR, PC
from ..arm.registers import register_range

from .instructions import Dcd, Mov, Mov1, Add, Add2, Sub, Orr1, Mul, Mov2, Add1, Mul1
from .instructions import Lsr1, Lsl1, And1, Sub1
from .instructions import B, Bl, Ble, Bgt, Beq, Blt, Cmp, Cmp2
from .instructions import Push, Pop, Str, Ldr, Ldr3, Str1, Ldr1, Adr
from .instructions import Mcr, Mrc
from .selector import ArmInstructionSelector
from .frame import ArmFrame

class ArmTarget(Target):
    def __init__(self):
        super().__init__('arm')
        self.make_parser()
        self.ins_sel = ArmInstructionSelector()
        self.FrameClass = ArmFrame

        self.add_lowering(Ldr3, lambda im: Ldr3(im.dst[0], im.others[0]))
        self.add_lowering(Str1, lambda im: Str1(im.src[1], im.src[0], im.others[0]))
        self.add_lowering(Ldr1, lambda im: Ldr1(im.dst[0], im.src[0], im.others[0]))
        self.add_lowering(Adr, lambda im: Adr(im.dst[0], im.others[0]))
        self.add_lowering(Mov2, lambda im: Mov2(im.dst[0], im.src[0]))
        self.add_lowering(Cmp2, lambda im: Cmp2(im.src[0], im.src[1]))
        self.add_lowering(Add1, lambda im: Add1(im.dst[0], im.src[0], im.src[1]))
        self.add_lowering(Add2, lambda im: Add2(im.dst[0], im.src[0], im.others[0]))
        self.add_lowering(Sub1, lambda im: Sub1(im.dst[0], im.src[0], im.src[1]))
        self.add_lowering(Mul1, lambda im: Mul1(im.dst[0], im.src[0], im.src[1]))
        self.add_lowering(Lsr1, lambda im: Lsr1(im.dst[0], im.src[0], im.src[1]))
        self.add_lowering(And1, lambda im: And1(im.dst[0], im.src[0], im.src[1]))
        self.add_lowering(Mov1, lambda im: Mov1(im.dst[0], im.others[0]))

    def make_parser(self):
        # Assembly grammar:
        self.add_keyword('r0')
        self.add_keyword('r1')
        self.add_keyword('r2')
        self.add_keyword('r3')
        self.add_keyword('r4')
        self.add_keyword('r5')
        self.add_keyword('r6')
        self.add_keyword('r7')
        self.add_keyword('r8')
        self.add_keyword('r9')
        self.add_keyword('r10')
        self.add_keyword('r11')
        self.add_keyword('r12')
        self.add_keyword('sp')
        self.add_keyword('lr')
        self.add_keyword('pc')

        self.add_rule('reg', ['r0'], lambda rhs: R0)
        self.add_rule('reg', ['r1'], lambda rhs: R1)
        self.add_rule('reg', ['r2'], lambda rhs: R2)
        self.add_rule('reg', ['r3'], lambda rhs: R3)
        self.add_rule('reg', ['r4'], lambda rhs: R4)
        self.add_rule('reg', ['r5'], lambda rhs: R5)
        self.add_rule('reg', ['r6'], lambda rhs: R6)
        self.add_rule('reg', ['r7'], lambda rhs: R7)
        self.add_rule('reg', ['r8'], lambda rhs: R8)
        self.add_rule('reg', ['r9'], lambda rhs: R9)
        self.add_rule('reg', ['r10'], lambda rhs: R10)
        self.add_rule('reg', ['r11'], lambda rhs: R11)
        self.add_rule('reg', ['r12'], lambda rhs: R12)
        self.add_rule('reg', ['sp'], lambda rhs: SP)
        self.add_rule('reg', ['lr'], lambda rhs: LR)
        self.add_rule('reg', ['pc'], lambda rhs: PC)

        self.add_keyword('dcd')
        self.add_instruction(['dcd', 'imm32'],
                lambda rhs: Dcd(rhs[1]))

        self.add_keyword('mov')
        self.add_instruction(['mov', 'reg', ',', 'imm32'],
                lambda rhs: Mov(rhs[1], rhs[3]))
        self.add_instruction(['mov', 'reg', ',', 'reg'],
                lambda rhs: Mov(rhs[1], rhs[3]))

        self.add_keyword('cmp')
        self.add_instruction(['cmp', 'reg', ',', 'imm32'],
                lambda rhs: Cmp(rhs[1], rhs[3]))
        self.add_instruction(['cmp', 'reg', ',', 'reg'],
                lambda rhs: Cmp(rhs[1], rhs[3]))

        # Arithmatic:
        self.add_keyword('add')
        self.add_instruction(['add', 'reg', ',', 'reg', ',', 'imm32'],
                lambda rhs: Add(rhs[1], rhs[3], rhs[5]))

        self.add_instruction(['add', 'reg', ',', 'reg', ',', 'reg'],
                lambda rhs: Add(rhs[1], rhs[3], rhs[5]))

        self.add_keyword('sub')
        self.add_instruction(['sub', 'reg', ',', 'reg', ',', 'imm32'],
                lambda rhs: Sub(rhs[1], rhs[3], rhs[5]))

        self.add_instruction(['sub', 'reg', ',', 'reg', ',', 'reg'],
                lambda rhs: Sub(rhs[1], rhs[3], rhs[5]))

        self.add_keyword('mul')
        self.add_instruction(['mul', 'reg', ',', 'reg', ',', 'reg'],
                lambda rhs: Mul(rhs[1], rhs[3], rhs[5]))

        self.add_keyword('orr')
        self.add_instruction(['orr', 'reg', ',', 'reg', ',', 'reg'],
                lambda rhs: Orr1(rhs[1], rhs[3], rhs[5]))

        self.add_keyword('and')
        self.add_instruction(['and', 'reg', ',', 'reg', ',', 'reg'],
                lambda rhs: And1(rhs[1], rhs[3], rhs[5]))

        self.add_keyword('lsr')
        self.add_instruction(['lsr', 'reg', ',', 'reg', ',', 'reg'],
                lambda rhs: Lsr1(rhs[1], rhs[3], rhs[5]))

        self.add_keyword('lsl')
        self.add_instruction(['lsl', 'reg', ',', 'reg', ',', 'reg'],
                lambda rhs: Lsl1(rhs[1], rhs[3], rhs[5]))


        # Jumping:
        self.add_keyword('b')
        self.add_instruction(['b', 'ID'], lambda rhs: B(rhs[1].val))
        self.add_keyword('ble')
        self.add_instruction(['ble', 'ID'], lambda rhs: Ble(rhs[1].val))
        self.add_keyword('bgt')
        self.add_instruction(['bgt', 'ID'], lambda rhs: Bgt(rhs[1].val))
        self.add_keyword('beq')
        self.add_instruction(['beq', 'ID'], lambda rhs: Beq(rhs[1].val))
        self.add_keyword('blt')
        self.add_instruction(['blt', 'ID'], lambda rhs: Blt(rhs[1].val))

        self.add_keyword('bl')
        self.add_instruction(['bl', 'ID'], lambda rhs: Bl(rhs[1].val))

        # memory:
        self.add_keyword('pop')
        self.add_instruction(['pop', 'reg_list'], lambda rhs: Pop(rhs[1]))

        self.add_keyword('push')
        self.add_instruction(['push', 'reg_list'], lambda rhs: Push(rhs[1]))

        self.add_keyword('ldr')
        self.add_instruction(['ldr', 'reg', ',', '[', 'reg', ',', 'imm8', ']'],
            lambda rhs: Ldr(rhs[1], rhs[4], rhs[6]))

        self.add_instruction(['ldr', 'reg', ',', 'ID'],
            lambda rhs: Ldr(rhs[1], rhs[3].val))

        self.add_keyword('str')
        self.add_instruction(['str', 'reg', ',', '[', 'reg', ',', 'imm8', ']'],
            lambda rhs: Str(rhs[1], rhs[4], rhs[6]))

        self.add_instruction(['str', 'reg', ',', '[', 'reg', ',', 'reg', ']'],
            lambda rhs: Str(rhs[1], rhs[4], rhs[6]))

        self.add_keyword('adr')
        self.add_instruction(['adr', 'reg', ',', 'ID'],
            lambda rhs: Adr(rhs[1], rhs[3].val))

        # Register list grammar:
        self.add_rule('reg_list', ['{', 'reg_list_inner', '}'],
            lambda rhs: rhs[1])
        self.add_rule('reg_list_inner', ['reg_or_range'],
            lambda rhs: rhs[0])
        self.add_rule('reg_list_inner', ['reg_or_range', ',', 'reg_list_inner'],
            lambda rhs: rhs[0] | rhs[2])
        self.add_rule('reg_or_range', ['reg'], lambda rhs: {rhs[0]})

        self.add_rule('reg_or_range', ['reg', '-', 'reg'],
            lambda rhs: register_range(rhs[0], rhs[2]))

        # Add MCR and MRC (co-processor)
        for i in range(16):
            creg = 'c{}'.format(i)
            self.add_keyword(creg)
            self.add_rule('coreg', [creg], i)

        for i in range(8, 16):
            px = 'p{}'.format(i)
            self.add_keyword(px)
            # Ran into trouble when using i inside lambda function:
            # When using inside lambda (as a closure), i is bound to the latest
            # value (15)
            self.add_rule('coproc', [px], i)

        self.add_keyword('mcr')
        self.add_instruction(['mcr', 'coproc', ',', 'imm3', ',', 'reg', ',', 'coreg', ',', 'coreg', ',', 'imm3'],
            lambda rhs: Mcr(rhs[1], rhs[3], rhs[5], rhs[7], rhs[9], rhs[11]))

        self.add_keyword('mrc')
        self.add_instruction(['mrc', 'coproc', ',', 'imm3', ',', 'reg', ',', 'coreg', ',', 'coreg', ',', 'imm3'],
            lambda rhs: Mrc(rhs[1], rhs[3], rhs[5], rhs[7], rhs[9], rhs[11]))