Mercurial > lcfOS
view python/arm_cm3.py @ 205:d77cb5962cc5
Added some handcoded arm code generation
author | Windel Bouwman |
---|---|
date | Sun, 23 Jun 2013 18:23:18 +0200 |
parents | ca1ea402f6a1 |
children | 6c6bf8890d8a |
line wrap: on
line source
import struct, types from target import Register, Instruction, Target from asmnodes import ASymbol, ANumber from ppci import CompilerError import ir def u16(h): return struct.pack('<H', h) def u32(x): return struct.pack('<I', x) armtarget = Target('arm') class ArmReg(Register): def __init__(self, num, name): super().__init__(name) self.num = num class ArmImm: def __init__(self, i): self.i = i class RegOp: def __init__(self, num): assert num < 8 self.num = num @classmethod def Create(cls, vop): if type(vop) is ASymbol: name = vop.name regs = {} for r in armtarget.registers: regs[r.name] = r if name in regs: r = regs[name] return cls(r.num) class Label: def __init__(self, name): self.name = name @classmethod def Create(cls, vop): if type(vop) is ASymbol: name = vop.name return cls(name) class Imm8: def __init__(self, imm): assert imm < 256 self.imm = imm @classmethod def Create(cls, vop): if type(vop) is ANumber and vop.number < 256: return cls(vop.number) class Imm3: def __init__(self, imm): assert imm < 8 assert type(imm) is int self.imm = imm @classmethod def Create(cls, vop): if type(vop) is ANumber and vop.number < 8: return cls(vop.number) class RegisterSet: def __init__(self, regs): pass # 8 bit registers: r0 = ArmReg(0, 'r0') armtarget.registers.append(r0) r4 = ArmReg(4, 'r4') armtarget.registers.append(r4) r5 = ArmReg(5, 'r5') armtarget.registers.append(r5) r6 = ArmReg(6, 'r6') armtarget.registers.append(r6) r7 = ArmReg(7, 'r7') armtarget.registers.append(r7) class ArmInstruction(Instruction): pass @armtarget.instruction class ldr_ins(ArmInstruction): mnemonic = 'ldr' opcode = 1337 irpattern = 'todo' @armtarget.instruction class dcd_ins(ArmInstruction): mnemonic = 'dcd' def __init__(self, expr): self.expr = expr def encode(self): return u32(self.expr) class Operand2: def __init__(self, expr): if type(expr) is ANumber: pass pass @armtarget.instruction class mov_ins(ArmInstruction): """ mov Rd, imm8, move immediate value into register """ mnemonic = 'mov' opcode = 4 # 00100 Rd(3) imm8 operands = (RegOp, Imm8) irpattern = ir.ImmLoad def __init__(self, rd, imm): self.imm = imm.imm self.r = rd.num @classmethod def FromIr(cls, ir_ins): pass def encode(self): rd = self.r opcode = self.opcode imm8 = self.imm h = (opcode << 11) | (rd << 8) | imm8 return u16(h) @armtarget.instruction class movregreg_ins(ArmInstruction): """ mov Rd, Rm """ mnemonic = 'mov' opcode = 8 # 01000 Rd(3) imm8 operands = (RegOp, RegOp) def __init__(self, rd, rm): self.rd = rd self.rm = rm def encode(self): rd = self.rd.num D = (rd & 0x8) >> 3 assert D < 2 rd = rd & 0x7 rm = self.rm.num assert rm < 16 opcode = self.opcode h = (opcode << 11) | (3 << 9) | (D << 7) | (rm << 3) | rd return u16(h) @armtarget.instruction class addregregimm3_ins(ArmInstruction): """ add Rd, Rn, imm3 """ mnemonic = 'add' opcode = 3 # 00011 operands = (RegOp, RegOp, Imm3) irpattern = 3 def __init__(self, rd, rn, imm3): self.rd = rd self.rn = rn self.imm3 = imm3 def encode(self): rd = self.rd.num rn = self.rn.num imm3 = self.imm3.imm opcode = self.opcode h = (opcode << 11) | (1 << 10) | (imm3 << 6) | (rn << 3) | rd return u16(h) @armtarget.instruction class cmpregimm8_ins(ArmInstruction): """ cmp Rn, imm8 """ mnemonic = 'cmp' opcode = 5 # 00101 operands = (RegOp, Imm8) def __init__(self, rn, imm): self.rn = rn self.imm = imm def encode(self): rn = self.rn.num imm = self.imm.imm opcode = self.opcode h = (opcode << 11) | (rn << 8) | imm return u16(h) @armtarget.instruction class jmp_ins(ArmInstruction): operands = (Label) mnemonic = 'jmp' def __init__(self, target_label): self.target = target_label def fixUp(self): pass def encode(self): h = 1337 # TODO return u16(h) @armtarget.instruction class push_ins(ArmInstruction): operands = (RegisterSet) mnemonic = 'push' def __init__(self, regs): self.regs = regs def encode(self): return u16(0) @armtarget.instruction class pop_ins(ArmInstruction): operands = (RegisterSet) mnemonic = 'pop' def __init__(self, regs): self.regs = regs def encode(self): return u16(0) @armtarget.instruction class yield_ins(ArmInstruction): operands = () mnemonic = 'yield' def encode(self): return u16(0xbf10)