Mercurial > lcfOS
diff python/target/msp430.py @ 290:7b38782ed496
File moves
author | Windel Bouwman |
---|---|
date | Sun, 24 Nov 2013 11:24:15 +0100 |
parents | python/msp430.py@ca1ea402f6a1 |
children | 534b94b40aa8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/target/msp430.py Sun Nov 24 11:24:15 2013 +0100 @@ -0,0 +1,248 @@ +from target import Register, Instruction, Target +from asmnodes import ASymbol, ANumber +from ppci import CompilerError +import struct +import types + +# Create the target class (singleton): +msp430target = Target("MSP430") + +REGISTER_MODE = 1 +SYMBOLIC_MODE = 3 +ABSOLUTE_MODE = 4 +#TODO: add more modes! +IMMEDIATE_MODE = 7 + +# Target description for the MSP430 processor + +class MSP430Reg(Register): + def __init__(self, num, name): + super().__init__(name) + self.num = num + +# 8 bit registers: +PCB = MSP430Reg(0, 'r0') +rpc = PCB +r11 = MSP430Reg(11, 'r11') +r12 = MSP430Reg(12, 'r12') +r13 = MSP430Reg(13, 'r13') +r14 = MSP430Reg(14, 'r14') +r15 = MSP430Reg(15, 'r15') + +class MSP430Mem: + pass + +msp430target.registers.append(r11) +msp430target.registers.append(r12) +msp430target.registers.append(r13) +msp430target.registers.append(r14) +msp430target.registers.append(r15) + +# .. etc + +#GR8 = RegisterClass((PCB, R15B)) + +class MSP430Operand: + def __init__(self, mode, param): + self.mode = mode + self.param = param + def regField(self): + if self.mode == REGISTER_MODE: + return self.param + elif self.mode == IMMEDIATE_MODE: + return rpc.num + def asField(self): + if self.mode == REGISTER_MODE: + return 0 + elif self.mode == IMMEDIATE_MODE: + return 3 + def adField(self): + if self.mode == REGISTER_MODE: + return 0 + elif self.mode == IMMEDIATE_MODE: + raise CompilerError('Cannot use immediate mode for destination operand') + def extraBytes(self): + 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('<H', h) + +class MSP430Instruction(Instruction): + b = 0 + +class BInstruction: + pass + +class MSP430CoreInstruction(Instruction): + pass + +######################### +# Single operand arithmatic: +######################### + +@msp430target.instruction +class reti_ins(MSP430Instruction): + mnemonic = 'reti' + operands = () + def encode(self): + h = 0x1300 + return pack_ins(h) + +class OneOpArith(MSP430Instruction): + operands = (MSP430Reg, ) + def __init__(self, op1): + self.op1 = op1 + def encode(self): + # TODO: + bits[15:10] = '00100' + h1 = (self.opcode << 4) + return pack_ins(h1) + +def oneOpIns(mne, opc): + """ Helper function to define a one operand arithmetic instruction """ + members = {'mnemonic': mne, 'opcode': opc} + ins_cls = type(mne + '_ins', (OneOpArith,), members) + msp430target.addInstruction(ins_cls) + +oneOpIns('rrc', 0) +oneOpIns('swpb', 1) +oneOpIns('rra', 2) +oneOpIns('sxt', 3) +oneOpIns('push', 4) +oneOpIns('call', 5) + +######################### +# Jump instructions: +######################### + +class JumpInstruction(Instruction): + def __init__(self, offset): + self.offset = offset + + def encode(self): + h = (1 << 13) | (self.condition << 10) | (self.offset) + return pack_ins(h) + +@msp430target.instruction +class jnz_ins(JumpInstruction): + mnemonic = 'jnz' + condition = 0 + +@msp430target.instruction +class jz_ins(JumpInstruction): + mnemonic = 'jz' + condition = 1 + +@msp430target.instruction +class jnc_ins(JumpInstruction): + mnemonic = 'jnc' + condition = 2 + +@msp430target.instruction +class jc_ins(JumpInstruction): + mnemonic = 'jc' + condition = 3 + +@msp430target.instruction +class jn_ins(JumpInstruction): + mnemonic = 'jn' + condition = 4 + +@msp430target.instruction +class jge_ins(JumpInstruction): + mnemonic = 'jge' + condition = 5 + +@msp430target.instruction +class jl_ins(JumpInstruction): + mnemonic = 'jl' + condition = 6 + +@msp430target.instruction +class jmp_ins(JumpInstruction): + mnemonic = 'jmp' + condition = 7 + +######################### +# Two operand arithmatic instructions: +######################### + + +class TwoOpArith(MSP430Instruction): + operands = (MSP430Operand, MSP430Operand) + def __init__(self, src, dst): + self.op1 = src + self.op2 = dst + + def encode(self): + """ + Smart things have been done by MSP430 designers. + As (2 bits) is the source addressing mode selector. + Ad (1 bit) is the destination adressing mode selector. + For the source there are 7 different addressing mode. + For the destination there are 4. + The trick is to use also the register to distuingish the + different modes. + """ + # TODO: Make memory also possible + + As = self.op1.asField() # addressing mode for the source + Ad = self.op2.adField() # Addressing mode for dst + b = self.b # When b=1, the operation is byte mode + source = self.op1.regField() + destination = self.op2.regField() + h = (self.opcode << 12) | (source << 8) + h |= (self.b << 6) | (As << 4) | (Ad << 7) | destination + additions = self.op1.extraBytes() + self.op2.extraBytes() + return pack_ins(h) + additions + + def decode(self, data): + pass + + +def twoOpIns(mne, opc): + """ Helper function to define a two operand arithmetic instruction """ + members = {'mnemonic': mne, 'opcode': opc} + ins_cls = type(mne + '_ins', (TwoOpArith,), members) + msp430target.addInstruction(ins_cls) + +twoOpIns('mov', 4) + +# This is equivalent to the helper function twoOpIns: +@msp430target.instruction +class add_ins(TwoOpArith): + """ Adds the source to the destination """ + mnemonic = 'add' + opcode = 5 + + def operate(self): + dst.value = dst.value + src.value + setFlags() + +twoOpIns('addc', 6) +twoOpIns('subc', 7) +twoOpIns('sub', 8) +twoOpIns('cmp', 9) +twoOpIns('dadd', 10) +twoOpIns('bit', 11) +twoOpIns('bic', 12) +twoOpIns('bis', 13) +twoOpIns('xor', 14) +twoOpIns('and', 15) +