Mercurial > lcfOS
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) |