msp430-decode.opc revision 1.2.8.1 1 1.1 christos /* -*- c -*- */
2 1.2.8.1 pgoyette /* Copyright (C) 2013-2016 Free Software Foundation, Inc.
3 1.1 christos Contributed by Red Hat.
4 1.1 christos Written by DJ Delorie.
5 1.1 christos
6 1.1 christos This file is part of the GNU opcodes library.
7 1.1 christos
8 1.1 christos This library is free software; you can redistribute it and/or modify
9 1.1 christos it under the terms of the GNU General Public License as published by
10 1.1 christos the Free Software Foundation; either version 3, or (at your option)
11 1.1 christos any later version.
12 1.1 christos
13 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT
14 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 1.1 christos License for more details.
17 1.1 christos
18 1.1 christos You should have received a copy of the GNU General Public License
19 1.1 christos along with this program; if not, write to the Free Software
20 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 1.1 christos MA 02110-1301, USA. */
22 1.1 christos
23 1.1 christos #include "sysdep.h"
24 1.1 christos #include <stdio.h>
25 1.1 christos #include <stdlib.h>
26 1.1 christos #include <string.h>
27 1.1 christos #include "ansidecl.h"
28 1.1 christos #include "opcode/msp430-decode.h"
29 1.1 christos
30 1.1 christos static int trace = 0;
31 1.1 christos
32 1.1 christos typedef struct
33 1.1 christos {
34 1.1 christos MSP430_Opcode_Decoded *msp430;
35 1.1 christos int (*getbyte)(void *);
36 1.1 christos void *ptr;
37 1.1 christos unsigned char *op;
38 1.1 christos int op_ptr;
39 1.1 christos int pc;
40 1.1 christos } LocalData;
41 1.1 christos
42 1.1 christos #define AU ATTRIBUTE_UNUSED
43 1.1 christos #define GETBYTE() getbyte_swapped (ld)
44 1.1 christos #define B ((unsigned long) GETBYTE ())
45 1.1 christos
46 1.1 christos static int
47 1.1 christos getbyte_swapped (LocalData *ld)
48 1.1 christos {
49 1.1 christos int b;
50 1.1 christos
51 1.1 christos if (ld->op_ptr == ld->msp430->n_bytes)
52 1.1 christos {
53 1.1 christos do
54 1.1 christos {
55 1.1 christos b = ld->getbyte (ld->ptr);
56 1.1 christos ld->op [(ld->msp430->n_bytes++)^1] = b;
57 1.1 christos }
58 1.1 christos while (ld->msp430->n_bytes & 1);
59 1.1 christos }
60 1.1 christos return ld->op[ld->op_ptr++];
61 1.1 christos }
62 1.1 christos
63 1.1 christos #define ID(x) msp430->id = x
64 1.1 christos
65 1.1 christos #define OP(n, t, r, a) (msp430->op[n].type = t, \
66 1.1 christos msp430->op[n].reg = r, \
67 1.1 christos msp430->op[n].addend = a)
68 1.1 christos
69 1.1 christos #define OPX(n, t, r1, r2, a) \
70 1.1 christos (msp430->op[n].type = t, \
71 1.1 christos msp430->op[n].reg = r1, \
72 1.1 christos msp430->op[n].reg2 = r2, \
73 1.1 christos msp430->op[n].addend = a)
74 1.1 christos
75 1.1 christos #define SYNTAX(x) msp430->syntax = x
76 1.1 christos #define UNSUPPORTED() msp430->syntax = "*unknown*"
77 1.1 christos
78 1.1 christos #define DC(c) OP (0, MSP430_Operand_Immediate, 0, c)
79 1.1 christos #define DR(r) OP (0, MSP430_Operand_Register, r, 0)
80 1.1 christos #define DM(r, a) OP (0, MSP430_Operand_Indirect, r, a)
81 1.1 christos #define DA(a) OP (0, MSP430_Operand_Indirect, MSR_None, a)
82 1.1 christos #define AD(r, ad) encode_ad (r, ad, ld, 0)
83 1.1 christos #define ADX(r, ad, x) encode_ad (r, ad, ld, x)
84 1.1 christos
85 1.1 christos #define SC(c) OP (1, MSP430_Operand_Immediate, 0, c)
86 1.1 christos #define SR(r) OP (1, MSP430_Operand_Register, r, 0)
87 1.1 christos #define SM(r, a) OP (1, MSP430_Operand_Indirect, r, a)
88 1.1 christos #define SA(a) OP (1, MSP430_Operand_Indirect, MSR_None, a)
89 1.1 christos #define SI(r) OP (1, MSP430_Operand_Indirect_Postinc, r, 0)
90 1.1 christos #define AS(r, as) encode_as (r, as, ld, 0)
91 1.1 christos #define ASX(r, as, x) encode_as (r, as, ld, x)
92 1.1 christos
93 1.1 christos #define BW(x) msp430->size = (x ? 8 : 16)
94 1.1 christos /* The last 20 is for SWPBX.Z and SXTX.A. */
95 1.1 christos #define ABW(a,x) msp430->size = (a ? ((x ? 8 : 16)) : (x ? 20 : 20))
96 1.1 christos
97 1.1 christos #define IMMU(bytes) immediate (bytes, 0, ld)
98 1.1 christos #define IMMS(bytes) immediate (bytes, 1, ld)
99 1.1 christos
100 1.1 christos /* Helper macros for known status bits settings. */
101 1.1 christos #define F_____ msp430->flags_1 = msp430->flags_0 = 0; msp430->flags_set = 0
102 1.1 christos #define F_VNZC msp430->flags_1 = msp430->flags_0 = 0; msp430->flags_set = 0x87
103 1.1 christos #define F_0NZC msp430->flags_1 = 0; msp430->flags_0 = 0x80; msp430->flags_set = 0x07
104 1.1 christos
105 1.1 christos
106 1.1 christos /* The chip is little-endian, but GETBYTE byte-swaps words because the
107 1.1 christos decoder is based on 16-bit "words" so *this* logic is big-endian. */
108 1.1 christos
109 1.1 christos static int
110 1.1 christos immediate (int bytes, int sign_extend, LocalData *ld)
111 1.1 christos {
112 1.1 christos unsigned long i = 0;
113 1.1 christos
114 1.1 christos switch (bytes)
115 1.1 christos {
116 1.1 christos case 1:
117 1.1 christos i |= B;
118 1.1 christos if (sign_extend && (i & 0x80))
119 1.1 christos i -= 0x100;
120 1.1 christos break;
121 1.1 christos case 2:
122 1.1 christos i |= B << 8;
123 1.1 christos i |= B;
124 1.1 christos if (sign_extend && (i & 0x8000))
125 1.1 christos i -= 0x10000;
126 1.1 christos break;
127 1.1 christos case 3:
128 1.1 christos i |= B << 16;
129 1.1 christos i |= B << 8;
130 1.1 christos i |= B;
131 1.1 christos if (sign_extend && (i & 0x800000))
132 1.1 christos i -= 0x1000000;
133 1.1 christos break;
134 1.1 christos case 4:
135 1.1 christos i |= B << 24;
136 1.1 christos i |= B << 16;
137 1.1 christos i |= B << 8;
138 1.1 christos i |= B;
139 1.1 christos if (sign_extend && (i & 0x80000000ULL))
140 1.1 christos i -= 0x100000000ULL;
141 1.1 christos break;
142 1.1 christos default:
143 1.1 christos fprintf (stderr,
144 1.1 christos "Programmer error: immediate() called with invalid byte count %d\n",
145 1.1 christos bytes);
146 1.1 christos abort ();
147 1.1 christos }
148 1.1 christos return i;
149 1.1 christos }
150 1.1 christos
151 1.1 christos /*
152 1.1 christos PC SP SR CG
153 1.1 christos As
154 1.1 christos 00 Rn - - R2 #0
155 1.1 christos 01 X(Rn) Sym - X(abs) #1
156 1.1 christos 10 (Rn) - - #4 #2
157 1.1 christos 11 (Rn++) #imm - #8 #-1
158 1.1 christos
159 1.1 christos Ad
160 1.1 christos 0 Rn - - - -
161 1.1 christos 1 X(Rn) Sym - X(abs) - */
162 1.1 christos
163 1.1 christos static void
164 1.1 christos encode_ad (int reg, int ad, LocalData *ld, int ext)
165 1.1 christos {
166 1.1 christos MSP430_Opcode_Decoded *msp430 = ld->msp430;
167 1.1 christos
168 1.1 christos if (ad)
169 1.1 christos {
170 1.1 christos int x = IMMU(2) | (ext << 16);
171 1.1 christos switch (reg)
172 1.1 christos {
173 1.1 christos case 0: /* (PC) -> Symbolic. */
174 1.1 christos DA (x + ld->pc + ld->op_ptr - 2);
175 1.1 christos break;
176 1.1 christos case 2: /* (SR) -> Absolute. */
177 1.1 christos DA (x);
178 1.1 christos break;
179 1.1 christos default:
180 1.1 christos DM (reg, x);
181 1.1 christos break;
182 1.1 christos }
183 1.1 christos }
184 1.1 christos else
185 1.1 christos {
186 1.1 christos DR (reg);
187 1.1 christos }
188 1.1 christos }
189 1.1 christos
190 1.1 christos static void
191 1.1 christos encode_as (int reg, int as, LocalData *ld, int ext)
192 1.1 christos {
193 1.1 christos MSP430_Opcode_Decoded *msp430 = ld->msp430;
194 1.1 christos int x;
195 1.1 christos
196 1.1 christos switch (as)
197 1.1 christos {
198 1.1 christos case 0:
199 1.1 christos switch (reg)
200 1.1 christos {
201 1.1 christos case 3:
202 1.1 christos SC (0);
203 1.1 christos break;
204 1.1 christos default:
205 1.1 christos SR (reg);
206 1.1 christos break;
207 1.1 christos }
208 1.1 christos break;
209 1.1 christos case 1:
210 1.1 christos switch (reg)
211 1.1 christos {
212 1.1 christos case 0: /* PC -> Symbolic. */
213 1.1 christos x = IMMU(2) | (ext << 16);
214 1.1 christos SA (x + ld->pc + ld->op_ptr - 2);
215 1.1 christos break;
216 1.1 christos case 2: /* SR -> Absolute. */
217 1.1 christos x = IMMU(2) | (ext << 16);
218 1.1 christos SA (x);
219 1.1 christos break;
220 1.1 christos case 3:
221 1.1 christos SC (1);
222 1.1 christos break;
223 1.1 christos default:
224 1.1 christos x = IMMU(2) | (ext << 16);
225 1.1 christos SM (reg, x);
226 1.1 christos break;
227 1.1 christos }
228 1.1 christos break;
229 1.1 christos case 2:
230 1.1 christos switch (reg)
231 1.1 christos {
232 1.1 christos case 2:
233 1.1 christos SC (4);
234 1.1 christos break;
235 1.1 christos case 3:
236 1.1 christos SC (2);
237 1.1 christos break;
238 1.1 christos case MSR_None:
239 1.1 christos SA (0);
240 1.1 christos default:
241 1.1 christos SM (reg, 0);
242 1.1 christos break;
243 1.1 christos }
244 1.1 christos break;
245 1.1 christos case 3:
246 1.1 christos switch (reg)
247 1.1 christos {
248 1.1 christos case 0:
249 1.1 christos {
250 1.1 christos /* This fetch *is* the *PC++ that the opcode encodes :-) */
251 1.1 christos x = IMMU(2) | (ext << 16);
252 1.1 christos SC (x);
253 1.1 christos }
254 1.1 christos break;
255 1.1 christos case 2:
256 1.1 christos SC (8);
257 1.1 christos break;
258 1.1 christos case 3:
259 1.1 christos SC (-1);
260 1.1 christos break;
261 1.1 christos default:
262 1.1 christos SI (reg);
263 1.1 christos break;
264 1.1 christos }
265 1.1 christos break;
266 1.1 christos }
267 1.1 christos }
268 1.1 christos
269 1.1 christos static void
270 1.1 christos encode_rep_zc (int srxt, int dsxt, LocalData *ld)
271 1.1 christos {
272 1.1 christos MSP430_Opcode_Decoded *msp430 = ld->msp430;
273 1.1 christos
274 1.1 christos msp430->repeat_reg = srxt & 1;
275 1.1 christos msp430->repeats = dsxt;
276 1.1 christos msp430->zc = (srxt & 2) ? 1 : 0;
277 1.1 christos }
278 1.1 christos
279 1.1 christos #define REPZC(s,d) encode_rep_zc (s, d, ld)
280 1.1 christos
281 1.1 christos static int
282 1.1 christos dopc_to_id (int dopc)
283 1.1 christos {
284 1.1 christos switch (dopc)
285 1.1 christos {
286 1.1 christos case 4: return MSO_mov;
287 1.1 christos case 5: return MSO_add;
288 1.1 christos case 6: return MSO_addc;
289 1.1 christos case 7: return MSO_subc;
290 1.1 christos case 8: return MSO_sub;
291 1.1 christos case 9: return MSO_cmp;
292 1.1 christos case 10: return MSO_dadd;
293 1.1 christos case 11: return MSO_bit;
294 1.1 christos case 12: return MSO_bic;
295 1.1 christos case 13: return MSO_bis;
296 1.1 christos case 14: return MSO_xor;
297 1.1 christos case 15: return MSO_and;
298 1.1 christos default: return MSO_unknown;
299 1.1 christos }
300 1.1 christos }
301 1.1 christos
302 1.1 christos static int
303 1.1 christos sopc_to_id (int sop, int c)
304 1.1 christos {
305 1.1 christos switch (sop * 2 + c)
306 1.1 christos {
307 1.1 christos case 0: return MSO_rrc;
308 1.1 christos case 1: return MSO_swpb;
309 1.1 christos case 2: return MSO_rra;
310 1.1 christos case 3: return MSO_sxt;
311 1.1 christos case 4: return MSO_push;
312 1.1 christos case 5: return MSO_call;
313 1.1 christos case 6: return MSO_reti;
314 1.1 christos default: return MSO_unknown;
315 1.1 christos }
316 1.1 christos }
317 1.1 christos
318 1.1 christos int
319 1.1 christos msp430_decode_opcode (unsigned long pc,
320 1.1 christos MSP430_Opcode_Decoded *msp430,
321 1.1 christos int (*getbyte)(void *),
322 1.1 christos void *ptr)
323 1.1 christos {
324 1.1 christos LocalData lds, *ld = &lds;
325 1.1 christos unsigned char op_buf[20] = {0};
326 1.1 christos unsigned char *op = op_buf;
327 1.1 christos int raddr;
328 1.1 christos int al_bit;
329 1.1 christos int srxt_bits, dsxt_bits;
330 1.1 christos
331 1.1 christos lds.msp430 = msp430;
332 1.1 christos lds.getbyte = getbyte;
333 1.1 christos lds.ptr = ptr;
334 1.1 christos lds.op = op;
335 1.1 christos lds.op_ptr = 0;
336 1.1 christos lds.pc = pc;
337 1.1 christos
338 1.1 christos memset (msp430, 0, sizeof (*msp430));
339 1.1 christos
340 1.1 christos /* These are overridden by an extension word. */
341 1.1 christos al_bit = 1;
342 1.1 christos srxt_bits = 0;
343 1.1 christos dsxt_bits = 0;
344 1.1 christos
345 1.1 christos post_extension_word:
346 1.1 christos ;
347 1.1 christos
348 1.1 christos /* 430X extention word. */
349 1.1 christos /** 0001 1srx t l 00 dsxt 430x */
350 1.1 christos
351 1.1 christos al_bit = l;
352 1.1 christos srxt_bits = srx * 2 + t;
353 1.1 christos dsxt_bits = dsxt;
354 1.1 christos op = op_buf + lds.op_ptr;
355 1.1 christos msp430->ofs_430x = 1;
356 1.1 christos goto post_extension_word;
357 1.1 christos
358 1.1 christos /* double-op insns:
359 1.1 christos opcode:4 sreg:4 Ad:1 BW:1 As:2 Dreg:4
360 1.1 christos
361 1.1 christos single-op insn:
362 1.1 christos opcode:9 BW:1 Ad:2 DSreg:4
363 1.1 christos
364 1.1 christos jumps:
365 1.1 christos opcode:3 Cond:3 pcrel:10. */
366 1.1 christos
367 1.1 christos /* Double-Operand "opcode" fields. */
368 1.1 christos /** VARY dopc 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 */
369 1.1 christos
370 1.1 christos /** dopc sreg a b as dreg %D%b %1,%0 */
371 1.1 christos
372 1.1 christos ID (dopc_to_id (dopc)); ASX (sreg, as, srxt_bits); ADX (dreg, a, dsxt_bits); ABW (al_bit, b);
373 1.1 christos if (a == 0 && as == 0)
374 1.1 christos REPZC (srxt_bits, dsxt_bits);
375 1.1 christos
376 1.1 christos switch (msp430->id)
377 1.1 christos {
378 1.1 christos case MSO_mov: F_____; break;
379 1.1 christos case MSO_add: F_VNZC; break;
380 1.1 christos case MSO_addc: F_VNZC; break;
381 1.1 christos case MSO_subc: F_VNZC; break;
382 1.1 christos case MSO_sub: F_VNZC; break;
383 1.1 christos case MSO_cmp: F_VNZC; break;
384 1.1 christos case MSO_dadd: F_VNZC; break;
385 1.1 christos case MSO_bit: F_0NZC; break;
386 1.1 christos case MSO_bic: F_____; break;
387 1.1 christos case MSO_bis: F_____; break;
388 1.1 christos case MSO_xor: F_VNZC; break;
389 1.1 christos case MSO_and: F_0NZC; break;
390 1.1 christos default: break;
391 1.1 christos }
392 1.1 christos
393 1.1 christos /** 0001 00so c b ad dreg %S%b %1 */
394 1.1 christos
395 1.1 christos ID (sopc_to_id (so,c)); ASX (dreg, ad, srxt_bits); ABW (al_bit, b);
396 1.1 christos
397 1.1 christos if (ad == 0)
398 1.1 christos REPZC (srxt_bits, dsxt_bits);
399 1.1 christos
400 1.1 christos /* The helper functions encode for source, but it's
401 1.1 christos both source and dest, with a few documented exceptions. */
402 1.1 christos msp430->op[0] = msp430->op[1];
403 1.1 christos
404 1.1 christos /* RETI ignores the operand. */
405 1.1 christos if (msp430->id == MSO_reti)
406 1.1 christos msp430->syntax = "%S";
407 1.1 christos
408 1.1 christos switch (msp430->id)
409 1.1 christos {
410 1.1 christos case MSO_rrc: F_VNZC; break;
411 1.1 christos case MSO_swpb: F_____; break;
412 1.1 christos case MSO_rra: F_0NZC; break;
413 1.1 christos case MSO_sxt: F_0NZC; break;
414 1.1 christos case MSO_push: F_____; break;
415 1.1 christos case MSO_call: F_____; break;
416 1.1 christos case MSO_reti: F_VNZC; break;
417 1.1 christos default: break;
418 1.1 christos }
419 1.1 christos
420 1.1 christos /* 20xx 0010 0000 ---- ----
421 1.1 christos 3cxx 0011 1100 ---- ----
422 1.1 christos 001j mp-- ---- ----. */
423 1.1 christos /** 001jmp aa addrlsbs %J %1 */
424 1.1 christos
425 1.1 christos raddr = (aa << 9) | (addrlsbs << 1);
426 1.1 christos if (raddr & 0x400)
427 1.1 christos raddr = raddr - 0x800;
428 1.1 christos /* This is a pc-relative jump, but we don't use SM because that
429 1.1 christos would load the target address from the memory at X(PC), not use
430 1.1 christos PC+X *as* the address. So we use SC to use the address, not the
431 1.1 christos data at that address. */
432 1.1 christos ID (MSO_jmp); SC (pc + raddr + msp430->n_bytes);
433 1.1 christos msp430->cond = jmp;
434 1.1 christos
435 1.1 christos /* Extended instructions. */
436 1.1 christos
437 1.1 christos /** 0000 srcr 0000 dstr MOVA @%1, %0 */
438 1.1 christos ID (MSO_mov); SM (srcr, 0); DR (dstr);
439 1.1 christos msp430->size = 20;
440 1.1 christos msp430->ofs_430x = 1;
441 1.1 christos
442 1.1 christos /** 0000 srcr 0001 dstr MOVA @%1+, %0 */
443 1.1 christos ID (MSO_mov); SI (srcr); DR (dstr);
444 1.1 christos msp430->size = 20;
445 1.1 christos msp430->ofs_430x = 1;
446 1.1 christos
447 1.1 christos /** 0000 srcr 0010 dstr MOVA &%1, %0 */
448 1.1 christos ID (MSO_mov); SA ((srcr << 16) + IMMU(2)); DR (dstr);
449 1.1 christos msp430->size = 20;
450 1.1 christos msp430->ofs_430x = 1;
451 1.1 christos
452 1.1 christos /** 0000 srcr 0011 dstr MOVA %1, %0 */
453 1.1 christos ID (MSO_mov); SM (srcr, IMMS(2)); DR (dstr);
454 1.1 christos msp430->size = 20;
455 1.1 christos msp430->ofs_430x = 1;
456 1.1 christos
457 1.1 christos /** 0000 srcr 0110 dstr MOVA %1, &%0 */
458 1.1 christos ID (MSO_mov); SR (srcr); DA ((dstr << 16) + IMMU(2));
459 1.1 christos msp430->size = 20;
460 1.1 christos msp430->ofs_430x = 1;
461 1.1 christos
462 1.1 christos /** 0000 srcr 0111 dstr MOVA %1, &%0 */
463 1.1 christos ID (MSO_mov); SR (srcr); DM (dstr, IMMS(2));
464 1.1 christos msp430->size = 20;
465 1.1 christos msp430->ofs_430x = 1;
466 1.1 christos
467 1.1 christos /** 0000 srcr 1000 dstr MOVA %1, %0 */
468 1.1 christos ID (MSO_mov); SC ((srcr << 16) + IMMU(2)); DR (dstr);
469 1.1 christos msp430->size = 20;
470 1.1 christos msp430->ofs_430x = 1;
471 1.1 christos
472 1.1 christos /** 0000 srcr 1001 dstr CMPA %1, %0 */
473 1.1 christos ID (MSO_cmp); SC ((srcr << 16) + IMMU(2)); DR (dstr);
474 1.1 christos msp430->size = 20;
475 1.1 christos msp430->ofs_430x = 1;
476 1.1 christos F_VNZC;
477 1.1 christos
478 1.1 christos /** 0000 srcr 1010 dstr ADDA %1, %0 */
479 1.1 christos ID (MSO_add); SC ((srcr << 16) + IMMU(2)); DR (dstr);
480 1.1 christos msp430->size = 20;
481 1.1 christos msp430->ofs_430x = 1;
482 1.1 christos F_VNZC;
483 1.1 christos
484 1.1 christos /** 0000 srcr 1011 dstr SUBA %1, %0 */
485 1.1 christos ID (MSO_sub); SC ((srcr << 16) + IMMU(2)); DR (dstr);
486 1.1 christos msp430->size = 20;
487 1.1 christos msp430->ofs_430x = 1;
488 1.1 christos F_VNZC;
489 1.1 christos
490 1.1 christos /** 0000 srcr 1011 dstr SUBA %1, %0 */
491 1.1 christos ID (MSO_sub); SC ((srcr << 16) + IMMU(2)); DR (dstr);
492 1.1 christos msp430->size = 20;
493 1.1 christos msp430->ofs_430x = 1;
494 1.1 christos F_VNZC;
495 1.1 christos
496 1.1 christos /** 0000 srcr 1100 dstr MOVA %1, %0 */
497 1.1 christos ID (MSO_mov); SR (srcr); DR (dstr);
498 1.1 christos msp430->size = 20;
499 1.1 christos msp430->ofs_430x = 1;
500 1.1 christos
501 1.1 christos /** 0000 srcr 1101 dstr CMPA %1, %0 */
502 1.1 christos ID (MSO_cmp); SR (srcr); DR (dstr);
503 1.1 christos msp430->size = 20;
504 1.1 christos msp430->ofs_430x = 1;
505 1.1 christos F_VNZC;
506 1.1 christos
507 1.1 christos /** 0000 srcr 1110 dstr ADDA %1, %0 */
508 1.1 christos ID (MSO_add); SR (srcr); DR (dstr);
509 1.1 christos msp430->size = 20;
510 1.1 christos msp430->ofs_430x = 1;
511 1.1 christos F_VNZC;
512 1.1 christos
513 1.1 christos /** 0000 srcr 1111 dstr SUBA %1, %0 */
514 1.1 christos ID (MSO_sub); SR (srcr); DR (dstr);
515 1.1 christos msp430->size = 20;
516 1.1 christos msp430->ofs_430x = 1;
517 1.1 christos F_VNZC;
518 1.1 christos
519 1.1 christos /** 0000 bt00 010w dstr RRCM.A %c, %0 */
520 1.1 christos ID (MSO_rrc); DR (dstr); SR (dstr);
521 1.1 christos msp430->repeats = bt;
522 1.1 christos msp430->size = w ? 16 : 20;
523 1.1 christos msp430->ofs_430x = 1;
524 1.1 christos F_0NZC;
525 1.1 christos
526 1.1 christos /** 0000 bt01 010w dstr RRAM.A %c, %0 */
527 1.1 christos ID (MSO_rra); DR (dstr); SR (dstr);
528 1.1 christos msp430->repeats = bt;
529 1.1 christos msp430->size = w ? 16 : 20;
530 1.1 christos msp430->ofs_430x = 1;
531 1.1 christos F_0NZC;
532 1.1 christos
533 1.1 christos /** 0000 bt10 010w dstr RLAM.A %c, %0 */
534 1.1 christos ID (MSO_add); DR (dstr); SR (dstr);
535 1.1 christos msp430->repeats = bt;
536 1.1 christos msp430->size = w ? 16 : 20;
537 1.1 christos msp430->ofs_430x = 1;
538 1.1 christos F_0NZC;
539 1.1 christos
540 1.1 christos /** 0000 bt11 010w dstr RRUM.A %c, %0 */
541 1.1 christos ID (MSO_rru); DR (dstr); SR (dstr);
542 1.1 christos msp430->repeats = bt;
543 1.1 christos msp430->size = w ? 16 : 20;
544 1.1 christos msp430->ofs_430x = 1;
545 1.1 christos F_0NZC;
546 1.1 christos
547 1.1 christos /** 0001 0011 0000 0000 RETI */
548 1.1 christos ID (MSO_reti);
549 1.1 christos msp430->size = 20;
550 1.1 christos msp430->ofs_430x = 1;
551 1.1 christos
552 1.1 christos /** 0001 0011 01as dstr CALLA %0 */
553 1.1 christos ID (MSO_call); AS (dstr, as);
554 1.1 christos msp430->size = 20;
555 1.1 christos msp430->ofs_430x = 1;
556 1.1 christos
557 1.1 christos /** 0001 0011 1000 extb CALLA %0 */
558 1.1 christos ID (MSO_call); SA (IMMU(2) | (extb << 16));
559 1.1 christos msp430->size = 20;
560 1.1 christos msp430->ofs_430x = 1;
561 1.1 christos
562 1.1 christos /** 0001 0011 1001 extb CALLA %0 */
563 1.1 christos raddr = IMMU(2) | (extb << 16);
564 1.1 christos if (raddr & 0x80000)
565 1.1 christos raddr -= 0x100000;
566 1.1 christos ID (MSO_call); SA (pc + raddr + msp430->n_bytes);
567 1.1 christos msp430->size = 20;
568 1.1 christos msp430->ofs_430x = 1;
569 1.1 christos
570 1.1 christos /** 0001 0011 1011 extb CALLA %0 */
571 1.1 christos ID (MSO_call); SC (IMMU(2) | (extb << 16));
572 1.1 christos msp430->size = 20;
573 1.1 christos msp430->ofs_430x = 1;
574 1.1 christos
575 1.1 christos /** 0001 010w bits srcr PUSHM.A %0 */
576 1.1 christos ID (MSO_push); SR (srcr);
577 1.1 christos msp430->size = w ? 16 : 20;
578 1.1 christos msp430->repeats = bits;
579 1.1 christos msp430->ofs_430x = 1;
580 1.1 christos
581 1.1 christos /** 0001 011w bits dstr POPM.A %0 */
582 1.1 christos ID (MSO_pop); DR (dstr);
583 1.1 christos msp430->size = w ? 16 : 20;
584 1.1 christos msp430->repeats = bits;
585 1.1 christos msp430->ofs_430x = 1;
586 1.1 christos
587 1.1 christos /** */
588 1.1 christos
589 1.1 christos return msp430->n_bytes;
590 1.1 christos }
591