Coverage Report

Created: 2025-07-08 11:15

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