]> Git Repo - binutils.git/blob - opcodes/v850-dis.c
x86: improve handling of insns with ambiguous operand sizes
[binutils.git] / opcodes / v850-dis.c
1 /* Disassemble V850 instructions.
2    Copyright (C) 1996-2020 Free Software Foundation, Inc.
3
4    This file is part of the GNU opcodes library.
5
6    This library is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10
11    It is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14    License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20
21
22 #include "sysdep.h"
23 #include <stdio.h>
24 #include <string.h>
25 #include "opcode/v850.h"
26 #include "disassemble.h"
27 #include "opintl.h"
28 #include "libiberty.h"
29
30 static const int v850_cacheop_codes[] =
31 {
32   0x00, 0x20, 0x40, 0x60, 0x61, 0x04, 0x06,
33   0x07, 0x24, 0x26, 0x27, 0x44, 0x64, 0x65, -1
34 };
35
36 static const int v850_prefop_codes[] =
37 { 0x00, 0x04, -1};
38
39 static void
40 print_value (int flags,
41              bfd_vma memaddr,
42              struct disassemble_info *info,
43              long value)
44 {
45   if (flags & V850_PCREL)
46     {
47       bfd_vma addr = value + memaddr;
48
49       if (flags & V850_INVERSE_PCREL)
50         addr = memaddr - value;
51       info->print_address_func (addr, info);
52     }
53   else if (flags & V850_OPERAND_DISP)
54     {
55       if (flags & V850_OPERAND_SIGNED)
56         {
57           info->fprintf_func (info->stream, "%ld", value);
58         }
59       else
60         {
61           info->fprintf_func (info->stream, "%lu", value);
62         }
63     }
64   else if ((flags & V850E_IMMEDIATE32)
65            || (flags & V850E_IMMEDIATE16HI))
66     {
67       info->fprintf_func (info->stream, "0x%lx", value);
68     }
69   else
70     {
71       if (flags & V850_OPERAND_SIGNED)
72         {
73           info->fprintf_func (info->stream, "%ld", value);
74         }
75       else
76         {
77           info->fprintf_func (info->stream, "%lu", value);
78         }
79     }
80 }
81
82 static long
83 get_operand_value (const struct v850_operand *operand,
84                    unsigned long insn,
85                    int bytes_read,
86                    bfd_vma memaddr,
87                    struct disassemble_info * info,
88                    bfd_boolean noerror,
89                    int *invalid)
90 {
91   unsigned long value;
92   bfd_byte buffer[4];
93
94   if ((operand->flags & V850E_IMMEDIATE16)
95       || (operand->flags & V850E_IMMEDIATE16HI))
96     {
97       int status = info->read_memory_func (memaddr + bytes_read, buffer, 2, info);
98
99       if (status == 0)
100         {
101           value = bfd_getl16 (buffer);
102
103           if (operand->flags & V850E_IMMEDIATE16HI)
104             value <<= 16;
105           else if (value & 0x8000)
106             value |= (-1UL << 16);
107
108           return value;
109         }
110
111       if (!noerror)
112         info->memory_error_func (status, memaddr + bytes_read, info);
113
114       return 0;
115     }
116
117   if (operand->flags & V850E_IMMEDIATE23)
118     {
119       int status = info->read_memory_func (memaddr + 2, buffer, 4, info);
120
121       if (status == 0)
122         {
123           value = bfd_getl32 (buffer);
124
125           value = (operand->extract) (value, invalid);
126
127           return value;
128         }
129
130       if (!noerror)
131         info->memory_error_func (status, memaddr + bytes_read, info);
132
133       return 0;
134     }
135
136   if (operand->flags & V850E_IMMEDIATE32)
137     {
138       int status = info->read_memory_func (memaddr + bytes_read, buffer, 4, info);
139
140       if (status == 0)
141         {
142           bytes_read += 4;
143           value = bfd_getl32 (buffer);
144
145           return value;
146         }
147
148       if (!noerror)
149         info->memory_error_func (status, memaddr + bytes_read, info);
150
151       return 0;
152     }
153
154   if (operand->extract)
155     value = (operand->extract) (insn, invalid);
156   else
157     {
158       if (operand->bits == -1)
159         value = (insn & operand->shift);
160       else
161         value = (insn >> operand->shift) & ((1ul << operand->bits) - 1);
162
163       if (operand->flags & V850_OPERAND_SIGNED)
164         {
165           unsigned long sign = 1ul << (operand->bits - 1);
166           value = (value ^ sign) - sign;
167         }
168     }
169
170   return value;
171 }
172
173 static const char *
174 get_v850_sreg_name (unsigned int reg)
175 {
176   static const char *const v850_sreg_names[] =
177     {
178      "eipc/vip/mpm", "eipsw/mpc", "fepc/tid", "fepsw/ppa", "ecr/vmecr", "psw/vmtid",
179      "sr6/fpsr/vmadr/dcc", "sr7/fpepc/dc0",
180      "sr8/fpst/vpecr/dcv1", "sr9/fpcc/vptid", "sr10/fpcfg/vpadr/spal", "sr11/spau",
181      "sr12/vdecr/ipa0l", "eiic/vdtid/ipa0u", "feic/ipa1l", "dbic/ipa1u",
182      "ctpc/ipa2l", "ctpsw/ipa2u", "dbpc/ipa3l", "dbpsw/ipa3u", "ctbp/dpa0l",
183      "dir/dpa0u", "bpc/dpa0u", "asid/dpa1l",
184      "bpav/dpa1u", "bpam/dpa2l", "bpdv/dpa2u", "bpdm/dpa3l", "eiwr/dpa3u",
185      "fewr", "dbwr", "bsel"
186     };
187
188   if (reg < ARRAY_SIZE (v850_sreg_names))
189     return v850_sreg_names[reg];
190   return _("<invalid s-reg number>");
191 }
192
193 static const char *
194 get_v850_reg_name (unsigned int reg)
195 {
196   static const char *const v850_reg_names[] =
197     {
198      "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7",
199      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
200      "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
201      "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp"
202     };
203
204   if (reg < ARRAY_SIZE (v850_reg_names))
205     return v850_reg_names[reg];
206   return _("<invalid reg number>");
207 }
208
209 static const char *
210 get_v850_vreg_name (unsigned int reg)
211 {
212   static const char *const v850_vreg_names[] =
213     {
214      "vr0", "vr1", "vr2", "vr3", "vr4", "vr5", "vr6", "vr7", "vr8", "vr9",
215      "vr10", "vr11", "vr12", "vr13", "vr14", "vr15", "vr16", "vr17", "vr18",
216      "vr19", "vr20", "vr21", "vr22", "vr23", "vr24", "vr25", "vr26", "vr27",
217      "vr28", "vr29", "vr30", "vr31"
218     };
219
220   if (reg < ARRAY_SIZE (v850_vreg_names))
221     return v850_vreg_names[reg];
222   return _("<invalid v-reg number>");
223 }
224
225 static const char *
226 get_v850_cc_name (unsigned int reg)
227 {
228   static const char *const v850_cc_names[] =
229     {
230      "v", "c/l", "z", "nh", "s/n", "t", "lt", "le",
231      "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt"
232     };
233
234   if (reg < ARRAY_SIZE (v850_cc_names))
235     return v850_cc_names[reg];
236   return _("<invalid CC-reg number>");
237 }
238
239 static const char *
240 get_v850_float_cc_name (unsigned int reg)
241 {
242   static const char *const v850_float_cc_names[] =
243     {
244      "f/t", "un/or", "eq/neq", "ueq/ogl", "olt/uge", "ult/oge", "ole/ugt", "ule/ogt",
245      "sf/st", "ngle/gle", "seq/sne", "ngl/gl", "lt/nlt", "nge/ge", "le/nle", "ngt/gt"
246     };
247
248   if (reg < ARRAY_SIZE (v850_float_cc_names))
249     return v850_float_cc_names[reg];
250   return _("<invalid float-CC-reg number>");
251 }
252
253 static const char *
254 get_v850_cacheop_name (unsigned int reg)
255 {
256   static const char *const v850_cacheop_names[] =
257     {
258      "chbii", "cibii", "cfali", "cisti", "cildi", "chbid", "chbiwbd",
259      "chbwbd", "cibid", "cibiwbd", "cibwbd", "cfald", "cistd", "cildd"
260     };
261
262   if (reg < ARRAY_SIZE (v850_cacheop_names))
263     return v850_cacheop_names[reg];
264   return _("<invalid cacheop number>");
265 }
266
267 static const char *
268 get_v850_prefop_name (unsigned int reg)
269 {
270   static const char *const v850_prefop_names[] =
271     { "prefi", "prefd" };
272
273   if (reg < ARRAY_SIZE (v850_prefop_names))
274     return v850_prefop_names[reg];
275   return _("<invalid prefop number>");
276 }
277
278 static int
279 disassemble (bfd_vma memaddr,
280              struct disassemble_info *info,
281              int bytes_read,
282              unsigned long insn)
283 {
284   struct v850_opcode *op = (struct v850_opcode *) v850_opcodes;
285   const struct v850_operand *operand;
286   int match = 0;
287   int target_processor;
288
289   switch (info->mach)
290     {
291     case 0:
292     default:
293       target_processor = PROCESSOR_V850;
294       break;
295
296     case bfd_mach_v850e:
297       target_processor = PROCESSOR_V850E;
298       break;
299
300     case bfd_mach_v850e1:
301       target_processor = PROCESSOR_V850E;
302       break;
303
304     case bfd_mach_v850e2:
305       target_processor = PROCESSOR_V850E2;
306       break;
307
308     case bfd_mach_v850e2v3:
309       target_processor = PROCESSOR_V850E2V3;
310       break;
311
312     case bfd_mach_v850e3v5:
313       target_processor = PROCESSOR_V850E3V5;
314       break;
315     }
316
317   /* If this is a two byte insn, then mask off the high bits.  */
318   if (bytes_read == 2)
319     insn &= 0xffff;
320
321   /* Find the opcode.  */
322   while (op->name)
323     {
324       if ((op->mask & insn) == op->opcode
325           && (op->processors & target_processor)
326           && !(op->processors & PROCESSOR_OPTION_ALIAS))
327         {
328           /* Code check start.  */
329           const unsigned char *opindex_ptr;
330           unsigned int opnum;
331           unsigned int memop;
332
333           for (opindex_ptr = op->operands, opnum = 1;
334                *opindex_ptr != 0;
335                opindex_ptr++, opnum++)
336             {
337               int invalid = 0;
338               long value;
339
340               operand = &v850_operands[*opindex_ptr];
341
342               value = get_operand_value (operand, insn, bytes_read, memaddr,
343                                          info, 1, &invalid);
344
345               if (invalid)
346                 goto next_opcode;
347
348               if ((operand->flags & V850_NOT_R0) && value == 0 && (op->memop) <=2)
349                 goto next_opcode;
350
351               if ((operand->flags & V850_NOT_SA) && value == 0xd)
352                 goto next_opcode;
353
354               if ((operand->flags & V850_NOT_IMM0) && value == 0)
355                 goto next_opcode;
356             }
357
358           /* Code check end.  */
359
360           match = 1;
361           (*info->fprintf_func) (info->stream, "%s\t", op->name);
362 #if 0
363           fprintf (stderr, "match: insn: %lx, mask: %lx, opcode: %lx, name: %s\n",
364                    insn, op->mask, op->opcode, op->name );
365 #endif
366
367           memop = op->memop;
368           /* Now print the operands.
369
370              MEMOP is the operand number at which a memory
371              address specification starts, or zero if this
372              instruction has no memory addresses.
373
374              A memory address is always two arguments.
375
376              This information allows us to determine when to
377              insert commas into the output stream as well as
378              when to insert disp[reg] expressions onto the
379              output stream.  */
380
381           for (opindex_ptr = op->operands, opnum = 1;
382                *opindex_ptr != 0;
383                opindex_ptr++, opnum++)
384             {
385               bfd_boolean square = FALSE;
386               long value;
387               int flag;
388               char *prefix;
389
390               operand = &v850_operands[*opindex_ptr];
391
392               value = get_operand_value (operand, insn, bytes_read, memaddr,
393                                          info, 0, 0);
394
395               /* The first operand is always output without any
396                  special handling.
397
398                  For the following arguments:
399
400                    If memop && opnum == memop + 1, then we need '[' since
401                    we're about to output the register used in a memory
402                    reference.
403
404                    If memop && opnum == memop + 2, then we need ']' since
405                    we just finished the register in a memory reference.  We
406                    also need a ',' before this operand.
407
408                    Else we just need a comma.
409
410                    We may need to output a trailing ']' if the last operand
411                    in an instruction is the register for a memory address.
412
413                    The exception (and there's always an exception) are the
414                    "jmp" insn which needs square brackets around it's only
415                    register argument, and the clr1/not1/set1/tst1 insns
416                    which [...] around their second register argument.  */
417
418               prefix = "";
419               if (operand->flags & V850_OPERAND_BANG)
420                 {
421                   prefix = "!";
422                 }
423               else if (operand->flags & V850_OPERAND_PERCENT)
424                 {
425                   prefix = "%";
426                 }
427
428               if (opnum == 1 && opnum == memop)
429                 {
430                   info->fprintf_func (info->stream, "%s[", prefix);
431                   square = TRUE;
432                 }
433               else if (   (strcmp ("stc.w", op->name) == 0
434                         || strcmp ("cache", op->name) == 0
435                         || strcmp ("pref",  op->name) == 0)
436                        && opnum == 2 && opnum == memop)
437                 {
438                   info->fprintf_func (info->stream, ", [");
439                   square = TRUE;
440                 }
441               else if (   (strcmp (op->name, "pushsp") == 0
442                         || strcmp (op->name, "popsp") == 0
443                         || strcmp (op->name, "dbpush" ) == 0)
444                        && opnum == 2)
445                 {
446                   info->fprintf_func (info->stream, "-");
447                 }
448               else if (opnum > 1
449                        && (v850_operands[*(opindex_ptr - 1)].flags
450                            & V850_OPERAND_DISP) != 0
451                        && opnum == memop)
452                 {
453                   info->fprintf_func (info->stream, "%s[", prefix);
454                   square = TRUE;
455                 }
456               else if (opnum == 2
457                        && (   op->opcode == 0x00e407e0 /* clr1 */
458                            || op->opcode == 0x00e207e0 /* not1 */
459                            || op->opcode == 0x00e007e0 /* set1 */
460                            || op->opcode == 0x00e607e0 /* tst1 */
461                            ))
462                 {
463                   info->fprintf_func (info->stream, ", %s[", prefix);
464                   square = TRUE;
465                 }
466               else if (opnum > 1)
467                 info->fprintf_func (info->stream, ", %s", prefix);
468
469               /* Extract the flags, ignoring ones which do not
470                  effect disassembly output.  */
471               flag = operand->flags & (V850_OPERAND_REG
472                                        | V850_REG_EVEN
473                                        | V850_OPERAND_EP
474                                        | V850_OPERAND_SRG
475                                        | V850E_OPERAND_REG_LIST
476                                        | V850_OPERAND_CC
477                                        | V850_OPERAND_VREG
478                                        | V850_OPERAND_CACHEOP
479                                        | V850_OPERAND_PREFOP
480                                        | V850_OPERAND_FLOAT_CC);
481
482               switch (flag)
483                 {
484                 case V850_OPERAND_REG:
485                   info->fprintf_func (info->stream, "%s", get_v850_reg_name (value));
486                   break;
487                 case (V850_OPERAND_REG|V850_REG_EVEN):
488                   info->fprintf_func (info->stream, "%s", get_v850_reg_name (value * 2));
489                   break;
490                 case V850_OPERAND_EP:
491                   info->fprintf_func (info->stream, "ep");
492                   break;
493                 case V850_OPERAND_SRG:
494                   info->fprintf_func (info->stream, "%s", get_v850_sreg_name (value));
495                   break;
496                 case V850E_OPERAND_REG_LIST:
497                   {
498                     static int list12_regs[32]   = { 30, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
499                                                      0,  0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
500                     int *regs;
501                     int i;
502                     unsigned int mask = 0;
503                     int pc = 0;
504
505                     switch (operand->shift)
506                       {
507                       case 0xffe00001: regs = list12_regs; break;
508                       default:
509                         /* xgettext:c-format */
510                         opcodes_error_handler (_("unknown operand shift: %x"),
511                                                operand->shift);
512                         abort ();
513                       }
514
515                     for (i = 0; i < 32; i++)
516                       {
517                         if (value & (1u << i))
518                           {
519                             switch (regs[ i ])
520                               {
521                               default:
522                                 mask |= (1u << regs[ i ]);
523                                 break;
524                               case 0:
525                                 /* xgettext:c-format */
526                                 opcodes_error_handler (_("unknown reg: %d"), i);
527                                 abort ();
528                                 break;
529                               case -1:
530                                 pc = 1;
531                                 break;
532                               }
533                           }
534                       }
535
536                     info->fprintf_func (info->stream, "{");
537
538                     if (mask || pc)
539                       {
540                         if (mask)
541                           {
542                             unsigned int bit;
543                             int shown_one = 0;
544
545                             for (bit = 0; bit < 32; bit++)
546                               if (mask & (1u << bit))
547                                 {
548                                   unsigned int first = bit;
549                                   unsigned int last;
550
551                                   if (shown_one)
552                                     info->fprintf_func (info->stream, ", ");
553                                   else
554                                     shown_one = 1;
555
556                                   info->fprintf_func (info->stream, "%s", get_v850_reg_name (first));
557
558                                   for (bit++; bit < 32; bit++)
559                                     if ((mask & (1u << bit)) == 0)
560                                       break;
561
562                                   last = bit;
563
564                                   if (last > first + 1)
565                                     {
566                                       info->fprintf_func (info->stream, " - %s", get_v850_reg_name (last - 1));
567                                     }
568                                 }
569                           }
570
571                         if (pc)
572                           info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
573                       }
574
575                     info->fprintf_func (info->stream, "}");
576                   }
577                   break;
578
579                 case V850_OPERAND_CC:
580                   info->fprintf_func (info->stream, "%s", get_v850_cc_name (value));
581                   break;
582
583                 case V850_OPERAND_FLOAT_CC:
584                   info->fprintf_func (info->stream, "%s", get_v850_float_cc_name (value));
585                   break;
586
587                 case V850_OPERAND_CACHEOP:
588                   {
589                     int idx;
590
591                     for (idx = 0; v850_cacheop_codes[idx] != -1; idx++)
592                       {
593                         if (value == v850_cacheop_codes[idx])
594                           {
595                             info->fprintf_func (info->stream, "%s",
596                                                 get_v850_cacheop_name (idx));
597                             goto MATCH_CACHEOP_CODE;
598                           }
599                       }
600                     info->fprintf_func (info->stream, "%d", (int) value);
601                   }
602                 MATCH_CACHEOP_CODE:
603                   break;
604
605                 case V850_OPERAND_PREFOP:
606                   {
607                     int idx;
608
609                     for (idx = 0; v850_prefop_codes[idx] != -1; idx++)
610                       {
611                         if (value == v850_prefop_codes[idx])
612                           {
613                             info->fprintf_func (info->stream, "%s",
614                                                 get_v850_prefop_name (idx));
615                             goto MATCH_PREFOP_CODE;
616                           }
617                       }
618                     info->fprintf_func (info->stream, "%d", (int) value);
619                   }
620                 MATCH_PREFOP_CODE:
621                   break;
622
623                 case V850_OPERAND_VREG:
624                   info->fprintf_func (info->stream, "%s", get_v850_vreg_name (value));
625                   break;
626
627                 default:
628                   print_value (operand->flags, memaddr, info, value);
629                   break;
630                 }
631
632               if (square)
633                 (*info->fprintf_func) (info->stream, "]");
634             }
635
636           /* All done. */
637           break;
638         }
639     next_opcode:
640       op++;
641     }
642
643   return match;
644 }
645
646 int
647 print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
648 {
649   int status, status2, match;
650   bfd_byte buffer[8];
651   int length = 0, code_length = 0;
652   unsigned long insn = 0, insn2 = 0;
653   int target_processor;
654
655   switch (info->mach)
656     {
657     case 0:
658     default:
659       target_processor = PROCESSOR_V850;
660       break;
661
662     case bfd_mach_v850e:
663       target_processor = PROCESSOR_V850E;
664       break;
665
666     case bfd_mach_v850e1:
667       target_processor = PROCESSOR_V850E;
668       break;
669
670     case bfd_mach_v850e2:
671       target_processor = PROCESSOR_V850E2;
672       break;
673
674     case bfd_mach_v850e2v3:
675       target_processor = PROCESSOR_V850E2V3;
676       break;
677
678     case bfd_mach_v850e3v5:
679       target_processor = PROCESSOR_V850E3V5;
680       break;
681     }
682
683   status = info->read_memory_func (memaddr, buffer, 2, info);
684
685   if (status)
686     {
687       info->memory_error_func (status, memaddr, info);
688       return -1;
689     }
690
691   insn = bfd_getl16 (buffer);
692
693   status2 = info->read_memory_func (memaddr+2, buffer, 2 , info);
694
695   if (!status2)
696     {
697       insn2 = bfd_getl16 (buffer);
698       /* fprintf (stderr, "insn2 0x%08lx\n", insn2); */
699     }
700
701   /* Special case.  */
702   if (length == 0
703       && ((target_processor & PROCESSOR_V850E2_UP) != 0))
704     {
705       if ((insn & 0xffff) == 0x02e0             /* jr 32bit */
706           && !status2 && (insn2 & 0x1) == 0)
707         {
708           length = 2;
709           code_length = 6;
710         }
711       else if ((insn & 0xffe0) == 0x02e0        /* jarl 32bit */
712                && !status2 && (insn2 & 0x1) == 0)
713         {
714           length = 2;
715           code_length = 6;
716         }
717       else if ((insn & 0xffe0) == 0x06e0        /* jmp 32bit */
718                && !status2 && (insn2 & 0x1) == 0)
719         {
720           length = 2;
721           code_length = 6;
722         }
723     }
724
725   if (length == 0
726       && ((target_processor & PROCESSOR_V850E3V5_UP) != 0))
727     {
728       if (   ((insn & 0xffe0) == 0x07a0         /* ld.dw 23bit (v850e3v5) */
729               && !status2 && (insn2 & 0x000f) == 0x0009)
730           || ((insn & 0xffe0) == 0x07a0         /* st.dw 23bit (v850e3v5) */
731               && !status2 && (insn2 & 0x000f) == 0x000f))
732         {
733           length = 4;
734           code_length = 6;
735         }
736     }
737
738   if (length == 0
739       && ((target_processor & PROCESSOR_V850E2V3_UP) != 0))
740     {
741       if (((insn & 0xffe0) == 0x0780            /* ld.b 23bit */
742            && !status2 && (insn2 & 0x000f) == 0x0005)
743           || ((insn & 0xffe0) == 0x07a0         /* ld.bu 23bit */
744               && !status2 && (insn2 & 0x000f) == 0x0005)
745           || ((insn & 0xffe0) == 0x0780         /* ld.h 23bit */
746               && !status2 && (insn2 & 0x000f) == 0x0007)
747           || ((insn & 0xffe0) == 0x07a0         /* ld.hu 23bit */
748               && !status2 && (insn2 & 0x000f) == 0x0007)
749           || ((insn & 0xffe0) == 0x0780         /* ld.w 23bit */
750               && !status2 && (insn2 & 0x000f) == 0x0009))
751         {
752           length = 4;
753           code_length = 6;
754         }
755       else if (((insn & 0xffe0) == 0x0780       /* st.b 23bit */
756                && !status2 && (insn2 & 0x000f) == 0x000d)
757               || ((insn & 0xffe0) == 0x07a0     /* st.h 23bit */
758                   && !status2 && (insn2 & 0x000f) == 0x000d)
759               || ((insn & 0xffe0) == 0x0780     /* st.w 23bit */
760                   && !status2 && (insn2 & 0x000f) == 0x000f))
761         {
762           length = 4;
763           code_length = 6;
764         }
765     }
766
767   if (length == 0
768       && target_processor != PROCESSOR_V850)
769     {
770       if ((insn & 0xffe0) == 0x0620)            /* 32 bit MOV */
771         {
772           length = 2;
773           code_length = 6;
774         }
775       else if ((insn & 0xffc0) == 0x0780        /* prepare {list}, imm5, imm16<<16 */
776                && !status2 && (insn2 & 0x001f) == 0x0013)
777         {
778           length = 4;
779           code_length = 6;
780         }
781       else if ((insn & 0xffc0) == 0x0780        /* prepare {list}, imm5, imm16 */
782                && !status2 && (insn2 & 0x001f) == 0x000b)
783         {
784           length = 4;
785           code_length = 6;
786         }
787       else if ((insn & 0xffc0) == 0x0780        /* prepare {list}, imm5, imm32 */
788                && !status2 && (insn2 & 0x001f) == 0x001b)
789         {
790           length = 4;
791           code_length = 8;
792         }
793     }
794
795   if (length == 4
796       || (length == 0
797           && (insn & 0x0600) == 0x0600))
798     {
799       /* This is a 4 byte insn.  */
800       status = info->read_memory_func (memaddr, buffer, 4, info);
801       if (!status)
802         {
803           insn = bfd_getl32 (buffer);
804
805           if (!length)
806             length = code_length = 4;
807         }
808     }
809
810   if (code_length > length)
811     {
812       status = info->read_memory_func (memaddr + length, buffer, code_length - length, info);
813       if (status)
814         length = 0;
815     }
816
817   if (length == 0 && !status)
818     length = code_length = 2;
819
820   if (length == 2)
821     insn &= 0xffff;
822
823   /* when the last 2 bytes of section is 0xffff, length will be 0 and cause infinitive loop */
824   if (length == 0)
825     return -1;
826
827   match = disassemble (memaddr, info, length, insn);
828
829   if (!match)
830     {
831       int l = 0;
832
833       status = info->read_memory_func (memaddr, buffer, code_length, info);
834
835       while (l < code_length)
836         {
837           if (code_length - l == 2)
838             {
839               insn = bfd_getl16 (buffer + l) & 0xffff;
840               info->fprintf_func (info->stream, ".short\t0x%04lx", insn);
841               l += 2;
842             }
843           else
844             {
845               insn = bfd_getl32 (buffer + l);
846               info->fprintf_func (info->stream, ".long\t0x%08lx", insn);
847               l += 4;
848             }
849         }
850     }
851
852   return code_length;
853 }
This page took 0.08226 seconds and 4 git commands to generate.