Mercurial > lcfOS
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)