Coverage Report

Created: 2026-07-12 09:22

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
109k
#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
491k
{
46
491k
  int status;
47
48
491k
  status = info->read_memory_func (addr, buffer, 2, info);
49
491k
  if (status == 0)
50
491k
    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
347
  if (status == EIO)
57
347
    {
58
347
      if (comm)
59
161
  sprintf (comm, _("Warning: disassembly unreliable - not enough bytes available"));
60
347
    }
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
347
  return false;
69
491k
}
70
71
static bool
72
msp430dis_opcode_unsigned (bfd_vma            addr,
73
         disassemble_info * info,
74
         unsigned short *   return_val,
75
         char *             comm)
76
375k
{
77
375k
  bfd_byte buffer[2];
78
79
375k
  if (msp430dis_read_two_bytes (addr, info, buffer, comm))
80
375k
    {
81
375k
      * return_val = bfd_getl16 (buffer);
82
375k
      return true;
83
375k
    }
84
221
  else
85
221
    {
86
221
      * return_val = 0;
87
221
      return false;
88
221
    }
89
375k
}
90
91
static bool
92
msp430dis_opcode_signed (bfd_vma            addr,
93
       disassemble_info * info,
94
       signed int *       return_val,
95
       char *             comm)
96
115k
{
97
115k
  bfd_byte buffer[2];
98
99
115k
  if (msp430dis_read_two_bytes (addr, info, buffer, comm))
100
115k
    {
101
115k
      int status;
102
103
115k
      status = bfd_getl_signed_16 (buffer);
104
115k
      if (status & 0x8000)
105
53.8k
  status |= -1U << 16;
106
115k
      * return_val = status;
107
115k
      return true;
108
115k
    }
109
126
  else
110
126
    {
111
126
      * return_val = 0;
112
126
      return false;
113
126
    }
114
115k
}
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
61.1k
{
123
  /* Pop with constant.  */
124
61.1k
  if (insn == 0x43b2)
125
0
    return 0;
126
61.1k
  if (insn == opcode->bin_opcode)
127
59.0k
    return 2;
128
129
2.13k
  if (opcode->fmt == 0)
130
1.55k
    {
131
1.55k
      if ((insn & 0x0f00) != 0x0300 || (insn & 0x0f00) != 0x0200)
132
1.55k
  return 0;
133
134
0
      strcpy (comm, "emulated...");
135
0
      *cycles = 1;
136
0
    }
137
585
  else
138
585
    {
139
585
      strcpy (comm, "return from interupt");
140
585
      *cycles = 5;
141
585
    }
142
143
585
  return 2;
144
2.13k
}
145
146
static int
147
print_as2_reg_name (int regno, char * op1, char * comm1,
148
        int c2, int c3, int cd)
149
30.3k
{
150
30.3k
  switch (regno)
151
30.3k
    {
152
3.52k
    case 2:
153
3.52k
      sprintf (op1, "#4");
154
3.52k
      sprintf (comm1, "r2 As==10");
155
3.52k
      return c2;
156
157
2.78k
    case 3:
158
2.78k
      sprintf (op1, "#2");
159
2.78k
      sprintf (comm1, "r3 As==10");
160
2.78k
      return c3;
161
162
24.0k
    default:
163
      /* Indexed register mode @Rn.  */
164
24.0k
      sprintf (op1, "@r%d", regno);
165
24.0k
      return cd;
166
30.3k
    }
167
30.3k
}
168
169
static int
170
print_as3_reg_name (int regno, char * op1, char * comm1,
171
        int c2, int c3, int cd)
172
43.7k
{
173
43.7k
  switch (regno)
174
43.7k
    {
175
2.98k
    case 2:
176
2.98k
      sprintf (op1, "#8");
177
2.98k
      sprintf (comm1, "r2 As==11");
178
2.98k
      return c2;
179
180
4.01k
    case 3:
181
4.01k
      sprintf (op1, "#-1");
182
4.01k
      sprintf (comm1, "r3 As==11");
183
4.01k
      return c3;
184
185
36.7k
    default:
186
      /* Post incremented @Rn+.  */
187
36.7k
      sprintf (op1, "@r%d+", regno);
188
36.7k
      return cd;
189
43.7k
    }
190
43.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
57.7k
{
202
57.7k
  int regs = 0, regd = 0;
203
57.7k
  int ad = 0, as = 0;
204
57.7k
  int where = 0;
205
57.7k
  int cmd_len = 2;
206
57.7k
  int dst = 0;
207
57.7k
  int fmt;
208
57.7k
  int extended_dst = extension_word & 0xf;
209
210
57.7k
  regd = insn & 0x0f;
211
57.7k
  regs = (insn & 0x0f00) >> 8;
212
57.7k
  as = (insn & 0x0030) >> 4;
213
57.7k
  ad = (insn & 0x0080) >> 7;
214
215
57.7k
  if (opcode->fmt < 0)
216
0
    fmt = (- opcode->fmt) - 1;
217
57.7k
  else
218
57.7k
    fmt = opcode->fmt;
219
220
57.7k
  switch (fmt)
221
57.7k
    {
222
3.76k
    case 0:     /* Emulated work with dst register.  */
223
3.76k
      if (regs != 2 && regs != 3 && regs != 1)
224
0
  return 0;
225
226
      /* Check if not clr insn.  */
227
3.76k
      if (opcode->bin_opcode == 0x4300 && (ad || as))
228
102
  return 0;
229
230
      /* Check if really inc, incd insns.  */
231
3.66k
      if ((opcode->bin_opcode & 0xff00) == 0x5300 && as == 3)
232
0
  return 0;
233
234
3.66k
      if (ad == 0)
235
1.37k
  {
236
1.37k
    *cycles = 1;
237
238
    /* Register.  */
239
1.37k
    if (regd == 0)
240
290
      {
241
290
        *cycles += 1;
242
290
        sprintf (op, "r0");
243
290
      }
244
1.08k
    else if (regd == 1)
245
132
      sprintf (op, "r1");
246
247
948
    else if (regd == 2)
248
138
      sprintf (op, "r2");
249
250
810
    else
251
810
      sprintf (op, "r%d", regd);
252
1.37k
  }
253
2.29k
      else  /* ad == 1 msp430dis_opcode.  */
254
2.29k
  {
255
2.29k
    if (regd == 0)
256
655
      {
257
        /* PC relative.  */
258
655
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
259
654
    {
260
654
      cmd_len += 2;
261
654
      *cycles = 4;
262
654
      if (extended_dst)
263
184
        {
264
184
          dst |= extended_dst << 16;
265
184
          sprintf (op, "0x%05x", dst);
266
184
          sprintf (comm, "PC rel. abs addr 0x%05lx",
267
184
             (long)((addr + 2 + dst) & 0xfffff));
268
184
        }
269
470
      else
270
470
        {
271
470
          sprintf (op, "0x%04x", dst);
272
470
          sprintf (comm, "PC rel. abs addr 0x%04x",
273
470
             PS ((short) (addr + 2) + dst));
274
470
        }
275
654
    }
276
1
        else
277
1
    return -1;
278
655
      }
279
1.64k
    else if (regd == 2)
280
274
      {
281
        /* Absolute.  */
282
274
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
283
272
    {
284
272
      cmd_len += 2;
285
272
      *cycles = 4;
286
272
      if (extended_dst)
287
173
        {
288
173
          dst |= extended_dst << 16;
289
173
          sprintf (op, "&0x%05x", dst & 0xfffff);
290
173
        }
291
99
      else
292
99
        sprintf (op, "&0x%04x", PS (dst));
293
272
    }
294
2
        else
295
2
    return -1;
296
274
      }
297
1.36k
    else
298
1.36k
      {
299
1.36k
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
300
1.36k
    {
301
1.36k
      cmd_len += 2;
302
1.36k
      *cycles = 4;
303
1.36k
      if (extended_dst)
304
550
        {
305
550
          dst |= extended_dst << 16;
306
550
          if (dst & 0x80000)
307
297
      dst |= -1U << 20;
308
550
        }
309
1.36k
      sprintf (op, "%d(r%d)", dst, regd);
310
1.36k
    }
311
1
        else
312
1
    return -1;
313
1.36k
      }
314
2.29k
  }
315
3.66k
      break;
316
317
17.8k
    case 2: /* rrc, push, call, swpb, rra, sxt, push, call, reti etc...  */
318
17.8k
      if (as == 0)
319
2.89k
  {
320
2.89k
    if (regd == 3)
321
331
      {
322
        /* Constsnts.  */
323
331
        sprintf (op, "#0");
324
331
        sprintf (comm, "r3 As==00");
325
331
      }
326
2.56k
    else
327
2.56k
      {
328
        /* Register.  */
329
2.56k
        sprintf (op, "r%d", regd);
330
2.56k
      }
331
2.89k
    *cycles = 1;
332
2.89k
  }
333
14.9k
      else if (as == 2)
334
1.84k
  {
335
1.84k
    * cycles = print_as2_reg_name (regd, op, comm, 1, 1, 3);
336
1.84k
  }
337
13.1k
      else if (as == 3)
338
4.07k
  {
339
4.07k
    if (regd == 0)
340
1.79k
      {
341
1.79k
        *cycles = 3;
342
        /* absolute. @pc+ */
343
1.79k
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
344
1.79k
    {
345
1.79k
      cmd_len += 2;
346
1.79k
      if (extended_dst)
347
760
        {
348
760
          dst |= extended_dst << 16;
349
760
          if (dst & 0x80000)
350
211
      dst |= -1U << 20;
351
760
          sprintf (op, "#%d", dst);
352
760
          if (dst > 9 || dst < 0)
353
760
      sprintf (comm, "#0x%05x", dst);
354
760
        }
355
1.03k
      else
356
1.03k
        {
357
1.03k
          sprintf (op, "#%d", dst);
358
1.03k
          if (dst > 9 || dst < 0)
359
915
      sprintf (comm, "#0x%04x", PS (dst));
360
1.03k
        }
361
1.79k
    }
362
1
        else
363
1
    return -1;
364
1.79k
      }
365
2.27k
    else
366
2.27k
      * cycles = print_as3_reg_name (regd, op, comm, 1, 1, 3);
367
4.07k
  }
368
9.07k
      else if (as == 1)
369
9.07k
  {
370
9.07k
    *cycles = 4;
371
9.07k
    if (regd == 0)
372
1.90k
      {
373
        /* PC relative.  */
374
1.90k
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
375
1.90k
    {
376
1.90k
      cmd_len += 2;
377
1.90k
      if (extended_dst)
378
131
        {
379
131
          dst |= extended_dst << 16;
380
131
          sprintf (op, "0x%05x", dst & 0xffff);
381
131
          sprintf (comm, "PC rel. 0x%05lx",
382
131
             (long)((addr + 2 + dst) & 0xfffff));
383
131
        }
384
1.76k
      else
385
1.76k
        {
386
1.76k
          sprintf (op, "0x%04x", PS (dst));
387
1.76k
          sprintf (comm, "PC rel. 0x%04x",
388
1.76k
             PS ((short) addr + 2 + dst));
389
1.76k
        }
390
1.90k
    }
391
5
        else
392
5
    return -1;
393
1.90k
      }
394
7.16k
    else if (regd == 2)
395
782
      {
396
        /* Absolute.  */
397
782
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
398
780
    {
399
780
      cmd_len += 2;
400
780
      if (extended_dst)
401
63
        {
402
63
          dst |= extended_dst << 16;
403
63
          sprintf (op, "&0x%05x", dst & 0xfffff);
404
63
        }
405
717
      else
406
717
        sprintf (op, "&0x%04x", PS (dst));
407
780
    }
408
2
        else
409
2
    return -1;
410
782
      }
411
6.38k
    else if (regd == 3)
412
1.80k
      {
413
1.80k
        *cycles = 1;
414
1.80k
        sprintf (op, "#1");
415
1.80k
        sprintf (comm, "r3 As==01");
416
1.80k
      }
417
4.58k
    else
418
4.58k
      {
419
        /* Indexed.  */
420
4.58k
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
421
4.58k
    {
422
4.58k
      cmd_len += 2;
423
4.58k
      if (extended_dst)
424
739
        {
425
739
          dst |= extended_dst << 16;
426
739
          if (dst & 0x80000)
427
645
      dst |= -1U << 20;
428
739
        }
429
4.58k
      sprintf (op, "%d(r%d)", dst, regd);
430
4.58k
      if (dst > 9 || dst < 0)
431
4.39k
        sprintf (comm, "%05x", dst);
432
4.58k
    }
433
1
        else
434
1
    return -1;
435
4.58k
      }
436
9.07k
  }
437
17.8k
      break;
438
439
36.1k
    case 3:     /* Jumps.  */
440
36.1k
      where = insn & 0x03ff;
441
36.1k
      if (where & 0x200)
442
19.1k
  where |= ~0x03ff;
443
36.1k
      if (where > 512 || where < -511)
444
1.36k
  return 0;
445
446
34.7k
      where *= 2;
447
34.7k
      sprintf (op, "$%+-8d", where + 2);
448
34.7k
      sprintf (comm, "abs 0x%lx", (long) (addr + 2 + where));
449
34.7k
      *cycles = 2;
450
34.7k
      return 2;
451
0
      break;
452
453
0
    default:
454
0
      cmd_len = 0;
455
57.7k
    }
456
457
21.5k
  return cmd_len;
458
57.7k
}
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
174k
{
472
174k
  int regs = 0, regd = 0;
473
174k
  int ad = 0, as = 0;
474
174k
  int cmd_len = 2;
475
174k
  int dst = 0;
476
174k
  int fmt;
477
174k
  int extended_dst = extension_word & 0xf;
478
174k
  int extended_src = (extension_word >> 7) & 0xf;
479
480
174k
  regd = insn & 0x0f;
481
174k
  regs = (insn & 0x0f00) >> 8;
482
174k
  as = (insn & 0x0030) >> 4;
483
174k
  ad = (insn & 0x0080) >> 7;
484
485
174k
  if (opcode->fmt < 0)
486
0
    fmt = (- opcode->fmt) - 1;
487
174k
  else
488
174k
    fmt = opcode->fmt;
489
490
174k
  if (fmt == 0)
491
25.4k
    {
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
25.4k
      if (regd != regs || as != ad)
503
22.4k
  return 0;    /* May be 'data' section.  */
504
505
2.96k
      if (ad == 0)
506
671
  {
507
    /* Register mode.  */
508
671
    if (regd == 3)
509
3
      {
510
3
        strcpy (comm1, _("Warning: illegal as emulation instr"));
511
3
        return -1;
512
3
      }
513
514
668
    sprintf (op1, "r%d", regd);
515
668
    *cycles = 1;
516
668
  }
517
2.28k
      else      /* ad == 1 */
518
2.28k
  {
519
2.28k
    if (regd == 0)
520
654
      {
521
        /* PC relative, Symbolic.  */
522
654
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
523
652
    {
524
652
      cmd_len += 4;
525
652
      *cycles = 6;
526
652
      sprintf (op1, "0x%04x", PS (dst));
527
652
      sprintf (comm1, "PC rel. 0x%04x",
528
652
         PS ((short) addr + 2 + dst));
529
652
      if (extension_word)
530
170
        {
531
170
          dst |= extended_dst << 16;
532
170
          if (dst & 0x80000)
533
28
      dst |= -1U << 20;
534
170
          sprintf (op1, "0x%05x", dst & 0xfffff);
535
170
          sprintf (comm1, "PC rel. 0x%05lx",
536
170
             (long)((addr + 2 + dst) & 0xfffff));
537
170
        }
538
652
    }
539
2
        else
540
2
    return -1;
541
654
      }
542
1.63k
    else if (regd == 2)
543
506
      {
544
        /* Absolute.  */
545
506
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
546
505
    {
547
505
      int src;
548
549
      /* If the 'src' field is not the same as the dst
550
         then this is not an rla instruction.  */
551
505
      if (msp430dis_opcode_signed (addr + 4, info, &src, comm2))
552
504
        {
553
504
          if (src != dst)
554
123
      return 0;
555
504
        }
556
1
      else
557
1
        return -1;
558
381
      cmd_len += 4;
559
381
      *cycles = 6;
560
381
      sprintf (op1, "&0x%04x", PS (dst));
561
381
      if (extension_word)
562
48
        {
563
48
          dst |= extended_dst << 16;
564
48
          sprintf (op1, "&0x%05x", dst & 0xfffff);
565
48
        }
566
381
    }
567
1
        else
568
1
    return -1;
569
506
      }
570
1.12k
    else
571
1.12k
      {
572
        /* Indexed.  */
573
1.12k
        if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
574
1.12k
    {
575
1.12k
      if (extension_word)
576
689
        {
577
689
          dst |= extended_dst << 16;
578
689
          if (dst & 0x80000)
579
82
      dst |= -1U << 20;
580
689
        }
581
1.12k
      cmd_len += 4;
582
1.12k
      *cycles = 6;
583
1.12k
      sprintf (op1, "%d(r%d)", dst, regd);
584
1.12k
      if (dst > 9 || dst < -9)
585
285
        sprintf (comm1, "#0x%05x", dst);
586
1.12k
    }
587
0
        else
588
0
    return -1;
589
1.12k
      }
590
2.28k
  }
591
592
2.83k
      *op2 = 0;
593
2.83k
      *comm2 = 0;
594
595
2.83k
      return cmd_len;
596
2.96k
    }
597
598
  /* Two operands exactly.  */
599
149k
  if (ad == 0 && regd == 3)
600
102
    {
601
      /* R2/R3 are illegal as dest: may be data section.  */
602
102
      strcpy (comm1, _("Warning: illegal as 2-op instr"));
603
102
      return -1;
604
102
    }
605
606
  /* Source.  */
607
148k
  if (as == 0)
608
45.1k
    {
609
45.1k
      *cycles = 1;
610
45.1k
      if (regs == 3)
611
1.96k
  {
612
    /* Constants.  */
613
1.96k
    sprintf (op1, "#0");
614
1.96k
    sprintf (comm1, "r3 As==00");
615
1.96k
  }
616
43.1k
      else
617
43.1k
  {
618
    /* Register.  */
619
43.1k
    sprintf (op1, "r%d", regs);
620
43.1k
  }
621
45.1k
    }
622
103k
  else if (as == 2)
623
28.1k
    {
624
28.1k
      * cycles = print_as2_reg_name (regs, op1, comm1, 1, 1, regs == 0 ? 3 : 2);
625
28.1k
    }
626
75.6k
  else if (as == 3)
627
43.5k
    {
628
43.5k
      if (regs == 0)
629
2.94k
  {
630
2.94k
    *cycles = 3;
631
    /* Absolute. @pc+.  */
632
2.94k
    if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
633
2.93k
      {
634
2.93k
        cmd_len += 2;
635
2.93k
        sprintf (op1, "#%d", dst);
636
2.93k
        if (dst > 9 || dst < 0)
637
2.64k
    sprintf (comm1, "#0x%04x", PS (dst));
638
2.93k
        if (extension_word)
639
671
    {
640
671
      dst &= 0xffff;
641
671
      dst |= extended_src << 16;
642
671
      if (dst & 0x80000)
643
181
        dst |= -1U << 20;
644
671
      sprintf (op1, "#%d", dst);
645
671
      if (dst > 9 || dst < 0)
646
545
        sprintf (comm1, "0x%05x", dst & 0xfffff);
647
671
    }
648
2.93k
      }
649
8
    else
650
8
      return -1;
651
2.94k
  }
652
40.6k
      else
653
40.6k
  * cycles = print_as3_reg_name (regs, op1, comm1, 1, 1, 2);
654
43.5k
    }
655
32.0k
  else if (as == 1)
656
32.0k
    {
657
32.0k
      if (regs == 0)
658
3.73k
  {
659
3.73k
    *cycles = 4;
660
    /* PC relative.  */
661
3.73k
    if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
662
3.72k
      {
663
3.72k
        cmd_len += 2;
664
3.72k
        sprintf (op1, "0x%04x", PS (dst));
665
3.72k
        sprintf (comm1, "PC rel. 0x%04x",
666
3.72k
           PS ((short) addr + 2 + dst));
667
3.72k
        if (extension_word)
668
446
    {
669
446
      dst &= 0xffff;
670
446
      dst |= extended_src << 16;
671
446
      if (dst & 0x80000)
672
85
        dst |= -1U << 20;
673
446
      sprintf (op1, "0x%05x", dst & 0xfffff);
674
446
      sprintf (comm1, "PC rel. 0x%05lx",
675
446
         (long) ((addr + 2 + dst) & 0xfffff));
676
446
    }
677
3.72k
      }
678
12
    else
679
12
      return -1;
680
3.73k
  }
681
28.3k
      else if (regs == 2)
682
8.51k
  {
683
8.51k
    *cycles = 2;
684
    /* Absolute.  */
685
8.51k
    if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
686
8.50k
      {
687
8.50k
        cmd_len += 2;
688
8.50k
        sprintf (op1, "&0x%04x", PS (dst));
689
8.50k
        sprintf (comm1, "0x%04x", PS (dst));
690
8.50k
        if (extension_word)
691
939
    {
692
939
      dst &= 0xffff;
693
939
      dst |= extended_src << 16;
694
939
      sprintf (op1, "&0x%05x", dst & 0xfffff);
695
939
      * comm1 = 0;
696
939
    }
697
8.50k
      }
698
15
    else
699
15
      return -1;
700
8.51k
  }
701
19.7k
      else if (regs == 3)
702
2.09k
  {
703
2.09k
    *cycles = 1;
704
2.09k
    sprintf (op1, "#1");
705
2.09k
    sprintf (comm1, "r3 As==01");
706
2.09k
  }
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.6k
      {
713
17.6k
        cmd_len += 2;
714
17.6k
        if (extension_word)
715
1.35k
    {
716
1.35k
      dst &= 0xffff;
717
1.35k
      dst |= extended_src << 16;
718
1.35k
      if (dst & 0x80000)
719
545
        dst |= -1U << 20;
720
1.35k
    }
721
17.6k
        sprintf (op1, "%d(r%d)", dst, regs);
722
17.6k
        if (dst > 9 || dst < -9)
723
16.8k
    sprintf (comm1, "0x%05x", dst);
724
17.6k
      }
725
10
    else
726
10
      return -1;
727
17.7k
  }
728
32.0k
    }
729
730
  /* Destination. Special care needed on addr + XXXX.  */
731
732
148k
  if (ad == 0)
733
86.8k
    {
734
      /* Register.  */
735
86.8k
      if (regd == 0)
736
17.1k
  {
737
17.1k
    *cycles += 1;
738
17.1k
    sprintf (op2, "r0");
739
17.1k
  }
740
69.7k
      else if (regd == 1)
741
9.98k
  sprintf (op2, "r1");
742
743
59.7k
      else if (regd == 2)
744
9.39k
  sprintf (op2, "r2");
745
746
50.3k
      else
747
50.3k
  sprintf (op2, "r%d", regd);
748
86.8k
    }
749
62.0k
  else  /* ad == 1.  */
750
62.0k
    {
751
62.0k
      * cycles += 3;
752
753
62.0k
      if (regd == 0)
754
6.93k
  {
755
    /* PC relative.  */
756
6.93k
    *cycles += 1;
757
6.93k
    if (msp430dis_opcode_signed (addr + cmd_len, info, &dst, comm2))
758
6.93k
      {
759
6.93k
        sprintf (op2, "0x%04x", PS (dst));
760
6.93k
        sprintf (comm2, "PC rel. 0x%04x",
761
6.93k
           PS ((short) addr + cmd_len + dst));
762
6.93k
        if (extension_word)
763
1.46k
    {
764
1.46k
      dst |= extended_dst << 16;
765
1.46k
      if (dst & 0x80000)
766
1.43k
        dst |= -1U << 20;
767
1.46k
      sprintf (op2, "0x%05x", dst & 0xfffff);
768
1.46k
      sprintf (comm2, "PC rel. 0x%05lx",
769
1.46k
         (long)((addr + cmd_len + dst) & 0xfffff));
770
1.46k
    }
771
6.93k
      }
772
2
    else
773
2
      return -1;
774
6.93k
    cmd_len += 2;
775
6.93k
  }
776
55.0k
      else if (regd == 2)
777
4.13k
  {
778
    /* Absolute.  */
779
4.13k
    if (msp430dis_opcode_signed (addr + cmd_len, info, &dst, comm2))
780
4.12k
      {
781
4.12k
        cmd_len += 2;
782
4.12k
        sprintf (op2, "&0x%04x", PS (dst));
783
4.12k
        if (extension_word)
784
571
    {
785
571
      dst |= extended_dst << 16;
786
571
      sprintf (op2, "&0x%05x", dst & 0xfffff);
787
571
    }
788
4.12k
      }
789
3
    else
790
3
      return -1;
791
4.13k
  }
792
50.9k
      else
793
50.9k
  {
794
50.9k
    if (msp430dis_opcode_signed (addr + cmd_len, info, &dst, comm2))
795
50.9k
      {
796
50.9k
        cmd_len += 2;
797
50.9k
        if (dst > 9 || dst < 0)
798
49.0k
    sprintf (comm2, "0x%04x", PS (dst));
799
50.9k
        if (extension_word)
800
1.68k
    {
801
1.68k
      dst |= extended_dst << 16;
802
1.68k
      if (dst & 0x80000)
803
1.27k
        dst |= -1U << 20;
804
1.68k
      if (dst > 9 || dst < 0)
805
1.52k
        sprintf (comm2, "0x%05x", dst & 0xfffff);
806
1.68k
    }
807
50.9k
        sprintf (op2, "%d(r%d)", dst, regd);
808
50.9k
      }
809
46
    else
810
46
      return -1;
811
50.9k
  }
812
62.0k
    }
813
814
148k
  return cmd_len;
815
148k
}
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
5.65k
{
826
5.65k
  int regs = 0, regd = 0;
827
5.65k
  int as = 0;
828
5.65k
  int cmd_len = 2;
829
5.65k
  int dst = 0;
830
5.65k
  unsigned short udst = 0;
831
832
5.65k
  regd = insn & 0x0f;
833
5.65k
  regs = (insn & 0x0f00) >> 8;
834
5.65k
  as = (insn & 0x0030) >> 4;
835
836
5.65k
  if (regd != 0)  /* Destination register is not a PC.  */
837
0
    return 0;
838
839
  /* dst is a source register.  */
840
5.65k
  if (as == 0)
841
3.24k
    {
842
      /* Constants.  */
843
3.24k
      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.24k
      else
850
3.24k
  {
851
    /* Register.  */
852
3.24k
    *cycles = 1;
853
3.24k
    sprintf (op1, "r%d", regs);
854
3.24k
  }
855
3.24k
    }
856
2.41k
  else if (as == 2)
857
394
    {
858
394
      * cycles = print_as2_reg_name (regs, op1, comm1, 2, 1, 2);
859
394
    }
860
2.02k
  else if (as == 3)
861
948
    {
862
948
      if (regs == 0)
863
83
  {
864
    /* Absolute. @pc+  */
865
83
    *cycles = 3;
866
83
    if (msp430dis_opcode_unsigned (addr + 2, info, &udst, comm1))
867
82
      {
868
82
        cmd_len += 2;
869
82
        sprintf (op1, "#0x%04x", PS (udst));
870
82
      }
871
1
    else
872
1
      return -1;
873
83
  }
874
865
      else
875
865
  * cycles = print_as3_reg_name (regs, op1, comm1, 1, 1, 2);
876
948
    }
877
1.07k
  else if (as == 1)
878
1.07k
    {
879
1.07k
      * cycles = 3;
880
881
1.07k
      if (regs == 0)
882
114
  {
883
    /* PC relative.  */
884
114
    if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
885
112
      {
886
112
        cmd_len += 2;
887
112
        (*cycles)++;
888
112
        sprintf (op1, "0x%04x", PS (dst));
889
112
        sprintf (comm1, "PC rel. 0x%04x",
890
112
           PS ((short) addr + 2 + dst));
891
112
      }
892
2
    else
893
2
      return -1;
894
114
  }
895
958
      else if (regs == 2)
896
357
  {
897
    /* Absolute.  */
898
357
    if (msp430dis_opcode_unsigned (addr + 2, info, &udst, comm1))
899
348
      {
900
348
        cmd_len += 2;
901
348
        sprintf (op1, "&0x%04x", PS (udst));
902
348
      }
903
9
    else
904
9
      return -1;
905
357
  }
906
601
      else if (regs == 3)
907
53
  {
908
53
    (*cycles)--;
909
53
    sprintf (op1, "#1");
910
53
    sprintf (comm1, "r3 As==01");
911
53
  }
912
548
      else
913
548
  {
914
    /* Indexed.  */
915
548
    if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
916
546
      {
917
546
        cmd_len += 2;
918
546
        sprintf (op1, "%d(r%d)", dst, regs);
919
546
      }
920
2
    else
921
2
      return -1;
922
548
  }
923
1.07k
    }
924
925
5.64k
  return cmd_len;
926
5.65k
}
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.01k
{
936
1.01k
  unsigned int   ureg = insn & 0xf;
937
1.01k
  int            reg = insn & 0xf;
938
1.01k
  int            am = (insn & 0xf0) >> 4;
939
1.01k
  int            cmd_len = 2;
940
1.01k
  unsigned short udst = 0;
941
1.01k
  int            dst = 0;
942
943
1.01k
  switch (am)
944
1.01k
    {
945
191
    case 4: /* CALLA Rdst */
946
191
      *cycles = 1;
947
191
      sprintf (op1, "r%d", reg);
948
191
      break;
949
950
129
    case 5: /* CALLA x(Rdst) */
951
129
      *cycles = 3;
952
129
      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
953
128
  {
954
128
    cmd_len += 2;
955
128
    sprintf (op1, "%d(r%d)", dst, reg);
956
128
    if (reg == 0)
957
58
      sprintf (comm1, "PC rel. 0x%05lx", (long) (addr + 2 + dst));
958
70
    else
959
70
      sprintf (comm1, "0x%05x", dst);
960
128
  }
961
1
      else
962
1
  return -1;
963
128
      break;
964
965
128
    case 6: /* CALLA @Rdst */
966
50
      *cycles = 2;
967
50
      sprintf (op1, "@r%d", reg);
968
50
      break;
969
970
76
    case 7: /* CALLA @Rdst+ */
971
76
      *cycles = 2;
972
76
      sprintf (op1, "@r%d+", reg);
973
76
      break;
974
975
123
    case 8: /* CALLA &abs20 */
976
123
      if (msp430dis_opcode_unsigned (addr + 2, info, &udst, comm1))
977
122
  {
978
122
    cmd_len += 2;
979
122
    *cycles = 4;
980
122
    sprintf (op1, "&%d", (ureg << 16) + udst);
981
122
    sprintf (comm1, "0x%05x", (ureg << 16) + udst);
982
122
  }
983
1
      else
984
1
  return -1;
985
122
      break;
986
987
399
    case 9: /* CALLA pcrel-sym */
988
399
      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
989
398
  {
990
398
    cmd_len += 2;
991
398
    *cycles = 4;
992
398
    sprintf (op1, "%d(PC)", (reg << 16) + dst);
993
398
    sprintf (comm1, "PC rel. 0x%05lx",
994
398
       (long) (addr + 2 + dst + (reg << 16)));
995
398
  }
996
1
      else
997
1
  return -1;
998
398
      break;
999
1000
398
    case 11: /* CALLA #imm20 */
1001
40
      if (msp430dis_opcode_unsigned (addr + 2, info, &udst, comm1))
1002
39
  {
1003
39
    cmd_len += 2;
1004
39
    *cycles = 4;
1005
39
    sprintf (op1, "#%d", (ureg << 16) + udst);
1006
39
    sprintf (comm1, "0x%05x", (ureg << 16) + udst);
1007
39
  }
1008
1
      else
1009
1
  return -1;
1010
39
      break;
1011
1012
39
    default:
1013
5
      strcpy (comm1, _("Warning: unrecognised CALLA addressing mode"));
1014
5
      return -1;
1015
1.01k
    }
1016
1017
1.00k
  return cmd_len;
1018
1.01k
}
1019
1020
int
1021
print_insn_msp430 (bfd_vma addr, disassemble_info *info)
1022
342k
{
1023
342k
  void *stream = info->stream;
1024
342k
  fprintf_ftype prin = info->fprintf_func;
1025
342k
  struct msp430_opcode_s *opcode;
1026
342k
  char op1[32], op2[32], comm1[64], comm2[64];
1027
342k
  int cmd_len = 0;
1028
342k
  unsigned short insn;
1029
342k
  int cycles = 0;
1030
342k
  char *bc = "";
1031
342k
  unsigned short extension_word = 0;
1032
342k
  unsigned short bits;
1033
1034
342k
  if (! msp430dis_opcode_unsigned (addr, info, &insn, NULL))
1035
164
    return -1;
1036
1037
341k
  if (((int) addr & 0xffff) > 0xffdf)
1038
0
    {
1039
0
      (*prin) (stream, "interrupt service routine at 0x%04x", 0xffff & insn);
1040
0
      return 2;
1041
0
    }
1042
1043
341k
  *comm1 = 0;
1044
341k
  *comm2 = 0;
1045
1046
  /* Check for an extension word.  */
1047
341k
  if ((insn & 0xf800) == 0x1800)
1048
22.5k
    {
1049
22.5k
      extension_word = insn;
1050
22.5k
      addr += 2;
1051
22.5k
      if (! msp430dis_opcode_unsigned (addr, info, &insn, NULL))
1052
22
  return -1;
1053
22.5k
   }
1054
1055
16.2M
  for (opcode = msp430_opcodes; opcode->name; opcode++)
1056
16.2M
    {
1057
16.2M
      if ((insn & opcode->bin_mask) == opcode->bin_opcode
1058
382k
    && opcode->bin_opcode != 0x9300)
1059
381k
  {
1060
381k
    *op1 = 0;
1061
381k
    *op2 = 0;
1062
381k
    *comm1 = 0;
1063
381k
    *comm2 = 0;
1064
1065
    /* r0 as destination. Ad should be zero.  */
1066
381k
    if (opcode->insn_opnumb == 3
1067
20.1k
        && (insn & 0x000f) == 0
1068
7.14k
        && (insn & 0x0080) == 0)
1069
5.65k
      {
1070
5.65k
        int ret =
1071
5.65k
    msp430_branchinstr (info, opcode, addr, insn, op1, comm1,
1072
5.65k
            &cycles);
1073
1074
5.65k
        if (ret == -1)
1075
14
    return -1;
1076
5.64k
        cmd_len += ret;
1077
5.64k
        if (cmd_len)
1078
5.64k
    break;
1079
5.64k
      }
1080
1081
376k
    switch (opcode->insn_opnumb)
1082
376k
      {
1083
0
        int n;
1084
0
        int reg;
1085
0
        int ret;
1086
1087
1.01k
      case 4:
1088
1.01k
        ret = msp430x_calla_instr (info, addr, insn,
1089
1.01k
           op1, comm1, & cycles);
1090
1.01k
        if (ret == -1)
1091
9
    return -1;
1092
1.00k
        cmd_len += ret;
1093
1.00k
        break;
1094
1095
4.58k
      case 5: /* PUSHM/POPM */
1096
4.58k
        n = (insn & 0xf0) >> 4;
1097
4.58k
        reg = (insn & 0xf);
1098
1099
4.58k
        sprintf (op1, "#%d", n + 1);
1100
4.58k
        if (opcode->bin_opcode == 0x1400)
1101
    /* PUSHM */
1102
3.15k
    sprintf (op2, "r%d", reg);
1103
1.43k
        else
1104
    /* POPM */
1105
1.43k
    sprintf (op2, "r%d", reg + n);
1106
4.58k
        if (insn & 0x100)
1107
1.96k
    sprintf (comm1, "16-bit words");
1108
2.62k
        else
1109
2.62k
    {
1110
2.62k
      sprintf (comm1, "20-bit words");
1111
2.62k
      bc =".a";
1112
2.62k
    }
1113
1114
4.58k
        cycles = 2; /*FIXME*/
1115
4.58k
        cmd_len = 2;
1116
4.58k
        break;
1117
1118
4.50k
      case 6: /* RRAM, RRCM, RRUM, RLAM.  */
1119
4.50k
        n = ((insn >> 10) & 0x3) + 1;
1120
4.50k
        reg = (insn & 0xf);
1121
4.50k
        if ((insn & 0x10) == 0)
1122
3.18k
    bc =".a";
1123
4.50k
        sprintf (op1, "#%d", n);
1124
4.50k
        sprintf (op2, "r%d", reg);
1125
4.50k
        cycles = 2; /*FIXME*/
1126
4.50k
        cmd_len = 2;
1127
4.50k
        break;
1128
1129
9.49k
      case 8: /* ADDA, CMPA, SUBA.  */
1130
9.49k
        reg = (insn & 0xf);
1131
9.49k
        n = (insn >> 8) & 0xf;
1132
9.49k
        if (insn & 0x40)
1133
6.52k
    {
1134
6.52k
      sprintf (op1, "r%d", n);
1135
6.52k
      cmd_len = 2;
1136
6.52k
    }
1137
2.97k
        else
1138
2.97k
    {
1139
2.97k
      n <<= 16;
1140
2.97k
      if (msp430dis_opcode_unsigned (addr + 2, info, &bits, comm1))
1141
2.96k
        {
1142
2.96k
          n |= bits;
1143
2.96k
          sprintf (op1, "#%d", n);
1144
2.96k
          if (n > 9 || n < 0)
1145
2.37k
      sprintf (comm1, "0x%05x", n);
1146
2.96k
        }
1147
7
      else
1148
7
        return -1;
1149
2.96k
      cmd_len = 4;
1150
2.96k
    }
1151
9.49k
        sprintf (op2, "r%d", reg);
1152
9.49k
        cycles = 2; /*FIXME*/
1153
9.49k
        break;
1154
1155
41.1k
      case 9: /* MOVA */
1156
41.1k
        reg = (insn & 0xf);
1157
41.1k
        n = (insn >> 8) & 0xf;
1158
41.1k
        switch ((insn >> 4) & 0xf)
1159
41.1k
    {
1160
17.9k
    case 0: /* MOVA @Rsrc, Rdst */
1161
17.9k
      cmd_len = 2;
1162
17.9k
      sprintf (op1, "@r%d", n);
1163
17.9k
      if (strcmp (opcode->name, "bra") != 0)
1164
13.5k
        sprintf (op2, "r%d", reg);
1165
17.9k
      break;
1166
1167
8.29k
    case 1: /* MOVA @Rsrc+, Rdst */
1168
8.29k
      cmd_len = 2;
1169
8.29k
      if (strcmp (opcode->name, "reta") != 0)
1170
7.15k
        {
1171
7.15k
          sprintf (op1, "@r%d+", n);
1172
7.15k
          if (strcmp (opcode->name, "bra") != 0)
1173
5.48k
      sprintf (op2, "r%d", reg);
1174
7.15k
        }
1175
8.29k
      break;
1176
1177
3.42k
    case 2: /* MOVA &abs20, Rdst */
1178
3.42k
      cmd_len = 4;
1179
3.42k
      n <<= 16;
1180
3.42k
      if (msp430dis_opcode_unsigned (addr + 2, info, &bits, comm1))
1181
3.41k
        {
1182
3.41k
          n |= bits;
1183
3.41k
          sprintf (op1, "&%d", n);
1184
3.41k
          if (n > 9 || n < 0)
1185
2.46k
      sprintf (comm1, "0x%05x", n);
1186
3.41k
          if (strcmp (opcode->name, "bra") != 0)
1187
2.48k
      sprintf (op2, "r%d", reg);
1188
3.41k
        }
1189
6
      else
1190
6
        return -1;
1191
3.41k
      break;
1192
1193
3.41k
    case 3: /* MOVA x(Rsrc), Rdst */
1194
3.01k
      cmd_len = 4;
1195
3.01k
      if (strcmp (opcode->name, "bra") != 0)
1196
2.50k
        sprintf (op2, "r%d", reg);
1197
3.01k
      reg = n;
1198
3.01k
      if (msp430dis_opcode_signed (addr + 2, info, &n, comm1))
1199
3.01k
        {
1200
3.01k
          sprintf (op1, "%d(r%d)", n, reg);
1201
3.01k
          if (n > 9 || n < 0)
1202
2.43k
      {
1203
2.43k
        if (reg == 0)
1204
1.63k
          sprintf (comm1, "PC rel. 0x%05lx",
1205
1.63k
             (long) (addr + 2 + n));
1206
797
        else
1207
797
          sprintf (comm1, "0x%05x", n);
1208
2.43k
      }
1209
3.01k
        }
1210
3
      else
1211
3
        return -1;
1212
3.01k
      break;
1213
1214
3.06k
    case 6: /* MOVA Rsrc, &abs20 */
1215
3.06k
      cmd_len = 4;
1216
3.06k
      reg <<= 16;
1217
3.06k
      if (msp430dis_opcode_unsigned (addr + 2, info, &bits, comm2))
1218
3.06k
        {
1219
3.06k
          reg |= bits;
1220
3.06k
          sprintf (op1, "r%d", n);
1221
3.06k
          sprintf (op2, "&%d", reg);
1222
3.06k
          if (reg > 9 || reg < 0)
1223
2.92k
      sprintf (comm2, "0x%05x", reg);
1224
3.06k
        }
1225
3
      else
1226
3
        return -1;
1227
3.06k
      break;
1228
1229
3.06k
    case 7: /* MOVA Rsrc, x(Rdst) */
1230
2.64k
      cmd_len = 4;
1231
2.64k
      sprintf (op1, "r%d", n);
1232
2.64k
      if (msp430dis_opcode_signed (addr + 2, info, &n, comm2))
1233
2.63k
        {
1234
2.63k
          sprintf (op2, "%d(r%d)", n, reg);
1235
2.63k
          if (n > 9 || n < 0)
1236
1.54k
      {
1237
1.54k
        if (reg == 0)
1238
395
          sprintf (comm2, "PC rel. 0x%05lx",
1239
395
             (long) (addr + 2 + n));
1240
1.15k
        else
1241
1.15k
          sprintf (comm2, "0x%05x", n);
1242
1.54k
      }
1243
2.63k
        }
1244
4
      else
1245
4
        return -1;
1246
2.63k
      break;
1247
1248
2.63k
    case 8: /* MOVA #imm20, Rdst */
1249
1.03k
      cmd_len = 4;
1250
1.03k
      n <<= 16;
1251
1.03k
      if (msp430dis_opcode_unsigned (addr + 2, info, &bits, comm1))
1252
1.02k
        {
1253
1.02k
          n |= bits;
1254
1.02k
          if (n & 0x80000)
1255
174
      n |= -1U << 20;
1256
1.02k
          sprintf (op1, "#%d", n);
1257
1.02k
          if (n > 9 || n < 0)
1258
761
      sprintf (comm1, "0x%05x", n);
1259
1.02k
          if (strcmp (opcode->name, "bra") != 0)
1260
1.02k
      sprintf (op2, "r%d", reg);
1261
1.02k
        }
1262
7
      else
1263
7
        return -1;
1264
1.02k
      break;
1265
1266
1.71k
    case 12: /* MOVA Rsrc, Rdst */
1267
1.71k
      cmd_len = 2;
1268
1.71k
      sprintf (op1, "r%d", n);
1269
1.71k
      if (strcmp (opcode->name, "bra") != 0)
1270
1.71k
        sprintf (op2, "r%d", reg);
1271
1.71k
      break;
1272
1273
0
    default:
1274
0
      break;
1275
41.1k
    }
1276
41.0k
        cycles = 2; /* FIXME */
1277
41.0k
        break;
1278
376k
      }
1279
1280
376k
    if (cmd_len)
1281
60.6k
      break;
1282
1283
315k
    switch (opcode->insn_opnumb)
1284
315k
      {
1285
0
        int ret;
1286
1287
61.1k
      case 0:
1288
61.1k
        cmd_len += msp430_nooperands (opcode, addr, insn, comm1, &cycles);
1289
61.1k
        break;
1290
174k
      case 2:
1291
174k
        ret =
1292
174k
    msp430_doubleoperand (info, opcode, addr, insn, op1, op2,
1293
174k
              comm1, comm2,
1294
174k
              extension_word,
1295
174k
              &cycles);
1296
1297
174k
        if (ret == -1)
1298
205
    return -1;
1299
174k
        cmd_len += ret;
1300
174k
        if (insn & BYTE_OPERATION)
1301
99.8k
    {
1302
99.8k
      if (extension_word != 0 && ((extension_word & BYTE_OPERATION) == 0))
1303
4.20k
        bc = ".a";
1304
95.6k
      else
1305
95.6k
        bc = ".b";
1306
99.8k
    }
1307
74.3k
        else if (extension_word)
1308
3.86k
    {
1309
3.86k
      if (extension_word & BYTE_OPERATION)
1310
1.44k
        bc = ".w";
1311
2.42k
      else
1312
2.42k
        {
1313
2.42k
          bc = ".?";
1314
2.42k
          sprintf (comm2, _("Warning: reserved use of A/L and B/W bits detected"));
1315
2.42k
        }
1316
3.86k
    }
1317
1318
174k
        break;
1319
57.7k
      case 1:
1320
57.7k
        ret =
1321
57.7k
    msp430_singleoperand (info, opcode, addr, insn, op1, comm1,
1322
57.7k
              extension_word,
1323
57.7k
              &cycles);
1324
1325
57.7k
        if (ret == -1)
1326
13
    return -1;
1327
57.7k
        cmd_len += ret;
1328
57.7k
        if (extension_word
1329
5.18k
      && (strcmp (opcode->name, "swpb") == 0
1330
4.96k
          || strcmp (opcode->name, "sxt") == 0))
1331
349
    {
1332
349
      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
349
      else if (extension_word & BYTE_OPERATION)
1338
310
        bc = ".w";
1339
39
      else
1340
39
        bc = ".a";
1341
349
    }
1342
57.4k
        else if (insn & BYTE_OPERATION && opcode->fmt != 3)
1343
6.13k
    {
1344
6.13k
      if (extension_word != 0 && ((extension_word & BYTE_OPERATION) == 0))
1345
988
        bc = ".a";
1346
5.14k
      else
1347
5.14k
        bc = ".b";
1348
6.13k
    }
1349
51.2k
        else if (extension_word)
1350
2.76k
    {
1351
2.76k
      if (extension_word & (1 << 6))
1352
874
        bc = ".w";
1353
1.89k
      else
1354
1.89k
        {
1355
1.89k
          bc = ".?";
1356
1.89k
          sprintf (comm2, _("Warning: reserved use of A/L and B/W bits detected"));
1357
1.89k
        }
1358
2.76k
    }
1359
57.7k
        break;
1360
22.1k
      default:
1361
22.1k
        break;
1362
315k
      }
1363
315k
  }
1364
1365
16.1M
      if (cmd_len)
1366
267k
  break;
1367
16.1M
    }
1368
1369
341k
  if (cmd_len < 1)
1370
7.64k
    {
1371
      /* Unknown opcode, or invalid combination of operands.  */
1372
7.64k
      if (extension_word)
1373
5.57k
  {
1374
5.57k
    prin (stream, ".word  0x%04x, 0x%04x; ????", extension_word, PS (insn));
1375
5.57k
    if (*comm1)
1376
0
      prin (stream, "\t %s", comm1);
1377
5.57k
    return 4;
1378
5.57k
  }
1379
2.07k
      (*prin) (stream, ".word 0x%04x; ????", PS (insn));
1380
2.07k
      return 2;
1381
7.64k
    }
1382
1383
  /* Display the repeat count (if set) for extended register mode.  */
1384
333k
  if (cmd_len == 2 && ((extension_word & 0xf) != 0))
1385
4.42k
    {
1386
4.42k
      if (extension_word & (1 << 7))
1387
1.34k
  prin (stream, "rpt r%d { ", extension_word & 0xf);
1388
3.08k
      else
1389
3.08k
  prin (stream, "rpt #%d { ", (extension_word & 0xf) + 1);
1390
4.42k
    }
1391
1392
  /* Special case:  RRC with an extension word and the ZC bit set is actually RRU.  */
1393
333k
  if (extension_word
1394
16.9k
      && (extension_word & IGNORE_CARRY_BIT)
1395
9.02k
      && strcmp (opcode->name, "rrc") == 0)
1396
446
    (*prin) (stream, "rrux%s", bc);
1397
333k
  else if (extension_word && opcode->name[strlen (opcode->name) - 1] != 'x')
1398
16.4k
    (*prin) (stream, "%sx%s", opcode->name, bc);
1399
317k
  else
1400
317k
    (*prin) (stream, "%s%s", opcode->name, bc);
1401
1402
333k
  if (*op1)
1403
273k
    (*prin) (stream, "\t%s", op1);
1404
333k
  if (*op2)
1405
199k
    (*prin) (stream, ",");
1406
1407
333k
  if (strlen (op1) < 7)
1408
257k
    (*prin) (stream, "\t");
1409
333k
  if (!strlen (op1))
1410
60.7k
    (*prin) (stream, "\t");
1411
1412
333k
  if (*op2)
1413
199k
    (*prin) (stream, "%s", op2);
1414
333k
  if (strlen (op2) < 8)
1415
294k
    (*prin) (stream, "\t");
1416
1417
333k
  if (*comm1 || *comm2)
1418
156k
    (*prin) (stream, ";");
1419
177k
  else if (cycles)
1420
118k
    {
1421
118k
      if (*op2)
1422
95.2k
  (*prin) (stream, ";");
1423
23.5k
      else
1424
23.5k
  {
1425
23.5k
    if (strlen (op1) < 7)
1426
19.9k
      (*prin) (stream, ";");
1427
3.66k
    else
1428
3.66k
      (*prin) (stream, "\t;");
1429
23.5k
  }
1430
118k
    }
1431
333k
  if (*comm1)
1432
108k
    (*prin) (stream, "%s", comm1);
1433
333k
  if (*comm1 && *comm2)
1434
16.8k
    (*prin) (stream, ",");
1435
333k
  if (*comm2)
1436
64.2k
    (*prin) (stream, " %s", comm2);
1437
1438
333k
  if (extension_word)
1439
16.9k
    cmd_len += 2;
1440
1441
333k
  return cmd_len;
1442
341k
}