Mercurial > lcfOS
view python/ppci/target/thumb/armtarget.py @ 394:988f3fb861e4
c3 code generator rewrite
author | Windel Bouwman |
---|---|
date | Thu, 22 May 2014 08:14:12 +0200 |
parents | 6df89163e114 |
children |
line wrap: on
line source
import struct from ..basetarget import Register, Instruction, Target, Label, Alignment from .instructions import Add2, Sub, Sub3, Add3, Cmp, Lsl, Orr, Add, Cmp2, Sub2, Add2, Mul, And from .instructions import Dcd, Pop, Push, Yield, Mov2, Mov3 from .instructions import B, Bl, Bne, Beq, Blt, Bgt from .instructions import Ldr, Str2, Ldr2, Str1, Ldr1, Ldr3 from .frame import ArmFrame from .arminstructionselector import ArmInstructionSelector from ..arm.registers import R0, R1, R2, R3, R4, R5, R6, R7, SP, LR, PC from ..arm.registers import register_range from ...assembler import BaseAssembler """ ARM target description. """ # TODO: encode this in DSL (domain specific language) # TBD: is this required? # TODO: make a difference between armv7 and armv5? class ThumbAssembler(BaseAssembler): def __init__(self, target): super().__init__(target) self.make_parser() class ThumbTarget(Target): def __init__(self): super().__init__('thumb') self.ins_sel = ArmInstructionSelector() self.FrameClass = ArmFrame self.add_rules() # Add lowering options: self.add_lowering(Str2, lambda im: Str2(im.src[1], im.src[0], im.others[0])) self.add_lowering(Ldr2, lambda im: Ldr2(im.dst[0], im.src[0], im.others[0])) self.add_lowering(Ldr3, lambda im: Ldr3(im.dst[0], im.others[0])) self.add_lowering(Mov3, lambda im: Mov3(im.dst[0], im.others[0])) self.add_lowering(Add2, lambda im: Add2(im.dst[0], im.src[0], im.others[0])) self.add_lowering(Sub2, lambda im: Sub2(im.dst[0], im.src[0], im.others[0])) self.add_lowering(Mov2, lambda im: Mov2(im.dst[0], im.src[0])) self.add_lowering(Add3, lambda im: Add3(im.dst[0], im.src[0], im.src[1])) self.add_lowering(Sub3, lambda im: Sub3(im.dst[0], im.src[0], im.src[1])) self.add_lowering(Mul, lambda im: Mul(im.src[0], im.dst[0])) self.add_lowering(And, lambda im: And(im.src[0], im.src[1])) self.add_lowering(Orr, lambda im: Orr(im.src[0], im.src[1])) self.add_lowering(Lsl, lambda im: Lsl(im.src[0], im.src[1])) self.add_lowering(Cmp, lambda im: Cmp(im.src[0], im.src[1])) self.assembler = ThumbAssembler(self) 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: Add(SP, SP, rhs[5])) self.add_keyword('cmp') self.add_instruction(['cmp', 'reg8', ',', 'reg8'], lambda rhs: Cmp(rhs[1], rhs[3])) self.add_instruction(['cmp', 'reg8', ',', 'imm8'], lambda rhs: Cmp2(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)