Mercurial > lcfOS
comparison python/arm_cm3.py @ 206:6c6bf8890d8a
Added push and pop encodings
author | Windel Bouwman |
---|---|
date | Fri, 28 Jun 2013 16:49:38 +0200 |
parents | d77cb5962cc5 |
children | 8b2f20aae086 |
comparison
equal
deleted
inserted
replaced
205:d77cb5962cc5 | 206:6c6bf8890d8a |
---|---|
1 import struct, types | 1 import struct, types |
2 from target import Register, Instruction, Target | 2 from target import Register, Instruction, Target, Imm8, Label, Imm3 |
3 from asmnodes import ASymbol, ANumber | 3 from asmnodes import ASymbol, ANumber, AUnop, ABinop |
4 from ppci import CompilerError | 4 from ppci import CompilerError |
5 import ir | 5 import ir |
6 | 6 |
7 def u16(h): | 7 def u16(h): |
8 return struct.pack('<H', h) | 8 return struct.pack('<H', h) |
14 | 14 |
15 class ArmReg(Register): | 15 class ArmReg(Register): |
16 def __init__(self, num, name): | 16 def __init__(self, num, name): |
17 super().__init__(name) | 17 super().__init__(name) |
18 self.num = num | 18 self.num = num |
19 | 19 def __repr__(self): |
20 class ArmImm: | 20 return self.name |
21 def __init__(self, i): | |
22 self.i = i | |
23 | 21 |
24 class RegOp: | 22 class RegOp: |
25 def __init__(self, num): | 23 def __init__(self, num): |
26 assert num < 8 | 24 assert num < 16 |
27 self.num = num | 25 self.num = num |
28 | 26 |
29 @classmethod | 27 @classmethod |
30 def Create(cls, vop): | 28 def Create(cls, vop): |
31 if type(vop) is ASymbol: | 29 if type(vop) is ASymbol: |
35 regs[r.name] = r | 33 regs[r.name] = r |
36 if name in regs: | 34 if name in regs: |
37 r = regs[name] | 35 r = regs[name] |
38 return cls(r.num) | 36 return cls(r.num) |
39 | 37 |
40 class Label: | 38 def getRegNum(n): |
41 def __init__(self, name): | 39 for r in armtarget.registers: |
42 self.name = name | 40 if r.num == n: |
43 | 41 return r |
42 | |
43 def getRegisterRange(n1, n2): | |
44 regs = [] | |
45 if n1.num < n2.num: | |
46 for n in range(n1.num, n2.num + 1): | |
47 r = getRegNum(n) | |
48 assert r | |
49 regs.append(r) | |
50 return regs | |
51 | |
52 class RegisterSet: | |
53 def __init__(self, regs): | |
54 assert type(regs) is set | |
55 self.regs = regs | |
56 def __repr__(self): | |
57 return ','.join([str(r) for r in self.regs]) | |
44 @classmethod | 58 @classmethod |
45 def Create(cls, vop): | 59 def Create(cls, vop): |
46 if type(vop) is ASymbol: | 60 assert type(vop) is AUnop and vop.operation == '{}' |
47 name = vop.name | 61 assert type(vop.arg) is list |
48 return cls(name) | 62 regs = set() |
49 | 63 for arg in vop.arg: |
50 class Imm8: | 64 if type(arg) is ASymbol: |
51 def __init__(self, imm): | 65 reg = RegOp.Create(arg) |
52 assert imm < 256 | 66 if not reg: |
53 self.imm = imm | 67 return |
54 | 68 regs.add(reg) |
55 @classmethod | 69 elif type(arg) is ABinop and arg.op == '-': |
56 def Create(cls, vop): | 70 reg1 = RegOp.Create(arg.arg1) |
57 if type(vop) is ANumber and vop.number < 256: | 71 reg2 = RegOp.Create(arg.arg2) |
58 return cls(vop.number) | 72 if not reg1: |
59 | 73 return |
60 class Imm3: | 74 if not reg2: |
61 def __init__(self, imm): | 75 return |
62 assert imm < 8 | 76 for r in getRegisterRange(reg1, reg2): |
63 assert type(imm) is int | 77 regs.add(r) |
64 self.imm = imm | 78 else: |
65 | 79 raise Exception('Cannot be') |
66 @classmethod | 80 return cls(regs) |
67 def Create(cls, vop): | 81 |
68 if type(vop) is ANumber and vop.number < 8: | 82 def registerNumbers(self): |
69 return cls(vop.number) | 83 return [r.num for r in self.regs] |
70 | |
71 class RegisterSet: | |
72 def __init__(self, regs): | |
73 pass | |
74 | 84 |
75 # 8 bit registers: | 85 # 8 bit registers: |
76 r0 = ArmReg(0, 'r0') | 86 r0 = ArmReg(0, 'r0') |
77 armtarget.registers.append(r0) | 87 armtarget.registers.append(r0) |
88 r1 = ArmReg(1, 'r1') | |
89 armtarget.registers.append(r1) | |
90 r2 = ArmReg(2, 'r2') | |
91 armtarget.registers.append(r2) | |
92 r3 = ArmReg(3, 'r3') | |
93 armtarget.registers.append(r3) | |
78 r4 = ArmReg(4, 'r4') | 94 r4 = ArmReg(4, 'r4') |
79 armtarget.registers.append(r4) | 95 armtarget.registers.append(r4) |
80 r5 = ArmReg(5, 'r5') | 96 r5 = ArmReg(5, 'r5') |
81 armtarget.registers.append(r5) | 97 armtarget.registers.append(r5) |
82 r6 = ArmReg(6, 'r6') | 98 r6 = ArmReg(6, 'r6') |
83 armtarget.registers.append(r6) | 99 armtarget.registers.append(r6) |
84 r7 = ArmReg(7, 'r7') | 100 r7 = ArmReg(7, 'r7') |
85 armtarget.registers.append(r7) | 101 armtarget.registers.append(r7) |
102 # Other registers: | |
103 # TODO | |
104 sp = ArmReg(13, 'sp') | |
105 armtarget.registers.append(sp) | |
106 lr = ArmReg(14, 'lr') | |
107 armtarget.registers.append(lr) | |
108 pc = ArmReg(15, 'pc') | |
109 armtarget.registers.append(pc) | |
86 | 110 |
87 class ArmInstruction(Instruction): | 111 class ArmInstruction(Instruction): |
88 pass | 112 pass |
89 | 113 |
90 @armtarget.instruction | |
91 class ldr_ins(ArmInstruction): | 114 class ldr_ins(ArmInstruction): |
92 mnemonic = 'ldr' | 115 mnemonic = 'ldr' |
93 opcode = 1337 | 116 opcode = 1337 |
94 irpattern = 'todo' | 117 irpattern = 'todo' |
95 | 118 |
96 @armtarget.instruction | |
97 class dcd_ins(ArmInstruction): | 119 class dcd_ins(ArmInstruction): |
98 mnemonic = 'dcd' | 120 mnemonic = 'dcd' |
99 def __init__(self, expr): | 121 def __init__(self, expr): |
100 self.expr = expr | 122 self.expr = expr |
101 def encode(self): | 123 def encode(self): |
102 return u32(self.expr) | 124 return u32(self.expr) |
103 | |
104 class Operand2: | |
105 def __init__(self, expr): | |
106 if type(expr) is ANumber: | |
107 pass | |
108 pass | |
109 | 125 |
110 @armtarget.instruction | 126 @armtarget.instruction |
111 class mov_ins(ArmInstruction): | 127 class mov_ins(ArmInstruction): |
112 """ mov Rd, imm8, move immediate value into register """ | 128 """ mov Rd, imm8, move immediate value into register """ |
113 mnemonic = 'mov' | 129 mnemonic = 'mov' |
184 h = (opcode << 11) | (rn << 8) | imm | 200 h = (opcode << 11) | (rn << 8) | imm |
185 return u16(h) | 201 return u16(h) |
186 | 202 |
187 @armtarget.instruction | 203 @armtarget.instruction |
188 class jmp_ins(ArmInstruction): | 204 class jmp_ins(ArmInstruction): |
189 operands = (Label) | 205 operands = (Label,) |
190 mnemonic = 'jmp' | 206 mnemonic = 'jmp' |
191 def __init__(self, target_label): | 207 def __init__(self, target_label): |
192 self.target = target_label | 208 self.target = target_label |
193 def fixUp(self): | 209 def fixUp(self): |
194 pass | 210 pass |
196 h = 1337 # TODO | 212 h = 1337 # TODO |
197 return u16(h) | 213 return u16(h) |
198 | 214 |
199 @armtarget.instruction | 215 @armtarget.instruction |
200 class push_ins(ArmInstruction): | 216 class push_ins(ArmInstruction): |
201 operands = (RegisterSet) | 217 operands = (RegisterSet,) |
202 mnemonic = 'push' | 218 mnemonic = 'push' |
203 def __init__(self, regs): | 219 def __init__(self, regs): |
220 print(self.operands) | |
221 assert (type(regs),) == self.operands, (type(regs),) | |
204 self.regs = regs | 222 self.regs = regs |
205 def encode(self): | 223 def __repr__(self): |
206 return u16(0) | 224 return '{0} {{{1}}}'.format(self.mnemonic, self.regs) |
225 def encode(self): | |
226 reg_list = 0 | |
227 M = 0 | |
228 for n in self.regs.registerNumbers(): | |
229 if n < 8: | |
230 reg_list |= (1 << n) | |
231 elif n == 14: | |
232 M = 1 | |
233 else: | |
234 raise NotImplementedError('not implemented for this register') | |
235 h = (0x5a << 9) | (M << 8) | reg_list | |
236 return u16(h) | |
207 | 237 |
208 @armtarget.instruction | 238 @armtarget.instruction |
209 class pop_ins(ArmInstruction): | 239 class pop_ins(ArmInstruction): |
210 operands = (RegisterSet) | 240 operands = (RegisterSet,) |
211 mnemonic = 'pop' | 241 mnemonic = 'pop' |
212 def __init__(self, regs): | 242 def __init__(self, regs): |
213 self.regs = regs | 243 self.regs = regs |
214 def encode(self): | 244 def encode(self): |
245 reg_list = 0 | |
246 P = 0 | |
247 for n in self.regs.registerNumbers(): | |
248 if n < 8: | |
249 reg_list |= (1 << n) | |
250 elif n == 15: | |
251 P = 1 | |
252 else: | |
253 raise NotImplementedError('not implemented for this register') | |
254 h = (0x5E << 9) | (P << 8) | reg_list | |
255 return u16(h) | |
215 return u16(0) | 256 return u16(0) |
216 | 257 |
217 @armtarget.instruction | 258 @armtarget.instruction |
218 class yield_ins(ArmInstruction): | 259 class yield_ins(ArmInstruction): |
219 operands = () | 260 operands = () |
220 mnemonic = 'yield' | 261 mnemonic = 'yield' |
221 def encode(self): | 262 def encode(self): |
222 return u16(0xbf10) | 263 return u16(0xbf10) |
223 | 264 |
265 armtarget.check() | |
266 |