Mercurial > lcfOS
diff python/msp430.py @ 201:d5debbfc0200
Added all 27 core instructions of msp430
author | Windel Bouwman |
---|---|
date | Thu, 13 Jun 2013 00:07:28 +0200 |
parents | 5e391d9a3381 |
children | f22b431f4113 |
line wrap: on
line diff
--- a/python/msp430.py Sun Jun 09 16:06:49 2013 +0200 +++ b/python/msp430.py Thu Jun 13 00:07:28 2013 +0200 @@ -1,4 +1,31 @@ from target import Register, Instruction, Target +from asmnodes import ASymbol, ANumber +from ppci import CompilerError +import struct, types + +# Create the target class (singleton): +msp430target = Target("MSP430") + +REGISTER_MODE = 1 +#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 @@ -9,41 +36,263 @@ # 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)) -# Two operand arithmatic instructions: +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() + -class TwoOpArith(Instruction): - operands = (MSP430Reg, MSP430Reg) - def __init__(self, op1, op2): +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 - self.op2 = op2 def encode(self): # TODO: - b1 = (self.opcode << 4) - b2 = 0 - ba = bytearray([b1, b2]) - return bytes(ba) + bits[15:10] = '00100' + h1 = (self.opcode << 4) + return pack_ins(h1) + +@msp430target.instruction +class rrc_ins(OneOpArith): + mnemonic = 'rrc' + opcode = 0 + +@msp430target.instruction +class swpb_ins(OneOpArith): + mnemonic = 'swpb' + opcode = 1 + +@msp430target.instruction +class rra_ins(OneOpArith): + mnemonic = 'rra' + opcode = 2 + +@msp430target.instruction +class sxt_ins(OneOpArith): + mnemonic = 'sxt' + opcode = 3 + +@msp430target.instruction +class push_ins(OneOpArith): + mnemonic = 'push' + opcode = 4 + +@msp430target.instruction +class call_ins(OneOpArith): + mnemonic = 'call' + opcode = 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 + +@msp430target.instruction class mov_ins(TwoOpArith): - # class variables: mnemonic = 'mov' opcode = 4 +@msp430target.instruction class add_ins(TwoOpArith): mnemonic = 'add' opcode = 5 -class MSP430(Target): - def __init__(self): - self.registers = [PCB, r13, r14, r15] - self.instructions = [mov_ins, add_ins] +@msp430target.instruction +class addc_ins(TwoOpArith): + mnemonic = 'addc' + opcode = 6 + +@msp430target.instruction +class subc_ins(TwoOpArith): + mnemonic = 'subc' + opcode = 7 + +@msp430target.instruction +class sub_ins(TwoOpArith): + mnemonic = 'sub' + opcode = 8 + +@msp430target.instruction +class cmp_ins(TwoOpArith): + """ Compare, substract source from destination """ + mnemonic = 'cmp' + opcode = 9 -t = MSP430() +@msp430target.instruction +class dadd_ins(TwoOpArith): + """ Decimal add source to destination """ + mnemonic = 'dadd' + opcode = 10 + +@msp430target.instruction +class bit_ins(TwoOpArith): + mnemonic = 'bit' + opcode = 11 + +@msp430target.instruction +class bic_ins(TwoOpArith): + mnemonic = 'bic' + opcode = 12 +@msp430target.instruction +class bis_ins(TwoOpArith): + mnemonic = 'bis' + opcode = 13 + +@msp430target.instruction +class xor_ins(TwoOpArith): + mnemonic = 'xor' + opcode = 14 + +@msp430target.instruction +class and_ins(TwoOpArith): + mnemonic = 'and' + opcode = 15 +