Mercurial > lcfOS
comparison python/arm_cm3.py @ 205:d77cb5962cc5
Added some handcoded arm code generation
author | Windel Bouwman |
---|---|
date | Sun, 23 Jun 2013 18:23:18 +0200 |
parents | ca1ea402f6a1 |
children | 6c6bf8890d8a |
comparison
equal
deleted
inserted
replaced
204:de3a68f677a5 | 205:d77cb5962cc5 |
---|---|
1 import struct, types | |
1 from target import Register, Instruction, Target | 2 from target import Register, Instruction, Target |
2 from asmnodes import ASymbol, ANumber | 3 from asmnodes import ASymbol, ANumber |
3 from ppci import CompilerError | 4 from ppci import CompilerError |
4 import struct, types | 5 import ir |
5 | 6 |
6 def u16(h): | 7 def u16(h): |
7 return struct.pack('<H', h) | 8 return struct.pack('<H', h) |
9 | |
10 def u32(x): | |
11 return struct.pack('<I', x) | |
8 | 12 |
9 armtarget = Target('arm') | 13 armtarget = Target('arm') |
10 | 14 |
11 class ArmReg(Register): | 15 class ArmReg(Register): |
12 def __init__(self, num, name): | 16 def __init__(self, num, name): |
31 regs[r.name] = r | 35 regs[r.name] = r |
32 if name in regs: | 36 if name in regs: |
33 r = regs[name] | 37 r = regs[name] |
34 return cls(r.num) | 38 return cls(r.num) |
35 | 39 |
40 class Label: | |
41 def __init__(self, name): | |
42 self.name = name | |
43 | |
44 @classmethod | |
45 def Create(cls, vop): | |
46 if type(vop) is ASymbol: | |
47 name = vop.name | |
48 return cls(name) | |
49 | |
36 class Imm8: | 50 class Imm8: |
37 def __init__(self, imm): | 51 def __init__(self, imm): |
38 assert imm < 256 | 52 assert imm < 256 |
39 self.imm = imm | 53 self.imm = imm |
40 | 54 |
52 @classmethod | 66 @classmethod |
53 def Create(cls, vop): | 67 def Create(cls, vop): |
54 if type(vop) is ANumber and vop.number < 8: | 68 if type(vop) is ANumber and vop.number < 8: |
55 return cls(vop.number) | 69 return cls(vop.number) |
56 | 70 |
71 class RegisterSet: | |
72 def __init__(self, regs): | |
73 pass | |
74 | |
57 # 8 bit registers: | 75 # 8 bit registers: |
76 r0 = ArmReg(0, 'r0') | |
77 armtarget.registers.append(r0) | |
58 r4 = ArmReg(4, 'r4') | 78 r4 = ArmReg(4, 'r4') |
59 armtarget.registers.append(r4) | 79 armtarget.registers.append(r4) |
60 r5 = ArmReg(5, 'r5') | 80 r5 = ArmReg(5, 'r5') |
61 armtarget.registers.append(r5) | 81 armtarget.registers.append(r5) |
62 r6 = ArmReg(6, 'r6') | 82 r6 = ArmReg(6, 'r6') |
69 | 89 |
70 @armtarget.instruction | 90 @armtarget.instruction |
71 class ldr_ins(ArmInstruction): | 91 class ldr_ins(ArmInstruction): |
72 mnemonic = 'ldr' | 92 mnemonic = 'ldr' |
73 opcode = 1337 | 93 opcode = 1337 |
74 | 94 irpattern = 'todo' |
95 | |
96 @armtarget.instruction | |
97 class dcd_ins(ArmInstruction): | |
98 mnemonic = 'dcd' | |
99 def __init__(self, expr): | |
100 self.expr = expr | |
101 def encode(self): | |
102 return u32(self.expr) | |
75 | 103 |
76 class Operand2: | 104 class Operand2: |
77 def __init__(self, expr): | 105 def __init__(self, expr): |
78 if type(expr) is ANumber: | 106 if type(expr) is ANumber: |
79 pass | 107 pass |
83 class mov_ins(ArmInstruction): | 111 class mov_ins(ArmInstruction): |
84 """ mov Rd, imm8, move immediate value into register """ | 112 """ mov Rd, imm8, move immediate value into register """ |
85 mnemonic = 'mov' | 113 mnemonic = 'mov' |
86 opcode = 4 # 00100 Rd(3) imm8 | 114 opcode = 4 # 00100 Rd(3) imm8 |
87 operands = (RegOp, Imm8) | 115 operands = (RegOp, Imm8) |
116 irpattern = ir.ImmLoad | |
88 def __init__(self, rd, imm): | 117 def __init__(self, rd, imm): |
89 self.imm = imm.imm | 118 self.imm = imm.imm |
90 self.r = rd.num | 119 self.r = rd.num |
120 | |
121 @classmethod | |
122 def FromIr(cls, ir_ins): | |
123 pass | |
124 | |
91 def encode(self): | 125 def encode(self): |
92 rd = self.r | 126 rd = self.r |
93 opcode = self.opcode | 127 opcode = self.opcode |
94 imm8 = self.imm | 128 imm8 = self.imm |
95 h = (opcode << 11) | (rd << 8) | imm8 | 129 h = (opcode << 11) | (rd << 8) | imm8 |
119 class addregregimm3_ins(ArmInstruction): | 153 class addregregimm3_ins(ArmInstruction): |
120 """ add Rd, Rn, imm3 """ | 154 """ add Rd, Rn, imm3 """ |
121 mnemonic = 'add' | 155 mnemonic = 'add' |
122 opcode = 3 # 00011 | 156 opcode = 3 # 00011 |
123 operands = (RegOp, RegOp, Imm3) | 157 operands = (RegOp, RegOp, Imm3) |
158 irpattern = 3 | |
124 def __init__(self, rd, rn, imm3): | 159 def __init__(self, rd, rn, imm3): |
125 self.rd = rd | 160 self.rd = rd |
126 self.rn = rn | 161 self.rn = rn |
127 self.imm3 = imm3 | 162 self.imm3 = imm3 |
128 def encode(self): | 163 def encode(self): |
148 opcode = self.opcode | 183 opcode = self.opcode |
149 h = (opcode << 11) | (rn << 8) | imm | 184 h = (opcode << 11) | (rn << 8) | imm |
150 return u16(h) | 185 return u16(h) |
151 | 186 |
152 @armtarget.instruction | 187 @armtarget.instruction |
188 class jmp_ins(ArmInstruction): | |
189 operands = (Label) | |
190 mnemonic = 'jmp' | |
191 def __init__(self, target_label): | |
192 self.target = target_label | |
193 def fixUp(self): | |
194 pass | |
195 def encode(self): | |
196 h = 1337 # TODO | |
197 return u16(h) | |
198 | |
199 @armtarget.instruction | |
200 class push_ins(ArmInstruction): | |
201 operands = (RegisterSet) | |
202 mnemonic = 'push' | |
203 def __init__(self, regs): | |
204 self.regs = regs | |
205 def encode(self): | |
206 return u16(0) | |
207 | |
208 @armtarget.instruction | |
209 class pop_ins(ArmInstruction): | |
210 operands = (RegisterSet) | |
211 mnemonic = 'pop' | |
212 def __init__(self, regs): | |
213 self.regs = regs | |
214 def encode(self): | |
215 return u16(0) | |
216 | |
217 @armtarget.instruction | |
153 class yield_ins(ArmInstruction): | 218 class yield_ins(ArmInstruction): |
154 operands = () | 219 operands = () |
155 mnemonic = 'yield' | 220 mnemonic = 'yield' |
156 def encode(self): | 221 def encode(self): |
157 return u16(0xbf10) | 222 return u16(0xbf10) |