# HG changeset patch # User Windel Bouwman # Date 1371316385 -7200 # Node ID ca1ea402f6a12902a1a4505d8c400bb959072d8f # Parent f22b431f41131d8eca3e55c85750f01d0e72c017 Added some arm instructions diff -r f22b431f4113 -r ca1ea402f6a1 python/arm_cm3.py --- 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): diff -r f22b431f4113 -r ca1ea402f6a1 python/asm.py --- a/python/asm.py Sat Jun 15 10:02:50 2013 +0200 +++ b/python/asm.py Sat Jun 15 19:13:05 2013 +0200 @@ -160,10 +160,11 @@ raise CompilerError('Cannot assemble without target') while self.output: vi = self.output.pop(0) - ri = self.target.mapInstruction(vi) - b = ri.encode() - assert type(b) is bytes - self.binout.extend(b) + if type(vi) is AInstruction: + ri = self.target.mapInstruction(vi) + b = ri.encode() + assert type(b) is bytes + self.binout.extend(b) def back_patch(self): """ Fix references to earlier labels """ diff -r f22b431f4113 -r ca1ea402f6a1 python/asmnodes.py --- a/python/asmnodes.py Sat Jun 15 10:02:50 2013 +0200 +++ b/python/asmnodes.py Sat Jun 15 19:13:05 2013 +0200 @@ -12,12 +12,12 @@ return '{0}:'.format(self.name) class AInstruction(ANode): - def __init__(self, opcode, operands): - self.opcode = opcode + def __init__(self, mnemonic, operands): + self.mnemonic = mnemonic self.operands = operands def __repr__(self): ops = ', '.join(map(str, self.operands)) - return '{0} {1}'.format(self.opcode, ops) + return '{0} {1}'.format(self.mnemonic, ops) class AExpression(ANode): def __add__(self, other): diff -r f22b431f4113 -r ca1ea402f6a1 python/msp430.py --- a/python/msp430.py Sat Jun 15 10:02:50 2013 +0200 +++ b/python/msp430.py Sat Jun 15 19:13:05 2013 +0200 @@ -12,25 +12,6 @@ #TODO: add more modes! IMMEDIATE_MODE = 7 - - -# 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 MSP430Operand(REGISTER_MODE, reg.num) - elif type(operand) is ANumber: - # Immediate mode: - return MSP430Operand(IMMEDIATE_MODE, operand.number) - raise CompilerError('Cannot map {0}'.format(operand)) - -msp430target.mapOperand = types.MethodType(mapOp, msp430target) - # Target description for the MSP430 processor class MSP430Reg(Register): @@ -83,7 +64,20 @@ if self.mode == IMMEDIATE_MODE: return pack_ins(self.param) return bytes() - + + @classmethod + def Create(cls, vop): + if type(vop) is ASymbol: + # try to map to register: + regs = {} + for r in msp430target.registers: + regs[r.name] = r + if vop.name in regs: + reg = regs[vop.name] + return cls(REGISTER_MODE, reg.num) + elif type(vop) is ANumber: + # Immediate mode: + return cls(IMMEDIATE_MODE, vop.number) def pack_ins(h): return struct.pack('