* config/tc-v850.c (md_assemble): Allow signed values for
[platform/upstream/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           else if (value & 0x8000)
122             value |= (-1L << 16);
123
124           return value;
125         }
126
127       if (!noerror)
128         info->memory_error_func (status, memaddr + bytes_read, info);
129
130       return 0;
131     }
132
133   if (operand->flags & V850E_IMMEDIATE23)
134     {
135       int status = info->read_memory_func (memaddr + 2, buffer, 4, info);
136
137       if (status == 0)
138         {
139           value = bfd_getl32 (buffer);
140
141           value = (operand->extract) (value, invalid);
142
143           return value;
144         }
145
146       if (!noerror)
147         info->memory_error_func (status, memaddr + bytes_read, info);
148
149       return 0;
150     }
151
152   if (operand->flags & V850E_IMMEDIATE32)
153     {
154       int status = info->read_memory_func (memaddr + bytes_read, buffer, 4, info);
155
156       if (status == 0)
157         {
158           bytes_read += 4;
159           value = bfd_getl32 (buffer);
160
161           return value;
162         }
163
164       if (!noerror)
165         info->memory_error_func (status, memaddr + bytes_read, info);
166
167       return 0;
168     }
169
170   if (operand->extract)
171     value = (operand->extract) (insn, invalid);
172   else
173     {
174       if (operand->bits == -1)
175         value = (insn & operand->shift);
176       else
177         value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
178
179       if (operand->flags & V850_OPERAND_SIGNED)
180         value = ((long)(value << (sizeof (long)*8 - operand->bits))
181                  >> (sizeof (long)*8 - operand->bits));
182     }
183
184   return value;
185 }
186
187
188 static int
189 disassemble (bfd_vma memaddr, struct disassemble_info *info, int bytes_read, unsigned long insn)
190 {
191   struct v850_opcode *op = (struct v850_opcode *)v850_opcodes;
192   const struct v850_operand *operand;
193   int match = 0;
194   int target_processor;
195
196   switch (info->mach)
197     {
198     case 0:
199     default:
200       target_processor = PROCESSOR_V850;
201       break;
202
203     case bfd_mach_v850e:
204       target_processor = PROCESSOR_V850E;
205       break;
206
207     case bfd_mach_v850e1:
208       target_processor = PROCESSOR_V850E;
209       break;
210
211     case bfd_mach_v850e2:
212       target_processor = PROCESSOR_V850E2;
213       break;
214
215     case bfd_mach_v850e2v3:
216       target_processor = PROCESSOR_V850E2V3;
217       break;
218     }
219
220   /* If this is a two byte insn, then mask off the high bits.  */
221   if (bytes_read == 2)
222     insn &= 0xffff;
223
224   /* Find the opcode.  */
225   while (op->name)
226     {
227       if ((op->mask & insn) == op->opcode
228           && (op->processors & target_processor)
229           && !(op->processors & PROCESSOR_OPTION_ALIAS))
230         {
231           /* Code check start.  */
232           const unsigned char *opindex_ptr;
233           unsigned int opnum;
234           unsigned int memop;
235
236           for (opindex_ptr = op->operands, opnum = 1;
237                *opindex_ptr != 0;
238                opindex_ptr++, opnum++)
239             {
240               int invalid = 0;
241               long value;
242
243               operand = &v850_operands[*opindex_ptr];
244
245               value = get_operand_value (operand, insn, bytes_read, memaddr, info, 1, &invalid);
246
247               if (invalid)
248                 goto next_opcode;
249
250               if ((operand->flags & V850_NOT_R0) && value == 0 && (op->memop) <=2)
251                 goto next_opcode;
252
253               if ((operand->flags & V850_NOT_SA) && value == 0xd)
254                 goto next_opcode;
255
256               if ((operand->flags & V850_NOT_IMM0) && value == 0)
257                 goto next_opcode;
258             }
259
260           /* Code check end.  */
261
262           match = 1;
263           (*info->fprintf_func) (info->stream, "%s\t", op->name);
264 #if 0
265           fprintf (stderr, "match: insn: %lx, mask: %lx, opcode: %lx, name: %s\n",
266                    insn, op->mask, op->opcode, op->name );
267 #endif
268
269           memop = op->memop;
270           /* Now print the operands.
271
272              MEMOP is the operand number at which a memory
273              address specification starts, or zero if this
274              instruction has no memory addresses.
275
276              A memory address is always two arguments.
277
278              This information allows us to determine when to
279              insert commas into the output stream as well as
280              when to insert disp[reg] expressions onto the
281              output stream.  */
282
283           for (opindex_ptr = op->operands, opnum = 1;
284                *opindex_ptr != 0;
285                opindex_ptr++, opnum++)
286             {
287               bfd_boolean square = FALSE;
288               long value;
289               int flag;
290               char *prefix;
291
292               operand = &v850_operands[*opindex_ptr];
293
294               value = get_operand_value (operand, insn, bytes_read, memaddr, info, 0, 0);
295
296               /* The first operand is always output without any
297                  special handling.
298
299                  For the following arguments:
300
301                    If memop && opnum == memop + 1, then we need '[' since
302                    we're about to output the register used in a memory
303                    reference.
304
305                    If memop && opnum == memop + 2, then we need ']' since
306                    we just finished the register in a memory reference.  We
307                    also need a ',' before this operand.
308
309                    Else we just need a comma.
310
311                    We may need to output a trailing ']' if the last operand
312                    in an instruction is the register for a memory address.
313
314                    The exception (and there's always an exception) are the
315                    "jmp" insn which needs square brackets around it's only
316                    register argument, and the clr1/not1/set1/tst1 insns
317                    which [...] around their second register argument.  */
318
319               prefix = "";
320               if (operand->flags & V850_OPERAND_BANG)
321                 {
322                   prefix = "!";
323                 }
324               else if (operand->flags & V850_OPERAND_PERCENT)
325                 {
326                   prefix = "%";
327                 }
328
329               if (opnum == 1 && opnum == memop)
330                 {
331                   info->fprintf_func (info->stream, "%s[", prefix);
332                   square = TRUE;
333                 }
334               else if (opnum > 1
335                        && (v850_operands[*(opindex_ptr - 1)].flags & V850_OPERAND_DISP) != 0
336                        && opnum == memop)
337                 {
338                   info->fprintf_func (info->stream, "%s[", prefix);
339                   square = TRUE;
340                 }
341               else if (opnum == 2
342                        && (   op->opcode == 0x00e407e0 /* clr1 */
343                            || op->opcode == 0x00e207e0 /* not1 */
344                            || op->opcode == 0x00e007e0 /* set1 */
345                            || op->opcode == 0x00e607e0 /* tst1 */
346                            ))
347                 {
348                   info->fprintf_func (info->stream, ", %s[", prefix);
349                   square = TRUE;
350                 }               
351               else if (opnum > 1)
352                 info->fprintf_func (info->stream, ", %s", prefix);
353
354               /* Extract the flags, ignoring ones which do not effect disassembly output.  */
355               flag = operand->flags & (V850_OPERAND_REG
356                                        | V850_REG_EVEN
357                                        | V850_OPERAND_EP
358                                        | V850_OPERAND_SRG
359                                        | V850E_OPERAND_REG_LIST
360                                        | V850_OPERAND_CC
361                                        | V850_OPERAND_FLOAT_CC);
362
363               switch (flag)
364                 {
365                 case V850_OPERAND_REG:  info->fprintf_func (info->stream, "%s", v850_reg_names[value]); break;
366                 case (V850_OPERAND_REG|V850_REG_EVEN):  info->fprintf_func (info->stream, "%s", v850_reg_names[value*2]); break;
367                 case V850_OPERAND_EP:   info->fprintf_func (info->stream, "ep"); break;
368                 case V850_OPERAND_SRG:  info->fprintf_func (info->stream, "%s", v850_sreg_names[value]); break;
369
370                 case V850E_OPERAND_REG_LIST:
371                   {
372                     static int list12_regs[32]   = { 30, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
373                                                      0,  0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
374                     int *regs;
375                     int i;
376                     unsigned long int mask = 0;
377                     int pc = 0;
378
379
380                     switch (operand->shift)
381                       {
382                       case 0xffe00001: regs = list12_regs; break;
383                       default:
384                         /* xgettext:c-format */
385                         fprintf (stderr, _("unknown operand shift: %x\n"), operand->shift );
386                         abort ();
387                       }
388
389                     for (i = 0; i < 32; i++)
390                       {
391                         if (value & (1 << i))
392                           {
393                             switch (regs[ i ])
394                               {
395                               default: mask |= (1 << regs[ i ]); break;
396                                 /* xgettext:c-format */
397                               case 0:  fprintf (stderr, _("unknown reg: %d\n"), i ); abort ();
398                               case -1: pc = 1; break;
399                               }
400                           }
401                       }
402
403                     info->fprintf_func (info->stream, "{");
404
405                     if (mask || pc)
406                       {
407                         if (mask)
408                           {
409                             unsigned int bit;
410                             int shown_one = 0;
411
412                             for (bit = 0; bit < 32; bit++)
413                               if (mask & (1 << bit))
414                                 {
415                                   unsigned long int first = bit;
416                                   unsigned long int last;
417
418                                   if (shown_one)
419                                     info->fprintf_func (info->stream, ", ");
420                                   else
421                                     shown_one = 1;
422
423                                   info->fprintf_func (info->stream, "%s", v850_reg_names[first]);
424
425                                   for (bit++; bit < 32; bit++)
426                                     if ((mask & (1 << bit)) == 0)
427                                       break;
428
429                                   last = bit;
430
431                                   if (last > first + 1)
432                                     {
433                                       info->fprintf_func (info->stream, " - %s", v850_reg_names[ last - 1 ]);
434                                     }
435                                 }
436                           }
437
438                         if (pc)
439                           info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
440                       }
441
442                     info->fprintf_func (info->stream, "}");
443                   }
444                   break;
445
446                 case V850_OPERAND_CC:   info->fprintf_func (info->stream, "%s", v850_cc_names[value]); break;
447                 case V850_OPERAND_FLOAT_CC:   info->fprintf_func (info->stream, "%s", v850_float_cc_names[value]); break;
448
449                 default:
450                   print_value (operand->flags, memaddr, info, value);
451                   break;
452                 }
453
454               if (square)
455                 (*info->fprintf_func) (info->stream, "]");
456             }
457
458           /* All done. */
459           break;
460         }
461     next_opcode:
462       op++;
463     }
464
465   return match;
466 }
467
468 int
469 print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
470 {
471   int status, status2, match;
472   bfd_byte buffer[8];
473   int length = 0, code_length = 0;
474   unsigned long insn = 0, insn2 = 0;
475   int target_processor;
476
477   switch (info->mach)
478     {
479     case 0:
480     default:
481       target_processor = PROCESSOR_V850;
482       break;
483
484     case bfd_mach_v850e:
485       target_processor = PROCESSOR_V850E;
486       break;
487
488     case bfd_mach_v850e1:
489       target_processor = PROCESSOR_V850E;
490       break;
491
492     case bfd_mach_v850e2:
493       target_processor = PROCESSOR_V850E2;
494       break;
495
496     case bfd_mach_v850e2v3:
497       target_processor = PROCESSOR_V850E2V3;
498       break;
499     }
500
501   status = info->read_memory_func (memaddr, buffer, 2, info);
502
503   if (status)
504     {
505       info->memory_error_func (status, memaddr, info);
506       return -1;
507     }
508
509   insn = bfd_getl16 (buffer);
510
511   status2 = info->read_memory_func (memaddr+2, buffer, 2 , info);
512
513   if (!status2)
514     {
515       insn2 = bfd_getl16 (buffer);
516       /* fprintf (stderr, "insn2 0x%08lx\n", insn2); */
517     }
518
519   /* Special case.  */
520   if (length == 0
521       && (target_processor == PROCESSOR_V850E2
522           || target_processor == PROCESSOR_V850E2V3))
523     {
524       if ((insn & 0xffff) == 0x02e0             /* jr 32bit */
525           && !status2 && (insn2 & 0x1) == 0)
526         {
527           length = 2;
528           code_length = 6;
529         }
530       else if ((insn & 0xffe0) == 0x02e0        /* jarl 32bit */
531                && !status2 && (insn2 & 0x1) == 0)
532         {
533           length = 2;
534           code_length = 6;
535         }
536       else if ((insn & 0xffe0) == 0x06e0        /* jmp 32bit */
537                && !status2 && (insn2 & 0x1) == 0)
538         {
539           length = 2;
540           code_length = 6;
541         }
542     }
543
544   if (length == 0
545       && target_processor == PROCESSOR_V850E2V3)
546     {
547       if (((insn & 0xffe0) == 0x0780            /* ld.b 23bit */
548            && !status2 && (insn2 & 0x000f) == 0x0005)
549           || ((insn & 0xffe0) == 0x07a0         /* ld.bu 23bit */
550               && !status2 && (insn2 & 0x000f) == 0x0005)
551           || ((insn & 0xffe0) == 0x0780         /* ld.h 23bit */
552               && !status2 && (insn2 & 0x000f) == 0x0007)
553           || ((insn & 0xffe0) == 0x07a0         /* ld.hu 23bit */
554               && !status2 && (insn2 & 0x000f) == 0x0007)
555           || ((insn & 0xffe0) == 0x0780         /* ld.w 23bit */
556               && !status2 && (insn2 & 0x000f) == 0x0009))
557         {
558           length = 4;
559           code_length = 6;
560         }
561       else if (((insn & 0xffe0) == 0x0780       /* st.b 23bit */
562                && !status2 && (insn2 & 0x000f) == 0x000d)
563               || ((insn & 0xffe0) == 0x07a0     /* st.h 23bit */
564                   && !status2 && (insn2 & 0x000f) == 0x000d)
565               || ((insn & 0xffe0) == 0x0780     /* st.w 23bit */
566                   && !status2 && (insn2 & 0x000f) == 0x000f))
567         {
568           length = 4;
569           code_length = 6;
570         }
571     }
572
573   if (length == 0
574       && target_processor != PROCESSOR_V850)
575     {
576       if ((insn & 0xffe0) == 0x0620)            /* 32 bit MOV */
577         {
578           length = 2;
579           code_length = 6;
580         }
581       else if ((insn & 0xffc0) == 0x0780        /* prepare {list}, imm5, imm16<<16 */
582                && !status2 && (insn2 & 0x001f) == 0x0013)
583         {
584           length = 4;
585           code_length = 6;
586         }
587       else if ((insn & 0xffc0) == 0x0780        /* prepare {list}, imm5, imm16 */
588                && !status2 && (insn2 & 0x001f) == 0x000b)
589         {
590           length = 4;
591           code_length = 6;
592         }
593       else if ((insn & 0xffc0) == 0x0780        /* prepare {list}, imm5, imm32 */
594                && !status2 && (insn2 & 0x001f) == 0x001b)
595         {
596           length = 4;
597           code_length = 8;
598         }
599     }
600
601   if (length == 4
602       || (length == 0
603           && (insn & 0x0600) == 0x0600))
604     {
605       /* This is a 4 byte insn.  */
606       status = info->read_memory_func (memaddr, buffer, 4, info);
607       if (!status)
608         {
609           insn = bfd_getl32 (buffer);
610
611           if (!length)
612             length = code_length = 4;
613         }
614     }
615
616   if (code_length > length)
617     {
618       status = info->read_memory_func (memaddr + length, buffer, code_length - length, info);
619       if (status)
620         length = 0;
621     }
622
623   if (length == 0 && !status)
624     length = code_length = 2;
625
626   if (length == 2)
627     insn &= 0xffff;
628
629   match = disassemble (memaddr, info, length, insn);
630
631   if (!match)
632     {
633       int l = 0;
634
635       status = info->read_memory_func (memaddr, buffer, code_length, info);
636
637       while (l < code_length)
638         {
639           if (code_length - l == 2)
640             {
641               insn = bfd_getl16 (buffer + l) & 0xffff;
642               info->fprintf_func (info->stream, ".short\t0x%04lx", insn);
643               l += 2;
644             }
645           else
646             {
647               insn = bfd_getl32 (buffer + l);
648               info->fprintf_func (info->stream, ".long\t0x%08lx", insn);
649               l += 4;
650             }
651         }
652     }
653
654   return code_length;
655 }