Mercurial > lcfOS
comparison python/arm_cm3.py @ 203:ca1ea402f6a1
Added some arm instructions
author | Windel Bouwman |
---|---|
date | Sat, 15 Jun 2013 19:13:05 +0200 |
parents | f22b431f4113 |
children | d77cb5962cc5 |
comparison
equal
deleted
inserted
replaced
202:f22b431f4113 | 203:ca1ea402f6a1 |
---|---|
6 def u16(h): | 6 def u16(h): |
7 return struct.pack('<H', h) | 7 return struct.pack('<H', h) |
8 | 8 |
9 armtarget = Target('arm') | 9 armtarget = Target('arm') |
10 | 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): | 11 class ArmReg(Register): |
31 def __init__(self, num, name): | 12 def __init__(self, num, name): |
32 super().__init__(name) | 13 super().__init__(name) |
33 self.num = num | 14 self.num = num |
34 | 15 |
35 class ArmImm: | 16 class ArmImm: |
36 def __init__(self, i): | 17 def __init__(self, i): |
37 self.i = i | 18 self.i = i |
38 | 19 |
20 class RegOp: | |
21 def __init__(self, num): | |
22 assert num < 8 | |
23 self.num = num | |
24 | |
25 @classmethod | |
26 def Create(cls, vop): | |
27 if type(vop) is ASymbol: | |
28 name = vop.name | |
29 regs = {} | |
30 for r in armtarget.registers: | |
31 regs[r.name] = r | |
32 if name in regs: | |
33 r = regs[name] | |
34 return cls(r.num) | |
35 | |
36 class Imm8: | |
37 def __init__(self, imm): | |
38 assert imm < 256 | |
39 self.imm = imm | |
40 | |
41 @classmethod | |
42 def Create(cls, vop): | |
43 if type(vop) is ANumber and vop.number < 256: | |
44 return cls(vop.number) | |
45 | |
46 class Imm3: | |
47 def __init__(self, imm): | |
48 assert imm < 8 | |
49 assert type(imm) is int | |
50 self.imm = imm | |
51 | |
52 @classmethod | |
53 def Create(cls, vop): | |
54 if type(vop) is ANumber and vop.number < 8: | |
55 return cls(vop.number) | |
56 | |
39 # 8 bit registers: | 57 # 8 bit registers: |
40 r4 = ArmReg(4, 'r4') | 58 r4 = ArmReg(4, 'r4') |
41 armtarget.registers.append(r4) | 59 armtarget.registers.append(r4) |
60 r5 = ArmReg(5, 'r5') | |
61 armtarget.registers.append(r5) | |
62 r6 = ArmReg(6, 'r6') | |
63 armtarget.registers.append(r6) | |
64 r7 = ArmReg(7, 'r7') | |
65 armtarget.registers.append(r7) | |
42 | 66 |
43 class ArmInstruction(Instruction): | 67 class ArmInstruction(Instruction): |
44 pass | 68 pass |
45 | 69 |
46 @armtarget.instruction | 70 @armtarget.instruction |
47 class ldr_ins(ArmInstruction): | 71 class ldr_ins(ArmInstruction): |
48 mnemonic = 'ldr' | 72 mnemonic = 'ldr' |
49 opcode = 1337 | 73 opcode = 1337 |
50 | 74 |
51 | 75 |
76 class Operand2: | |
77 def __init__(self, expr): | |
78 if type(expr) is ANumber: | |
79 pass | |
80 pass | |
81 | |
52 @armtarget.instruction | 82 @armtarget.instruction |
53 class mov_ins(ArmInstruction): | 83 class mov_ins(ArmInstruction): |
54 """ mov Rd, imm8, move immediate value into register """ | 84 """ mov Rd, imm8, move immediate value into register """ |
55 mnemonic = 'mov' | 85 mnemonic = 'mov' |
56 opcode = 4 # 00100 | 86 opcode = 4 # 00100 Rd(3) imm8 |
57 operands = (ArmReg, ArmImm) | 87 operands = (RegOp, Imm8) |
58 def __init__(self, r, imm): | 88 def __init__(self, rd, imm): |
59 self.imm = imm.i | 89 self.imm = imm.imm |
60 self.r = r.num | 90 self.r = rd.num |
61 def encode(self): | 91 def encode(self): |
62 rd = self.r | 92 rd = self.r |
63 opcode = self.opcode | 93 opcode = self.opcode |
64 imm8 = self.imm | 94 imm8 = self.imm |
65 h = (opcode << 11) | (rd << 8) | imm8 | 95 h = (opcode << 11) | (rd << 8) | imm8 |
66 return u16(h) | 96 return u16(h) |
67 | 97 |
98 @armtarget.instruction | |
99 class movregreg_ins(ArmInstruction): | |
100 """ mov Rd, Rm """ | |
101 mnemonic = 'mov' | |
102 opcode = 8 # 01000 Rd(3) imm8 | |
103 operands = (RegOp, RegOp) | |
104 def __init__(self, rd, rm): | |
105 self.rd = rd | |
106 self.rm = rm | |
107 def encode(self): | |
108 rd = self.rd.num | |
109 D = (rd & 0x8) >> 3 | |
110 assert D < 2 | |
111 rd = rd & 0x7 | |
112 rm = self.rm.num | |
113 assert rm < 16 | |
114 opcode = self.opcode | |
115 h = (opcode << 11) | (3 << 9) | (D << 7) | (rm << 3) | rd | |
116 return u16(h) | |
117 | |
118 @armtarget.instruction | |
119 class addregregimm3_ins(ArmInstruction): | |
120 """ add Rd, Rn, imm3 """ | |
121 mnemonic = 'add' | |
122 opcode = 3 # 00011 | |
123 operands = (RegOp, RegOp, Imm3) | |
124 def __init__(self, rd, rn, imm3): | |
125 self.rd = rd | |
126 self.rn = rn | |
127 self.imm3 = imm3 | |
128 def encode(self): | |
129 rd = self.rd.num | |
130 rn = self.rn.num | |
131 imm3 = self.imm3.imm | |
132 opcode = self.opcode | |
133 h = (opcode << 11) | (1 << 10) | (imm3 << 6) | (rn << 3) | rd | |
134 return u16(h) | |
135 | |
136 @armtarget.instruction | |
137 class cmpregimm8_ins(ArmInstruction): | |
138 """ cmp Rn, imm8 """ | |
139 mnemonic = 'cmp' | |
140 opcode = 5 # 00101 | |
141 operands = (RegOp, Imm8) | |
142 def __init__(self, rn, imm): | |
143 self.rn = rn | |
144 self.imm = imm | |
145 def encode(self): | |
146 rn = self.rn.num | |
147 imm = self.imm.imm | |
148 opcode = self.opcode | |
149 h = (opcode << 11) | (rn << 8) | imm | |
150 return u16(h) | |
68 | 151 |
69 @armtarget.instruction | 152 @armtarget.instruction |
70 class yield_ins(ArmInstruction): | 153 class yield_ins(ArmInstruction): |
71 operands = () | 154 operands = () |
72 mnemonic = 'yield' | 155 mnemonic = 'yield' |