202
|
1 from target import Register, Instruction, Target
|
|
2 from asmnodes import ASymbol, ANumber
|
|
3 from ppci import CompilerError
|
|
4 import struct, types
|
|
5
|
|
6 def u16(h):
|
|
7 return struct.pack('<H', h)
|
|
8
|
|
9 armtarget = Target('arm')
|
|
10
|
|
11 # Add a custom operand mapping method:
|
|
12 def mapOp(self, operand):
|
|
13 if type(operand) is ASymbol:
|
|
14 # try to map to register:
|
|
15 regs = {}
|
|
16 for r in self.registers:
|
|
17 regs[r.name] = r
|
|
18 if operand.name in regs:
|
|
19 reg = regs[operand.name]
|
|
20 return reg
|
|
21 elif type(operand) is ANumber:
|
|
22 return ArmImm(operand.number)
|
|
23 raise CompilerError('Cannot map {0}'.format(operand))
|
|
24
|
|
25 armtarget.mapOperand = types.MethodType(mapOp, armtarget)
|
|
26
|
|
27 # Define:
|
|
28 registers = 'r0,r1,r2,r3,r4,r5'
|
|
29
|
|
30 class ArmReg(Register):
|
|
31 def __init__(self, num, name):
|
|
32 super().__init__(name)
|
|
33 self.num = num
|
|
34
|
|
35 class ArmImm:
|
|
36 def __init__(self, i):
|
|
37 self.i = i
|
|
38
|
|
39 # 8 bit registers:
|
|
40 r4 = ArmReg(4, 'r4')
|
|
41 armtarget.registers.append(r4)
|
|
42
|
|
43 class ArmInstruction(Instruction):
|
|
44 pass
|
|
45
|
|
46 @armtarget.instruction
|
|
47 class ldr_ins(ArmInstruction):
|
|
48 mnemonic = 'ldr'
|
|
49 opcode = 1337
|
|
50
|
|
51
|
|
52 @armtarget.instruction
|
|
53 class mov_ins(ArmInstruction):
|
|
54 """ mov Rd, imm8, move immediate value into register """
|
|
55 mnemonic = 'mov'
|
|
56 opcode = 4 # 00100
|
|
57 operands = (ArmReg, ArmImm)
|
|
58 def __init__(self, r, imm):
|
|
59 self.imm = imm.i
|
|
60 self.r = r.num
|
|
61 def encode(self):
|
|
62 rd = self.r
|
|
63 opcode = self.opcode
|
|
64 imm8 = self.imm
|
|
65 h = (opcode << 11) | (rd << 8) | imm8
|
|
66 return u16(h)
|
|
67
|
|
68
|
|
69 @armtarget.instruction
|
|
70 class yield_ins(ArmInstruction):
|
|
71 operands = ()
|
|
72 mnemonic = 'yield'
|
|
73 def encode(self):
|
|
74 return u16(0xbf10)
|
|
75
|