annotate python/ppci/target/msp430/instructions.py @ 391:a139da1f44f6

Merge
author Windel Bouwman
date Fri, 16 May 2014 12:30:10 +0200
parents 86b02c98a717
children
rev   line source
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
1
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
2 from ..basetarget import Register, Instruction, Target
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
3 from ..token import Token, u16, bit_range
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
4 from .registers import Msp430Register
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
5
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
6
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
7 class Msp430Token(Token):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
8 def __init__(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
9 super().__init__(16)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
10
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
11 condition = bit_range(10, 13)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
12 opcode = bit_range(12, 16)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
13 register = bit_range(0, 4)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
14 destination = bit_range(0, 4)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
15 source = bit_range(8, 12)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
16 bw = bit_range(6, 7) # TODO: actually a single bit!
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
17 Ad = bit_range(7, 8) # TODO: actually a single bit!
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
18 As = bit_range(4, 6)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
19
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
20 def encode(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
21 return u16(self.bit_value)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
22
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
23 REGISTER_MODE = 1
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
24 SYMBOLIC_MODE = 3
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
25 ABSOLUTE_MODE = 4
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
26 #TODO: add more modes!
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
27 IMMEDIATE_MODE = 7
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
28
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
29 class Msp430Operand:
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
30 pass
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
31
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
32 class Msp430DestinationOperand(Msp430Operand):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
33 def __init__(self, param):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
34 if isinstance(param, Msp430Register):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
35 self.reg = param.num
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
36 self.Ad = 0
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
37 else:
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
38 raise Exception()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
39
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
40
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
41 class Msp430SourceOperand(Msp430Operand):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
42 def __init__(self, param):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
43 if isinstance(param, Msp430Register):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
44 self.reg = param.num
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
45 self.As = 0
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
46 self.extra_bytes = bytes()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
47 elif isinstance(param, int):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
48 self.reg = 0
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
49 self.As = 3
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
50 self.extra_bytes = u16(param)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
51 else:
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
52 raise Exception()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
53
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
54
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
55 class Msp430Instruction(Instruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
56 b = 0
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
57 def __init__(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
58 self.token = Msp430Token()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
59
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
60
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
61 class Reti(Msp430Instruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
62 def encode(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
63 self.token[0:16] = 0x1300
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
64 return self.token.encode()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
65
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
66
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
67 #########################
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
68 # Jump instructions:
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
69 #########################
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
70
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
71 class JumpInstruction(Msp430Instruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
72 def __init__(self, target):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
73 super().__init__()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
74 self.target = target
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
75
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
76 def encode(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
77 self.token.condition = self.condition
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
78 self.token.offset = 0
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
79 self.token[13] = 1
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
80 return self.token.encode()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
81
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
82 def relocations(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
83 return [(self.target, 'msp_reloc')]
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
84
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
85
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
86 class Jnz(JumpInstruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
87 condition = 0
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
88
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
89
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
90 class Jz(JumpInstruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
91 condition = 1
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
92
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
93
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
94 class Jnc(JumpInstruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
95 condition = 2
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
96
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
97
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
98 class Jc(JumpInstruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
99 condition = 3
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
100
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
101
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
102 class Jn(JumpInstruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
103 condition = 4
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
104
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
105
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
106 class Jge(JumpInstruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
107 condition = 5
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
108
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
109
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
110 class Jl(JumpInstruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
111 condition = 6
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
112
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
113
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
114 class Jmp(JumpInstruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
115 condition = 7
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
116
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
117
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
118 #########################
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
119 # Single operand arithmatic:
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
120 #########################
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
121
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
122
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
123 class OneOpArith(Msp430Instruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
124 def __init__(self, op1):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
125 self.op1 = op1
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
126
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
127 def encode(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
128 # TODO:
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
129 bits[15:10] = '00100'
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
130 h1 = (self.opcode << 4)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
131 return pack_ins(h1)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
132
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
133
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
134 def oneOpIns(mne, opc):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
135 """ Helper function to define a one operand arithmetic instruction """
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
136 members = {'opcode': opc}
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
137 ins_cls = type(mne + '_ins', (OneOpArith,), members)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
138
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
139
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
140 oneOpIns('rrc', 0)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
141 oneOpIns('swpb', 1)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
142 oneOpIns('rra', 2)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
143 oneOpIns('sxt', 3)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
144 oneOpIns('push', 4)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
145 oneOpIns('call', 5)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
146
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
147
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
148 #########################
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
149 # Two operand arithmatic instructions:
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
150 #########################
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
151
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
152
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
153 class TwoOpArith(Msp430Instruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
154 def __init__(self, src, dst):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
155 super().__init__()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
156 self.src = Msp430SourceOperand(src)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
157 self.dst = Msp430DestinationOperand(dst)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
158
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
159 def encode(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
160 """
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
161 Smart things have been done by MSP430 designers.
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
162 As (2 bits) is the source addressing mode selector.
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
163 Ad (1 bit) is the destination adressing mode selector.
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
164 For the source there are 7 different addressing mode.
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
165 For the destination there are 4.
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
166 The trick is to use also the register to distuingish the
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
167 different modes.
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
168 """
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
169 # TODO: Make memory also possible
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
170 self.token.bw = self.b # When b=1, the operation is byte mode
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
171 self.token.As = self.src.As
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
172 self.token.Ad = self.dst.Ad
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
173 self.token.destination = self.dst.reg
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
174 self.token.source = self.src.reg
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
175 self.token.opcode = self.opcode
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
176 return self.token.encode() + self.src.extra_bytes
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
177
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
178
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
179 def twoOpIns(mne, opc):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
180 """ Helper function to define a two operand arithmetic instruction """
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
181 members = {'opcode': opc}
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
182 ins_cls = type(mne + '_ins', (TwoOpArith,), members)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
183
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
184
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
185 class Mov(TwoOpArith):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
186 """ Moves the source to the destination """
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
187 opcode = 4
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
188
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
189
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
190 # This is equivalent to the helper function twoOpIns:
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
191 class Add(TwoOpArith):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
192 """ Adds the source to the destination """
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
193 mnemonic = 'add'
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
194 opcode = 5
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
195
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
196
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
197 twoOpIns('addc', 6)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
198 twoOpIns('subc', 7)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
199 twoOpIns('sub', 8)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
200
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
201
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
202 class Cmp(TwoOpArith):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
203 opcode = 9
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
204
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
205
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
206 twoOpIns('dadd', 10)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
207 twoOpIns('bit', 11)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
208 twoOpIns('bic', 12)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
209 twoOpIns('bis', 13)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
210 twoOpIns('xor', 14)
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
211 twoOpIns('and', 15)