Coverage Report

Created: 2023-06-29 07:13

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