comparison python/msp430.py @ 201:d5debbfc0200

Added all 27 core instructions of msp430
author Windel Bouwman
date Thu, 13 Jun 2013 00:07:28 +0200
parents 5e391d9a3381
children f22b431f4113
comparison
equal deleted inserted replaced
200:5e391d9a3381 201:d5debbfc0200
1 from target import Register, Instruction, Target 1 from target import Register, Instruction, Target
2 from asmnodes import ASymbol, ANumber
3 from ppci import CompilerError
4 import struct, types
5
6 # Create the target class (singleton):
7 msp430target = Target("MSP430")
8
9 REGISTER_MODE = 1
10 #TODO: add more modes!
11 IMMEDIATE_MODE = 7
12
13 # Add a custom operand mapping method:
14 def mapOp(self, operand):
15 if type(operand) is ASymbol:
16 # try to map to register:
17 regs = {}
18 for r in self.registers:
19 regs[r.name] = r
20 if operand.name in regs:
21 reg = regs[operand.name]
22 return MSP430Operand(REGISTER_MODE, reg.num)
23 elif type(operand) is ANumber:
24 # Immediate mode:
25 return MSP430Operand(IMMEDIATE_MODE, operand.number)
26 raise CompilerError('Cannot map {0}'.format(operand))
27
28 msp430target.mapOperand = types.MethodType(mapOp, msp430target)
2 29
3 # Target description for the MSP430 processor 30 # Target description for the MSP430 processor
4 31
5 class MSP430Reg(Register): 32 class MSP430Reg(Register):
6 def __init__(self, num, name): 33 def __init__(self, num, name):
7 super().__init__(name) 34 super().__init__(name)
8 self.num = num 35 self.num = num
9 36
10 # 8 bit registers: 37 # 8 bit registers:
11 PCB = MSP430Reg(0, 'r0') 38 PCB = MSP430Reg(0, 'r0')
39 rpc = PCB
40 r11 = MSP430Reg(11, 'r11')
41 r12 = MSP430Reg(12, 'r12')
12 r13 = MSP430Reg(13, 'r13') 42 r13 = MSP430Reg(13, 'r13')
13 r14 = MSP430Reg(14, 'r14') 43 r14 = MSP430Reg(14, 'r14')
14 r15 = MSP430Reg(15, 'r15') 44 r15 = MSP430Reg(15, 'r15')
15 45
46 class MSP430Mem:
47 pass
48
49 msp430target.registers.append(r11)
50 msp430target.registers.append(r12)
51 msp430target.registers.append(r13)
52 msp430target.registers.append(r14)
53 msp430target.registers.append(r15)
54
16 # .. etc 55 # .. etc
17 56
18 #GR8 = RegisterClass((PCB, R15B)) 57 #GR8 = RegisterClass((PCB, R15B))
19 58
59 class MSP430Operand:
60 def __init__(self, mode, param):
61 self.mode = mode
62 self.param = param
63 def regField(self):
64 if self.mode == REGISTER_MODE:
65 return self.param
66 elif self.mode == IMMEDIATE_MODE:
67 return rpc.num
68 def asField(self):
69 if self.mode == REGISTER_MODE:
70 return 0
71 elif self.mode == IMMEDIATE_MODE:
72 return 3
73 def adField(self):
74 if self.mode == REGISTER_MODE:
75 return 0
76 elif self.mode == IMMEDIATE_MODE:
77 raise CompilerError('Cannot use immediate mode for destination operand')
78 def extraBytes(self):
79 if self.mode == IMMEDIATE_MODE:
80 return pack_ins(self.param)
81 return bytes()
82
83
84 def pack_ins(h):
85 return struct.pack('<H', h)
86
87 class MSP430Instruction(Instruction):
88 b = 0
89
90 class BInstruction:
91 pass
92
93 class MSP430CoreInstruction(Instruction):
94 pass
95
96 #########################
97 # Single operand arithmatic:
98 #########################
99
100 @msp430target.instruction
101 class reti_ins(MSP430Instruction):
102 mnemonic = 'reti'
103 operands = ()
104 def encode(self):
105 h = 0x1300
106 return pack_ins(h)
107
108 class OneOpArith(MSP430Instruction):
109 operands = (MSP430Reg, )
110 def __init__(self, op1):
111 self.op1 = op1
112 def encode(self):
113 # TODO:
114 bits[15:10] = '00100'
115 h1 = (self.opcode << 4)
116 return pack_ins(h1)
117
118 @msp430target.instruction
119 class rrc_ins(OneOpArith):
120 mnemonic = 'rrc'
121 opcode = 0
122
123 @msp430target.instruction
124 class swpb_ins(OneOpArith):
125 mnemonic = 'swpb'
126 opcode = 1
127
128 @msp430target.instruction
129 class rra_ins(OneOpArith):
130 mnemonic = 'rra'
131 opcode = 2
132
133 @msp430target.instruction
134 class sxt_ins(OneOpArith):
135 mnemonic = 'sxt'
136 opcode = 3
137
138 @msp430target.instruction
139 class push_ins(OneOpArith):
140 mnemonic = 'push'
141 opcode = 4
142
143 @msp430target.instruction
144 class call_ins(OneOpArith):
145 mnemonic = 'call'
146 opcode = 5
147
148 #########################
149 # Jump instructions:
150 #########################
151
152 class JumpInstruction(Instruction):
153 def __init__(self, offset):
154 self.offset = offset
155
156 def encode(self):
157 h = (1 << 13) | (self.condition << 10) | (self.offset)
158 return pack_ins(h)
159
160 @msp430target.instruction
161 class jnz_ins(JumpInstruction):
162 mnemonic = 'jnz'
163 condition = 0
164
165 @msp430target.instruction
166 class jz_ins(JumpInstruction):
167 mnemonic = 'jz'
168 condition = 1
169
170 @msp430target.instruction
171 class jnc_ins(JumpInstruction):
172 mnemonic = 'jnc'
173 condition = 2
174
175 @msp430target.instruction
176 class jc_ins(JumpInstruction):
177 mnemonic = 'jc'
178 condition = 3
179
180 @msp430target.instruction
181 class jn_ins(JumpInstruction):
182 mnemonic = 'jn'
183 condition = 4
184
185 @msp430target.instruction
186 class jge_ins(JumpInstruction):
187 mnemonic = 'jge'
188 condition = 5
189
190 @msp430target.instruction
191 class jl_ins(JumpInstruction):
192 mnemonic = 'jl'
193 condition = 6
194
195 @msp430target.instruction
196 class jmp_ins(JumpInstruction):
197 mnemonic = 'jmp'
198 condition = 7
199
200 #########################
20 # Two operand arithmatic instructions: 201 # Two operand arithmatic instructions:
21 202 #########################
22 class TwoOpArith(Instruction): 203
23 operands = (MSP430Reg, MSP430Reg) 204
24 def __init__(self, op1, op2): 205 class TwoOpArith(MSP430Instruction):
25 self.op1 = op1 206 operands = (MSP430Operand, MSP430Operand)
26 self.op2 = op2 207 def __init__(self, src, dst):
27 def encode(self): 208 self.op1 = src
28 # TODO: 209 self.op2 = dst
29 b1 = (self.opcode << 4) 210
30 b2 = 0 211 def encode(self):
31 ba = bytearray([b1, b2]) 212 """
32 return bytes(ba) 213 Smart things have been done by MSP430 designers.
33 214 As (2 bits) is the source addressing mode selector.
215 Ad (1 bit) is the destination adressing mode selector.
216 For the source there are 7 different addressing mode.
217 For the destination there are 4.
218 The trick is to use also the register to distuingish the
219 different modes.
220
221 """
222 # TODO: Make memory also possible
223
224 As = self.op1.asField() # addressing mode for the source
225 Ad = self.op2.adField() # Addressing mode for dst
226 b = self.b # When b=1, the operation is byte mode
227 source = self.op1.regField()
228 destination = self.op2.regField()
229 h = (self.opcode << 12) | (source << 8)
230 h |= (self.b << 6) | (As << 4) | (Ad << 7) | destination
231 additions = self.op1.extraBytes() + self.op2.extraBytes()
232 return pack_ins(h) + additions
233
234 def decode(self, data):
235 pass
236
237 @msp430target.instruction
34 class mov_ins(TwoOpArith): 238 class mov_ins(TwoOpArith):
35 # class variables:
36 mnemonic = 'mov' 239 mnemonic = 'mov'
37 opcode = 4 240 opcode = 4
38 241
242 @msp430target.instruction
39 class add_ins(TwoOpArith): 243 class add_ins(TwoOpArith):
40 mnemonic = 'add' 244 mnemonic = 'add'
41 opcode = 5 245 opcode = 5
42 246
43 class MSP430(Target): 247 @msp430target.instruction
44 def __init__(self): 248 class addc_ins(TwoOpArith):
45 self.registers = [PCB, r13, r14, r15] 249 mnemonic = 'addc'
46 self.instructions = [mov_ins, add_ins] 250 opcode = 6
47 251
48 t = MSP430() 252 @msp430target.instruction
49 253 class subc_ins(TwoOpArith):
254 mnemonic = 'subc'
255 opcode = 7
256
257 @msp430target.instruction
258 class sub_ins(TwoOpArith):
259 mnemonic = 'sub'
260 opcode = 8
261
262 @msp430target.instruction
263 class cmp_ins(TwoOpArith):
264 """ Compare, substract source from destination """
265 mnemonic = 'cmp'
266 opcode = 9
267
268 @msp430target.instruction
269 class dadd_ins(TwoOpArith):
270 """ Decimal add source to destination """
271 mnemonic = 'dadd'
272 opcode = 10
273
274 @msp430target.instruction
275 class bit_ins(TwoOpArith):
276 mnemonic = 'bit'
277 opcode = 11
278
279 @msp430target.instruction
280 class bic_ins(TwoOpArith):
281 mnemonic = 'bic'
282 opcode = 12
283
284 @msp430target.instruction
285 class bis_ins(TwoOpArith):
286 mnemonic = 'bis'
287 opcode = 13
288
289 @msp430target.instruction
290 class xor_ins(TwoOpArith):
291 mnemonic = 'xor'
292 opcode = 14
293
294 @msp430target.instruction
295 class and_ins(TwoOpArith):
296 mnemonic = 'and'
297 opcode = 15
298