Mercurial > lcfOS
changeset 202:f22b431f4113
Added arm add instruction
author | Windel Bouwman |
---|---|
date | Sat, 15 Jun 2013 10:02:50 +0200 |
parents | d5debbfc0200 |
children | ca1ea402f6a1 |
files | python/arm_cm3.py python/msp430.py python/target.py python/testasm.py |
diffstat | 4 files changed, 137 insertions(+), 86 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/arm_cm3.py Sat Jun 15 10:02:50 2013 +0200 @@ -0,0 +1,75 @@ +from target import Register, Instruction, Target +from asmnodes import ASymbol, ANumber +from ppci import CompilerError +import struct, types + +def u16(h): + return struct.pack('<H', h) + +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) + self.num = num + +class ArmImm: + def __init__(self, i): + self.i = i + +# 8 bit registers: +r4 = ArmReg(4, 'r4') +armtarget.registers.append(r4) + +class ArmInstruction(Instruction): + pass + +@armtarget.instruction +class ldr_ins(ArmInstruction): + mnemonic = 'ldr' + opcode = 1337 + + +@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 + def encode(self): + rd = self.r + opcode = self.opcode + imm8 = self.imm + h = (opcode << 11) | (rd << 8) | imm8 + return u16(h) + + +@armtarget.instruction +class yield_ins(ArmInstruction): + operands = () + mnemonic = 'yield' + def encode(self): + return u16(0xbf10) +
--- a/python/msp430.py Thu Jun 13 00:07:28 2013 +0200 +++ b/python/msp430.py Sat Jun 15 10:02:50 2013 +0200 @@ -7,9 +7,13 @@ msp430target = Target("MSP430") REGISTER_MODE = 1 +SYMBOLIC_MODE = 3 +ABSOLUTE_MODE = 4 #TODO: add more modes! IMMEDIATE_MODE = 7 + + # Add a custom operand mapping method: def mapOp(self, operand): if type(operand) is ASymbol: @@ -115,35 +119,18 @@ 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 +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) -@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 +oneOpIns('rrc', 0) +oneOpIns('swpb', 1) +oneOpIns('rra', 2) +oneOpIns('sxt', 3) +oneOpIns('push', 4) +oneOpIns('call', 5) ######################### # Jump instructions: @@ -217,7 +204,6 @@ For the destination there are 4. The trick is to use also the register to distuingish the different modes. - """ # TODO: Make memory also possible @@ -234,65 +220,34 @@ def decode(self, data): pass -@msp430target.instruction -class mov_ins(TwoOpArith): - mnemonic = 'mov' - opcode = 4 +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 -@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 + def operate(self): + dst.value = dst.value + src.value + setFlags() -@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 +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) -@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 -
--- a/python/target.py Thu Jun 13 00:07:28 2013 +0200 +++ b/python/target.py Sat Jun 15 10:02:50 2013 +0200 @@ -27,9 +27,12 @@ def instruction(self, cls): """ Decorator function that registers an instruction to this target """ - self.instructions.append(cls) + self.addInstruction(cls) return cls + def addInstruction(self, ins_class): + self.instructions.append(ins_class) + def mapOperand(self, operand): """ Try to map an operand to a target type """ if type(operand) is ASymbol:
--- a/python/testasm.py Thu Jun 13 00:07:28 2013 +0200 +++ b/python/testasm.py Sat Jun 15 10:02:50 2013 +0200 @@ -5,6 +5,7 @@ from asmnodes import AInstruction, ABinop, AUnop, ASymbol, ALabel, ANumber from asm import tokenize, Assembler import msp430 +import arm_cm3 class AssemblerLexingCase(unittest.TestCase): """ Tests the assemblers lexer """ @@ -130,12 +131,12 @@ def testMov1337(self): line1 = "mov 0x1337, r12" self.a.assemble_line(line1) - self.assertEqual(bytes([0x3C, 0x40, 0x37, 0x13]), self.a.binout) + self.assertEqual(bytes.fromhex('3C403713'), self.a.binout) def testAdd(self): line1 = "add r15, r13" self.a.assemble_line(line1) - self.assertEqual(bytes([0x0D, 0x5F]), self.a.binout) + self.assertEqual(bytes.fromhex('0D5F'), self.a.binout) def testReti(self): line1 = "reti" @@ -147,6 +148,23 @@ self.assertEqual(27, len(self.t.instructions)) +class AssemblerARMTestCase(unittest.TestCase): + def setUp(self): + self.t = arm_cm3.armtarget + self.a = Assembler(target=self.t) + + def testMapOperand(self): + pass + + def testMovImm8(self): + self.a.assemble('mov r4, 100') + self.assertEqual(bytes.fromhex('6424'), self.a.binout) + + def testYield(self): + self.a.assemble('yield') + self.assertEqual(bytes.fromhex('10bf'), self.a.binout) + + if __name__ == '__main__': # cProfile.run('unittest.main()') unittest.main()