2004-01-26 Andrew Cagney <cagney@redhat.com>
[external/binutils.git] / gdb / xstormy16-tdep.c
1 /* Target-dependent code for the Sanyo Xstormy16a (LC590000) processor.
2
3    Copyright 2001, 2002, 2003, 2004 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,
20    Boston, MA 02111-1307, USA.  */
21
22 #include "defs.h"
23 #include "value.h"
24 #include "inferior.h"
25 #include "symfile.h"
26 #include "arch-utils.h"
27 #include "regcache.h"
28 #include "gdbcore.h"
29 #include "objfiles.h"
30 #include "dis-asm.h"
31
32 struct gdbarch_tdep
33 {
34   /* gdbarch target dependent data here. Currently unused for Xstormy16. */
35 };
36
37 /* Extra info which is saved in each frame_info. */
38 struct frame_extra_info
39 {
40   int framesize;
41   int frameless_p;
42 };
43
44 enum gdb_regnum
45 {
46   /* Xstormy16 has 16 general purpose registers (R0-R15) plus PC.
47      Functions will return their values in register R2-R7 as they fit.
48      Otherwise a hidden pointer to an big enough area is given as argument
49      to the function in r2. Further arguments are beginning in r3 then.
50      R13 is used as frame pointer when GCC compiles w/o optimization
51      R14 is used as "PSW", displaying the CPU status.
52      R15 is used implicitely as stack pointer. */
53   E_R0_REGNUM,
54   E_R1_REGNUM,
55   E_R2_REGNUM, E_1ST_ARG_REGNUM = E_R2_REGNUM, E_PTR_RET_REGNUM = E_R2_REGNUM,
56   E_R3_REGNUM,
57   E_R4_REGNUM,
58   E_R5_REGNUM,
59   E_R6_REGNUM,
60   E_R7_REGNUM, E_LST_ARG_REGNUM = E_R7_REGNUM,
61   E_R8_REGNUM,
62   E_R9_REGNUM,
63   E_R10_REGNUM,
64   E_R11_REGNUM,
65   E_R12_REGNUM,
66   E_R13_REGNUM, E_FP_REGNUM = E_R13_REGNUM,
67   E_R14_REGNUM, E_PSW_REGNUM = E_R14_REGNUM,
68   E_R15_REGNUM, E_SP_REGNUM = E_R15_REGNUM,
69   E_PC_REGNUM,
70   E_NUM_REGS
71 };
72
73 /* Size of instructions, registers, etc. */
74 enum
75 {
76   xstormy16_inst_size = 2,
77   xstormy16_reg_size = 2,
78   xstormy16_pc_size = 4
79 };
80
81 /* Size of return datatype which fits into the remaining return registers. */
82 #define E_MAX_RETTYPE_SIZE(regnum)      ((E_LST_ARG_REGNUM - (regnum) + 1) \
83                                         * xstormy16_reg_size)
84
85 /* Size of return datatype which fits into all return registers. */
86 enum
87 {
88   E_MAX_RETTYPE_SIZE_IN_REGS = E_MAX_RETTYPE_SIZE (E_R2_REGNUM)
89 };
90
91
92 /* Size of all registers as a whole. */
93 enum
94 {
95   E_ALL_REGS_SIZE = (E_NUM_REGS - 1) * xstormy16_reg_size + xstormy16_pc_size
96 };
97
98 /* Function: xstormy16_register_name
99    Returns the name of the standard Xstormy16 register N. */
100
101 static const char *
102 xstormy16_register_name (int regnum)
103 {
104   static char *register_names[] = {
105     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
106     "r8", "r9", "r10", "r11", "r12", "r13",
107     "psw", "sp", "pc"
108   };
109
110   if (regnum < 0 ||
111       regnum >= sizeof (register_names) / sizeof (register_names[0]))
112     internal_error (__FILE__, __LINE__,
113                     "xstormy16_register_name: illegal register number %d",
114                     regnum);
115   else
116     return register_names[regnum];
117
118 }
119
120 /* Function: xstormy16_register_byte 
121    Returns the byte position in the register cache for register N. */
122
123 static int
124 xstormy16_register_byte (int regnum)
125 {
126   if (regnum < 0 || regnum >= E_NUM_REGS)
127     internal_error (__FILE__, __LINE__,
128                     "xstormy16_register_byte: illegal register number %d",
129                     regnum);
130   else
131     /* All registers occupy 2 bytes in the regcache except for PC
132        which is the last one. Therefore the byte position is still
133        simply a multiple of 2. */
134     return regnum * xstormy16_reg_size;
135 }
136
137 /* Function: xstormy16_register_raw_size
138    Returns the number of bytes occupied by the register on the target. */
139
140 static int
141 xstormy16_register_raw_size (int regnum)
142 {
143   if (regnum < 0 || regnum >= E_NUM_REGS)
144     internal_error (__FILE__, __LINE__,
145                     "xstormy16_register_raw_size: illegal register number %d",
146                     regnum);
147   /* Only the PC has 4 Byte, all other registers 2 Byte. */
148   else if (regnum == E_PC_REGNUM)
149     return xstormy16_pc_size;
150   else
151     return xstormy16_reg_size;
152 }
153
154 /* Function: xstormy16_reg_virtual_type 
155    Returns the default type for register N. */
156
157 static struct type *
158 xstormy16_reg_virtual_type (int regnum)
159 {
160   if (regnum < 0 || regnum >= E_NUM_REGS)
161     internal_error (__FILE__, __LINE__,
162                     "xstormy16_register_virtual_type: illegal register number %d",
163                     regnum);
164   else if (regnum == E_PC_REGNUM)
165     return builtin_type_uint32;
166   else
167     return builtin_type_uint16;
168 }
169
170 /* Function: xstormy16_get_saved_register
171    Find a register's saved value on the call stack. */
172
173 static void
174 xstormy16_get_saved_register (char *raw_buffer,
175                               int *optimized,
176                               CORE_ADDR *addrp,
177                               struct frame_info *fi,
178                               int regnum, enum lval_type *lval)
179 {
180   deprecated_generic_get_saved_register (raw_buffer, optimized, addrp, fi, regnum, lval);
181 }
182
183 /* Function: xstormy16_type_is_scalar
184    Makes the decision if a given type is a scalar types.  Scalar
185    types are returned in the registers r2-r7 as they fit. */
186
187 static int
188 xstormy16_type_is_scalar (struct type *t)
189 {
190   return (TYPE_CODE(t) != TYPE_CODE_STRUCT
191           && TYPE_CODE(t) != TYPE_CODE_UNION
192           && TYPE_CODE(t) != TYPE_CODE_ARRAY);
193 }
194
195 /* Function: xstormy16_extract_return_value
196    Copy the function's return value into VALBUF. 
197    This function is called only in the context of "target function calls",
198    ie. when the debugger forces a function to be called in the child, and
199    when the debugger forces a function to return prematurely via the
200    "return" command. */
201
202 static void
203 xstormy16_extract_return_value (struct type *type, char *regbuf, char *valbuf)
204 {
205   CORE_ADDR return_buffer;
206   int offset = 0;
207
208   if (xstormy16_type_is_scalar (type)
209       && TYPE_LENGTH (type) <= E_MAX_RETTYPE_SIZE_IN_REGS)
210     {
211       /* Scalar return values of <= 12 bytes are returned in 
212          E_1ST_ARG_REGNUM to E_LST_ARG_REGNUM. */
213       memcpy (valbuf,
214               &regbuf[DEPRECATED_REGISTER_BYTE (E_1ST_ARG_REGNUM)] + offset,
215               TYPE_LENGTH (type));
216     }
217   else
218     {
219       /* Aggregates and return values > 12 bytes are returned in memory,
220          pointed to by R2. */
221       return_buffer =
222         extract_unsigned_integer (regbuf + DEPRECATED_REGISTER_BYTE (E_PTR_RET_REGNUM),
223                                   DEPRECATED_REGISTER_RAW_SIZE (E_PTR_RET_REGNUM));
224
225       read_memory (return_buffer, valbuf, TYPE_LENGTH (type));
226     }
227 }
228
229 /* Function: xstormy16_push_arguments
230    Setup the function arguments for GDB to call a function in the inferior.
231    Called only in the context of a target function call from the debugger.
232    Returns the value of the SP register after the args are pushed.
233 */
234
235 static CORE_ADDR
236 xstormy16_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
237                           int struct_return, CORE_ADDR struct_addr)
238 {
239   CORE_ADDR stack_dest = sp;
240   int argreg = E_1ST_ARG_REGNUM;
241   int i, j;
242   int typelen, slacklen;
243   char *val;
244
245   /* If struct_return is true, then the struct return address will
246      consume one argument-passing register.  */
247   if (struct_return)
248     argreg++;
249
250   /* Arguments are passed in R2-R7 as they fit. If an argument doesn't
251      fit in the remaining registers we're switching over to the stack.
252      No argument is put on stack partially and as soon as we switched
253      over to stack no further argument is put in a register even if it
254      would fit in the remaining unused registers. */
255   for (i = 0; i < nargs && argreg <= E_LST_ARG_REGNUM; i++)
256     {
257       typelen = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
258       if (typelen > E_MAX_RETTYPE_SIZE (argreg))
259         break;
260
261       /* Put argument into registers wordwise. */
262       val = VALUE_CONTENTS (args[i]);
263       for (j = 0; j < typelen; j += xstormy16_reg_size)
264         write_register (argreg++,
265                         extract_unsigned_integer (val + j,
266                                                   typelen - j ==
267                                                   1 ? 1 :
268                                                   xstormy16_reg_size));
269     }
270
271   /* Align SP */
272   if (stack_dest & 1)
273     ++stack_dest;
274
275   /* Loop backwards through remaining arguments and push them on the stack,
276      wordaligned. */
277   for (j = nargs - 1; j >= i; j--)
278     {
279       typelen = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[j]));
280       slacklen = typelen & 1;
281       val = alloca (typelen + slacklen);
282       memcpy (val, VALUE_CONTENTS (args[j]), typelen);
283       memset (val + typelen, 0, slacklen);
284
285       /* Now write this data to the stack. The stack grows upwards. */
286       write_memory (stack_dest, val, typelen + slacklen);
287       stack_dest += typelen + slacklen;
288     }
289
290   /* And that should do it.  Return the new stack pointer. */
291   return stack_dest;
292 }
293
294 /* Function: xstormy16_push_return_address (pc)
295    Setup the return address for GDB to call a function in the inferior.
296    Called only in the context of a target function call from the debugger.
297    Returns the value of the SP register when the operation is finished
298    (which may or may not be the same as before).
299 */
300
301 static CORE_ADDR
302 xstormy16_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
303 {
304   unsigned char buf[xstormy16_pc_size];
305
306   store_unsigned_integer (buf, xstormy16_pc_size, entry_point_address ());
307   write_memory (sp, buf, xstormy16_pc_size);
308   return sp + xstormy16_pc_size;
309 }
310
311 /* Function: xstormy16_pop_frame
312    Destroy the innermost (Top-Of-Stack) stack frame, restoring the 
313    machine state that was in effect before the frame was created. 
314    Used in the contexts of the "return" command, and of 
315    target function calls from the debugger.
316 */
317
318 static void
319 xstormy16_pop_frame (void)
320 {
321   struct frame_info *fi = get_current_frame ();
322   int i;
323
324   if (fi == NULL)
325     return;                     /* paranoia */
326
327   if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
328                                    get_frame_base (fi)))
329     {
330       generic_pop_dummy_frame ();
331     }
332   else
333     {
334       /* Restore the saved regs. */
335       for (i = 0; i < NUM_REGS; i++)
336         if (deprecated_get_frame_saved_regs (fi)[i])
337           {
338             if (i == SP_REGNUM)
339               write_register (i, deprecated_get_frame_saved_regs (fi)[i]);
340             else if (i == E_PC_REGNUM)
341               write_register (i, read_memory_integer (deprecated_get_frame_saved_regs (fi)[i],
342                                                       xstormy16_pc_size));
343             else
344               write_register (i, read_memory_integer (deprecated_get_frame_saved_regs (fi)[i],
345                                                       xstormy16_reg_size));
346           }
347       /* Restore the PC */
348       write_register (PC_REGNUM, DEPRECATED_FRAME_SAVED_PC (fi));
349       flush_cached_frames ();
350     }
351   return;
352 }
353
354 /* Function: xstormy16_store_struct_return
355    Copy the (struct) function return value to its destined location. 
356    Called only in the context of a target function call from the debugger.
357 */
358
359 static void
360 xstormy16_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
361 {
362   write_register (E_PTR_RET_REGNUM, addr);
363 }
364
365 /* Function: xstormy16_store_return_value
366    Copy the function return value from VALBUF into the 
367    proper location for a function return. 
368    Called only in the context of the "return" command.
369 */
370
371 static void
372 xstormy16_store_return_value (struct type *type, char *valbuf)
373 {
374   CORE_ADDR return_buffer;
375   char buf[xstormy16_reg_size];
376
377   if (xstormy16_type_is_scalar (type) && TYPE_LENGTH (type) == 1)
378     {
379       /* Add leading zeros to the value. */
380       memset (buf, 0, xstormy16_reg_size);
381       memcpy (buf, valbuf, 1);
382       deprecated_write_register_gen (E_1ST_ARG_REGNUM, buf);
383     }
384   else if (xstormy16_type_is_scalar (type) &&
385            TYPE_LENGTH (type) <= E_MAX_RETTYPE_SIZE_IN_REGS)
386     deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (E_1ST_ARG_REGNUM),
387                                      valbuf, TYPE_LENGTH (type));
388   else
389     {
390       return_buffer = read_register (E_PTR_RET_REGNUM);
391       write_memory (return_buffer, valbuf, TYPE_LENGTH (type));
392     }
393 }
394
395 /* Function: xstormy16_extract_struct_value_address
396    Returns the address in which a function should return a struct value. 
397    Used in the contexts of the "return" command, and of 
398    target function calls from the debugger.
399 */
400
401 static CORE_ADDR
402 xstormy16_extract_struct_value_address (struct regcache *regcache)
403 {
404   /* FIXME: cagney/2004-01-17: Does the ABI guarantee that the return
405      address regster is preserved across function calls?  Probably
406      not, making this function wrong.  */
407   ULONGEST val;
408   regcache_raw_read_unsigned (regcache, E_PTR_RET_REGNUM, &val);
409   return val;
410 }
411
412 /* Function: xstormy16_use_struct_convention 
413    Returns non-zero if the given struct type will be returned using
414    a special convention, rather than the normal function return method. 
415    7sed in the contexts of the "return" command, and of 
416    target function calls from the debugger.
417 */
418
419 static int
420 xstormy16_use_struct_convention (int gcc_p, struct type *type)
421 {
422   return !xstormy16_type_is_scalar (type)
423     || TYPE_LENGTH (type) > E_MAX_RETTYPE_SIZE_IN_REGS;
424 }
425
426 /* Function: frame_saved_register
427    Returns the value that regnum had in frame fi
428    (saved in fi or in one of its children).  
429 */
430
431 static CORE_ADDR
432 xstormy16_frame_saved_register (struct frame_info *fi, int regnum)
433 {
434   int size = xstormy16_register_raw_size (regnum);
435   char *buf = (char *) alloca (size);
436
437   deprecated_generic_get_saved_register (buf, NULL, NULL, fi, regnum, NULL);
438   return (CORE_ADDR) extract_unsigned_integer (buf, size);
439 }
440
441 /* Function: xstormy16_scan_prologue
442    Decode the instructions within the given address range.
443    Decide when we must have reached the end of the function prologue.
444    If a frame_info pointer is provided, fill in its saved_regs etc.
445
446    Returns the address of the first instruction after the prologue. 
447 */
448
449 static CORE_ADDR
450 xstormy16_scan_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
451                          struct frame_info *fi, int *frameless)
452 {
453   CORE_ADDR sp = 0, fp = 0;
454   CORE_ADDR next_addr;
455   ULONGEST inst, inst2;
456   LONGEST offset;
457   int regnum;
458
459   if (frameless)
460     *frameless = 1;
461   if (fi)
462     {
463       /* In a call dummy, don't touch the frame. */
464       if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
465                                        get_frame_base (fi)))
466         return start_addr;
467
468       /* Grab the frame-relative values of SP and FP, needed below. 
469          The frame_saved_register function will find them on the
470          stack or in the registers as appropriate. */
471       sp = xstormy16_frame_saved_register (fi, E_SP_REGNUM);
472       fp = xstormy16_frame_saved_register (fi, E_FP_REGNUM);
473
474       /* Initialize framesize with size of PC put on stack by CALLF inst. */
475       get_frame_extra_info (fi)->framesize = xstormy16_pc_size;
476     }
477   for (next_addr = start_addr;
478        next_addr < end_addr; next_addr += xstormy16_inst_size)
479     {
480       inst = read_memory_unsigned_integer (next_addr, xstormy16_inst_size);
481       inst2 = read_memory_unsigned_integer (next_addr + xstormy16_inst_size,
482                                             xstormy16_inst_size);
483
484       if (inst >= 0x0082 && inst <= 0x008d)     /* push r2 .. push r13 */
485         {
486           if (fi)
487             {
488               regnum = inst & 0x000f;
489               deprecated_get_frame_saved_regs (fi)[regnum] = get_frame_extra_info (fi)->framesize;
490               get_frame_extra_info (fi)->framesize += xstormy16_reg_size;
491             }
492         }
493
494       /* optional stack allocation for args and local vars <= 4 byte */
495       else if (inst == 0x301f || inst == 0x303f)        /* inc r15, #0x1/#0x3 */
496         {
497           if (fi)               /* Record the frame size. */
498             get_frame_extra_info (fi)->framesize += ((inst & 0x0030) >> 4) + 1;
499         }
500
501       /* optional stack allocation for args and local vars > 4 && < 16 byte */
502       else if ((inst & 0xff0f) == 0x510f)       /* 51Hf   add r15, #0xH */
503         {
504           if (fi)               /* Record the frame size. */
505             get_frame_extra_info (fi)->framesize += (inst & 0x00f0) >> 4;
506         }
507
508       /* optional stack allocation for args and local vars >= 16 byte */
509       else if (inst == 0x314f && inst2 >= 0x0010)       /* 314f HHHH  add r15, #0xH */
510         {
511           if (fi)               /* Record the frame size. */
512             get_frame_extra_info (fi)->framesize += inst2;
513           next_addr += xstormy16_inst_size;
514         }
515
516       else if (inst == 0x46fd)  /* mov r13, r15 */
517         {
518           if (fi)               /* Record that the frame pointer is in use. */
519             get_frame_extra_info (fi)->frameless_p = 0;
520           if (frameless)
521             *frameless = 0;
522         }
523
524       /* optional copying of args in r2-r7 to r10-r13 */
525       /* Probably only in optimized case but legal action for prologue */
526       else if ((inst & 0xff00) == 0x4600        /* 46SD   mov rD, rS */
527                && (inst & 0x00f0) >= 0x0020 && (inst & 0x00f0) <= 0x0070
528                && (inst & 0x000f) >= 0x00a0 && (inst & 0x000f) <= 0x000d)
529         ;
530
531       /* optional copying of args in r2-r7 to stack */
532       /* 72DS HHHH   mov.b (rD, 0xHHHH), r(S-8) (bit3 always 1, bit2-0 = reg) */
533       /* 73DS HHHH   mov.w (rD, 0xHHHH), r(S-8) */
534       else if ((inst & 0xfed8) == 0x72d8 && (inst & 0x0007) >= 2)
535         {
536           if (fi)
537             {
538               regnum = inst & 0x0007;
539               /* Only 12 of 16 bits of the argument are used for the
540                  signed offset. */
541               offset = (LONGEST) (inst2 & 0x0fff);
542               if (offset & 0x0800)
543                 offset -= 0x1000;
544
545               deprecated_get_frame_saved_regs (fi)[regnum] = get_frame_extra_info (fi)->framesize + offset;
546             }
547           next_addr += xstormy16_inst_size;
548         }
549
550 #if 0
551       /* 2001-08-10: Not part of the prologue anymore due to change in
552          ABI. r8 and r9 are not used for argument passing anymore. */
553
554       /* optional copying of r8, r9 to stack */
555       /* 46S7; 73Df HHHH   mov.w r7,rS; mov.w (rD, 0xHHHH), r7 D=8,9; S=13,15 */
556       /* 46S7; 72df HHHH   mov.w r7,rS; mov.b (rD, 0xHHHH), r7 D=8,9; S=13,15 */
557       else if ((inst & 0xffef) == 0x4687 && (inst2 & 0xfedf) == 0x72df)
558         {
559           next_addr += xstormy16_inst_size;
560           if (fi)
561             {
562               regnum = (inst & 0x00f0) >> 4;
563               inst = inst2;
564               inst2 = read_memory_unsigned_integer (next_addr
565                                                     + xstormy16_inst_size,
566                                                     xstormy16_inst_size);
567               /* Only 12 of 16 bits of the argument are used for the
568                  signed offset. */
569               offset = (LONGEST) (inst2 & 0x0fff);
570               if (offset & 0x0800)
571                 offset -= 0x1000;
572
573               fi->saved_regs[regnum] = fi->extra_info->framesize + offset;
574             }
575           next_addr += xstormy16_inst_size;
576         }
577 #endif
578
579       else                      /* Not a prologue instruction. */
580         break;
581     }
582
583   if (fi)
584     {
585       /* Special handling for the "saved" address of the SP:
586          The SP is of course never saved on the stack at all, so
587          by convention what we put here is simply the previous 
588          _value_ of the SP (as opposed to an address where the
589          previous value would have been pushed).  */
590       if (get_frame_extra_info (fi)->frameless_p)
591         {
592           deprecated_get_frame_saved_regs (fi)[E_SP_REGNUM] = sp - get_frame_extra_info (fi)->framesize;
593           deprecated_update_frame_base_hack (fi, sp);
594         }
595       else
596         {
597           deprecated_get_frame_saved_regs (fi)[E_SP_REGNUM] = fp - get_frame_extra_info (fi)->framesize;
598           deprecated_update_frame_base_hack (fi, fp);
599         }
600
601       /* So far only offsets to the beginning of the frame are
602          saved in the saved_regs. Now we now the relation between
603          sp, fp and framesize. We know the beginning of the frame
604          so we can translate the register offsets to real addresses. */
605       for (regnum = 0; regnum < E_SP_REGNUM; ++regnum)
606         if (deprecated_get_frame_saved_regs (fi)[regnum])
607           deprecated_get_frame_saved_regs (fi)[regnum] += deprecated_get_frame_saved_regs (fi)[E_SP_REGNUM];
608
609       /* Save address of PC on stack. */
610       deprecated_get_frame_saved_regs (fi)[E_PC_REGNUM] = deprecated_get_frame_saved_regs (fi)[E_SP_REGNUM];
611     }
612
613   return next_addr;
614 }
615
616 /* Function: xstormy16_skip_prologue
617    If the input address is in a function prologue, 
618    returns the address of the end of the prologue;
619    else returns the input address.
620
621    Note: the input address is likely to be the function start, 
622    since this function is mainly used for advancing a breakpoint
623    to the first line, or stepping to the first line when we have
624    stepped into a function call.  */
625
626 static CORE_ADDR
627 xstormy16_skip_prologue (CORE_ADDR pc)
628 {
629   CORE_ADDR func_addr = 0, func_end = 0;
630   char *func_name;
631
632   if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
633     {
634       struct symtab_and_line sal;
635       struct symbol *sym;
636
637       /* Don't trust line number debug info in frameless functions. */
638       int frameless = 1;
639       CORE_ADDR plg_end = xstormy16_scan_prologue (func_addr, func_end,
640                                                    NULL, &frameless);
641       if (frameless)
642         return plg_end;
643
644       /* Found a function.  */
645       sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL, NULL);
646       /* Don't use line number debug info for assembly source files. */
647       if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
648         {
649           sal = find_pc_line (func_addr, 0);
650           if (sal.end && sal.end < func_end)
651             {
652               /* Found a line number, use it as end of prologue.  */
653               return sal.end;
654             }
655         }
656       /* No useable line symbol.  Use result of prologue parsing method. */
657       return plg_end;
658     }
659
660   /* No function symbol -- just return the PC. */
661
662   return (CORE_ADDR) pc;
663 }
664
665 /* The epilogue is defined here as the area at the end of a function,
666    either on the `ret' instruction itself or after an instruction which
667    destroys the function's stack frame. */
668 static int
669 xstormy16_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
670 {
671   CORE_ADDR addr, func_addr = 0, func_end = 0;
672
673   if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
674     {
675       ULONGEST inst, inst2;
676       CORE_ADDR addr = func_end - xstormy16_inst_size;
677
678       /* The Xstormy16 epilogue is max. 14 bytes long. */
679       if (pc < func_end - 7 * xstormy16_inst_size)
680         return 0;
681
682       /* Check if we're on a `ret' instruction.  Otherwise it's
683          too dangerous to proceed. */
684       inst = read_memory_unsigned_integer (addr, xstormy16_inst_size);
685       if (inst != 0x0003)
686         return 0;
687
688       while ((addr -= xstormy16_inst_size) >= func_addr)
689         {
690           inst = read_memory_unsigned_integer (addr, xstormy16_inst_size);
691           if (inst >= 0x009a && inst <= 0x009d) /* pop r10...r13 */
692             continue;
693           if (inst == 0x305f || inst == 0x307f) /* dec r15, #0x1/#0x3 */
694             break;
695           inst2 = read_memory_unsigned_integer (addr - xstormy16_inst_size,
696                                                 xstormy16_inst_size);
697           if (inst2 == 0x314f && inst >= 0x8000)        /* add r15, neg. value */
698             {
699               addr -= xstormy16_inst_size;
700               break;
701             }
702           return 0;
703         }
704       if (pc > addr)
705         return 1;
706     }
707   return 0;
708 }
709
710 /* Function: xstormy16_frame_init_saved_regs
711    Set up the 'saved_regs' array.
712    This is a data structure containing the addresses on the stack 
713    where each register has been saved, for each stack frame.  
714    Registers that have not been saved will have zero here.
715    The stack register is special: rather than the address where the 
716    stack register has been saved, saved_regs[SP_REGNUM] will have the
717    actual value of the previous frame's stack register. 
718
719    This function may be called in any context where the saved register
720    values may be needed (backtrace, frame_info, frame_register).  On
721    many targets, it is called directly by init_extra_frame_info, in
722    part because the information may be needed immediately by
723    frame_chain.  */
724
725 static void
726 xstormy16_frame_init_saved_regs (struct frame_info *fi)
727 {
728   CORE_ADDR func_addr, func_end;
729
730   if (!deprecated_get_frame_saved_regs (fi))
731     {
732       frame_saved_regs_zalloc (fi);
733
734       /* Find the beginning of this function, so we can analyze its
735          prologue. */
736       if (find_pc_partial_function (get_frame_pc (fi), NULL, &func_addr, &func_end))
737         xstormy16_scan_prologue (func_addr, get_frame_pc (fi), fi, NULL);
738       /* Else we're out of luck (can't debug completely stripped code). 
739          FIXME. */
740     }
741 }
742
743 /* Function: xstormy16_frame_saved_pc
744    Returns the return address for the selected frame. 
745    Called by frame_info, legacy_frame_chain_valid, and sometimes by
746    get_prev_frame.  */
747
748 static CORE_ADDR
749 xstormy16_frame_saved_pc (struct frame_info *fi)
750 {
751   CORE_ADDR saved_pc;
752
753   if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
754                                    get_frame_base (fi)))
755     {
756       saved_pc = deprecated_read_register_dummy (get_frame_pc (fi),
757                                                  get_frame_base (fi),
758                                                  E_PC_REGNUM);
759     }
760   else
761     {
762       saved_pc = read_memory_unsigned_integer (deprecated_get_frame_saved_regs (fi)[E_PC_REGNUM],
763                                                xstormy16_pc_size);
764     }
765
766   return saved_pc;
767 }
768
769 /* Function: xstormy16_init_extra_frame_info
770    This is the constructor function for the frame_info struct, 
771    called whenever a new frame_info is created (from create_new_frame,
772    and from get_prev_frame).
773 */
774
775 static void
776 xstormy16_init_extra_frame_info (int fromleaf, struct frame_info *fi)
777 {
778   if (!get_frame_extra_info (fi))
779     {
780       frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
781       get_frame_extra_info (fi)->framesize = 0;
782       get_frame_extra_info (fi)->frameless_p = 1;       /* Default frameless, detect framed */
783
784       /* By default, the fi->frame is set to the value of the FP reg by gdb.
785          This may not always be right; we may be in a frameless function,
786          or we may be in the prologue, before the FP has been set up.
787          Unfortunately, we can't make this determination without first
788          calling scan_prologue, and we can't do that unles we know the
789          get_frame_pc (fi).  */
790
791       if (!get_frame_pc (fi))
792         {
793           /* Sometimes we are called from get_prev_frame without
794              the PC being set up first.  Long history, don't ask.
795              Fortunately this will never happen from the outermost
796              frame, so we should be able to get the saved pc from
797              the next frame. */
798           if (get_next_frame (fi))
799             deprecated_update_frame_pc_hack (fi, xstormy16_frame_saved_pc (get_next_frame (fi)));
800         }
801
802       /* Take care of the saved_regs right here (non-lazy). */
803       xstormy16_frame_init_saved_regs (fi);
804     }
805 }
806
807 /* Function: xstormy16_frame_chain
808    Returns a pointer to the stack frame of the calling function.
809    Called only from get_prev_frame.  Needed for backtrace, "up", etc.
810 */
811
812 static CORE_ADDR
813 xstormy16_frame_chain (struct frame_info *fi)
814 {
815   if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
816                                    get_frame_base (fi)))
817     {
818       /* Call dummy's frame is the same as caller's.  */
819       return get_frame_base (fi);
820     }
821   else
822     {
823       /* Return computed offset from this frame's fp. */
824       return get_frame_base (fi) - get_frame_extra_info (fi)->framesize;
825     }
826 }
827
828 static int
829 xstormy16_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
830 {
831   return chain < 0x8000 && DEPRECATED_FRAME_SAVED_PC (thisframe) >= 0x8000 &&
832     (get_frame_extra_info (thisframe)->frameless_p ||
833      get_frame_base (thisframe) - get_frame_extra_info (thisframe)->framesize == chain);
834 }
835
836 /* Function: xstormy16_saved_pc_after_call Returns the previous PC
837    immediately after a function call.  This function is meant to
838    bypass the regular frame_register() mechanism, ie. it is meant to
839    work even if the frame isn't complete.  Called by
840    step_over_function, and sometimes by get_prev_frame.  */
841
842 static CORE_ADDR
843 xstormy16_saved_pc_after_call (struct frame_info *ignore)
844 {
845   CORE_ADDR sp, pc, tmp;
846
847   sp = read_register (E_SP_REGNUM) - xstormy16_pc_size;
848   pc = read_memory_integer (sp, xstormy16_pc_size);
849
850   /* Skip over jump table entry if necessary.  */
851   if ((tmp = SKIP_TRAMPOLINE_CODE (pc)))
852     pc = tmp;
853
854   return pc;
855 }
856
857 const static unsigned char *
858 xstormy16_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
859 {
860   static unsigned char breakpoint[] = { 0x06, 0x0 };
861   *lenptr = sizeof (breakpoint);
862   return breakpoint;
863 }
864
865 /* Given a pointer to a jump table entry, return the address
866    of the function it jumps to.  Return 0 if not found. */
867 static CORE_ADDR
868 xstormy16_resolve_jmp_table_entry (CORE_ADDR faddr)
869 {
870   struct obj_section *faddr_sect = find_pc_section (faddr);
871
872   if (faddr_sect)
873     {
874       LONGEST inst, inst2, addr;
875       char buf[2 * xstormy16_inst_size];
876
877       /* Return faddr if it's not pointing into the jump table. */
878       if (strcmp (faddr_sect->the_bfd_section->name, ".plt"))
879         return faddr;
880
881       if (!target_read_memory (faddr, buf, sizeof buf))
882         {
883           inst = extract_unsigned_integer (buf, xstormy16_inst_size);
884           inst2 = extract_unsigned_integer (buf + xstormy16_inst_size,
885                                             xstormy16_inst_size);
886           addr = inst2 << 8 | (inst & 0xff);
887           return addr;
888         }
889     }
890   return 0;
891 }
892
893 /* Given a function's address, attempt to find (and return) the
894    address of the corresponding jump table entry.  Return 0 if
895    not found. */
896 static CORE_ADDR
897 xstormy16_find_jmp_table_entry (CORE_ADDR faddr)
898 {
899   struct obj_section *faddr_sect = find_pc_section (faddr);
900
901   if (faddr_sect)
902     {
903       struct obj_section *osect;
904
905       /* Return faddr if it's already a pointer to a jump table entry. */
906       if (!strcmp (faddr_sect->the_bfd_section->name, ".plt"))
907         return faddr;
908
909       ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
910       {
911         if (!strcmp (osect->the_bfd_section->name, ".plt"))
912           break;
913       }
914
915       if (osect < faddr_sect->objfile->sections_end)
916         {
917           CORE_ADDR addr;
918           for (addr = osect->addr;
919                addr < osect->endaddr; addr += 2 * xstormy16_inst_size)
920             {
921               int status;
922               LONGEST inst, inst2, faddr2;
923               char buf[2 * xstormy16_inst_size];
924
925               if (target_read_memory (addr, buf, sizeof buf))
926                 return 0;
927               inst = extract_unsigned_integer (buf, xstormy16_inst_size);
928               inst2 = extract_unsigned_integer (buf + xstormy16_inst_size,
929                                                 xstormy16_inst_size);
930               faddr2 = inst2 << 8 | (inst & 0xff);
931               if (faddr == faddr2)
932                 return addr;
933             }
934         }
935     }
936   return 0;
937 }
938
939 static CORE_ADDR
940 xstormy16_skip_trampoline_code (CORE_ADDR pc)
941 {
942   int tmp = xstormy16_resolve_jmp_table_entry (pc);
943
944   if (tmp && tmp != pc)
945     return tmp;
946   return 0;
947 }
948
949 static int
950 xstormy16_in_solib_call_trampoline (CORE_ADDR pc, char *name)
951 {
952   return xstormy16_skip_trampoline_code (pc) != 0;
953 }
954
955 static CORE_ADDR
956 xstormy16_pointer_to_address (struct type *type, const void *buf)
957 {
958   enum type_code target = TYPE_CODE (TYPE_TARGET_TYPE (type));
959   CORE_ADDR addr = extract_unsigned_integer (buf, TYPE_LENGTH (type));
960
961   if (target == TYPE_CODE_FUNC || target == TYPE_CODE_METHOD)
962     {
963       CORE_ADDR addr2 = xstormy16_resolve_jmp_table_entry (addr);
964       if (addr2)
965         addr = addr2;
966     }
967
968   return addr;
969 }
970
971 static void
972 xstormy16_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr)
973 {
974   enum type_code target = TYPE_CODE (TYPE_TARGET_TYPE (type));
975
976   if (target == TYPE_CODE_FUNC || target == TYPE_CODE_METHOD)
977     {
978       CORE_ADDR addr2 = xstormy16_find_jmp_table_entry (addr);
979       if (addr2)
980         addr = addr2;
981     }
982   store_unsigned_integer (buf, TYPE_LENGTH (type), addr);
983 }
984
985 static CORE_ADDR
986 xstormy16_stack_align (CORE_ADDR addr)
987 {
988   if (addr & 1)
989     ++addr;
990   return addr;
991 }
992
993 static void
994 xstormy16_save_dummy_frame_tos (CORE_ADDR sp)
995 {
996   generic_save_dummy_frame_tos (sp - xstormy16_pc_size);
997 }
998
999 /* Function: xstormy16_gdbarch_init
1000    Initializer function for the xstormy16 gdbarch vector.
1001    Called by gdbarch.  Sets up the gdbarch vector(s) for this target. */
1002
1003 static struct gdbarch *
1004 xstormy16_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1005 {
1006   static LONGEST call_dummy_words[1] = { 0 };
1007   struct gdbarch_tdep *tdep = NULL;
1008   struct gdbarch *gdbarch;
1009
1010   /* find a candidate among the list of pre-declared architectures. */
1011   arches = gdbarch_list_lookup_by_info (arches, &info);
1012   if (arches != NULL)
1013     return (arches->gdbarch);
1014
1015 #if 0
1016   tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
1017 #endif
1018
1019   gdbarch = gdbarch_alloc (&info, 0);
1020
1021   /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
1022      ready to unwind the PC first (see frame.c:get_prev_frame()).  */
1023   set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
1024
1025   /*
1026    * Basic register fields and methods.
1027    */
1028
1029   set_gdbarch_num_regs (gdbarch, E_NUM_REGS);
1030   set_gdbarch_num_pseudo_regs (gdbarch, 0);
1031   set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
1032   set_gdbarch_deprecated_fp_regnum (gdbarch, E_FP_REGNUM);
1033   set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
1034   set_gdbarch_register_name (gdbarch, xstormy16_register_name);
1035   set_gdbarch_deprecated_register_size (gdbarch, xstormy16_reg_size);
1036   set_gdbarch_deprecated_register_bytes (gdbarch, E_ALL_REGS_SIZE);
1037   set_gdbarch_deprecated_register_byte (gdbarch, xstormy16_register_byte);
1038   set_gdbarch_deprecated_register_raw_size (gdbarch, xstormy16_register_raw_size);
1039   set_gdbarch_deprecated_max_register_raw_size (gdbarch, xstormy16_pc_size);
1040   set_gdbarch_deprecated_register_virtual_size (gdbarch, xstormy16_register_raw_size);
1041   set_gdbarch_deprecated_max_register_virtual_size (gdbarch, 4);
1042   set_gdbarch_deprecated_register_virtual_type (gdbarch, xstormy16_reg_virtual_type);
1043
1044   /*
1045    * Frame Info
1046    */
1047   set_gdbarch_deprecated_init_extra_frame_info (gdbarch,
1048                                      xstormy16_init_extra_frame_info);
1049   set_gdbarch_deprecated_frame_init_saved_regs (gdbarch,
1050                                      xstormy16_frame_init_saved_regs);
1051   set_gdbarch_deprecated_frame_chain (gdbarch, xstormy16_frame_chain);
1052   set_gdbarch_deprecated_get_saved_register (gdbarch, xstormy16_get_saved_register);
1053   set_gdbarch_deprecated_saved_pc_after_call (gdbarch, xstormy16_saved_pc_after_call);
1054   set_gdbarch_deprecated_frame_saved_pc (gdbarch, xstormy16_frame_saved_pc);
1055   set_gdbarch_skip_prologue (gdbarch, xstormy16_skip_prologue);
1056   set_gdbarch_deprecated_frame_chain_valid (gdbarch, xstormy16_frame_chain_valid);
1057
1058   set_gdbarch_in_function_epilogue_p (gdbarch,
1059                                       xstormy16_in_function_epilogue_p);
1060
1061   /* 
1062    * Miscelany
1063    */
1064   /* Stack grows up. */
1065   set_gdbarch_inner_than (gdbarch, core_addr_greaterthan);
1066   /* This value is almost never non-zero... */
1067   set_gdbarch_frame_args_skip (gdbarch, 0);
1068
1069   /*
1070    * Call Dummies
1071    * 
1072    * These values and methods are used when gdb calls a target function.  */
1073   set_gdbarch_deprecated_push_return_address (gdbarch, xstormy16_push_return_address);
1074   set_gdbarch_deprecated_extract_return_value (gdbarch, xstormy16_extract_return_value);
1075   set_gdbarch_deprecated_push_arguments (gdbarch, xstormy16_push_arguments);
1076   set_gdbarch_deprecated_pop_frame (gdbarch, xstormy16_pop_frame);
1077   set_gdbarch_deprecated_store_struct_return (gdbarch, xstormy16_store_struct_return);
1078   set_gdbarch_deprecated_store_return_value (gdbarch, xstormy16_store_return_value);
1079   set_gdbarch_deprecated_extract_struct_value_address (gdbarch, xstormy16_extract_struct_value_address);
1080   set_gdbarch_use_struct_convention (gdbarch,
1081                                      xstormy16_use_struct_convention);
1082   set_gdbarch_deprecated_call_dummy_words (gdbarch, call_dummy_words);
1083   set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, 0);
1084   set_gdbarch_breakpoint_from_pc (gdbarch, xstormy16_breakpoint_from_pc);
1085
1086   set_gdbarch_char_signed (gdbarch, 0);
1087   set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1088   set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1089   set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1090   set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
1091
1092   set_gdbarch_address_to_pointer (gdbarch, xstormy16_address_to_pointer);
1093   set_gdbarch_pointer_to_address (gdbarch, xstormy16_pointer_to_address);
1094
1095   set_gdbarch_deprecated_stack_align (gdbarch, xstormy16_stack_align);
1096
1097   set_gdbarch_deprecated_save_dummy_frame_tos (gdbarch, xstormy16_save_dummy_frame_tos);
1098
1099   set_gdbarch_skip_trampoline_code (gdbarch, xstormy16_skip_trampoline_code);
1100
1101   set_gdbarch_in_solib_call_trampoline (gdbarch,
1102                                         xstormy16_in_solib_call_trampoline);
1103
1104   /* Should be using push_dummy_call.  */
1105   set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
1106
1107   set_gdbarch_print_insn (gdbarch, print_insn_xstormy16);
1108
1109   return gdbarch;
1110 }
1111
1112 /* Function: _initialize_xstormy16_tdep
1113    Initializer function for the Sanyo Xstormy16a module.
1114    Called by gdb at start-up. */
1115
1116 extern initialize_file_ftype _initialize_xstormy16_tdep; /* -Wmissing-prototypes */
1117
1118 void
1119 _initialize_xstormy16_tdep (void)
1120 {
1121   register_gdbarch_init (bfd_arch_xstormy16, xstormy16_gdbarch_init);
1122 }