Coverage Report

Created: 2026-10-02 09:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/opcodes/msp430-dis.c
Line
Count
Source
1
/* Disassemble MSP430 instructions.
2
   Copyright (C) 2002-2026 Free Software Foundation, Inc.
3
4
   Contributed by Dmitry Diky <diwil@mail.ru>
5
6
   This file is part of the GNU opcodes library.
7
8
   This library is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3, or (at your option)
11
   any later version.
12
13
   It is distributed in the hope that it will be useful, but WITHOUT
14
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16
   License for more details.
17
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21
   MA 02110-1301, USA.  */
22
23
#include "sysdep.h"
24
#include <stdio.h>
25
#include <ctype.h>
26
#include <sys/types.h>
27
#include <errno.h>
28
29
#include "disassemble.h"
30
#include "opintl.h"
31
#include "libiberty.h"
32
33
#define DASM_SECTION
34
#include "opcode/msp430.h"
35
#undef DASM_SECTION
36
37
38
113k
#define PS(x)   (0xffff & (x))
39
40
static bool
41
msp430dis_read_two_bytes (bfd_vma            addr,
42
        disassemble_info * info,
43
        bfd_byte *         buffer,
44
        char *             comm)
45
539k
{
46
539k
  int status;
47
48
539k
  status = info->read_memory_func (addr, buffer, 2, info);
49
539k
  if (status == 0)
50
538k
    return true;
51
52
  /* PR 20150: A status of EIO means that there were no more bytes left
53
     to read in the current section.  This can happen when disassembling
54
     interrupt vectors for example.  Avoid cluttering the output with
55
     unhelpful error messages in this case.  */
56
465
  if (status == EIO)
57
465
    {
58
465
      if (comm)
59
214
  sprintf (comm, _("Warning: disassembly unreliable - not enough bytes available"));
60
465
    }
61
0
  else
62
0
    {
63
0
      info->memory_error_func (status, addr, info);
64
0
      if (comm)
65
0
  sprintf (comm, _("Error: read from memory failed"));
66
0
    }
67
68
465
  return false;
69
539k
}
70
71
static bool
72
msp430dis_opcode_unsigned (bfd_vma            addr,
73
         disassemble_info * info,
74
         unsigned short *   return_val,
75
         char *             comm)
76
420k
{
77
420k
  bfd_byte buffer[2];
78
79
420k
  if (msp430dis_read_two_bytes (addr, info, buffer, comm))
80
420k
    {
81
420k
      * return_val = bfd_getl16 (buffer);
82
420k
      return true;
83
420k
    }
84
289
  else
85
289
    {
86
289
      * return_val = 0;
87
289
      return false;
88
289
    }
89
420k
}
90
91
static bool
92
msp430dis_opcode_signed (bfd_vma            addr,
93
       disassemble_info * info,
94
       signed int *       return_val,
95
       char *             comm)
96
118k
{
97
118k
  bfd_byte buffer[2];
98
99
118k
  if (msp430dis_read_two_bytes (addr, info, buffer, comm))
100
117k
    {
101
117k
      int status;
102
103
117k
      status = bfd_getl_signed_16 (buffer);
104
117k
      if (status & 0x8000)
105
54.0k
  status |= -1U << 16;
106
117k
      * return_val = status;
107
117k
      return true;
108
117k
    }
109
176
  else
110
176
    {
111
176
      * return_val = 0;
112
176
      return false;
113
176
    }
114
118k
}
115
116
static int
117
msp430_nooperands (struct msp430_opcode_s *opcode,
118
       bfd_vma addr ATTRIBUTE_UNUSED,
119
       unsigned short insn ATTRIBUTE_UNUSED,
120
       char *comm,
121
       int *cycles)
122
68.1k
{
123
  /* Pop with constant.  */
124
68.1k
  if (insn == 0x43b2)
125
0
    return 0;
126
68.1k
  if (insn == opcode->bin_opcode)
127
65.5k
    return 2;
128
129
2.50k
  if (opcode->fmt == 0)
130
1.59k
    {
131
1.59k
      if ((insn & 0x0f00) != 0x0300 || (insn & 0x0f00) != 0x0200)
132
1.59k
  return 0;
133
134
0
      strcpy (comm, "emulated...");
135
0
      *cycles = 1;
136
0
    }
137
911
  else
138
911
    {
139
911
      strcpy (comm, "return from interupt");
140
911
      *cycles = 5;
141
911
    }
142
143
911
  return 2;
144
2.50k
}
145
146
static int
147
print_as2_reg_name (int regno, char * op1, char * comm1,
148
        int c2, int c3, int cd)
149
32.3k
{
150
32.3k
  switch (regno)
151
32.3k
    {
152
4.12k
    case 2:
153
4.12k
      sprintf (op1, "#4");
154
4.12k
      sprintf (comm1, "r2 As==10");
155
4.12k
      return c2;
156
157
2.24k
    case 3:
158
2.24k
      sprintf (op1, "#2");
159
2.24k
      sprintf (comm1, "r3 As==10");
160
2.24k
      return c3;
161
162
25.9k
    default:
163
      /* Indexed register mode @Rn.  */
164
25.9k
      sprintf (op1, "@r%d", regno);
165
25.9k
      return cd;
166
32.3k
    }
167
32.3k
}
168
169
static int
170
print_as3_reg_name (int regno, char * op1, char * comm1,
171
        int c2, int c3, int cd)
172
39.7k
{
173
39.7k
  switch (regno)
174
39.7k
    {
175
2.48k
    case 2:
176
2.48k
      sprintf (op1, "#8");
177
2.48k
      sprintf (comm1, "r2 As==11");
178
2.48k
      return c2;
179
180
3.54k
    case 3:
181
3.54k
      sprintf (op1, "#-1");
182
3.54k
      sprintf (comm1, "r3 As==11");
183
3.54k
      return c3;
184
185
33.7k
    default:
186
      /* Post incremented @Rn+.  */
187
33.7k
      sprintf (op1, "@r%d+", regno);
188
33.7k
      return cd;
189
39.7k
    }
190
39.7k
}
191
192
static int
193
msp430_singleoperand (disassemble_info *info,
194
          struct msp430_opcode_s *opcode,
195
          bfd_vma addr,
196
          unsigned short insn,
197
          char *op,
198
          char *comm,
199
          unsigned short extension_word,
200
          int *cycles)
201
63.5k
{
202
63.5k
  int regs = 0, regd = 0;
203
63.5k
  int ad = 0, as = 0;
204
63.5k
  int where = 0;
205
63.5k
  int cmd_len = 2;
206
63.5k
  int dst = 0;
207
63.5k
  int fmt;
208
63.5k
  int extended_dst = extension_word & 0xf;
209
210
63.5k
  regd = insn & 0x0f;
211
63.5k
  regs = (insn & 0x0f00) >> 8;
212
63.5k
  as = (insn & 0x0030) >> 4;
213
63.5k
  ad = (insn & 0x0080) >> 7;
214
215
63.5k
  if (opcode->fmt < 0)
216
0
    fmt = (- opcode->fmt) - 1;
217
63.5k
  else
218
63.5k
    fmt = opcode->fmt;
219
220
63.5k
  switch (fmt)
221
63.5k
    {
222
4.40k
    case 0:     /* Emulated work with dst register.  */
223
4.40k
      if (regs != 2 && regs != 3 && regs != 1)
224
0
  return 0;
225
226
      /* Check if not clr insn.  */
227
4.40k
      if (opcode->bin_opcode == 0x4300 && (ad || as))
228
105
  return 0;
229
230
      /* Check if really inc, incd insns.  */
231
4.30k
      if ((opcode->bin_opcode & 0xff00) == 0x5300 && as == 3)
232
0
  return 0;
233
234
4.30k
      if (ad == 0)
235
2.59k
  {
236
2.59k
    *cycles = 1;
237
238
    /* Register.  */
239
2.59k
    if (regd == 0)
240
448
      {
241
448
        *cycles += 1;
242
448
        sprintf (op, "r0");
243
448
      }
244
2.15k
    else if (regd == 1)
245
776
      sprintf (op, "r1");
246
247
1.37k
    else if (regd == 2)
248
147
      sprintf (op, "r2");
249
250
1.22k
    else
251
1.22k
      sprintf (op, "r%d", regd);
252
2.59k
  }
253
1.70k
      else  /* ad == 1 msp430dis_opcode.  */
254
1.70k
  {
255
1.70k
    if (regd == 0)
256
284
      {
257
        /* PC relative.  */
258
284
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
259
283
    {
260
283
      cmd_len += 2;
261
283
      *cycles = 4;
262
283
      if (extended_dst)
263
77
        {
264
77
          dst |= extended_dst << 16;
265
77
          sprintf (op, "0x%05x", dst);
266
77
          sprintf (comm, "PC rel. abs addr 0x%05lx",
267
77
             (long)((addr + 2 + dst) & 0xfffff));
268
77
        }
269
206
      else
270
206
        {
271
206
          sprintf (op, "0x%04x", dst);
272
206
          sprintf (comm, "PC rel. abs addr 0x%04x",
273
206
             PS ((short) (addr + 2) + dst));
274
206
        }
275
283
    }
276
1
        else
277
1
    return -1;
278
284
      }
279
1.42k
    else if (regd == 2)
280
411
      {
281
        /* Absolute.  */
282
411
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
283
408
    {
284
408
      cmd_len += 2;
285
408
      *cycles = 4;
286
408
      if (extended_dst)
287
172
        {
288
172
          dst |= extended_dst << 16;
289
172
          sprintf (op, "&0x%05x", dst & 0xfffff);
290
172
        }
291
236
      else
292
236
        sprintf (op, "&0x%04x", PS (dst));
293
408
    }
294
3
        else
295
3
    return -1;
296
411
      }
297
1.00k
    else
298
1.00k
      {
299
1.00k
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
300
1.00k
    {
301
1.00k
      cmd_len += 2;
302
1.00k
      *cycles = 4;
303
1.00k
      if (extended_dst)
304
209
        {
305
209
          dst |= extended_dst << 16;
306
209
          if (dst & 0x80000)
307
83
      dst |= -1U << 20;
308
209
        }
309
1.00k
      sprintf (op, "%d(r%d)", dst, regd);
310
1.00k
    }
311
3
        else
312
3
    return -1;
313
1.00k
      }
314
1.70k
  }
315
4.29k
      break;
316
317
20.6k
    case 2: /* rrc, push, call, swpb, rra, sxt, push, call, reti etc...  */
318
20.6k
      if (as == 0)
319
3.29k
  {
320
3.29k
    if (regd == 3)
321
269
      {
322
        /* Constsnts.  */
323
269
        sprintf (op, "#0");
324
269
        sprintf (comm, "r3 As==00");
325
269
      }
326
3.02k
    else
327
3.02k
      {
328
        /* Register.  */
329
3.02k
        sprintf (op, "r%d", regd);
330
3.02k
      }
331
3.29k
    *cycles = 1;
332
3.29k
  }
333
17.3k
      else if (as == 2)
334
2.43k
  {
335
2.43k
    * cycles = print_as2_reg_name (regd, op, comm, 1, 1, 3);
336
2.43k
  }
337
14.8k
      else if (as == 3)
338
4.10k
  {
339
4.10k
    if (regd == 0)
340
2.08k
      {
341
2.08k
        *cycles = 3;
342
        /* absolute. @pc+ */
343
2.08k
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
344
2.08k
    {
345
2.08k
      cmd_len += 2;
346
2.08k
      if (extended_dst)
347
1.03k
        {
348
1.03k
          dst |= extended_dst << 16;
349
1.03k
          if (dst & 0x80000)
350
221
      dst |= -1U << 20;
351
1.03k
          sprintf (op, "#%d", dst);
352
1.03k
          if (dst > 9 || dst < 0)
353
1.03k
      sprintf (comm, "#0x%05x", dst);
354
1.03k
        }
355
1.05k
      else
356
1.05k
        {
357
1.05k
          sprintf (op, "#%d", dst);
358
1.05k
          if (dst > 9 || dst < 0)
359
941
      sprintf (comm, "#0x%04x", PS (dst));
360
1.05k
        }
361
2.08k
    }
362
1
        else
363
1
    return -1;
364
2.08k
      }
365
2.01k
    else
366
2.01k
      * cycles = print_as3_reg_name (regd, op, comm, 1, 1, 3);
367
4.10k
  }
368
10.7k
      else if (as == 1)
369
10.7k
  {
370
10.7k
    *cycles = 4;
371
10.7k
    if (regd == 0)
372
2.43k
      {
373
        /* PC relative.  */
374
2.43k
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
375
2.42k
    {
376
2.42k
      cmd_len += 2;
377
2.42k
      if (extended_dst)
378
170
        {
379
170
          dst |= extended_dst << 16;
380
170
          sprintf (op, "0x%05x", dst & 0xffff);
381
170
          sprintf (comm, "PC rel. 0x%05lx",
382
170
             (long)((addr + 2 + dst) & 0xfffff));
383
170
        }
384
2.25k
      else
385
2.25k
        {
386
2.25k
          sprintf (op, "0x%04x", PS (dst));
387
2.25k
          sprintf (comm, "PC rel. 0x%04x",
388
2.25k
             PS ((short) addr + 2 + dst));
389
2.25k
        }
390
2.42k
    }
391
6
        else
392
6
    return -1;
393
2.43k
      }
394
8.34k
    else if (regd == 2)
395
1.12k
      {
396
        /* Absolute.  */
397
1.12k
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
398
1.11k
    {
399
1.11k
      cmd_len += 2;
400
1.11k
      if (extended_dst)
401
43
        {
402
43
          dst |= extended_dst << 16;
403
43
          sprintf (op, "&0x%05x", dst & 0xfffff);
404
43
        }
405
1.07k
      else
406
1.07k
        sprintf (op, "&0x%04x", PS (dst));
407
1.11k
    }
408
6
        else
409
6
    return -1;
410
1.12k
      }
411
7.22k
    else if (regd == 3)
412
1.38k
      {
413
1.38k
        *cycles = 1;
414
1.38k
        sprintf (op, "#1");
415
1.38k
        sprintf (comm, "r3 As==01");
416
1.38k
      }
417
5.83k
    else
418
5.83k
      {
419
        /* Indexed.  */
420
5.83k
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
421
5.83k
    {
422
5.83k
      cmd_len += 2;
423
5.83k
      if (extended_dst)
424
1.02k
        {
425
1.02k
          dst |= extended_dst << 16;
426
1.02k
          if (dst & 0x80000)
427
900
      dst |= -1U << 20;
428
1.02k
        }
429
5.83k
      sprintf (op, "%d(r%d)", dst, regd);
430
5.83k
      if (dst > 9 || dst < 0)
431
5.47k
        sprintf (comm, "%05x", dst);
432
5.83k
    }
433
3
        else
434
3
    return -1;
435
5.83k
      }
436
10.7k
  }
437
20.5k
      break;
438
439
38.5k
    case 3:     /* Jumps.  */
440
38.5k
      where = insn & 0x03ff;
441
38.5k
      if (where & 0x200)
442
19.7k
  where |= ~0x03ff;
443
38.5k
      if (where > 512 || where < -511)
444
1.86k
  return 0;
445
446
36.6k
      where *= 2;
447
36.6k
      sprintf (op, "$%+-8d", where + 2);
448
36.6k
      sprintf (comm, "abs 0x%lx", (long) (addr + 2 + where));
449
36.6k
      *cycles = 2;
450
36.6k
      return 2;
451
0
      break;
452
453
0
    default:
454
0
      cmd_len = 0;
455
63.5k
    }
456
457
24.8k
  return cmd_len;
458
63.5k
}
459
460
static int
461
msp430_doubleoperand (disassemble_info *info,
462
          struct msp430_opcode_s *opcode,
463
          bfd_vma addr,
464
          unsigned short insn,
465
          char *op1,
466
          char *op2,
467
          char *comm1,
468
          char *comm2,
469
          unsigned short extension_word,
470
          int *cycles)
471
186k
{
472
186k
  int regs = 0, regd = 0;
473
186k
  int ad = 0, as = 0;
474
186k
  int cmd_len = 2;
475
186k
  int dst = 0;
476
186k
  int fmt;
477
186k
  int extended_dst = extension_word & 0xf;
478
186k
  int extended_src = (extension_word >> 7) & 0xf;
479
480
186k
  regd = insn & 0x0f;
481
186k
  regs = (insn & 0x0f00) >> 8;
482
186k
  as = (insn & 0x0030) >> 4;
483
186k
  ad = (insn & 0x0080) >> 7;
484
485
186k
  if (opcode->fmt < 0)
486
0
    fmt = (- opcode->fmt) - 1;
487
186k
  else
488
186k
    fmt = opcode->fmt;
489
490
186k
  if (fmt == 0)
491
28.1k
    {
492
      /* Special case: rla and rlc are the only 2 emulated instructions that
493
   fall into two operand instructions.  */
494
      /* With dst, there are only:
495
   Rm         Register,
496
         x(Rm)      Indexed,
497
         0xXXXX     Relative,
498
         &0xXXXX      Absolute
499
         emulated_ins   dst
500
         basic_ins      dst, dst.  */
501
502
28.1k
      if (regd != regs || as != ad)
503
25.5k
  return 0;    /* May be 'data' section.  */
504
505
2.52k
      if (ad == 0)
506
624
  {
507
    /* Register mode.  */
508
624
    if (regd == 3)
509
3
      {
510
3
        strcpy (comm1, _("Warning: illegal as emulation instr"));
511
3
        return -1;
512
3
      }
513
514
621
    sprintf (op1, "r%d", regd);
515
621
    *cycles = 1;
516
621
  }
517
1.90k
      else      /* ad == 1 */
518
1.90k
  {
519
1.90k
    if (regd == 0)
520
689
      {
521
        /* PC relative, Symbolic.  */
522
689
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
523
685
    {
524
685
      cmd_len += 4;
525
685
      *cycles = 6;
526
685
      sprintf (op1, "0x%04x", PS (dst));
527
685
      sprintf (comm1, "PC rel. 0x%04x",
528
685
         PS ((short) addr + 2 + dst));
529
685
      if (extension_word)
530
182
        {
531
182
          dst |= extended_dst << 16;
532
182
          if (dst & 0x80000)
533
51
      dst |= -1U << 20;
534
182
          sprintf (op1, "0x%05x", dst & 0xfffff);
535
182
          sprintf (comm1, "PC rel. 0x%05lx",
536
182
             (long)((addr + 2 + dst) & 0xfffff));
537
182
        }
538
685
    }
539
4
        else
540
4
    return -1;
541
689
      }
542
1.21k
    else if (regd == 2)
543
537
      {
544
        /* Absolute.  */
545
537
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
546
536
    {
547
536
      int src;
548
549
      /* If the 'src' field is not the same as the dst
550
         then this is not an rla instruction.  */
551
536
      if (msp430dis_opcode_signed (addr + 4, info, &src, comm2))
552
535
        {
553
535
          if (src != dst)
554
137
      return 0;
555
535
        }
556
1
      else
557
1
        return -1;
558
398
      cmd_len += 4;
559
398
      *cycles = 6;
560
398
      sprintf (op1, "&0x%04x", PS (dst));
561
398
      if (extension_word)
562
51
        {
563
51
          dst |= extended_dst << 16;
564
51
          sprintf (op1, "&0x%05x", dst & 0xfffff);
565
51
        }
566
398
    }
567
1
        else
568
1
    return -1;
569
537
      }
570
677
    else
571
677
      {
572
        /* Indexed.  */
573
677
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
574
676
    {
575
676
      if (extension_word)
576
223
        {
577
223
          dst |= extended_dst << 16;
578
223
          if (dst & 0x80000)
579
70
      dst |= -1U << 20;
580
223
        }
581
676
      cmd_len += 4;
582
676
      *cycles = 6;
583
676
      sprintf (op1, "%d(r%d)", dst, regd);
584
676
      if (dst > 9 || dst < -9)
585
470
        sprintf (comm1, "#0x%05x", dst);
586
676
    }
587
1
        else
588
1
    return -1;
589
677
      }
590
1.90k
  }
591
592
2.38k
      *op2 = 0;
593
2.38k
      *comm2 = 0;
594
595
2.38k
      return cmd_len;
596
2.52k
    }
597
598
  /* Two operands exactly.  */
599
158k
  if (ad == 0 && regd == 3)
600
100
    {
601
      /* R2/R3 are illegal as dest: may be data section.  */
602
100
      strcpy (comm1, _("Warning: illegal as 2-op instr"));
603
100
      return -1;
604
100
    }
605
606
  /* Source.  */
607
158k
  if (as == 0)
608
55.6k
    {
609
55.6k
      *cycles = 1;
610
55.6k
      if (regs == 3)
611
1.65k
  {
612
    /* Constants.  */
613
1.65k
    sprintf (op1, "#0");
614
1.65k
    sprintf (comm1, "r3 As==00");
615
1.65k
  }
616
54.0k
      else
617
54.0k
  {
618
    /* Register.  */
619
54.0k
    sprintf (op1, "r%d", regs);
620
54.0k
  }
621
55.6k
    }
622
102k
  else if (as == 2)
623
29.2k
    {
624
29.2k
      * cycles = print_as2_reg_name (regs, op1, comm1, 1, 1, regs == 0 ? 3 : 2);
625
29.2k
    }
626
73.2k
  else if (as == 3)
627
40.5k
    {
628
40.5k
      if (regs == 0)
629
3.66k
  {
630
3.66k
    *cycles = 3;
631
    /* Absolute. @pc+.  */
632
3.66k
    if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
633
3.64k
      {
634
3.64k
        cmd_len += 2;
635
3.64k
        sprintf (op1, "#%d", dst);
636
3.64k
        if (dst > 9 || dst < 0)
637
3.25k
    sprintf (comm1, "#0x%04x", PS (dst));
638
3.64k
        if (extension_word)
639
856
    {
640
856
      dst &= 0xffff;
641
856
      dst |= extended_src << 16;
642
856
      if (dst & 0x80000)
643
239
        dst |= -1U << 20;
644
856
      sprintf (op1, "#%d", dst);
645
856
      if (dst > 9 || dst < 0)
646
685
        sprintf (comm1, "0x%05x", dst & 0xfffff);
647
856
    }
648
3.64k
      }
649
15
    else
650
15
      return -1;
651
3.66k
  }
652
36.9k
      else
653
36.9k
  * cycles = print_as3_reg_name (regs, op1, comm1, 1, 1, 2);
654
40.5k
    }
655
32.6k
  else if (as == 1)
656
32.6k
    {
657
32.6k
      if (regs == 0)
658
4.70k
  {
659
4.70k
    *cycles = 4;
660
    /* PC relative.  */
661
4.70k
    if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
662
4.69k
      {
663
4.69k
        cmd_len += 2;
664
4.69k
        sprintf (op1, "0x%04x", PS (dst));
665
4.69k
        sprintf (comm1, "PC rel. 0x%04x",
666
4.69k
           PS ((short) addr + 2 + dst));
667
4.69k
        if (extension_word)
668
677
    {
669
677
      dst &= 0xffff;
670
677
      dst |= extended_src << 16;
671
677
      if (dst & 0x80000)
672
141
        dst |= -1U << 20;
673
677
      sprintf (op1, "0x%05x", dst & 0xfffff);
674
677
      sprintf (comm1, "PC rel. 0x%05lx",
675
677
         (long) ((addr + 2 + dst) & 0xfffff));
676
677
    }
677
4.69k
      }
678
13
    else
679
13
      return -1;
680
4.70k
  }
681
27.9k
      else if (regs == 2)
682
7.99k
  {
683
7.99k
    *cycles = 2;
684
    /* Absolute.  */
685
7.99k
    if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
686
7.98k
      {
687
7.98k
        cmd_len += 2;
688
7.98k
        sprintf (op1, "&0x%04x", PS (dst));
689
7.98k
        sprintf (comm1, "0x%04x", PS (dst));
690
7.98k
        if (extension_word)
691
963
    {
692
963
      dst &= 0xffff;
693
963
      dst |= extended_src << 16;
694
963
      sprintf (op1, "&0x%05x", dst & 0xfffff);
695
963
      * comm1 = 0;
696
963
    }
697
7.98k
      }
698
15
    else
699
15
      return -1;
700
7.99k
  }
701
19.9k
      else if (regs == 3)
702
2.24k
  {
703
2.24k
    *cycles = 1;
704
2.24k
    sprintf (op1, "#1");
705
2.24k
    sprintf (comm1, "r3 As==01");
706
2.24k
  }
707
17.7k
      else
708
17.7k
  {
709
17.7k
    *cycles = 3;
710
    /* Indexed.  */
711
17.7k
    if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
712
17.7k
      {
713
17.7k
        cmd_len += 2;
714
17.7k
        if (extension_word)
715
1.43k
    {
716
1.43k
      dst &= 0xffff;
717
1.43k
      dst |= extended_src << 16;
718
1.43k
      if (dst & 0x80000)
719
580
        dst |= -1U << 20;
720
1.43k
    }
721
17.7k
        sprintf (op1, "%d(r%d)", dst, regs);
722
17.7k
        if (dst > 9 || dst < -9)
723
16.5k
    sprintf (comm1, "0x%05x", dst);
724
17.7k
      }
725
15
    else
726
15
      return -1;
727
17.7k
  }
728
32.6k
    }
729
730
  /* Destination. Special care needed on addr + XXXX.  */
731
732
158k
  if (ad == 0)
733
97.8k
    {
734
      /* Register.  */
735
97.8k
      if (regd == 0)
736
18.6k
  {
737
18.6k
    *cycles += 1;
738
18.6k
    sprintf (op2, "r0");
739
18.6k
  }
740
79.1k
      else if (regd == 1)
741
18.6k
  sprintf (op2, "r1");
742
743
60.4k
      else if (regd == 2)
744
10.9k
  sprintf (op2, "r2");
745
746
49.4k
      else
747
49.4k
  sprintf (op2, "r%d", regd);
748
97.8k
    }
749
60.3k
  else  /* ad == 1.  */
750
60.3k
    {
751
60.3k
      * cycles += 3;
752
753
60.3k
      if (regd == 0)
754
8.14k
  {
755
    /* PC relative.  */
756
8.14k
    *cycles += 1;
757
8.14k
    if (msp430dis_opcode_signed (addr + cmd_len, info, &dst, comm2))
758
8.14k
      {
759
8.14k
        sprintf (op2, "0x%04x", PS (dst));
760
8.14k
        sprintf (comm2, "PC rel. 0x%04x",
761
8.14k
           PS ((short) addr + cmd_len + dst));
762
8.14k
        if (extension_word)
763
1.62k
    {
764
1.62k
      dst |= extended_dst << 16;
765
1.62k
      if (dst & 0x80000)
766
1.53k
        dst |= -1U << 20;
767
1.62k
      sprintf (op2, "0x%05x", dst & 0xfffff);
768
1.62k
      sprintf (comm2, "PC rel. 0x%05lx",
769
1.62k
         (long)((addr + cmd_len + dst) & 0xfffff));
770
1.62k
    }
771
8.14k
      }
772
4
    else
773
4
      return -1;
774
8.14k
    cmd_len += 2;
775
8.14k
  }
776
52.2k
      else if (regd == 2)
777
3.78k
  {
778
    /* Absolute.  */
779
3.78k
    if (msp430dis_opcode_signed (addr + cmd_len, info, &dst, comm2))
780
3.77k
      {
781
3.77k
        cmd_len += 2;
782
3.77k
        sprintf (op2, "&0x%04x", PS (dst));
783
3.77k
        if (extension_word)
784
747
    {
785
747
      dst |= extended_dst << 16;
786
747
      sprintf (op2, "&0x%05x", dst & 0xfffff);
787
747
    }
788
3.77k
      }
789
4
    else
790
4
      return -1;
791
3.78k
  }
792
48.4k
      else
793
48.4k
  {
794
48.4k
    if (msp430dis_opcode_signed (addr + cmd_len, info, &dst, comm2))
795
48.3k
      {
796
48.3k
        cmd_len += 2;
797
48.3k
        if (dst > 9 || dst < 0)
798
46.4k
    sprintf (comm2, "0x%04x", PS (dst));
799
48.3k
        if (extension_word)
800
1.58k
    {
801
1.58k
      dst |= extended_dst << 16;
802
1.58k
      if (dst & 0x80000)
803
1.19k
        dst |= -1U << 20;
804
1.58k
      if (dst > 9 || dst < 0)
805
1.38k
        sprintf (comm2, "0x%05x", dst & 0xfffff);
806
1.58k
    }
807
48.3k
        sprintf (op2, "%d(r%d)", dst, regd);
808
48.3k
      }
809
57
    else
810
57
      return -1;
811
48.4k
  }
812
60.3k
    }
813
814
158k
  return cmd_len;
815
158k
}
816
817
static int
818
msp430_branchinstr (disassemble_info *info,
819
        struct msp430_opcode_s *opcode ATTRIBUTE_UNUSED,
820
        bfd_vma addr ATTRIBUTE_UNUSED,
821
        unsigned short insn,
822
        char *op1,
823
        char *comm1,
824
        int *cycles)
825
6.31k
{
826
6.31k
  int regs = 0, regd = 0;
827
6.31k
  int as = 0;
828
6.31k
  int cmd_len = 2;
829
6.31k
  int dst = 0;
830
6.31k
  unsigned short udst = 0;
831
832
6.31k
  regd = insn & 0x0f;
833
6.31k
  regs = (insn & 0x0f00) >> 8;
834
6.31k
  as = (insn & 0x0030) >> 4;
835
836
6.31k
  if (regd != 0)  /* Destination register is not a PC.  */
837
0
    return 0;
838
839
  /* dst is a source register.  */
840
6.31k
  if (as == 0)
841
3.38k
    {
842
      /* Constants.  */
843
3.38k
      if (regs == 3)
844
0
  {
845
0
    *cycles = 1;
846
0
    sprintf (op1, "#0");
847
0
    sprintf (comm1, "r3 As==00");
848
0
  }
849
3.38k
      else
850
3.38k
  {
851
    /* Register.  */
852
3.38k
    *cycles = 1;
853
3.38k
    sprintf (op1, "r%d", regs);
854
3.38k
  }
855
3.38k
    }
856
2.93k
  else if (as == 2)
857
635
    {
858
635
      * cycles = print_as2_reg_name (regs, op1, comm1, 2, 1, 2);
859
635
    }
860
2.29k
  else if (as == 3)
861
955
    {
862
955
      if (regs == 0)
863
86
  {
864
    /* Absolute. @pc+  */
865
86
    *cycles = 3;
866
86
    if (msp430dis_opcode_unsigned (addr + 2, info, &udst, comm1))
867
86
      {
868
86
        cmd_len += 2;
869
86
        sprintf (op1, "#0x%04x", PS (udst));
870
86
      }
871
0
    else
872
0
      return -1;
873
86
  }
874
869
      else
875
869
  * cycles = print_as3_reg_name (regs, op1, comm1, 1, 1, 2);
876
955
    }
877
1.34k
  else if (as == 1)
878
1.34k
    {
879
1.34k
      * cycles = 3;
880
881
1.34k
      if (regs == 0)
882
218
  {
883
    /* PC relative.  */
884
218
    if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
885
216
      {
886
216
        cmd_len += 2;
887
216
        (*cycles)++;
888
216
        sprintf (op1, "0x%04x", PS (dst));
889
216
        sprintf (comm1, "PC rel. 0x%04x",
890
216
           PS ((short) addr + 2 + dst));
891
216
      }
892
2
    else
893
2
      return -1;
894
218
  }
895
1.12k
      else if (regs == 2)
896
508
  {
897
    /* Absolute.  */
898
508
    if (msp430dis_opcode_unsigned (addr + 2, info, &udst, comm1))
899
497
      {
900
497
        cmd_len += 2;
901
497
        sprintf (op1, "&0x%04x", PS (udst));
902
497
      }
903
11
    else
904
11
      return -1;
905
508
  }
906
616
      else if (regs == 3)
907
78
  {
908
78
    (*cycles)--;
909
78
    sprintf (op1, "#1");
910
78
    sprintf (comm1, "r3 As==01");
911
78
  }
912
538
      else
913
538
  {
914
    /* Indexed.  */
915
538
    if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
916
535
      {
917
535
        cmd_len += 2;
918
535
        sprintf (op1, "%d(r%d)", dst, regs);
919
535
      }
920
3
    else
921
3
      return -1;
922
538
  }
923
1.34k
    }
924
925
6.29k
  return cmd_len;
926
6.31k
}
927
928
static int
929
msp430x_calla_instr (disassemble_info * info,
930
         bfd_vma            addr,
931
         unsigned short     insn,
932
         char *             op1,
933
         char *             comm1,
934
         int *              cycles)
935
1.75k
{
936
1.75k
  unsigned int   ureg = insn & 0xf;
937
1.75k
  int            reg = insn & 0xf;
938
1.75k
  int            am = (insn & 0xf0) >> 4;
939
1.75k
  int            cmd_len = 2;
940
1.75k
  unsigned short udst = 0;
941
1.75k
  int            dst = 0;
942
943
1.75k
  switch (am)
944
1.75k
    {
945
278
    case 4: /* CALLA Rdst */
946
278
      *cycles = 1;
947
278
      sprintf (op1, "r%d", reg);
948
278
      break;
949
950
376
    case 5: /* CALLA x(Rdst) */
951
376
      *cycles = 3;
952
376
      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
953
375
  {
954
375
    cmd_len += 2;
955
375
    sprintf (op1, "%d(r%d)", dst, reg);
956
375
    if (reg == 0)
957
156
      sprintf (comm1, "PC rel. 0x%05lx", (long) (addr + 2 + dst));
958
219
    else
959
219
      sprintf (comm1, "0x%05x", dst);
960
375
  }
961
1
      else
962
1
  return -1;
963
375
      break;
964
965
375
    case 6: /* CALLA @Rdst */
966
128
      *cycles = 2;
967
128
      sprintf (op1, "@r%d", reg);
968
128
      break;
969
970
84
    case 7: /* CALLA @Rdst+ */
971
84
      *cycles = 2;
972
84
      sprintf (op1, "@r%d+", reg);
973
84
      break;
974
975
338
    case 8: /* CALLA &abs20 */
976
338
      if (msp430dis_opcode_unsigned (addr + 2, info, &udst, comm1))
977
335
  {
978
335
    cmd_len += 2;
979
335
    *cycles = 4;
980
335
    sprintf (op1, "&%d", (ureg << 16) + udst);
981
335
    sprintf (comm1, "0x%05x", (ureg << 16) + udst);
982
335
  }
983
3
      else
984
3
  return -1;
985
335
      break;
986
987
496
    case 9: /* CALLA pcrel-sym */
988
496
      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
989
495
  {
990
495
    cmd_len += 2;
991
495
    *cycles = 4;
992
495
    sprintf (op1, "%d(PC)", (reg << 16) + dst);
993
495
    sprintf (comm1, "PC rel. 0x%05lx",
994
495
       (long) (addr + 2 + dst + (reg << 16)));
995
495
  }
996
1
      else
997
1
  return -1;
998
495
      break;
999
1000
495
    case 11: /* CALLA #imm20 */
1001
49
      if (msp430dis_opcode_unsigned (addr + 2, info, &udst, comm1))
1002
48
  {
1003
48
    cmd_len += 2;
1004
48
    *cycles = 4;
1005
48
    sprintf (op1, "#%d", (ureg << 16) + udst);
1006
48
    sprintf (comm1, "0x%05x", (ureg << 16) + udst);
1007
48
  }
1008
1
      else
1009
1
  return -1;
1010
48
      break;
1011
1012
48
    default:
1013
10
      strcpy (comm1, _("Warning: unrecognised CALLA addressing mode"));
1014
10
      return -1;
1015
1.75k
    }
1016
1017
1.74k
  return cmd_len;
1018
1.75k
}
1019
1020
int
1021
print_insn_msp430 (bfd_vma addr, disassemble_info *info)
1022
382k
{
1023
382k
  void *stream = info->stream;
1024
382k
  fprintf_ftype prin = info->fprintf_func;
1025
382k
  struct msp430_opcode_s *opcode;
1026
382k
  char op1[32], op2[32], comm1[64], comm2[64];
1027
382k
  int cmd_len = 0;
1028
382k
  unsigned short insn;
1029
382k
  int cycles = 0;
1030
382k
  char *bc = "";
1031
382k
  unsigned short extension_word = 0;
1032
382k
  unsigned short bits;
1033
1034
382k
  if (! msp430dis_opcode_unsigned (addr, info, &insn, NULL))
1035
218
    return -1;
1036
1037
381k
  if (((int) addr & 0xffff) > 0xffdf)
1038
1
    {
1039
1
      (*prin) (stream, "interrupt service routine at 0x%04x", 0xffff & insn);
1040
1
      return 2;
1041
1
    }
1042
1043
381k
  *comm1 = 0;
1044
381k
  *comm2 = 0;
1045
1046
  /* Check for an extension word.  */
1047
381k
  if ((insn & 0xf800) == 0x1800)
1048
24.6k
    {
1049
24.6k
      extension_word = insn;
1050
24.6k
      addr += 2;
1051
24.6k
      if (! msp430dis_opcode_unsigned (addr, info, &insn, NULL))
1052
33
  return -1;
1053
24.6k
   }
1054
1055
19.3M
  for (opcode = msp430_opcodes; opcode->name; opcode++)
1056
19.3M
    {
1057
19.3M
      if ((insn & opcode->bin_mask) == opcode->bin_opcode
1058
435k
    && opcode->bin_opcode != 0x9300)
1059
434k
  {
1060
434k
    *op1 = 0;
1061
434k
    *op2 = 0;
1062
434k
    *comm1 = 0;
1063
434k
    *comm2 = 0;
1064
1065
    /* r0 as destination. Ad should be zero.  */
1066
434k
    if (opcode->insn_opnumb == 3
1067
29.8k
        && (insn & 0x000f) == 0
1068
7.79k
        && (insn & 0x0080) == 0)
1069
6.31k
      {
1070
6.31k
        int ret =
1071
6.31k
    msp430_branchinstr (info, opcode, addr, insn, op1, comm1,
1072
6.31k
            &cycles);
1073
1074
6.31k
        if (ret == -1)
1075
16
    return -1;
1076
6.29k
        cmd_len += ret;
1077
6.29k
        if (cmd_len)
1078
6.29k
    break;
1079
6.29k
      }
1080
1081
428k
    switch (opcode->insn_opnumb)
1082
428k
      {
1083
0
        int n;
1084
0
        int reg;
1085
0
        int ret;
1086
1087
1.75k
      case 4:
1088
1.75k
        ret = msp430x_calla_instr (info, addr, insn,
1089
1.75k
           op1, comm1, & cycles);
1090
1.75k
        if (ret == -1)
1091
16
    return -1;
1092
1.74k
        cmd_len += ret;
1093
1.74k
        break;
1094
1095
5.83k
      case 5: /* PUSHM/POPM */
1096
5.83k
        n = (insn & 0xf0) >> 4;
1097
5.83k
        reg = (insn & 0xf);
1098
1099
5.83k
        sprintf (op1, "#%d", n + 1);
1100
5.83k
        if (opcode->bin_opcode == 0x1400)
1101
    /* PUSHM */
1102
4.69k
    sprintf (op2, "r%d", reg);
1103
1.13k
        else
1104
    /* POPM */
1105
1.13k
    sprintf (op2, "r%d", reg + n);
1106
5.83k
        if (insn & 0x100)
1107
1.74k
    sprintf (comm1, "16-bit words");
1108
4.09k
        else
1109
4.09k
    {
1110
4.09k
      sprintf (comm1, "20-bit words");
1111
4.09k
      bc =".a";
1112
4.09k
    }
1113
1114
5.83k
        cycles = 2; /*FIXME*/
1115
5.83k
        cmd_len = 2;
1116
5.83k
        break;
1117
1118
6.37k
      case 6: /* RRAM, RRCM, RRUM, RLAM.  */
1119
6.37k
        n = ((insn >> 10) & 0x3) + 1;
1120
6.37k
        reg = (insn & 0xf);
1121
6.37k
        if ((insn & 0x10) == 0)
1122
4.77k
    bc =".a";
1123
6.37k
        sprintf (op1, "#%d", n);
1124
6.37k
        sprintf (op2, "r%d", reg);
1125
6.37k
        cycles = 2; /*FIXME*/
1126
6.37k
        cmd_len = 2;
1127
6.37k
        break;
1128
1129
11.1k
      case 8: /* ADDA, CMPA, SUBA.  */
1130
11.1k
        reg = (insn & 0xf);
1131
11.1k
        n = (insn >> 8) & 0xf;
1132
11.1k
        if (insn & 0x40)
1133
7.75k
    {
1134
7.75k
      sprintf (op1, "r%d", n);
1135
7.75k
      cmd_len = 2;
1136
7.75k
    }
1137
3.36k
        else
1138
3.36k
    {
1139
3.36k
      n <<= 16;
1140
3.36k
      if (msp430dis_opcode_unsigned (addr + 2, info, &bits, comm1))
1141
3.35k
        {
1142
3.35k
          n |= bits;
1143
3.35k
          sprintf (op1, "#%d", n);
1144
3.35k
          if (n > 9 || n < 0)
1145
2.80k
      sprintf (comm1, "0x%05x", n);
1146
3.35k
        }
1147
7
      else
1148
7
        return -1;
1149
3.35k
      cmd_len = 4;
1150
3.35k
    }
1151
11.1k
        sprintf (op2, "r%d", reg);
1152
11.1k
        cycles = 2; /*FIXME*/
1153
11.1k
        break;
1154
1155
53.1k
      case 9: /* MOVA */
1156
53.1k
        reg = (insn & 0xf);
1157
53.1k
        n = (insn >> 8) & 0xf;
1158
53.1k
        switch ((insn >> 4) & 0xf)
1159
53.1k
    {
1160
24.3k
    case 0: /* MOVA @Rsrc, Rdst */
1161
24.3k
      cmd_len = 2;
1162
24.3k
      sprintf (op1, "@r%d", n);
1163
24.3k
      if (strcmp (opcode->name, "bra") != 0)
1164
18.7k
        sprintf (op2, "r%d", reg);
1165
24.3k
      break;
1166
1167
10.5k
    case 1: /* MOVA @Rsrc+, Rdst */
1168
10.5k
      cmd_len = 2;
1169
10.5k
      if (strcmp (opcode->name, "reta") != 0)
1170
9.58k
        {
1171
9.58k
          sprintf (op1, "@r%d+", n);
1172
9.58k
          if (strcmp (opcode->name, "bra") != 0)
1173
8.12k
      sprintf (op2, "r%d", reg);
1174
9.58k
        }
1175
10.5k
      break;
1176
1177
3.98k
    case 2: /* MOVA &abs20, Rdst */
1178
3.98k
      cmd_len = 4;
1179
3.98k
      n <<= 16;
1180
3.98k
      if (msp430dis_opcode_unsigned (addr + 2, info, &bits, comm1))
1181
3.97k
        {
1182
3.97k
          n |= bits;
1183
3.97k
          sprintf (op1, "&%d", n);
1184
3.97k
          if (n > 9 || n < 0)
1185
3.08k
      sprintf (comm1, "0x%05x", n);
1186
3.97k
          if (strcmp (opcode->name, "bra") != 0)
1187
3.09k
      sprintf (op2, "r%d", reg);
1188
3.97k
        }
1189
7
      else
1190
7
        return -1;
1191
3.97k
      break;
1192
1193
3.97k
    case 3: /* MOVA x(Rsrc), Rdst */
1194
3.34k
      cmd_len = 4;
1195
3.34k
      if (strcmp (opcode->name, "bra") != 0)
1196
2.85k
        sprintf (op2, "r%d", reg);
1197
3.34k
      reg = n;
1198
3.34k
      if (msp430dis_opcode_signed (addr + 2, info, &n, comm1))
1199
3.33k
        {
1200
3.33k
          sprintf (op1, "%d(r%d)", n, reg);
1201
3.33k
          if (n > 9 || n < 0)
1202
2.54k
      {
1203
2.54k
        if (reg == 0)
1204
1.76k
          sprintf (comm1, "PC rel. 0x%05lx",
1205
1.76k
             (long) (addr + 2 + n));
1206
775
        else
1207
775
          sprintf (comm1, "0x%05x", n);
1208
2.54k
      }
1209
3.33k
        }
1210
9
      else
1211
9
        return -1;
1212
3.33k
      break;
1213
1214
4.09k
    case 6: /* MOVA Rsrc, &abs20 */
1215
4.09k
      cmd_len = 4;
1216
4.09k
      reg <<= 16;
1217
4.09k
      if (msp430dis_opcode_unsigned (addr + 2, info, &bits, comm2))
1218
4.09k
        {
1219
4.09k
          reg |= bits;
1220
4.09k
          sprintf (op1, "r%d", n);
1221
4.09k
          sprintf (op2, "&%d", reg);
1222
4.09k
          if (reg > 9 || reg < 0)
1223
3.87k
      sprintf (comm2, "0x%05x", reg);
1224
4.09k
        }
1225
6
      else
1226
6
        return -1;
1227
4.09k
      break;
1228
1229
4.09k
    case 7: /* MOVA Rsrc, x(Rdst) */
1230
3.06k
      cmd_len = 4;
1231
3.06k
      sprintf (op1, "r%d", n);
1232
3.06k
      if (msp430dis_opcode_signed (addr + 2, info, &n, comm2))
1233
3.06k
        {
1234
3.06k
          sprintf (op2, "%d(r%d)", n, reg);
1235
3.06k
          if (n > 9 || n < 0)
1236
1.71k
      {
1237
1.71k
        if (reg == 0)
1238
368
          sprintf (comm2, "PC rel. 0x%05lx",
1239
368
             (long) (addr + 2 + n));
1240
1.34k
        else
1241
1.34k
          sprintf (comm2, "0x%05x", n);
1242
1.71k
      }
1243
3.06k
        }
1244
7
      else
1245
7
        return -1;
1246
3.06k
      break;
1247
1248
3.06k
    case 8: /* MOVA #imm20, Rdst */
1249
1.71k
      cmd_len = 4;
1250
1.71k
      n <<= 16;
1251
1.71k
      if (msp430dis_opcode_unsigned (addr + 2, info, &bits, comm1))
1252
1.70k
        {
1253
1.70k
          n |= bits;
1254
1.70k
          if (n & 0x80000)
1255
358
      n |= -1U << 20;
1256
1.70k
          sprintf (op1, "#%d", n);
1257
1.70k
          if (n > 9 || n < 0)
1258
1.06k
      sprintf (comm1, "0x%05x", n);
1259
1.70k
          if (strcmp (opcode->name, "bra") != 0)
1260
1.70k
      sprintf (op2, "r%d", reg);
1261
1.70k
        }
1262
3
      else
1263
3
        return -1;
1264
1.70k
      break;
1265
1266
2.03k
    case 12: /* MOVA Rsrc, Rdst */
1267
2.03k
      cmd_len = 2;
1268
2.03k
      sprintf (op1, "r%d", n);
1269
2.03k
      if (strcmp (opcode->name, "bra") != 0)
1270
2.03k
        sprintf (op2, "r%d", reg);
1271
2.03k
      break;
1272
1273
0
    default:
1274
0
      break;
1275
53.1k
    }
1276
53.0k
        cycles = 2; /* FIXME */
1277
53.0k
        break;
1278
428k
      }
1279
1280
428k
    if (cmd_len)
1281
78.1k
      break;
1282
1283
350k
    switch (opcode->insn_opnumb)
1284
350k
      {
1285
0
        int ret;
1286
1287
68.1k
      case 0:
1288
68.1k
        cmd_len += msp430_nooperands (opcode, addr, insn, comm1, &cycles);
1289
68.1k
        break;
1290
186k
      case 2:
1291
186k
        ret =
1292
186k
    msp430_doubleoperand (info, opcode, addr, insn, op1, op2,
1293
186k
              comm1, comm2,
1294
186k
              extension_word,
1295
186k
              &cycles);
1296
1297
186k
        if (ret == -1)
1298
233
    return -1;
1299
186k
        cmd_len += ret;
1300
186k
        if (insn & BYTE_OPERATION)
1301
106k
    {
1302
106k
      if (extension_word != 0 && ((extension_word & BYTE_OPERATION) == 0))
1303
3.69k
        bc = ".a";
1304
103k
      else
1305
103k
        bc = ".b";
1306
106k
    }
1307
79.3k
        else if (extension_word)
1308
4.28k
    {
1309
4.28k
      if (extension_word & BYTE_OPERATION)
1310
1.61k
        bc = ".w";
1311
2.66k
      else
1312
2.66k
        {
1313
2.66k
          bc = ".?";
1314
2.66k
          sprintf (comm2, _("Warning: reserved use of A/L and B/W bits detected"));
1315
2.66k
        }
1316
4.28k
    }
1317
1318
186k
        break;
1319
63.5k
      case 1:
1320
63.5k
        ret =
1321
63.5k
    msp430_singleoperand (info, opcode, addr, insn, op1, comm1,
1322
63.5k
              extension_word,
1323
63.5k
              &cycles);
1324
1325
63.5k
        if (ret == -1)
1326
23
    return -1;
1327
63.5k
        cmd_len += ret;
1328
63.5k
        if (extension_word
1329
5.30k
      && (strcmp (opcode->name, "swpb") == 0
1330
5.06k
          || strcmp (opcode->name, "sxt") == 0))
1331
826
    {
1332
826
      if (insn & BYTE_OPERATION)
1333
0
        {
1334
0
          bc = ".?";
1335
0
          sprintf (comm2, _("Warning: reserved use of A/L and B/W bits detected"));
1336
0
        }
1337
826
      else if (extension_word & BYTE_OPERATION)
1338
717
        bc = ".w";
1339
109
      else
1340
109
        bc = ".a";
1341
826
    }
1342
62.7k
        else if (insn & BYTE_OPERATION && opcode->fmt != 3)
1343
6.74k
    {
1344
6.74k
      if (extension_word != 0 && ((extension_word & BYTE_OPERATION) == 0))
1345
1.05k
        bc = ".a";
1346
5.69k
      else
1347
5.69k
        bc = ".b";
1348
6.74k
    }
1349
55.9k
        else if (extension_word)
1350
2.30k
    {
1351
2.30k
      if (extension_word & (1 << 6))
1352
672
        bc = ".w";
1353
1.63k
      else
1354
1.63k
        {
1355
1.63k
          bc = ".?";
1356
1.63k
          sprintf (comm2, _("Warning: reserved use of A/L and B/W bits detected"));
1357
1.63k
        }
1358
2.30k
    }
1359
63.5k
        break;
1360
32.0k
      default:
1361
32.0k
        break;
1362
350k
      }
1363
350k
  }
1364
1365
19.2M
      if (cmd_len)
1366
288k
  break;
1367
19.2M
    }
1368
1369
381k
  if (cmd_len < 1)
1370
8.53k
    {
1371
      /* Unknown opcode, or invalid combination of operands.  */
1372
8.53k
      if (extension_word)
1373
5.89k
  {
1374
5.89k
    prin (stream, ".word  0x%04x, 0x%04x; ????", extension_word, PS (insn));
1375
5.89k
    if (*comm1)
1376
0
      prin (stream, "\t %s", comm1);
1377
5.89k
    return 4;
1378
5.89k
  }
1379
2.63k
      (*prin) (stream, ".word 0x%04x; ????", PS (insn));
1380
2.63k
      return 2;
1381
8.53k
    }
1382
1383
  /* Display the repeat count (if set) for extended register mode.  */
1384
373k
  if (cmd_len == 2 && ((extension_word & 0xf) != 0))
1385
4.93k
    {
1386
4.93k
      if (extension_word & (1 << 7))
1387
1.40k
  prin (stream, "rpt r%d { ", extension_word & 0xf);
1388
3.52k
      else
1389
3.52k
  prin (stream, "rpt #%d { ", (extension_word & 0xf) + 1);
1390
4.93k
    }
1391
1392
  /* Special case:  RRC with an extension word and the ZC bit set is actually RRU.  */
1393
373k
  if (extension_word
1394
18.6k
      && (extension_word & IGNORE_CARRY_BIT)
1395
9.01k
      && strcmp (opcode->name, "rrc") == 0)
1396
312
    (*prin) (stream, "rrux%s", bc);
1397
372k
  else if (extension_word && opcode->name[strlen (opcode->name) - 1] != 'x')
1398
18.3k
    (*prin) (stream, "%sx%s", opcode->name, bc);
1399
354k
  else
1400
354k
    (*prin) (stream, "%s%s", opcode->name, bc);
1401
1402
373k
  if (*op1)
1403
305k
    (*prin) (stream, "\t%s", op1);
1404
373k
  if (*op2)
1405
225k
    (*prin) (stream, ",");
1406
1407
373k
  if (strlen (op1) < 7)
1408
292k
    (*prin) (stream, "\t");
1409
373k
  if (!strlen (op1))
1410
67.4k
    (*prin) (stream, "\t");
1411
1412
373k
  if (*op2)
1413
225k
    (*prin) (stream, "%s", op2);
1414
373k
  if (strlen (op2) < 8)
1415
335k
    (*prin) (stream, "\t");
1416
1417
373k
  if (*comm1 || *comm2)
1418
162k
    (*prin) (stream, ";");
1419
210k
  else if (cycles)
1420
145k
    {
1421
145k
      if (*op2)
1422
118k
  (*prin) (stream, ";");
1423
26.6k
      else
1424
26.6k
  {
1425
26.6k
    if (strlen (op1) < 7)
1426
22.7k
      (*prin) (stream, ";");
1427
3.92k
    else
1428
3.92k
      (*prin) (stream, "\t;");
1429
26.6k
  }
1430
145k
    }
1431
373k
  if (*comm1)
1432
115k
    (*prin) (stream, "%s", comm1);
1433
373k
  if (*comm1 && *comm2)
1434
16.8k
    (*prin) (stream, ",");
1435
373k
  if (*comm2)
1436
63.9k
    (*prin) (stream, " %s", comm2);
1437
1438
373k
  if (extension_word)
1439
18.6k
    cmd_len += 2;
1440
1441
373k
  return cmd_len;
1442
381k
}