Coverage Report

Created: 2026-07-25 10:20

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