* hppa.h (pa_opcodes): Use "cX" completer instead of "cx" in fstqx
[external/binutils.git] / opcodes / v850-dis.c
1 /* Disassemble V850 instructions.
2    Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007, 2010,
3    2012  Free Software Foundation, Inc.
4
5    This file is part of the GNU opcodes library.
6
7    This library is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3, or (at your option)
10    any later version.
11
12    It is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20    MA 02110-1301, USA.  */
21
22
23 #include "sysdep.h"
24 #include <stdio.h>
25 #include "opcode/v850.h"
26 #include "dis-asm.h"
27 #include "opintl.h"
28
29 static const char *const v850_reg_names[] =
30 {
31   "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7",
32   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
33   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
34   "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp"
35 };
36
37 static const char *const v850_sreg_names[] =
38 {
39   "eipc/vip/mpm", "eipsw/mpc", "fepc/tid", "fepsw/ppa", "ecr/vmecr", "psw/vmtid",
40   "sr6/fpsr/vmadr/dcc", "sr7/fpepc/dc0",
41   "sr8/fpst/vpecr/dcv1", "sr9/fpcc/vptid", "sr10/fpcfg/vpadr/spal", "sr11/spau",
42   "sr12/vdecr/ipa0l", "eiic/vdtid/ipa0u", "feic/ipa1l", "dbic/ipa1u",
43   "ctpc/ipa2l", "ctpsw/ipa2u", "dbpc/ipa3l", "dbpsw/ipa3u", "ctbp/dpa0l",
44   "dir/dpa0u", "bpc/dpa0u", "asid/dpa1l",
45   "bpav/dpa1u", "bpam/dpa2l", "bpdv/dpa2u", "bpdm/dpa3l", "eiwr/dpa3u",
46   "fewr", "dbwr", "bsel"
47 };
48
49 static const char *const v850_cc_names[] =
50 {
51   "v", "c/l", "z", "nh", "s/n", "t", "lt", "le",
52   "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt"
53 };
54
55 static const char *const v850_float_cc_names[] =
56 {
57   "f/t", "un/or", "eq/neq", "ueq/ogl", "olt/uge", "ult/oge", "ole/ugt", "ule/ogt",
58   "sf/st", "ngle/gle", "seq/sne", "ngl/gl", "lt/nlt", "nge/ge", "le/nle", "ngt/gt"
59 };
60
61
62 static void
63 print_value (int flags, bfd_vma memaddr, struct disassemble_info *info, long value)
64 {
65   if (flags & V850_PCREL)
66     {
67       bfd_vma addr = value + memaddr;
68       info->print_address_func (addr, info);
69     }
70   else if (flags & V850_OPERAND_DISP)
71     {
72       if (flags & V850_OPERAND_SIGNED)
73         {
74           info->fprintf_func (info->stream, "%ld", value);
75         }
76       else
77         {
78           info->fprintf_func (info->stream, "%lu", value);
79         }
80     }
81   else if (flags & V850E_IMMEDIATE32)
82     {
83       info->fprintf_func (info->stream, "0x%lx", value);
84     }
85   else
86     {
87       if (flags & V850_OPERAND_SIGNED)
88         {
89           info->fprintf_func (info->stream, "%ld", value);
90         }
91       else
92         {
93           info->fprintf_func (info->stream, "%lu", value);
94         }
95     }
96 }
97
98 static long
99 get_operand_value (const struct v850_operand *operand,
100                    unsigned long insn,
101                    int bytes_read,
102                    bfd_vma memaddr,
103                    struct disassemble_info * info,
104                    bfd_boolean noerror,
105                    int *invalid)
106 {
107   long value;
108   bfd_byte buffer[4];
109
110   if ((operand->flags & V850E_IMMEDIATE16)
111       || (operand->flags & V850E_IMMEDIATE16HI))
112     {
113       int status = info->read_memory_func (memaddr + bytes_read, buffer, 2, info);
114
115       if (status == 0)
116         {
117           value = bfd_getl16 (buffer);
118
119           if (operand->flags & V850E_IMMEDIATE16HI)
120             value <<= 16;
121
122           return value;
123         }
124
125       if (!noerror)
126         info->memory_error_func (status, memaddr + bytes_read, info);
127
128       return 0;
129     }
130
131   if (operand->flags & V850E_IMMEDIATE23)
132     {
133       int status = info->read_memory_func (memaddr + 2, buffer, 4, info);
134
135       if (status == 0)
136         {
137           value = bfd_getl32 (buffer);
138
139           value = (operand->extract) (value, invalid);
140
141           return value;
142         }
143
144       if (!noerror)
145         info->memory_error_func (status, memaddr + bytes_read, info);
146
147       return 0;
148     }
149
150   if (operand->flags & V850E_IMMEDIATE32)
151     {
152       int status = info->read_memory_func (memaddr + bytes_read, buffer, 4, info);
153
154       if (status == 0)
155         {
156           bytes_read += 4;
157           value = bfd_getl32 (buffer);
158
159           return value;
160         }
161
162       if (!noerror)
163         info->memory_error_func (status, memaddr + bytes_read, info);
164
165       return 0;
166     }
167
168   if (operand->extract)
169     value = (operand->extract) (insn, invalid);
170   else
171     {
172       if (operand->bits == -1)
173         value = (insn & operand->shift);
174       else
175         value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
176
177       if (operand->flags & V850_OPERAND_SIGNED)
178         value = ((long)(value << (sizeof (long)*8 - operand->bits))
179                  >> (sizeof (long)*8 - operand->bits));
180     }
181
182   return value;
183 }
184
185
186 static int
187 disassemble (bfd_vma memaddr, struct disassemble_info *info, int bytes_read, unsigned long insn)
188 {
189   struct v850_opcode *op = (struct v850_opcode *)v850_opcodes;
190   const struct v850_operand *operand;
191   int match = 0;
192   int target_processor;
193
194   switch (info->mach)
195     {
196     case 0:
197     default:
198       target_processor = PROCESSOR_V850;
199       break;
200
201     case bfd_mach_v850e:
202       target_processor = PROCESSOR_V850E;
203       break;
204
205     case bfd_mach_v850e1:
206       target_processor = PROCESSOR_V850E;
207       break;
208
209     case bfd_mach_v850e2:
210       target_processor = PROCESSOR_V850E2;
211       break;
212
213     case bfd_mach_v850e2v3:
214       target_processor = PROCESSOR_V850E2V3;
215       break;
216     }
217
218   /* If this is a two byte insn, then mask off the high bits.  */
219   if (bytes_read == 2)
220     insn &= 0xffff;
221
222   /* Find the opcode.  */
223   while (op->name)
224     {
225       if ((op->mask & insn) == op->opcode
226           && (op->processors & target_processor)
227           && !(op->processors & PROCESSOR_OPTION_ALIAS))
228         {
229           /* Code check start.  */
230           const unsigned char *opindex_ptr;
231           unsigned int opnum;
232           unsigned int memop;
233
234           for (opindex_ptr = op->operands, opnum = 1;
235                *opindex_ptr != 0;
236                opindex_ptr++, opnum++)
237             {
238               int invalid = 0;
239               long value;
240
241               operand = &v850_operands[*opindex_ptr];
242
243               value = get_operand_value (operand, insn, bytes_read, memaddr, info, 1, &invalid);
244
245               if (invalid)
246                 goto next_opcode;
247
248               if ((operand->flags & V850_NOT_R0) && value == 0 && (op->memop) <=2)
249                 goto next_opcode;
250
251               if ((operand->flags & V850_NOT_SA) && value == 0xd)
252                 goto next_opcode;
253
254               if ((operand->flags & V850_NOT_IMM0) && value == 0)
255                 goto next_opcode;
256             }
257
258           /* Code check end.  */
259
260           match = 1;
261           (*info->fprintf_func) (info->stream, "%s\t", op->name);
262 #if 0
263           fprintf (stderr, "match: insn: %lx, mask: %lx, opcode: %lx, name: %s\n",
264                    insn, op->mask, op->opcode, op->name );
265 #endif
266
267           memop = op->memop;
268           /* Now print the operands.
269
270              MEMOP is the operand number at which a memory
271              address specification starts, or zero if this
272              instruction has no memory addresses.
273
274              A memory address is always two arguments.
275
276              This information allows us to determine when to
277              insert commas into the output stream as well as
278              when to insert disp[reg] expressions onto the
279              output stream.  */
280
281           for (opindex_ptr = op->operands, opnum = 1;
282                *opindex_ptr != 0;
283                opindex_ptr++, opnum++)
284             {
285               bfd_boolean square = FALSE;
286               long value;
287               int flag;
288               char *prefix;
289
290               operand = &v850_operands[*opindex_ptr];
291
292               value = get_operand_value (operand, insn, bytes_read, memaddr, info, 0, 0);
293
294               /* The first operand is always output without any
295                  special handling.
296
297                  For the following arguments:
298
299                    If memop && opnum == memop + 1, then we need '[' since
300                    we're about to output the register used in a memory
301                    reference.
302
303                    If memop && opnum == memop + 2, then we need ']' since
304                    we just finished the register in a memory reference.  We
305                    also need a ',' before this operand.
306
307                    Else we just need a comma.
308
309                    We may need to output a trailing ']' if the last operand
310                    in an instruction is the register for a memory address.
311
312                    The exception (and there's always an exception) are the
313                    "jmp" insn which needs square brackets around it's only
314                    register argument, and the clr1/not1/set1/tst1 insns
315                    which [...] around their second register argument.  */
316
317               prefix = "";
318               if (operand->flags & V850_OPERAND_BANG)
319                 {
320                   prefix = "!";
321                 }
322               else if (operand->flags & V850_OPERAND_PERCENT)
323                 {
324                   prefix = "%";
325                 }
326
327               if (opnum == 1 && opnum == memop)
328                 {
329                   info->fprintf_func (info->stream, "%s[", prefix);
330                   square = TRUE;
331                 }
332               else if (opnum > 1
333                        && (v850_operands[*(opindex_ptr - 1)].flags & V850_OPERAND_DISP) != 0
334                        && opnum == memop)
335                 {
336                   info->fprintf_func (info->stream, "%s[", prefix);
337                   square = TRUE;
338                 }
339               else if (opnum == 2
340                        && (   op->opcode == 0x00e407e0 /* clr1 */
341                            || op->opcode == 0x00e207e0 /* not1 */
342                            || op->opcode == 0x00e007e0 /* set1 */
343                            || op->opcode == 0x00e607e0 /* tst1 */
344                            ))
345                 {
346                   info->fprintf_func (info->stream, ", %s[", prefix);
347                   square = TRUE;
348                 }               
349               else if (opnum > 1)
350                 info->fprintf_func (info->stream, ", %s", prefix);
351
352               /* Extract the flags, ignoring ones which do not effect disassembly output.  */
353               flag = operand->flags & (V850_OPERAND_REG
354                                        | V850_REG_EVEN
355                                        | V850_OPERAND_EP
356                                        | V850_OPERAND_SRG
357                                        | V850E_OPERAND_REG_LIST
358                                        | V850_OPERAND_CC
359                                        | V850_OPERAND_FLOAT_CC);
360
361               switch (flag)
362                 {
363                 case V850_OPERAND_REG:  info->fprintf_func (info->stream, "%s", v850_reg_names[value]); break;
364                 case (V850_OPERAND_REG|V850_REG_EVEN):  info->fprintf_func (info->stream, "%s", v850_reg_names[value*2]); break;
365                 case V850_OPERAND_EP:   info->fprintf_func (info->stream, "ep"); break;
366                 case V850_OPERAND_SRG:  info->fprintf_func (info->stream, "%s", v850_sreg_names[value]); break;
367
368                 case V850E_OPERAND_REG_LIST:
369                   {
370                     static int list12_regs[32]   = { 30, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
371                                                      0,  0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
372                     int *regs;
373                     int i;
374                     unsigned long int mask = 0;
375                     int pc = 0;
376
377
378                     switch (operand->shift)
379                       {
380                       case 0xffe00001: regs = list12_regs; break;
381                       default:
382                         /* xgettext:c-format */
383                         fprintf (stderr, _("unknown operand shift: %x\n"), operand->shift );
384                         abort ();
385                       }
386
387                     for (i = 0; i < 32; i++)
388                       {
389                         if (value & (1 << i))
390                           {
391                             switch (regs[ i ])
392                               {
393                               default: mask |= (1 << regs[ i ]); break;
394                                 /* xgettext:c-format */
395                               case 0:  fprintf (stderr, _("unknown reg: %d\n"), i ); abort ();
396                               case -1: pc = 1; break;
397                               }
398                           }
399                       }
400
401                     info->fprintf_func (info->stream, "{");
402
403                     if (mask || pc)
404                       {
405                         if (mask)
406                           {
407                             unsigned int bit;
408                             int shown_one = 0;
409
410                             for (bit = 0; bit < 32; bit++)
411                               if (mask & (1 << bit))
412                                 {
413                                   unsigned long int first = bit;
414                                   unsigned long int last;
415
416                                   if (shown_one)
417                                     info->fprintf_func (info->stream, ", ");
418                                   else
419                                     shown_one = 1;
420
421                                   info->fprintf_func (info->stream, "%s", v850_reg_names[first]);
422
423                                   for (bit++; bit < 32; bit++)
424                                     if ((mask & (1 << bit)) == 0)
425                                       break;
426
427                                   last = bit;
428
429                                   if (last > first + 1)
430                                     {
431                                       info->fprintf_func (info->stream, " - %s", v850_reg_names[ last - 1 ]);
432                                     }
433                                 }
434                           }
435
436                         if (pc)
437                           info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
438                       }
439
440                     info->fprintf_func (info->stream, "}");
441                   }
442                   break;
443
444                 case V850_OPERAND_CC:   info->fprintf_func (info->stream, "%s", v850_cc_names[value]); break;
445                 case V850_OPERAND_FLOAT_CC:   info->fprintf_func (info->stream, "%s", v850_float_cc_names[value]); break;
446
447                 default:
448                   print_value (operand->flags, memaddr, info, value);
449                   break;
450                 }
451
452               if (square)
453                 (*info->fprintf_func) (info->stream, "]");
454             }
455
456           /* All done. */
457           break;
458         }
459     next_opcode:
460       op++;
461     }
462
463   return match;
464 }
465
466 int
467 print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
468 {
469   int status, status2, match;
470   bfd_byte buffer[8];
471   int length = 0, code_length = 0;
472   unsigned long insn = 0, insn2 = 0;
473   int target_processor;
474
475   switch (info->mach)
476     {
477     case 0:
478     default:
479       target_processor = PROCESSOR_V850;
480       break;
481
482     case bfd_mach_v850e:
483       target_processor = PROCESSOR_V850E;
484       break;
485
486     case bfd_mach_v850e1:
487       target_processor = PROCESSOR_V850E;
488       break;
489
490     case bfd_mach_v850e2:
491       target_processor = PROCESSOR_V850E2;
492       break;
493
494     case bfd_mach_v850e2v3:
495       target_processor = PROCESSOR_V850E2V3;
496       break;
497     }
498
499   status = info->read_memory_func (memaddr, buffer, 2, info);
500
501   if (status)
502     {
503       info->memory_error_func (status, memaddr, info);
504       return -1;
505     }
506
507   insn = bfd_getl16 (buffer);
508
509   status2 = info->read_memory_func (memaddr+2, buffer, 2 , info);
510
511   if (!status2)
512     {
513       insn2 = bfd_getl16 (buffer);
514       /* fprintf (stderr, "insn2 0x%08lx\n", insn2); */
515     }
516
517   /* Special case.  */
518   if (length == 0
519       && (target_processor == PROCESSOR_V850E2
520           || target_processor == PROCESSOR_V850E2V3))
521     {
522       if ((insn & 0xffff) == 0x02e0             /* jr 32bit */
523           && !status2 && (insn2 & 0x1) == 0)
524         {
525           length = 2;
526           code_length = 6;
527         }
528       else if ((insn & 0xffe0) == 0x02e0        /* jarl 32bit */
529                && !status2 && (insn2 & 0x1) == 0)
530         {
531           length = 2;
532           code_length = 6;
533         }
534       else if ((insn & 0xffe0) == 0x06e0        /* jmp 32bit */
535                && !status2 && (insn2 & 0x1) == 0)
536         {
537           length = 2;
538           code_length = 6;
539         }
540     }
541
542   if (length == 0
543       && target_processor == PROCESSOR_V850E2V3)
544     {
545       if (((insn & 0xffe0) == 0x0780            /* ld.b 23bit */
546            && !status2 && (insn2 & 0x000f) == 0x0005)
547           || ((insn & 0xffe0) == 0x07a0         /* ld.bu 23bit */
548               && !status2 && (insn2 & 0x000f) == 0x0005)
549           || ((insn & 0xffe0) == 0x0780         /* ld.h 23bit */
550               && !status2 && (insn2 & 0x000f) == 0x0007)
551           || ((insn & 0xffe0) == 0x07a0         /* ld.hu 23bit */
552               && !status2 && (insn2 & 0x000f) == 0x0007)
553           || ((insn & 0xffe0) == 0x0780         /* ld.w 23bit */
554               && !status2 && (insn2 & 0x000f) == 0x0009))
555         {
556           length = 4;
557           code_length = 6;
558         }
559       else if (((insn & 0xffe0) == 0x0780       /* st.b 23bit */
560                && !status2 && (insn2 & 0x000f) == 0x000d)
561               || ((insn & 0xffe0) == 0x07a0     /* st.h 23bit */
562                   && !status2 && (insn2 & 0x000f) == 0x000d)
563               || ((insn & 0xffe0) == 0x0780     /* st.w 23bit */
564                   && !status2 && (insn2 & 0x000f) == 0x000f))
565         {
566           length = 4;
567           code_length = 6;
568         }
569     }
570
571   if (length == 0
572       && target_processor != PROCESSOR_V850)
573     {
574       if ((insn & 0xffe0) == 0x0620)            /* 32 bit MOV */
575         {
576           length = 2;
577           code_length = 6;
578         }
579       else if ((insn & 0xffc0) == 0x0780        /* prepare {list}, imm5, imm16<<16 */
580                && !status2 && (insn2 & 0x001f) == 0x0013)
581         {
582           length = 4;
583           code_length = 6;
584         }
585       else if ((insn & 0xffc0) == 0x0780        /* prepare {list}, imm5, imm16 */
586                && !status2 && (insn2 & 0x001f) == 0x000b)
587         {
588           length = 4;
589           code_length = 6;
590         }
591       else if ((insn & 0xffc0) == 0x0780        /* prepare {list}, imm5, imm32 */
592                && !status2 && (insn2 & 0x001f) == 0x001b)
593         {
594           length = 4;
595           code_length = 8;
596         }
597     }
598
599   if (length == 4
600       || (length == 0
601           && (insn & 0x0600) == 0x0600))
602     {
603       /* This is a 4 byte insn.  */
604       status = info->read_memory_func (memaddr, buffer, 4, info);
605       if (!status)
606         {
607           insn = bfd_getl32 (buffer);
608
609           if (!length)
610             length = code_length = 4;
611         }
612     }
613
614   if (code_length > length)
615     {
616       status = info->read_memory_func (memaddr + length, buffer, code_length - length, info);
617       if (status)
618         length = 0;
619     }
620
621   if (length == 0 && !status)
622     length = code_length = 2;
623
624   if (length == 2)
625     insn &= 0xffff;
626
627   match = disassemble (memaddr, info, length, insn);
628
629   if (!match)
630     {
631       int l = 0;
632
633       status = info->read_memory_func (memaddr, buffer, code_length, info);
634
635       while (l < code_length)
636         {
637           if (code_length - l == 2)
638             {
639               insn = bfd_getl16 (buffer + l) & 0xffff;
640               info->fprintf_func (info->stream, ".short\t0x%04lx", insn);
641               l += 2;
642             }
643           else
644             {
645               insn = bfd_getl32 (buffer + l);
646               info->fprintf_func (info->stream, ".long\t0x%08lx", insn);
647               l += 4;
648             }
649         }
650     }
651
652   return code_length;
653 }