Error Buddy

Do you have an error message from your application? Then find the answer with Error Buddy. You can search over 40000 source code files and troubleshooting documents using our beta lucene/nutch search interface or if you prefer, search as normal using google. With LXR technology you can drill right down into the line of source code where it came from with full cross-referencing.

If after searching you didn't get your ideal answer, or you are still unclear what the error means, you can choose to post that question to the community forums following the link included in the search results.

corestack/ binutils-2.15/ opcodes/ d30v-dis.c [1.6]
001 /* Disassemble D30V instructions.
002    Copyright 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
003 
004 This program is free software; you can redistribute it and/or modify
005 it under the terms of the GNU General Public License as published by
006 the Free Software Foundation; either version 2 of the License, or
007 (at your option) any later version.
008 
009 This program is distributed in the hope that it will be useful,
010 but WITHOUT ANY WARRANTY; without even the implied warranty of
011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012 GNU General Public License for more details.
013 
014 You should have received a copy of the GNU General Public License
015 along with this program; if not, write to the Free Software
016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
017 
018 #include <stdio.h>
019 #include "sysdep.h"
020 #include "opcode/d30v.h"
021 #include "dis-asm.h"
022 #include "opintl.h"
023 
024 #define PC_MASK 0xFFFFFFFF
025 
026 static int lookup_opcode PARAMS ((struct d30v_insn *insn, long num, int is_long));
027 static void print_insn PARAMS ((struct disassemble_info *info, bfd_vma memaddr, long long num,
028                                  struct d30v_insn *insn, int is_long, int show_ext));
029 static int extract_value PARAMS ((long long num, struct d30v_operand *oper, int is_long));
030 
031 int
032 print_insn_d30v (memaddr, info)
033      bfd_vma memaddr;
034      struct disassemble_info *info;
035 {
036   int status, result;
037   bfd_byte buffer[12];
038   unsigned long in1, in2;
039   struct d30v_insn insn;
040   long long num;
041 
042   insn.form = (struct d30v_format *) NULL;
043 
044   info->bytes_per_line = 8;
045   info->bytes_per_chunk = 4;
046   info->display_endian = BFD_ENDIAN_BIG;
047 
048   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
049   if (status != 0)
050     {
051       (*info->memory_error_func) (status, memaddr, info);
052       return -1;
053     }
054   in1 = bfd_getb32 (buffer);
055 
056   status = (*info->read_memory_func) (memaddr + 4, buffer, 4, info);
057   if (status != 0)
058     {
059       info->bytes_per_line = 8;
060       if (!(result = lookup_opcode (&insn, in1, 0)))
061         (*info->fprintf_func) (info->stream, ".long\t0x%x", in1);
062       else
063         print_insn (info, memaddr, (long long) in1, &insn, 0, result);
064       return 4;
065     }
066   in2 = bfd_getb32 (buffer);
067 
068   if (in1 & in2 & FM01)
069     {
070       /* LONG instruction.  */
071       if (!(result = lookup_opcode (&insn, in1, 1)))
072         {
073           (*info->fprintf_func) (info->stream, ".long\t0x%x,0x%x", in1, in2);
074           return 8;
075         }
076       num = (long long) in1 << 32 | in2;
077       print_insn (info, memaddr, num, &insn, 1, result);
078     }
079   else
080     {
081       num = in1;
082       if (!(result = lookup_opcode (&insn, in1, 0)))
083         (*info->fprintf_func) (info->stream, ".long\t0x%x", in1);
084       else
085         print_insn (info, memaddr, num, &insn, 0, result);
086 
087       switch (((in1 >> 31) << 1) | (in2 >> 31))
088         {
089         case 0:
090           (*info->fprintf_func) (info->stream, "\t||\t");
091           break;
092         case 1:
093           (*info->fprintf_func) (info->stream, "\t->\t");
094           break;
095         case 2:
096           (*info->fprintf_func) (info->stream, "\t<-\t");
097         default:
098           break;
099         }
100 
101       insn.form = (struct d30v_format *) NULL;
102       num = in2;
103       if (!(result = lookup_opcode (&insn, in2, 0)))
104         (*info->fprintf_func) (info->stream, ".long\t0x%x", in2);
105       else
106         print_insn (info, memaddr, num, &insn, 0, result);
107     }
108   return 8;
109 }
110 
111 /* Return 0 if lookup fails,
112    1 if found and only one form,
113    2 if found and there are short and long forms.  */
114 
115 static int
116 lookup_opcode (insn, num, is_long)
117      struct d30v_insn *insn;
118      long num;
119      int is_long;
120 {
121   int i = 0, index;
122   struct d30v_format *f;
123   struct d30v_opcode *op = (struct d30v_opcode *) d30v_opcode_table;
124   int op1 = (num >> 25) & 0x7;
125   int op2 = (num >> 20) & 0x1f;
126   int mod = (num >> 18) & 0x3;
127 
128   /* Find the opcode.  */
129   do
130     {
131       if ((op->op1 == op1) && (op->op2 == op2))
132         break;
133       op++;
134     }
135   while (op->name);
136 
137   if (!op || !op->name)
138     return 0;
139 
140   while (op->op1 == op1 && op->op2 == op2)
141     {
142       /* Scan through all the formats for the opcode.  */
143       index = op->format[i++];
144       do
145         {
146           f = (struct d30v_format *) &d30v_format_table[index];
147           while (f->form == index)
148             {
149               if ((!is_long || f->form >= LONG) && (f->modifier == mod))
150                 {
151                   insn->form = f;
152                   break;
153                 }
154               f++;
155             }
156           if (insn->form)
157             break;
158         }
159       while ((index = op->format[i++]) != 0);
160       if (insn->form)
161         break;
162       op++;
163       i = 0;
164     }
165   if (insn->form == NULL)
166     return 0;
167 
168   insn->op = op;
169   insn->ecc = (num >> 28) & 0x7;
170   if (op->format[1])
171     return 2;
172   else
173     return 1;
174 }
175 
176 static void
177 print_insn (info, memaddr, num, insn, is_long, show_ext)
178      struct disassemble_info *info;
179      bfd_vma memaddr;
180      long long num;
181      struct d30v_insn *insn;
182      int is_long;
183      int show_ext;
184 {
185   int val, opnum, need_comma = 0;
186   struct d30v_operand *oper;
187   int i, match, opind = 0, need_paren = 0, found_control = 0;
188 
189   (*info->fprintf_func) (info->stream, "%s", insn->op->name);
190 
191   /* Check for CMP or CMPU.  */
192   if (d30v_operand_table[insn->form->operands[0]].flags & OPERAND_NAME)
193     {
194       opind++;
195       val =
196         extract_value (num,
197                        (struct d30v_operand *) &d30v_operand_table[insn->form->operands[0]],
198                        is_long);
199       (*info->fprintf_func) (info->stream, "%s", d30v_cc_names[val]);
200     }
201 
202   /* Add in ".s" or ".l".  */
203   if (show_ext == 2)
204     {
205       if (is_long)
206         (*info->fprintf_func) (info->stream, ".l");
207       else
208         (*info->fprintf_func) (info->stream, ".s");
209     }
210 
211   if (insn->ecc)
212     (*info->fprintf_func) (info->stream, "/%s", d30v_ecc_names[insn->ecc]);
213 
214   (*info->fprintf_func) (info->stream, "\t");
215 
216   while ((opnum = insn->form->operands[opind++]) != 0)
217     {
218       int bits;
219       oper = (struct d30v_operand *) &d30v_operand_table[opnum];
220       bits = oper->bits;
221       if (oper->flags & OPERAND_SHIFT)
222         bits += 3;
223 
224       if (need_comma
225           && oper->flags != OPERAND_PLUS
226           && oper->flags != OPERAND_MINUS)
227         {
228           need_comma = 0;
229           (*info->fprintf_func) (info->stream, ", ");
230         }
231 
232       if (oper->flags == OPERAND_ATMINUS)
233         {
234           (*info->fprintf_func) (info->stream, "@-");
235           continue;
236         }
237       if (oper->flags == OPERAND_MINUS)
238         {
239           (*info->fprintf_func) (info->stream, "-");
240           continue;
241         }
242       if (oper->flags == OPERAND_PLUS)
243         {
244           (*info->fprintf_func) (info->stream, "+");
245           continue;
246         }
247       if (oper->flags == OPERAND_ATSIGN)
248         {
249           (*info->fprintf_func) (info->stream, "@");
250           continue;
251         }
252       if (oper->flags == OPERAND_ATPAR)
253         {
254           (*info->fprintf_func) (info->stream, "@(");
255           need_paren = 1;
256           continue;
257         }
258 
259       if (oper->flags == OPERAND_SPECIAL)
260         continue;
261 
262       val = extract_value (num, oper, is_long);
263 
264       if (oper->flags & OPERAND_REG)
265         {
266           match = 0;
267           if (oper->flags & OPERAND_CONTROL)
268             {
269               struct d30v_operand *oper3 =
270                 (struct d30v_operand *) &d30v_operand_table[insn->form->operands[2]];
271               int id = extract_value (num, oper3, is_long);
272               found_control = 1;
273               switch (id)
274                 {
275                 case 0:
276                   val |= OPERAND_CONTROL;
277                   break;
278                 case 1:
279                 case 2:
280                   val = OPERAND_CONTROL + MAX_CONTROL_REG + id;
281                   break;
282                 case 3:
283                   val |= OPERAND_FLAG;
284                   break;
285                 default:
286                   fprintf (stderr, "illegal id (%d)\n", id);
287                 }
288             }
289           else if (oper->flags & OPERAND_ACC)
290             val |= OPERAND_ACC;
291           else if (oper->flags & OPERAND_FLAG)
292             val |= OPERAND_FLAG;
293           for (i = 0; i < reg_name_cnt (); i++)
294             {
295               if (val == pre_defined_registers[i].value)
296                 {
297                   if (pre_defined_registers[i].pname)
298                     (*info->fprintf_func)
299                       (info->stream, "%s", pre_defined_registers[i].pname);
300                   else
301                     (*info->fprintf_func)
302                       (info->stream, "%s", pre_defined_registers[i].name);
303                   match = 1;
304                   break;
305                 }
306             }
307           if (match == 0)
308             {
309               /* This would only get executed if a register was not in
310                  the register table.  */
311               (*info->fprintf_func)
312                 (info->stream, _("<unknown register %d>"), val & 0x3F);
313             }
314         }
315       /* repeati has a relocation, but its first argument is a plain
316          immediate.  OTOH instructions like djsri have a pc-relative
317          delay target, but an absolute jump target.  Therefore, a test
318          of insn->op->reloc_flag is not specific enough; we must test
319          if the actual operand we are handling now is pc-relative.  */
320       else if (oper->flags & OPERAND_PCREL)
321         {
322           int neg = 0;
323 
324           /* IMM6S3 is unsigned.  */
325           if (oper->flags & OPERAND_SIGNED || bits == 32)
326             {
327               long max;
328               max = (1 << (bits - 1));
329               if (val & max)
330                 {
331                   if (bits == 32)
332                     val = -val;
333                   else
334                     val = -val & ((1 << bits) - 1);
335                   neg = 1;
336                 }
337             }
338           if (neg)
339             {
340               (*info->fprintf_func) (info->stream, "-%x\t(", val);
341               (*info->print_address_func) ((memaddr - val) & PC_MASK, info);
342               (*info->fprintf_func) (info->stream, ")");
343             }
344           else
345             {
346               (*info->fprintf_func) (info->stream, "%x\t(", val);
347               (*info->print_address_func) ((memaddr + val) & PC_MASK, info);
348               (*info->fprintf_func) (info->stream, ")");
349             }
350         }
351       else if (insn->op->reloc_flag == RELOC_ABS)
352         {
353           (*info->print_address_func) (val, info);
354         }
355       else
356         {
357           if (oper->flags & OPERAND_SIGNED)
358             {
359               int max = (1 << (bits - 1));
360               if (val & max)
361                 {
362                   val = -val;
363                   if (bits < 32)
364                     val &= ((1 << bits) - 1);
365                   (*info->fprintf_func) (info->stream, "-");
366                 }
367             }
368           (*info->fprintf_func) (info->stream, "0x%x", val);
369         }
370       /* If there is another operand, then write a comma and space.  */
371       if (insn->form->operands[opind] && !(found_control && opind == 2))
372         need_comma = 1;
373     }
374   if (need_paren)
375     (*info->fprintf_func) (info->stream, ")");
376 }
377 
378 static int
379 extract_value (num, oper, is_long)
380      long long num;
381      struct d30v_operand *oper;
382      int is_long;
383 {
384   int val;
385   int shift = 12 - oper->position;
386   int mask = (0xFFFFFFFF >> (32 - oper->bits));
387 
388   if (is_long)
389     {
390       if (oper->bits == 32)
391         {
392           /* Piece together 32-bit constant.  */
393           val = ((num & 0x3FFFF)
394                  | ((num & 0xFF00000) >> 2)
395                  | ((num & 0x3F00000000LL) >> 6));
396         }
397       else
398         val = (num >> (32 + shift)) & mask;
399     }
400   else
401     val = (num >> shift) & mask;
402 
403   if (oper->flags & OPERAND_SHIFT)
404     val <<= 3;
405 
406   return val;
407 }

Powered by Lucene and the LXR engine.