Mercurial > lcfOS
diff python/arm_cm3.py @ 203:ca1ea402f6a1
Added some arm instructions
author | Windel Bouwman |
---|---|
date | Sat, 15 Jun 2013 19:13:05 +0200 |
parents | f22b431f4113 |
children | d77cb5962cc5 |
line wrap: on
line diff
--- a/python/arm_cm3.py Sat Jun 15 10:02:50 2013 +0200 +++ b/python/arm_cm3.py Sat Jun 15 19:13:05 2013 +0200 @@ -8,25 +8,6 @@ armtarget = Target('arm') -# Add a custom operand mapping method: -def mapOp(self, operand): - if type(operand) is ASymbol: - # try to map to register: - regs = {} - for r in self.registers: - regs[r.name] = r - if operand.name in regs: - reg = regs[operand.name] - return reg - elif type(operand) is ANumber: - return ArmImm(operand.number) - raise CompilerError('Cannot map {0}'.format(operand)) - -armtarget.mapOperand = types.MethodType(mapOp, armtarget) - -# Define: -registers = 'r0,r1,r2,r3,r4,r5' - class ArmReg(Register): def __init__(self, num, name): super().__init__(name) @@ -36,9 +17,52 @@ 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 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) + # 8 bit registers: 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 @@ -49,15 +73,21 @@ opcode = 1337 +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 - operands = (ArmReg, ArmImm) - def __init__(self, r, imm): - self.imm = imm.i - self.r = r.num + opcode = 4 # 00100 Rd(3) imm8 + operands = (RegOp, Imm8) + def __init__(self, rd, imm): + self.imm = imm.imm + self.r = rd.num def encode(self): rd = self.r opcode = self.opcode @@ -65,6 +95,59 @@ 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) + 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 yield_ins(ArmInstruction):