comparison python/target/msp430.py @ 290:7b38782ed496

File moves
author Windel Bouwman
date Sun, 24 Nov 2013 11:24:15 +0100
parents python/msp430.py@ca1ea402f6a1
children 534b94b40aa8
comparison
equal deleted inserted replaced
289:bd2593de3ff8 290:7b38782ed496
1 from target import Register, Instruction, Target
2 from asmnodes import ASymbol, ANumber
3 from ppci import CompilerError
4 import struct
5 import types
6
7 # Create the target class (singleton):
8 msp430target = Target("MSP430")
9
10 REGISTER_MODE = 1
11 SYMBOLIC_MODE = 3
12 ABSOLUTE_MODE = 4
13 #TODO: add more modes!
14 IMMEDIATE_MODE = 7
15
16 # Target description for the MSP430 processor
17
18 class MSP430Reg(Register):
19 def __init__(self, num, name):
20 super().__init__(name)
21 self.num = num
22
23 # 8 bit registers:
24 PCB = MSP430Reg(0, 'r0')
25 rpc = PCB
26 r11 = MSP430Reg(11, 'r11')
27 r12 = MSP430Reg(12, 'r12')
28 r13 = MSP430Reg(13, 'r13')
29 r14 = MSP430Reg(14, 'r14')
30 r15 = MSP430Reg(15, 'r15')
31
32 class MSP430Mem:
33 pass
34
35 msp430target.registers.append(r11)
36 msp430target.registers.append(r12)
37 msp430target.registers.append(r13)
38 msp430target.registers.append(r14)
39 msp430target.registers.append(r15)
40
41 # .. etc
42
43 #GR8 = RegisterClass((PCB, R15B))
44
45 class MSP430Operand:
46 def __init__(self, mode, param):
47 self.mode = mode
48 self.param = param
49 def regField(self):
50 if self.mode == REGISTER_MODE:
51 return self.param
52 elif self.mode == IMMEDIATE_MODE:
53 return rpc.num
54 def asField(self):
55 if self.mode == REGISTER_MODE:
56 return 0
57 elif self.mode == IMMEDIATE_MODE:
58 return 3
59 def adField(self):
60 if self.mode == REGISTER_MODE:
61 return 0
62 elif self.mode == IMMEDIATE_MODE:
63 raise CompilerError('Cannot use immediate mode for destination operand')
64 def extraBytes(self):
65 if self.mode == IMMEDIATE_MODE:
66 return pack_ins(self.param)
67 return bytes()
68
69 @classmethod
70 def Create(cls, vop):
71 if type(vop) is ASymbol:
72 # try to map to register:
73 regs = {}
74 for r in msp430target.registers:
75 regs[r.name] = r
76 if vop.name in regs:
77 reg = regs[vop.name]
78 return cls(REGISTER_MODE, reg.num)
79 elif type(vop) is ANumber:
80 # Immediate mode:
81 return cls(IMMEDIATE_MODE, vop.number)
82
83 def pack_ins(h):
84 return struct.pack('<H', h)
85
86 class MSP430Instruction(Instruction):
87 b = 0
88
89 class BInstruction:
90 pass
91
92 class MSP430CoreInstruction(Instruction):
93 pass
94
95 #########################
96 # Single operand arithmatic:
97 #########################
98
99 @msp430target.instruction
100 class reti_ins(MSP430Instruction):
101 mnemonic = 'reti'
102 operands = ()
103 def encode(self):
104 h = 0x1300
105 return pack_ins(h)
106
107 class OneOpArith(MSP430Instruction):
108 operands = (MSP430Reg, )
109 def __init__(self, op1):
110 self.op1 = op1
111 def encode(self):
112 # TODO:
113 bits[15:10] = '00100'
114 h1 = (self.opcode << 4)
115 return pack_ins(h1)
116
117 def oneOpIns(mne, opc):
118 """ Helper function to define a one operand arithmetic instruction """
119 members = {'mnemonic': mne, 'opcode': opc}
120 ins_cls = type(mne + '_ins', (OneOpArith,), members)
121 msp430target.addInstruction(ins_cls)
122
123 oneOpIns('rrc', 0)
124 oneOpIns('swpb', 1)
125 oneOpIns('rra', 2)
126 oneOpIns('sxt', 3)
127 oneOpIns('push', 4)
128 oneOpIns('call', 5)
129
130 #########################
131 # Jump instructions:
132 #########################
133
134 class JumpInstruction(Instruction):
135 def __init__(self, offset):
136 self.offset = offset
137
138 def encode(self):
139 h = (1 << 13) | (self.condition << 10) | (self.offset)
140 return pack_ins(h)
141
142 @msp430target.instruction
143 class jnz_ins(JumpInstruction):
144 mnemonic = 'jnz'
145 condition = 0
146
147 @msp430target.instruction
148 class jz_ins(JumpInstruction):
149 mnemonic = 'jz'
150 condition = 1
151
152 @msp430target.instruction
153 class jnc_ins(JumpInstruction):
154 mnemonic = 'jnc'
155 condition = 2
156
157 @msp430target.instruction
158 class jc_ins(JumpInstruction):
159 mnemonic = 'jc'
160 condition = 3
161
162 @msp430target.instruction
163 class jn_ins(JumpInstruction):
164 mnemonic = 'jn'
165 condition = 4
166
167 @msp430target.instruction
168 class jge_ins(JumpInstruction):
169 mnemonic = 'jge'
170 condition = 5
171
172 @msp430target.instruction
173 class jl_ins(JumpInstruction):
174 mnemonic = 'jl'
175 condition = 6
176
177 @msp430target.instruction
178 class jmp_ins(JumpInstruction):
179 mnemonic = 'jmp'
180 condition = 7
181
182 #########################
183 # Two operand arithmatic instructions:
184 #########################
185
186
187 class TwoOpArith(MSP430Instruction):
188 operands = (MSP430Operand, MSP430Operand)
189 def __init__(self, src, dst):
190 self.op1 = src
191 self.op2 = dst
192
193 def encode(self):
194 """
195 Smart things have been done by MSP430 designers.
196 As (2 bits) is the source addressing mode selector.
197 Ad (1 bit) is the destination adressing mode selector.
198 For the source there are 7 different addressing mode.
199 For the destination there are 4.
200 The trick is to use also the register to distuingish the
201 different modes.
202 """
203 # TODO: Make memory also possible
204
205 As = self.op1.asField() # addressing mode for the source
206 Ad = self.op2.adField() # Addressing mode for dst
207 b = self.b # When b=1, the operation is byte mode
208 source = self.op1.regField()
209 destination = self.op2.regField()
210 h = (self.opcode << 12) | (source << 8)
211 h |= (self.b << 6) | (As << 4) | (Ad << 7) | destination
212 additions = self.op1.extraBytes() + self.op2.extraBytes()
213 return pack_ins(h) + additions
214
215 def decode(self, data):
216 pass
217
218
219 def twoOpIns(mne, opc):
220 """ Helper function to define a two operand arithmetic instruction """
221 members = {'mnemonic': mne, 'opcode': opc}
222 ins_cls = type(mne + '_ins', (TwoOpArith,), members)
223 msp430target.addInstruction(ins_cls)
224
225 twoOpIns('mov', 4)
226
227 # This is equivalent to the helper function twoOpIns:
228 @msp430target.instruction
229 class add_ins(TwoOpArith):
230 """ Adds the source to the destination """
231 mnemonic = 'add'
232 opcode = 5
233
234 def operate(self):
235 dst.value = dst.value + src.value
236 setFlags()
237
238 twoOpIns('addc', 6)
239 twoOpIns('subc', 7)
240 twoOpIns('sub', 8)
241 twoOpIns('cmp', 9)
242 twoOpIns('dadd', 10)
243 twoOpIns('bit', 11)
244 twoOpIns('bic', 12)
245 twoOpIns('bis', 13)
246 twoOpIns('xor', 14)
247 twoOpIns('and', 15)
248