2004-02-12 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / xstormy16-tdep.c
CommitLineData
0c884e17 1/* Target-dependent code for the Sanyo Xstormy16a (LC590000) processor.
f4f9705a 2
07be497a 3 Copyright 2001, 2002, 2003, 2004 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"
a89aa300 30#include "dis-asm.h"
0c884e17
CV
31
32struct 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. */
38struct frame_extra_info
39{
40 int framesize;
41 int frameless_p;
42};
43
44enum 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. */
74enum
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. */
86enum
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. */
93enum
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
fa88f677 101static const char *
0c884e17
CV
102xstormy16_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
123static int
124xstormy16_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
140static int
141xstormy16_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
0c884e17
CV
154/* Function: xstormy16_reg_virtual_type
155 Returns the default type for register N. */
156
157static struct type *
158xstormy16_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
173static void
174xstormy16_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{
bdcdd535 180 deprecated_generic_get_saved_register (raw_buffer, optimized, addrp, fi, regnum, lval);
0c884e17
CV
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
187static int
188xstormy16_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
202static void
203xstormy16_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,
62700349 214 &regbuf[DEPRECATED_REGISTER_BYTE (E_1ST_ARG_REGNUM)] + offset,
0c884e17
CV
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 =
62700349 222 extract_unsigned_integer (regbuf + DEPRECATED_REGISTER_BYTE (E_PTR_RET_REGNUM),
12c266ea 223 DEPRECATED_REGISTER_RAW_SIZE (E_PTR_RET_REGNUM));
0c884e17
CV
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
235static CORE_ADDR
236xstormy16_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
a78f21af 301static CORE_ADDR
0c884e17
CV
302xstormy16_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
303{
304 unsigned char buf[xstormy16_pc_size];
305
88a82a65 306 store_unsigned_integer (buf, xstormy16_pc_size, entry_point_address ());
0c884e17
CV
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
318static void
319xstormy16_pop_frame (void)
320{
321 struct frame_info *fi = get_current_frame ();
322 int i;
323
324 if (fi == NULL)
325 return; /* paranoia */
326
1e2330ba
AC
327 if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
328 get_frame_base (fi)))
0c884e17
CV
329 {
330 generic_pop_dummy_frame ();
331 }
332 else
333 {
334 /* Restore the saved regs. */
335 for (i = 0; i < NUM_REGS; i++)
1b1d3794 336 if (deprecated_get_frame_saved_regs (fi)[i])
0c884e17
CV
337 {
338 if (i == SP_REGNUM)
1b1d3794 339 write_register (i, deprecated_get_frame_saved_regs (fi)[i]);
0c884e17 340 else if (i == E_PC_REGNUM)
1b1d3794 341 write_register (i, read_memory_integer (deprecated_get_frame_saved_regs (fi)[i],
0c884e17
CV
342 xstormy16_pc_size));
343 else
1b1d3794 344 write_register (i, read_memory_integer (deprecated_get_frame_saved_regs (fi)[i],
0c884e17
CV
345 xstormy16_reg_size));
346 }
347 /* Restore the PC */
8bedc050 348 write_register (PC_REGNUM, DEPRECATED_FRAME_SAVED_PC (fi));
0c884e17
CV
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
359static void
360xstormy16_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
371static void
372xstormy16_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);
4caf0990 382 deprecated_write_register_gen (E_1ST_ARG_REGNUM, buf);
0c884e17
CV
383 }
384 else if (xstormy16_type_is_scalar (type) &&
385 TYPE_LENGTH (type) <= E_MAX_RETTYPE_SIZE_IN_REGS)
62700349 386 deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (E_1ST_ARG_REGNUM),
73937e03 387 valbuf, TYPE_LENGTH (type));
0c884e17
CV
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
401static CORE_ADDR
07be497a 402xstormy16_extract_struct_value_address (struct regcache *regcache)
0c884e17 403{
07be497a
AC
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;
0c884e17
CV
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
419static int
420xstormy16_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
431static CORE_ADDR
432xstormy16_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
bdcdd535 437 deprecated_generic_get_saved_register (buf, NULL, NULL, fi, regnum, NULL);
0c884e17
CV
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
449static CORE_ADDR
211a4f69
CV
450xstormy16_scan_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
451 struct frame_info *fi, int *frameless)
0c884e17
CV
452{
453 CORE_ADDR sp = 0, fp = 0;
454 CORE_ADDR next_addr;
455 ULONGEST inst, inst2;
456 LONGEST offset;
457 int regnum;
458
211a4f69
CV
459 if (frameless)
460 *frameless = 1;
0c884e17
CV
461 if (fi)
462 {
463 /* In a call dummy, don't touch the frame. */
1e2330ba
AC
464 if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
465 get_frame_base (fi)))
0c884e17
CV
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. */
da50a4b7 475 get_frame_extra_info (fi)->framesize = xstormy16_pc_size;
0c884e17
CV
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;
1b1d3794 489 deprecated_get_frame_saved_regs (fi)[regnum] = get_frame_extra_info (fi)->framesize;
da50a4b7 490 get_frame_extra_info (fi)->framesize += xstormy16_reg_size;
0c884e17
CV
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. */
da50a4b7 498 get_frame_extra_info (fi)->framesize += ((inst & 0x0030) >> 4) + 1;
0c884e17
CV
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. */
da50a4b7 505 get_frame_extra_info (fi)->framesize += (inst & 0x00f0) >> 4;
0c884e17
CV
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. */
da50a4b7 512 get_frame_extra_info (fi)->framesize += inst2;
0c884e17
CV
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. */
da50a4b7 519 get_frame_extra_info (fi)->frameless_p = 0;
211a4f69
CV
520 if (frameless)
521 *frameless = 0;
0c884e17
CV
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
1b1d3794 545 deprecated_get_frame_saved_regs (fi)[regnum] = get_frame_extra_info (fi)->framesize + offset;
0c884e17
CV
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). */
da50a4b7 590 if (get_frame_extra_info (fi)->frameless_p)
0c884e17 591 {
1b1d3794 592 deprecated_get_frame_saved_regs (fi)[E_SP_REGNUM] = sp - get_frame_extra_info (fi)->framesize;
b0c6b05c 593 deprecated_update_frame_base_hack (fi, sp);
0c884e17
CV
594 }
595 else
596 {
1b1d3794 597 deprecated_get_frame_saved_regs (fi)[E_SP_REGNUM] = fp - get_frame_extra_info (fi)->framesize;
b0c6b05c 598 deprecated_update_frame_base_hack (fi, fp);
0c884e17
CV
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)
1b1d3794
AC
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];
0c884e17
CV
608
609 /* Save address of PC on stack. */
1b1d3794 610 deprecated_get_frame_saved_regs (fi)[E_PC_REGNUM] = deprecated_get_frame_saved_regs (fi)[E_SP_REGNUM];
0c884e17
CV
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
626static CORE_ADDR
627xstormy16_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
211a4f69
CV
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
0c884e17 644 /* Found a function. */
176620f1 645 sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL, NULL);
211a4f69 646 /* Don't use line number debug info for assembly source files. */
0c884e17
CV
647 if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
648 {
0c884e17
CV
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 }
211a4f69
CV
656 /* No useable line symbol. Use result of prologue parsing method. */
657 return plg_end;
0c884e17
CV
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. */
668static int
669xstormy16_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
ac2adee5
AC
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. */
0c884e17
CV
724
725static void
726xstormy16_frame_init_saved_regs (struct frame_info *fi)
727{
728 CORE_ADDR func_addr, func_end;
729
1b1d3794 730 if (!deprecated_get_frame_saved_regs (fi))
0c884e17
CV
731 {
732 frame_saved_regs_zalloc (fi);
733
734 /* Find the beginning of this function, so we can analyze its
735 prologue. */
50abf9e5
AC
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);
0c884e17
CV
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.
e6ba3bc9
AC
745 Called by frame_info, legacy_frame_chain_valid, and sometimes by
746 get_prev_frame. */
0c884e17
CV
747
748static CORE_ADDR
749xstormy16_frame_saved_pc (struct frame_info *fi)
750{
751 CORE_ADDR saved_pc;
752
1e2330ba
AC
753 if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
754 get_frame_base (fi)))
0c884e17 755 {
1e2330ba
AC
756 saved_pc = deprecated_read_register_dummy (get_frame_pc (fi),
757 get_frame_base (fi),
135c175f 758 E_PC_REGNUM);
0c884e17
CV
759 }
760 else
761 {
1b1d3794 762 saved_pc = read_memory_unsigned_integer (deprecated_get_frame_saved_regs (fi)[E_PC_REGNUM],
0c884e17
CV
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
775static void
776xstormy16_init_extra_frame_info (int fromleaf, struct frame_info *fi)
777{
da50a4b7 778 if (!get_frame_extra_info (fi))
0c884e17 779 {
a00a19e9 780 frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
da50a4b7
AC
781 get_frame_extra_info (fi)->framesize = 0;
782 get_frame_extra_info (fi)->frameless_p = 1; /* Default frameless, detect framed */
0c884e17
CV
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
50abf9e5 789 get_frame_pc (fi). */
0c884e17 790
50abf9e5 791 if (!get_frame_pc (fi))
0c884e17
CV
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. */
11c02a10
AC
798 if (get_next_frame (fi))
799 deprecated_update_frame_pc_hack (fi, xstormy16_frame_saved_pc (get_next_frame (fi)));
0c884e17
CV
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
812static CORE_ADDR
813xstormy16_frame_chain (struct frame_info *fi)
814{
1e2330ba
AC
815 if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
816 get_frame_base (fi)))
0c884e17
CV
817 {
818 /* Call dummy's frame is the same as caller's. */
1e2330ba 819 return get_frame_base (fi);
0c884e17
CV
820 }
821 else
822 {
823 /* Return computed offset from this frame's fp. */
da50a4b7 824 return get_frame_base (fi) - get_frame_extra_info (fi)->framesize;
0c884e17
CV
825 }
826}
827
828static int
829xstormy16_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
830{
8bedc050 831 return chain < 0x8000 && DEPRECATED_FRAME_SAVED_PC (thisframe) >= 0x8000 &&
da50a4b7
AC
832 (get_frame_extra_info (thisframe)->frameless_p ||
833 get_frame_base (thisframe) - get_frame_extra_info (thisframe)->framesize == chain);
0c884e17
CV
834}
835
ac2adee5
AC
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. */
0c884e17
CV
841
842static CORE_ADDR
843xstormy16_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
f4f9705a 857const static unsigned char *
0c884e17
CV
858xstormy16_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. */
867static CORE_ADDR
868xstormy16_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. */
896static CORE_ADDR
897xstormy16_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
939static CORE_ADDR
940xstormy16_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
949static int
950xstormy16_in_solib_call_trampoline (CORE_ADDR pc, char *name)
951{
952 return xstormy16_skip_trampoline_code (pc) != 0;
953}
954
955static CORE_ADDR
66140c26 956xstormy16_pointer_to_address (struct type *type, const void *buf)
0c884e17
CV
957{
958 enum type_code target = TYPE_CODE (TYPE_TARGET_TYPE (type));
7c0b4a20 959 CORE_ADDR addr = extract_unsigned_integer (buf, TYPE_LENGTH (type));
0c884e17
CV
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
971static void
972xstormy16_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 }
fbd9dcd3 982 store_unsigned_integer (buf, TYPE_LENGTH (type), addr);
0c884e17
CV
983}
984
985static CORE_ADDR
986xstormy16_stack_align (CORE_ADDR addr)
987{
988 if (addr & 1)
989 ++addr;
990 return addr;
991}
992
a78f21af 993static void
0c884e17
CV
994xstormy16_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
1003static struct gdbarch *
1004xstormy16_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
a5afb99f
AC
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()). */
0968aa8c 1023 set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
a5afb99f 1024
0c884e17
CV
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);
0ba6dca9 1032 set_gdbarch_deprecated_fp_regnum (gdbarch, E_FP_REGNUM);
0c884e17
CV
1033 set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
1034 set_gdbarch_register_name (gdbarch, xstormy16_register_name);
b1e29e33 1035 set_gdbarch_deprecated_register_size (gdbarch, xstormy16_reg_size);
b8b527c5 1036 set_gdbarch_deprecated_register_bytes (gdbarch, E_ALL_REGS_SIZE);
9c04cab7
AC
1037 set_gdbarch_deprecated_register_byte (gdbarch, xstormy16_register_byte);
1038 set_gdbarch_deprecated_register_raw_size (gdbarch, xstormy16_register_raw_size);
a0ed5532 1039 set_gdbarch_deprecated_max_register_raw_size (gdbarch, xstormy16_pc_size);
9c04cab7 1040 set_gdbarch_deprecated_register_virtual_size (gdbarch, xstormy16_register_raw_size);
a0ed5532 1041 set_gdbarch_deprecated_max_register_virtual_size (gdbarch, 4);
9c04cab7 1042 set_gdbarch_deprecated_register_virtual_type (gdbarch, xstormy16_reg_virtual_type);
0c884e17
CV
1043
1044 /*
1045 * Frame Info
1046 */
e9582e71 1047 set_gdbarch_deprecated_init_extra_frame_info (gdbarch,
0c884e17 1048 xstormy16_init_extra_frame_info);
f30ee0bc 1049 set_gdbarch_deprecated_frame_init_saved_regs (gdbarch,
0c884e17 1050 xstormy16_frame_init_saved_regs);
618ce49f 1051 set_gdbarch_deprecated_frame_chain (gdbarch, xstormy16_frame_chain);
129c1cd6 1052 set_gdbarch_deprecated_get_saved_register (gdbarch, xstormy16_get_saved_register);
6913c89a 1053 set_gdbarch_deprecated_saved_pc_after_call (gdbarch, xstormy16_saved_pc_after_call);
8bedc050 1054 set_gdbarch_deprecated_frame_saved_pc (gdbarch, xstormy16_frame_saved_pc);
0c884e17 1055 set_gdbarch_skip_prologue (gdbarch, xstormy16_skip_prologue);
618ce49f 1056 set_gdbarch_deprecated_frame_chain_valid (gdbarch, xstormy16_frame_chain_valid);
0c884e17
CV
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);
0c884e17 1066
0c884e17
CV
1067 /*
1068 * Call Dummies
1069 *
1070 * These values and methods are used when gdb calls a target function. */
28f617b3 1071 set_gdbarch_deprecated_push_return_address (gdbarch, xstormy16_push_return_address);
26e9b323 1072 set_gdbarch_deprecated_extract_return_value (gdbarch, xstormy16_extract_return_value);
b81774d8 1073 set_gdbarch_deprecated_push_arguments (gdbarch, xstormy16_push_arguments);
749b82f6 1074 set_gdbarch_deprecated_pop_frame (gdbarch, xstormy16_pop_frame);
4183d812 1075 set_gdbarch_deprecated_store_struct_return (gdbarch, xstormy16_store_struct_return);
ebba8386 1076 set_gdbarch_deprecated_store_return_value (gdbarch, xstormy16_store_return_value);
74055713 1077 set_gdbarch_deprecated_extract_struct_value_address (gdbarch, xstormy16_extract_struct_value_address);
0c884e17
CV
1078 set_gdbarch_use_struct_convention (gdbarch,
1079 xstormy16_use_struct_convention);
b1e29e33
AC
1080 set_gdbarch_deprecated_call_dummy_words (gdbarch, call_dummy_words);
1081 set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, 0);
0c884e17
CV
1082 set_gdbarch_breakpoint_from_pc (gdbarch, xstormy16_breakpoint_from_pc);
1083
71c08af0 1084 set_gdbarch_char_signed (gdbarch, 0);
0c884e17
CV
1085 set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1086 set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1087 set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1088 set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
1089
1090 set_gdbarch_address_to_pointer (gdbarch, xstormy16_address_to_pointer);
1091 set_gdbarch_pointer_to_address (gdbarch, xstormy16_pointer_to_address);
1092
f27dd7fd 1093 set_gdbarch_deprecated_stack_align (gdbarch, xstormy16_stack_align);
0c884e17 1094
a59fe496 1095 set_gdbarch_deprecated_save_dummy_frame_tos (gdbarch, xstormy16_save_dummy_frame_tos);
0c884e17
CV
1096
1097 set_gdbarch_skip_trampoline_code (gdbarch, xstormy16_skip_trampoline_code);
1098
1099 set_gdbarch_in_solib_call_trampoline (gdbarch,
1100 xstormy16_in_solib_call_trampoline);
1101
6c0e89ed 1102 /* Should be using push_dummy_call. */
b46e02f6 1103 set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
6c0e89ed 1104
36482093
AC
1105 set_gdbarch_print_insn (gdbarch, print_insn_xstormy16);
1106
0c884e17
CV
1107 return gdbarch;
1108}
1109
1110/* Function: _initialize_xstormy16_tdep
1111 Initializer function for the Sanyo Xstormy16a module.
1112 Called by gdb at start-up. */
1113
a78f21af
AC
1114extern initialize_file_ftype _initialize_xstormy16_tdep; /* -Wmissing-prototypes */
1115
0c884e17
CV
1116void
1117_initialize_xstormy16_tdep (void)
1118{
0c884e17 1119 register_gdbarch_init (bfd_arch_xstormy16, xstormy16_gdbarch_init);
0c884e17 1120}
This page took 0.33468 seconds and 4 git commands to generate.