* mn10300.igen (OP_F0F4): Need to load contents of register AN0
[platform/upstream/binutils.git] / gdb / arm-tdep.c
1 /* Target-dependent code for the Acorn Risc Machine, for GDB, the GNU Debugger.
2    Copyright (C) 1988, 1989, 1991, 1992, 1993, 1995, 1996
3    Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program 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 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #include "defs.h"
22 #include "frame.h"
23 #include "inferior.h"
24 #include "gdbcmd.h"
25
26 /* Set to true if the 32-bit mode is in use. */
27
28 int arm_apcs_32 = 1;
29
30 CORE_ADDR
31 arm_addr_bits_remove (val)
32 CORE_ADDR val;
33 {
34   return (val & (arm_apcs_32 ? 0xfffffffc : 0x03fffffc));
35 }
36
37 CORE_ADDR
38 arm_saved_pc_after_call (frame)
39      struct frame_info *frame;
40 {
41   return ADDR_BITS_REMOVE (read_register (LR_REGNUM));
42 }
43
44 /* APCS (ARM procedure call standard) defines the following prologue:
45
46    mov          ip, sp
47   [stmfd        sp!, {a1,a2,a3,a4}]
48    stmfd        sp!, {...,fp,ip,lr,pc}
49   [stfe         f7, [sp, #-12]!]
50   [stfe         f6, [sp, #-12]!]
51   [stfe         f5, [sp, #-12]!]
52   [stfe         f4, [sp, #-12]!]
53    sub          fp, ip, #nn     // nn == 20 or 4 depending on second ins
54 */
55
56 CORE_ADDR
57 arm_skip_prologue (pc)
58 CORE_ADDR pc;
59 {
60   unsigned long inst;
61   CORE_ADDR skip_pc = pc;
62
63   inst = read_memory_integer (skip_pc, 4);
64   if (inst != 0xe1a0c00d)  /* mov ip, sp */
65     return pc;
66
67   skip_pc += 4;
68   inst = read_memory_integer (skip_pc, 4);
69   if ((inst & 0xfffffff0) == 0xe92d0000)  /* stmfd sp!,{a1,a2,a3,a4}  */
70     {
71       skip_pc += 4;
72       inst = read_memory_integer (skip_pc, 4);
73     }
74
75   if ((inst & 0xfffff800) != 0xe92dd800)  /* stmfd sp!,{...,fp,ip,lr,pc} */
76     return pc;
77
78   skip_pc += 4;
79   inst = read_memory_integer (skip_pc, 4);
80
81   /* Any insns after this point may float into the code, if it makes
82      for better instruction scheduling, so we skip them only if
83      we find them, but still consdier the function to be frame-ful  */
84
85   /* We may have either one sfmfd instruction here, or several stfe insns,
86      depending on the version of floating point code we support.  */
87   if ((inst & 0xffbf0fff) == 0xec2d0200)  /* sfmfd fn, <cnt>, [sp]! */
88     {
89       skip_pc += 4;
90       inst = read_memory_integer (skip_pc, 4);
91     }
92   else
93     {
94       while ((inst & 0xffff8fff) == 0xed6d0103) /* stfe fn, [sp, #-12]! */
95         {
96           skip_pc += 4;
97           inst = read_memory_integer (skip_pc, 4);
98         }
99     }
100
101   if ((inst & 0xfffff000) == 0xe24cb000) /* sub fp, ip, #nn */
102     skip_pc += 4;
103
104   return skip_pc;
105 }
106
107 void
108 arm_frame_find_saved_regs (frame_info, saved_regs_addr)
109      struct frame_info *frame_info;
110      struct frame_saved_regs *saved_regs_addr;
111 {
112   register int regnum;
113   register int frame;
114   register int next_addr;
115   register int return_data_save;
116   register int saved_register_mask;
117
118   memset (saved_regs_addr, '\0', sizeof (*saved_regs_addr));
119   frame = frame_info->frame;
120   return_data_save = read_memory_integer (frame, 4) & 0x03fffffc - 12;
121   saved_register_mask = read_memory_integer (return_data_save, 4);
122   next_addr = frame - 12;
123   for (regnum = 4; regnum < 10; regnum++)
124     if (saved_register_mask & (1 << regnum))
125       {
126         next_addr -= 4;
127         saved_regs_addr->regs[regnum] = next_addr;
128       }
129   if (read_memory_integer (return_data_save + 4, 4) == 0xed6d7103)
130     {
131       next_addr -= 12;
132       saved_regs_addr->regs[F0_REGNUM + 7] = next_addr;
133     }
134   if (read_memory_integer (return_data_save + 8, 4) == 0xed6d6103)
135     {
136       next_addr -= 12;
137       saved_regs_addr->regs[F0_REGNUM + 6] = next_addr;
138     }
139   if (read_memory_integer (return_data_save + 12, 4) == 0xed6d5103)
140     {
141       next_addr -= 12;
142       saved_regs_addr->regs[F0_REGNUM + 5] = next_addr;
143     }
144   if (read_memory_integer(return_data_save + 16, 4) == 0xed6d4103)
145     {
146       next_addr -= 12;
147       saved_regs_addr->regs[F0_REGNUM + 4] = next_addr;
148     }
149   saved_regs_addr->regs[SP_REGNUM] = next_addr;
150   saved_regs_addr->regs[PC_REGNUM] = frame - 4;
151   saved_regs_addr->regs[PS_REGNUM] = frame - 4;
152   saved_regs_addr->regs[FP_REGNUM] = frame - 12;
153 }
154
155 void
156 arm_push_dummy_frame ()
157 {
158   register CORE_ADDR sp = read_register (SP_REGNUM);
159   register int regnum;
160
161   /* opcode for ldmdb fp,{v1-v6,fp,ip,lr,pc}^ */
162   sp = push_word (sp, 0xe92dbf0); /* dummy return_data_save ins */
163   /* push a pointer to the dummy instruction minus 12 */
164   sp = push_word (sp, read_register (SP_REGNUM) - 16);
165   sp = push_word (sp, read_register (PS_REGNUM));
166   sp = push_word (sp, read_register (SP_REGNUM));
167   sp = push_word (sp, read_register (FP_REGNUM));
168   for (regnum = 9; regnum >= 4; regnum --)
169     sp = push_word (sp, read_register (regnum));
170   write_register (FP_REGNUM, read_register (SP_REGNUM) - 8);
171   write_register (SP_REGNUM, sp);
172 }
173
174 void
175 arm_pop_frame ()
176 {
177   register CORE_ADDR fp = read_register (FP_REGNUM);
178   register unsigned long return_data_save =
179     read_memory_integer (ADDR_BITS_REMOVE (read_memory_integer (fp, 4)) - 12,
180                          4);
181   register int regnum;
182
183   write_register (PS_REGNUM, read_memory_integer (fp - 4, 4));
184   write_register (PC_REGNUM, ADDR_BITS_REMOVE (read_register (PS_REGNUM)));
185   write_register (SP_REGNUM, read_memory_integer (fp - 8, 4));
186   write_register (FP_REGNUM, read_memory_integer (fp - 12, 4));
187   fp -= 12;
188   for (regnum = 9; regnum >= 4; regnum--)
189     {
190       if (return_data_save & (1 << regnum))
191         {
192           fp -= 4;
193           write_register (regnum, read_memory_integer (fp, 4));
194         }
195     }
196   flush_cached_frames ();
197 }
198
199 static void
200 print_fpu_flags (flags)
201 int flags;
202 {
203     if (flags & (1 << 0)) fputs ("IVO ", stdout);
204     if (flags & (1 << 1)) fputs ("DVZ ", stdout);
205     if (flags & (1 << 2)) fputs ("OFL ", stdout);
206     if (flags & (1 << 3)) fputs ("UFL ", stdout);
207     if (flags & (1 << 4)) fputs ("INX ", stdout);
208     putchar ('\n');
209 }
210
211 void
212 arm_float_info ()
213 {
214     register unsigned long status = read_register (FPS_REGNUM);
215     int type;
216
217     type = (status >> 24) & 127;
218     printf ("%s FPU type %d\n",
219             (status & (1<<31)) ? "Hardware" : "Software",
220             type);
221     fputs ("mask: ", stdout);
222     print_fpu_flags (status >> 16);
223     fputs ("flags: ", stdout);
224     print_fpu_flags (status);
225 }
226
227 static void
228 arm_othernames ()
229 {
230   static int toggle;
231   static char *original[] = ORIGINAL_REGISTER_NAMES;
232   static char *extra_crispy[] = ADDITIONAL_REGISTER_NAMES;
233
234   memcpy (reg_names, toggle ? extra_crispy : original, sizeof(original));
235   toggle = !toggle;
236 }
237
238 /* FIXME:  Fill in with the 'right thing', see asm 
239    template in arm-convert.s */
240
241 void 
242 convert_from_extended (ptr, dbl)
243 void *ptr;
244 double *dbl;
245 {
246   *dbl = *(double*)ptr;
247 }
248
249 void 
250 convert_to_extended (dbl, ptr)
251 void *ptr;
252 double *dbl;
253 {
254   *(double*)ptr = *dbl;
255 }
256
257 int
258 arm_nullified_insn (inst)
259      unsigned long inst;
260 {
261   unsigned long cond = inst & 0xf0000000;
262   unsigned long status_reg;
263
264   if (cond == INST_AL || cond == INST_NV)
265     return 0;
266
267   status_reg = read_register (PS_REGNUM);
268
269   switch (cond)
270     {
271     case INST_EQ:
272       return ((status_reg & FLAG_Z) == 0);
273     case INST_NE:
274       return ((status_reg & FLAG_Z) != 0);
275     case INST_CS:
276       return ((status_reg & FLAG_C) == 0);
277     case INST_CC:
278       return ((status_reg & FLAG_C) != 0);
279     case INST_MI:
280       return ((status_reg & FLAG_N) == 0);
281     case INST_PL:
282       return ((status_reg & FLAG_N) != 0);
283     case INST_VS:
284       return ((status_reg & FLAG_V) == 0);
285     case INST_VC:
286       return ((status_reg & FLAG_V) != 0);
287     case INST_HI:
288       return ((status_reg & (FLAG_C | FLAG_Z)) != FLAG_C);
289     case INST_LS:
290       return (((status_reg & (FLAG_C | FLAG_Z)) ^ FLAG_C) == 0);
291     case INST_GE:
292       return (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0));
293     case INST_LT:
294       return (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0));
295     case INST_GT:
296       return (((status_reg & FLAG_Z) != 0) ||
297               (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0)));
298     case INST_LE:
299       return (((status_reg & FLAG_Z) == 0) &&
300               (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0)));
301     }
302   return 0;
303 }
304
305 #define submask(x) ((1L << ((x) + 1)) - 1)
306 #define bit(obj,st) (((obj) & (1L << (st))) >> st)
307 #define bits(obj,st,fn) \
308   (((obj) & submask (fn) & ~ submask ((st) - 1)) >> (st))
309 #define sbits(obj,st,fn) \
310   ((long) (bits(obj,st,fn) | ((long) bit(obj,fn) * ~ submask (fn - st))))
311 #define BranchDest(addr,instr) \
312   ((CORE_ADDR) (((long) (addr)) + 8 + (sbits (instr, 0, 23) << 2)))
313 #define ARM_PC_32 1
314
315 static unsigned long
316 shifted_reg_val (inst, carry, pc_val)
317      unsigned long inst;
318      int carry;
319      unsigned long pc_val;
320 {
321   unsigned long res, shift;
322   int rm = bits (inst, 0, 3);
323   unsigned long shifttype = bits (inst, 5, 6);
324  
325   if (bit(inst, 4))
326     {
327       int rs = bits (inst, 8, 11);
328       shift = (rs == 15 ? pc_val + 8 : read_register (rs)) & 0xFF;
329     }
330   else
331     shift = bits (inst, 7, 11);
332  
333   res = (rm == 15 
334          ? ((pc_val | (ARM_PC_32 ? 0 : read_register (PS_REGNUM)))
335             + (bit (inst, 4) ? 12 : 8)) 
336          : read_register (rm));
337
338   switch (shifttype)
339     {
340     case 0: /* LSL */
341       res = shift >= 32 ? 0 : res << shift;
342       break;
343       
344     case 1: /* LSR */
345       res = shift >= 32 ? 0 : res >> shift;
346       break;
347
348     case 2: /* ASR */
349       if (shift >= 32) shift = 31;
350       res = ((res & 0x80000000L)
351              ? ~((~res) >> shift) : res >> shift);
352       break;
353
354     case 3: /* ROR/RRX */
355       shift &= 31;
356       if (shift == 0)
357         res = (res >> 1) | (carry ? 0x80000000L : 0);
358       else
359         res = (res >> shift) | (res << (32-shift));
360       break;
361     }
362
363   return res & 0xffffffff;
364 }
365
366
367 CORE_ADDR
368 arm_get_next_pc (pc)
369      CORE_ADDR pc;
370 {
371   unsigned long pc_val = (unsigned long) pc;
372   unsigned long this_instr = read_memory_integer (pc, 4);
373   unsigned long status = read_register (PS_REGNUM);
374   CORE_ADDR nextpc = (CORE_ADDR) (pc_val + 4);  /* Default case */
375
376   if (! arm_nullified_insn (this_instr))
377     {
378       switch (bits(this_instr, 24, 27))
379         {
380         case 0x0: case 0x1: /* data processing */
381         case 0x2: case 0x3:
382           {
383             unsigned long operand1, operand2, result = 0;
384             unsigned long rn;
385             int c;
386  
387             if (bits(this_instr, 12, 15) != 15)
388               break;
389
390             if (bits (this_instr, 22, 25) == 0
391                 && bits (this_instr, 4, 7) == 9)  /* multiply */
392               error ("Illegal update to pc in instruction");
393
394             /* Multiply into PC */
395             c = (status & FLAG_C) ? 1 : 0;
396             rn = bits (this_instr, 16, 19);
397             operand1 = (rn == 15) ? pc_val + 8 : read_register (rn);
398  
399             if (bit (this_instr, 25))
400               {
401                 unsigned long immval = bits (this_instr, 0, 7);
402                 unsigned long rotate = 2 * bits (this_instr, 8, 11);
403                 operand2 = ((immval >> rotate) | (immval << (32-rotate))
404                             & 0xffffffff);
405               }
406             else  /* operand 2 is a shifted register */
407               operand2 = shifted_reg_val (this_instr, c, pc_val);
408  
409             switch (bits (this_instr, 21, 24))
410               {
411               case 0x0: /*and*/
412                 result = operand1 & operand2;
413                 break;
414
415               case 0x1: /*eor*/
416                 result = operand1 ^ operand2;
417                 break;
418
419               case 0x2: /*sub*/
420                 result = operand1 - operand2;
421                 break;
422
423               case 0x3: /*rsb*/
424                 result = operand2 - operand1;
425                 break;
426
427               case 0x4:  /*add*/
428                 result = operand1 + operand2;
429                 break;
430
431               case 0x5: /*adc*/
432                 result = operand1 + operand2 + c;
433                 break;
434
435               case 0x6: /*sbc*/
436                 result = operand1 - operand2 + c;
437                 break;
438
439               case 0x7: /*rsc*/
440                 result = operand2 - operand1 + c;
441                 break;
442
443               case 0x8: case 0x9: case 0xa: case 0xb: /* tst, teq, cmp, cmn */
444                 result = (unsigned long) nextpc;
445                 break;
446
447               case 0xc: /*orr*/
448                 result = operand1 | operand2;
449                 break;
450
451               case 0xd: /*mov*/
452                 /* Always step into a function.  */
453                 result = operand2;
454                 break;
455
456               case 0xe: /*bic*/
457                 result = operand1 & ~operand2;
458                 break;
459
460               case 0xf: /*mvn*/
461                 result = ~operand2;
462                 break;
463               }
464             nextpc = (CORE_ADDR) ADDR_BITS_REMOVE (result);
465
466             if (nextpc == pc)
467               error ("Infinite loop detected");
468             break;
469           }
470  
471         case 0x4: case 0x5: /* data transfer */
472         case 0x6: case 0x7:
473           if (bit (this_instr, 20))
474             {
475               /* load */
476               if (bits (this_instr, 12, 15) == 15)
477                 {
478                   /* rd == pc */
479                   unsigned long  rn;
480                   unsigned long base;
481  
482                   if (bit (this_instr, 22))
483                     error ("Illegal update to pc in instruction");
484
485                   /* byte write to PC */
486                   rn = bits (this_instr, 16, 19);
487                   base = (rn == 15) ? pc_val + 8 : read_register (rn);
488                   if (bit (this_instr, 24))
489                     {
490                       /* pre-indexed */
491                       int c = (status & FLAG_C) ? 1 : 0;
492                       unsigned long offset =
493                         (bit (this_instr, 25)
494                          ? shifted_reg_val (this_instr, c, pc_val)
495                          : bits (this_instr, 0, 11));
496
497                       if (bit (this_instr, 23))
498                         base += offset;
499                       else
500                         base -= offset;
501                     }
502                   nextpc = (CORE_ADDR) read_memory_integer ((CORE_ADDR) base, 
503                                                             4);
504  
505                   nextpc = ADDR_BITS_REMOVE (nextpc);
506
507                   if (nextpc == pc)
508                     error ("Infinite loop detected");
509                 }
510             }
511           break;
512  
513         case 0x8: case 0x9: /* block transfer */
514           if (bit (this_instr, 20))
515             {
516               /* LDM */
517               if (bit (this_instr, 15))
518                 {
519                   /* loading pc */
520                   int offset = 0;
521
522                   if (bit (this_instr, 23))
523                     {
524                       /* up */
525                       unsigned long reglist = bits (this_instr, 0, 14);
526                       unsigned long regbit;
527
528                       for (; reglist != 0; reglist &= ~regbit)
529                         {
530                           regbit = reglist & (-reglist);
531                           offset += 4;
532                         }
533
534                       if (bit (this_instr, 24)) /* pre */
535                         offset += 4;
536                     }
537                   else if (bit (this_instr, 24))
538                     offset = -4;
539  
540                   {
541                     unsigned long rn_val = 
542                       read_register (bits (this_instr, 16, 19));
543                     nextpc =
544                       (CORE_ADDR) read_memory_integer ((CORE_ADDR) (rn_val
545                                                                     + offset),
546                                                        4);
547                   }
548                   nextpc = ADDR_BITS_REMOVE (nextpc);
549                   if (nextpc == pc)
550                     error ("Infinite loop detected");
551                 }
552             }
553           break;
554  
555         case 0xb:           /* branch & link */
556         case 0xa:           /* branch */
557           {
558             nextpc = BranchDest (pc, this_instr);
559
560             nextpc = ADDR_BITS_REMOVE (nextpc);
561             if (nextpc == pc)
562               error ("Infinite loop detected");
563             break;
564           }
565  
566         case 0xc: case 0xd:
567         case 0xe:           /* coproc ops */
568         case 0xf:           /* SWI */
569           break;
570
571         default:
572           fprintf (stderr, "Bad bit-field extraction\n");
573           return (pc);
574         }
575     }
576
577   return nextpc;
578 }
579
580 void
581 _initialize_arm_tdep ()
582 {
583   tm_print_insn = print_insn_little_arm;
584
585   add_com ("othernames", class_obscure, arm_othernames,
586            "Switch to the other set of register names.");
587
588   add_show_from_set (add_set_cmd ("apcs32", no_class,
589                                   var_integer, (char *)&arm_apcs_32,
590                                   "Set usage of ARM 32-bit mode.\n", &setlist),
591                      &showlist);
592
593 }