view python/target/armtarget.py @ 341:4d204f6f7d4e devel

Rewrite of assembler parts
author Windel Bouwman
date Fri, 28 Feb 2014 18:07:14 +0100
parents c7cc54c0dfdf
children
line wrap: on
line source

import struct
from .basetarget import Register, Instruction, Target, Label, Alignment
from .basetarget import Imm32, Imm8, Imm7, Imm3
from .arminstructions import Add2, Sub, Add3, Cmp, Lsl, Orr
from .arminstructions import Dcd, Pop, Push, Yield, Mov2, Mov3
from .arminstructions import B, Bl, Bne, Beq, Blt, Bgt
from .arminstructions import Ldr, Str2, Ldr2, Str1, Ldr1

from .armframe import ArmFrame
from .arminstructionselector import ArmInstructionSelector
from .armregisters import R0, R1, R2, R3, R4, R5, R6, R7, SP, LR, PC
from .armregisters import register_range


""" ARM target description. """

# TODO: encode this in DSL (domain specific language)
# TBD: is this required?
# TODO: make a difference between armv7 and armv5?

thumb_assembly_rules = []
def add_rule(rhs, f):
    thumb_assembly_rules.append(('instruction', rhs, f))


class ThumbTarget(Target):
    def __init__(self):
        super().__init__('thumb')
        self.ins_sel = ArmInstructionSelector()
        self.FrameClass = ArmFrame
        self.add_rules()

    def add_rules(self):

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

        self.add_keyword('mov')
        self.add_instruction(['mov', 'reg8', ',', 'reg8'],
                lambda rhs: Mov2(rhs[1], rhs[3]))

        self.add_instruction(['mov', 'reg8', ',', 'imm8'],
                lambda rhs: Mov3(rhs[1], rhs[3]))

        self.add_keyword('add')
        self.add_instruction(['add', 'reg8', ',', 'reg8', ',', 'imm3'],
                lambda rhs: Add2(rhs[1], rhs[3], rhs[5]))

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

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

        self.add_instruction(['sub', 'sp', ',', 'sp', ',', 'imm8'],
                lambda rhs: Sub(SP, SP, rhs[5]))

        self.add_instruction(['add', 'sp', ',', 'sp', ',', 'imm8'],
                lambda rhs: Sub(SP, SP, rhs[5]))

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

        self.add_keyword('lsl')
        self.add_instruction(['lsl', 'reg8', ',', 'reg8'],
                lambda rhs: Lsl(rhs[1], rhs[3]))

        self.add_keyword('str')
        self.add_instruction(['str', 'reg8', ',', '[', 'reg8', '+', 'imm5', ']'],
                lambda rhs: Str2(rhs[1], rhs[4], rhs[6]))

        self.add_keyword('ldr')
        self.add_instruction(['ldr', 'reg8', ',', '[', 'reg8', '+', 'imm5', ']'],
                lambda rhs: Ldr2(rhs[1], rhs[4], rhs[6]))

        self.add_instruction(['str', 'reg8', ',', '[', 'sp', '+', 'imm8', ']'],
                lambda rhs: Str1(rhs[1], rhs[6]))

        self.add_instruction(['ldr', 'reg8', ',', '[', 'sp', '+', 'imm8', ']'],
                lambda rhs: Ldr1(rhs[1], rhs[6]))

        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('yield')
        self.add_instruction(['yield'], lambda rhs: Yield())

        self.add_keyword('b')
        self.add_keyword('bl')
        self.add_instruction(['b', 'ID'], lambda rhs: B(rhs[1].val))
        self.add_instruction(['bl', 'ID'], lambda rhs: Bl(rhs[1].val))
        self.add_keyword('beq')
        self.add_keyword('bne')
        self.add_keyword('blt')
        self.add_keyword('bgt')
        self.add_instruction(['beq', 'ID'], lambda rhs: Beq(rhs[1].val))
        self.add_instruction(['bne', 'ID'], lambda rhs: Bne(rhs[1].val))
        self.add_instruction(['blt', 'ID'], lambda rhs: Blt(rhs[1].val))
        self.add_instruction(['bgt', 'ID'], lambda rhs: Bgt(rhs[1].val))

        self.add_keyword('align')
        self.add_instruction(['align', 'imm8'], lambda rhs: Alignment(rhs[1]))

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

        # Additional rules:

        # 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', ['reg8'], lambda rhs: {rhs[0]})
        self.add_rule('reg_or_range', ['lr'], lambda rhs: {LR})
        self.add_rule('reg_or_range', ['pc'], lambda rhs: {PC})

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

        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('sp')
        self.add_keyword('lr')
        self.add_keyword('pc')
        self.add_rule('reg8', ['r0'], lambda rhs: R0)
        self.add_rule('reg8', ['r1'], lambda rhs: R1)
        self.add_rule('reg8', ['r2'], lambda rhs: R2)
        self.add_rule('reg8', ['r3'], lambda rhs: R3)
        self.add_rule('reg8', ['r4'], lambda rhs: R4)
        self.add_rule('reg8', ['r5'], lambda rhs: R5)
        self.add_rule('reg8', ['r6'], lambda rhs: R6)
        self.add_rule('reg8', ['r7'], lambda rhs: R7)
        # Constants:
        self.add_rule('imm32', ['val32'], lambda x: x[0].val)
        self.add_rule('imm32', ['imm8'], lambda x: x[0])
        self.add_rule('imm8', ['val8'], lambda x: x[0].val)
        self.add_rule('imm8', ['imm5'], lambda x: x[0])
        self.add_rule('imm5', ['val5'], lambda x: x[0].val)
        self.add_rule('imm5', ['imm3'], lambda x: x[0])
        self.add_rule('imm3', ['val3'], lambda x: x[0].val)



class ArmArmTarget(Target):
    def __init__(self):
        super().__init__('arm_arm')

        # Assembly grammar:
        self.add_keyword('mov')
        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_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_instruction(['mov', 'reg', ',', 'imm8'],
                lambda rhs: Yield())

        self.add_rule('imm32', ['val32'], lambda x: x[0].val)
        self.add_rule('imm32', ['imm8'], lambda x: x[0])
        self.add_rule('imm8', ['val8'], lambda x: x[0].val)
        self.add_rule('imm8', ['imm5'], lambda x: x[0])
        self.add_rule('imm5', ['val5'], lambda x: x[0].val)
        self.add_rule('imm5', ['imm3'], lambda x: x[0])
        self.add_rule('imm3', ['val3'], lambda x: x[0].val)