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