Mercurial > lcfOS
view python/ppci/target/arm/__init__.py @ 381:6df89163e114
Fix section and ldr pseudo instruction
author | Windel Bouwman |
---|---|
date | Sat, 26 Apr 2014 17:41:56 +0200 |
parents | 19eacf4f7270 |
children | 2a970e7270e2 |
line wrap: on
line source
from ..basetarget import Target, Label 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 .instructions import LdrPseudo from .selector import ArmInstructionSelector from .frame import ArmFrame from ...assembler import BaseAssembler class ArmAssembler(BaseAssembler): def __init__(self, target): super().__init__(target) self.target.add_keyword('section') self.target.add_instruction(['section', 'ID'], lambda rhs: self.select_section(rhs[1].val)) self.make_parser() self.lit_pool = [] self.lit_counter = 0 def select_section(self, name): self.flush() self.stream.select_section(name) def flush(self): while self.lit_pool: i = self.lit_pool.pop(0) self.emit(i) def add_literal(self, v): """ For use in the pseudo instruction LDR r0, =SOMESYM """ # Invent some label for the literal and store it. self.lit_counter += 1 label_name = "_lit_{}".format(self.lit_counter) self.lit_pool.append(Label(label_name)) self.lit_pool.append(Dcd(v)) return label_name class ArmTarget(Target): def __init__(self): super().__init__('arm') self.make_parser() self.ins_sel = ArmInstructionSelector() self.FrameClass = ArmFrame self.assembler = ArmAssembler(self) 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 emit_global(self, outs, lname): outs.emit(Label(lname)) outs.emit(Dcd(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)) # This is a pseudo instruction: self.add_instruction(['ldr', 'reg', ',', '=', 'ID'], lambda rhs: LdrPseudo(rhs[1], rhs[4].val, self.assembler.add_literal)) 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]))