comparison python/ppci/target/msp430/instructions.py @ 342:86b02c98a717 devel

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