2003-09-11 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
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"
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
154/* Function: xstormy16_register_virtual_size
155 Returns the number of bytes occupied by the register as represented
156 internally by gdb. */
157
158static int
159xstormy16_register_virtual_size (int regnum)
160{
161 return xstormy16_register_raw_size (regnum);
162}
163
164/* Function: xstormy16_reg_virtual_type
165 Returns the default type for register N. */
166
167static struct type *
168xstormy16_reg_virtual_type (int regnum)
169{
170 if (regnum < 0 || regnum >= E_NUM_REGS)
171 internal_error (__FILE__, __LINE__,
172 "xstormy16_register_virtual_type: illegal register number %d",
173 regnum);
174 else if (regnum == E_PC_REGNUM)
175 return builtin_type_uint32;
176 else
177 return builtin_type_uint16;
178}
179
180/* Function: xstormy16_get_saved_register
181 Find a register's saved value on the call stack. */
182
183static void
184xstormy16_get_saved_register (char *raw_buffer,
185 int *optimized,
186 CORE_ADDR *addrp,
187 struct frame_info *fi,
188 int regnum, enum lval_type *lval)
189{
bdcdd535 190 deprecated_generic_get_saved_register (raw_buffer, optimized, addrp, fi, regnum, lval);
0c884e17
CV
191}
192
193/* Function: xstormy16_type_is_scalar
194 Makes the decision if a given type is a scalar types. Scalar
195 types are returned in the registers r2-r7 as they fit. */
196
197static int
198xstormy16_type_is_scalar (struct type *t)
199{
200 return (TYPE_CODE(t) != TYPE_CODE_STRUCT
201 && TYPE_CODE(t) != TYPE_CODE_UNION
202 && TYPE_CODE(t) != TYPE_CODE_ARRAY);
203}
204
205/* Function: xstormy16_extract_return_value
206 Copy the function's return value into VALBUF.
207 This function is called only in the context of "target function calls",
208 ie. when the debugger forces a function to be called in the child, and
209 when the debugger forces a function to return prematurely via the
210 "return" command. */
211
212static void
213xstormy16_extract_return_value (struct type *type, char *regbuf, char *valbuf)
214{
215 CORE_ADDR return_buffer;
216 int offset = 0;
217
218 if (xstormy16_type_is_scalar (type)
219 && TYPE_LENGTH (type) <= E_MAX_RETTYPE_SIZE_IN_REGS)
220 {
221 /* Scalar return values of <= 12 bytes are returned in
222 E_1ST_ARG_REGNUM to E_LST_ARG_REGNUM. */
223 memcpy (valbuf,
224 &regbuf[REGISTER_BYTE (E_1ST_ARG_REGNUM)] + offset,
225 TYPE_LENGTH (type));
226 }
227 else
228 {
229 /* Aggregates and return values > 12 bytes are returned in memory,
230 pointed to by R2. */
231 return_buffer =
7c0b4a20
AC
232 extract_unsigned_integer (regbuf + REGISTER_BYTE (E_PTR_RET_REGNUM),
233 REGISTER_RAW_SIZE (E_PTR_RET_REGNUM));
0c884e17
CV
234
235 read_memory (return_buffer, valbuf, TYPE_LENGTH (type));
236 }
237}
238
239/* Function: xstormy16_push_arguments
240 Setup the function arguments for GDB to call a function in the inferior.
241 Called only in the context of a target function call from the debugger.
242 Returns the value of the SP register after the args are pushed.
243*/
244
245static CORE_ADDR
246xstormy16_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
247 int struct_return, CORE_ADDR struct_addr)
248{
249 CORE_ADDR stack_dest = sp;
250 int argreg = E_1ST_ARG_REGNUM;
251 int i, j;
252 int typelen, slacklen;
253 char *val;
254
255 /* If struct_return is true, then the struct return address will
256 consume one argument-passing register. */
257 if (struct_return)
258 argreg++;
259
260 /* Arguments are passed in R2-R7 as they fit. If an argument doesn't
261 fit in the remaining registers we're switching over to the stack.
262 No argument is put on stack partially and as soon as we switched
263 over to stack no further argument is put in a register even if it
264 would fit in the remaining unused registers. */
265 for (i = 0; i < nargs && argreg <= E_LST_ARG_REGNUM; i++)
266 {
267 typelen = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
268 if (typelen > E_MAX_RETTYPE_SIZE (argreg))
269 break;
270
271 /* Put argument into registers wordwise. */
272 val = VALUE_CONTENTS (args[i]);
273 for (j = 0; j < typelen; j += xstormy16_reg_size)
274 write_register (argreg++,
275 extract_unsigned_integer (val + j,
276 typelen - j ==
277 1 ? 1 :
278 xstormy16_reg_size));
279 }
280
281 /* Align SP */
282 if (stack_dest & 1)
283 ++stack_dest;
284
285 /* Loop backwards through remaining arguments and push them on the stack,
286 wordaligned. */
287 for (j = nargs - 1; j >= i; j--)
288 {
289 typelen = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[j]));
290 slacklen = typelen & 1;
291 val = alloca (typelen + slacklen);
292 memcpy (val, VALUE_CONTENTS (args[j]), typelen);
293 memset (val + typelen, 0, slacklen);
294
295 /* Now write this data to the stack. The stack grows upwards. */
296 write_memory (stack_dest, val, typelen + slacklen);
297 stack_dest += typelen + slacklen;
298 }
299
300 /* And that should do it. Return the new stack pointer. */
301 return stack_dest;
302}
303
304/* Function: xstormy16_push_return_address (pc)
305 Setup the return address for GDB to call a function in the inferior.
306 Called only in the context of a target function call from the debugger.
307 Returns the value of the SP register when the operation is finished
308 (which may or may not be the same as before).
309*/
310
a78f21af 311static CORE_ADDR
0c884e17
CV
312xstormy16_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
313{
314 unsigned char buf[xstormy16_pc_size];
315
88a82a65 316 store_unsigned_integer (buf, xstormy16_pc_size, entry_point_address ());
0c884e17
CV
317 write_memory (sp, buf, xstormy16_pc_size);
318 return sp + xstormy16_pc_size;
319}
320
321/* Function: xstormy16_pop_frame
322 Destroy the innermost (Top-Of-Stack) stack frame, restoring the
323 machine state that was in effect before the frame was created.
324 Used in the contexts of the "return" command, and of
325 target function calls from the debugger.
326*/
327
328static void
329xstormy16_pop_frame (void)
330{
331 struct frame_info *fi = get_current_frame ();
332 int i;
333
334 if (fi == NULL)
335 return; /* paranoia */
336
1e2330ba
AC
337 if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
338 get_frame_base (fi)))
0c884e17
CV
339 {
340 generic_pop_dummy_frame ();
341 }
342 else
343 {
344 /* Restore the saved regs. */
345 for (i = 0; i < NUM_REGS; i++)
b2fb4676 346 if (get_frame_saved_regs (fi)[i])
0c884e17
CV
347 {
348 if (i == SP_REGNUM)
b2fb4676 349 write_register (i, get_frame_saved_regs (fi)[i]);
0c884e17 350 else if (i == E_PC_REGNUM)
b2fb4676 351 write_register (i, read_memory_integer (get_frame_saved_regs (fi)[i],
0c884e17
CV
352 xstormy16_pc_size));
353 else
b2fb4676 354 write_register (i, read_memory_integer (get_frame_saved_regs (fi)[i],
0c884e17
CV
355 xstormy16_reg_size));
356 }
357 /* Restore the PC */
8bedc050 358 write_register (PC_REGNUM, DEPRECATED_FRAME_SAVED_PC (fi));
0c884e17
CV
359 flush_cached_frames ();
360 }
361 return;
362}
363
364/* Function: xstormy16_store_struct_return
365 Copy the (struct) function return value to its destined location.
366 Called only in the context of a target function call from the debugger.
367*/
368
369static void
370xstormy16_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
371{
372 write_register (E_PTR_RET_REGNUM, addr);
373}
374
375/* Function: xstormy16_store_return_value
376 Copy the function return value from VALBUF into the
377 proper location for a function return.
378 Called only in the context of the "return" command.
379*/
380
381static void
382xstormy16_store_return_value (struct type *type, char *valbuf)
383{
384 CORE_ADDR return_buffer;
385 char buf[xstormy16_reg_size];
386
387 if (xstormy16_type_is_scalar (type) && TYPE_LENGTH (type) == 1)
388 {
389 /* Add leading zeros to the value. */
390 memset (buf, 0, xstormy16_reg_size);
391 memcpy (buf, valbuf, 1);
4caf0990 392 deprecated_write_register_gen (E_1ST_ARG_REGNUM, buf);
0c884e17
CV
393 }
394 else if (xstormy16_type_is_scalar (type) &&
395 TYPE_LENGTH (type) <= E_MAX_RETTYPE_SIZE_IN_REGS)
73937e03
AC
396 deprecated_write_register_bytes (REGISTER_BYTE (E_1ST_ARG_REGNUM),
397 valbuf, TYPE_LENGTH (type));
0c884e17
CV
398 else
399 {
400 return_buffer = read_register (E_PTR_RET_REGNUM);
401 write_memory (return_buffer, valbuf, TYPE_LENGTH (type));
402 }
403}
404
405/* Function: xstormy16_extract_struct_value_address
406 Returns the address in which a function should return a struct value.
407 Used in the contexts of the "return" command, and of
408 target function calls from the debugger.
409*/
410
411static CORE_ADDR
412xstormy16_extract_struct_value_address (char *regbuf)
413{
7c0b4a20
AC
414 return extract_unsigned_integer (regbuf + xstormy16_register_byte (E_PTR_RET_REGNUM),
415 xstormy16_reg_size);
0c884e17
CV
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 650 /* Found a function. */
176620f1 651 sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, 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
ac2adee5
AC
726 values may be needed (backtrace, frame_info, frame_register). On
727 many targets, it is called directly by init_extra_frame_info, in
728 part because the information may be needed immediately by
729 frame_chain. */
0c884e17
CV
730
731static void
732xstormy16_frame_init_saved_regs (struct frame_info *fi)
733{
734 CORE_ADDR func_addr, func_end;
735
b2fb4676 736 if (!get_frame_saved_regs (fi))
0c884e17
CV
737 {
738 frame_saved_regs_zalloc (fi);
739
740 /* Find the beginning of this function, so we can analyze its
741 prologue. */
50abf9e5
AC
742 if (find_pc_partial_function (get_frame_pc (fi), NULL, &func_addr, &func_end))
743 xstormy16_scan_prologue (func_addr, get_frame_pc (fi), fi, NULL);
0c884e17
CV
744 /* Else we're out of luck (can't debug completely stripped code).
745 FIXME. */
746 }
747}
748
749/* Function: xstormy16_frame_saved_pc
750 Returns the return address for the selected frame.
e6ba3bc9
AC
751 Called by frame_info, legacy_frame_chain_valid, and sometimes by
752 get_prev_frame. */
0c884e17
CV
753
754static CORE_ADDR
755xstormy16_frame_saved_pc (struct frame_info *fi)
756{
757 CORE_ADDR saved_pc;
758
1e2330ba
AC
759 if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
760 get_frame_base (fi)))
0c884e17 761 {
1e2330ba
AC
762 saved_pc = deprecated_read_register_dummy (get_frame_pc (fi),
763 get_frame_base (fi),
135c175f 764 E_PC_REGNUM);
0c884e17
CV
765 }
766 else
767 {
b2fb4676 768 saved_pc = read_memory_unsigned_integer (get_frame_saved_regs (fi)[E_PC_REGNUM],
0c884e17
CV
769 xstormy16_pc_size);
770 }
771
772 return saved_pc;
773}
774
775/* Function: xstormy16_init_extra_frame_info
776 This is the constructor function for the frame_info struct,
777 called whenever a new frame_info is created (from create_new_frame,
778 and from get_prev_frame).
779*/
780
781static void
782xstormy16_init_extra_frame_info (int fromleaf, struct frame_info *fi)
783{
da50a4b7 784 if (!get_frame_extra_info (fi))
0c884e17 785 {
a00a19e9 786 frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
da50a4b7
AC
787 get_frame_extra_info (fi)->framesize = 0;
788 get_frame_extra_info (fi)->frameless_p = 1; /* Default frameless, detect framed */
0c884e17
CV
789
790 /* By default, the fi->frame is set to the value of the FP reg by gdb.
791 This may not always be right; we may be in a frameless function,
792 or we may be in the prologue, before the FP has been set up.
793 Unfortunately, we can't make this determination without first
794 calling scan_prologue, and we can't do that unles we know the
50abf9e5 795 get_frame_pc (fi). */
0c884e17 796
50abf9e5 797 if (!get_frame_pc (fi))
0c884e17
CV
798 {
799 /* Sometimes we are called from get_prev_frame without
800 the PC being set up first. Long history, don't ask.
801 Fortunately this will never happen from the outermost
802 frame, so we should be able to get the saved pc from
803 the next frame. */
11c02a10
AC
804 if (get_next_frame (fi))
805 deprecated_update_frame_pc_hack (fi, xstormy16_frame_saved_pc (get_next_frame (fi)));
0c884e17
CV
806 }
807
808 /* Take care of the saved_regs right here (non-lazy). */
809 xstormy16_frame_init_saved_regs (fi);
810 }
811}
812
813/* Function: xstormy16_frame_chain
814 Returns a pointer to the stack frame of the calling function.
815 Called only from get_prev_frame. Needed for backtrace, "up", etc.
816*/
817
818static CORE_ADDR
819xstormy16_frame_chain (struct frame_info *fi)
820{
1e2330ba
AC
821 if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
822 get_frame_base (fi)))
0c884e17
CV
823 {
824 /* Call dummy's frame is the same as caller's. */
1e2330ba 825 return get_frame_base (fi);
0c884e17
CV
826 }
827 else
828 {
829 /* Return computed offset from this frame's fp. */
da50a4b7 830 return get_frame_base (fi) - get_frame_extra_info (fi)->framesize;
0c884e17
CV
831 }
832}
833
834static int
835xstormy16_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
836{
8bedc050 837 return chain < 0x8000 && DEPRECATED_FRAME_SAVED_PC (thisframe) >= 0x8000 &&
da50a4b7
AC
838 (get_frame_extra_info (thisframe)->frameless_p ||
839 get_frame_base (thisframe) - get_frame_extra_info (thisframe)->framesize == chain);
0c884e17
CV
840}
841
ac2adee5
AC
842/* Function: xstormy16_saved_pc_after_call Returns the previous PC
843 immediately after a function call. This function is meant to
844 bypass the regular frame_register() mechanism, ie. it is meant to
845 work even if the frame isn't complete. Called by
846 step_over_function, and sometimes by get_prev_frame. */
0c884e17
CV
847
848static CORE_ADDR
849xstormy16_saved_pc_after_call (struct frame_info *ignore)
850{
851 CORE_ADDR sp, pc, tmp;
852
853 sp = read_register (E_SP_REGNUM) - xstormy16_pc_size;
854 pc = read_memory_integer (sp, xstormy16_pc_size);
855
856 /* Skip over jump table entry if necessary. */
857 if ((tmp = SKIP_TRAMPOLINE_CODE (pc)))
858 pc = tmp;
859
860 return pc;
861}
862
f4f9705a 863const static unsigned char *
0c884e17
CV
864xstormy16_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
865{
866 static unsigned char breakpoint[] = { 0x06, 0x0 };
867 *lenptr = sizeof (breakpoint);
868 return breakpoint;
869}
870
871/* Given a pointer to a jump table entry, return the address
872 of the function it jumps to. Return 0 if not found. */
873static CORE_ADDR
874xstormy16_resolve_jmp_table_entry (CORE_ADDR faddr)
875{
876 struct obj_section *faddr_sect = find_pc_section (faddr);
877
878 if (faddr_sect)
879 {
880 LONGEST inst, inst2, addr;
881 char buf[2 * xstormy16_inst_size];
882
883 /* Return faddr if it's not pointing into the jump table. */
884 if (strcmp (faddr_sect->the_bfd_section->name, ".plt"))
885 return faddr;
886
887 if (!target_read_memory (faddr, buf, sizeof buf))
888 {
889 inst = extract_unsigned_integer (buf, xstormy16_inst_size);
890 inst2 = extract_unsigned_integer (buf + xstormy16_inst_size,
891 xstormy16_inst_size);
892 addr = inst2 << 8 | (inst & 0xff);
893 return addr;
894 }
895 }
896 return 0;
897}
898
899/* Given a function's address, attempt to find (and return) the
900 address of the corresponding jump table entry. Return 0 if
901 not found. */
902static CORE_ADDR
903xstormy16_find_jmp_table_entry (CORE_ADDR faddr)
904{
905 struct obj_section *faddr_sect = find_pc_section (faddr);
906
907 if (faddr_sect)
908 {
909 struct obj_section *osect;
910
911 /* Return faddr if it's already a pointer to a jump table entry. */
912 if (!strcmp (faddr_sect->the_bfd_section->name, ".plt"))
913 return faddr;
914
915 ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
916 {
917 if (!strcmp (osect->the_bfd_section->name, ".plt"))
918 break;
919 }
920
921 if (osect < faddr_sect->objfile->sections_end)
922 {
923 CORE_ADDR addr;
924 for (addr = osect->addr;
925 addr < osect->endaddr; addr += 2 * xstormy16_inst_size)
926 {
927 int status;
928 LONGEST inst, inst2, faddr2;
929 char buf[2 * xstormy16_inst_size];
930
931 if (target_read_memory (addr, buf, sizeof buf))
932 return 0;
933 inst = extract_unsigned_integer (buf, xstormy16_inst_size);
934 inst2 = extract_unsigned_integer (buf + xstormy16_inst_size,
935 xstormy16_inst_size);
936 faddr2 = inst2 << 8 | (inst & 0xff);
937 if (faddr == faddr2)
938 return addr;
939 }
940 }
941 }
942 return 0;
943}
944
945static CORE_ADDR
946xstormy16_skip_trampoline_code (CORE_ADDR pc)
947{
948 int tmp = xstormy16_resolve_jmp_table_entry (pc);
949
950 if (tmp && tmp != pc)
951 return tmp;
952 return 0;
953}
954
955static int
956xstormy16_in_solib_call_trampoline (CORE_ADDR pc, char *name)
957{
958 return xstormy16_skip_trampoline_code (pc) != 0;
959}
960
961static CORE_ADDR
66140c26 962xstormy16_pointer_to_address (struct type *type, const void *buf)
0c884e17
CV
963{
964 enum type_code target = TYPE_CODE (TYPE_TARGET_TYPE (type));
7c0b4a20 965 CORE_ADDR addr = extract_unsigned_integer (buf, TYPE_LENGTH (type));
0c884e17
CV
966
967 if (target == TYPE_CODE_FUNC || target == TYPE_CODE_METHOD)
968 {
969 CORE_ADDR addr2 = xstormy16_resolve_jmp_table_entry (addr);
970 if (addr2)
971 addr = addr2;
972 }
973
974 return addr;
975}
976
977static void
978xstormy16_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr)
979{
980 enum type_code target = TYPE_CODE (TYPE_TARGET_TYPE (type));
981
982 if (target == TYPE_CODE_FUNC || target == TYPE_CODE_METHOD)
983 {
984 CORE_ADDR addr2 = xstormy16_find_jmp_table_entry (addr);
985 if (addr2)
986 addr = addr2;
987 }
fbd9dcd3 988 store_unsigned_integer (buf, TYPE_LENGTH (type), addr);
0c884e17
CV
989}
990
991static CORE_ADDR
992xstormy16_stack_align (CORE_ADDR addr)
993{
994 if (addr & 1)
995 ++addr;
996 return addr;
997}
998
a78f21af 999static void
0c884e17
CV
1000xstormy16_save_dummy_frame_tos (CORE_ADDR sp)
1001{
1002 generic_save_dummy_frame_tos (sp - xstormy16_pc_size);
1003}
1004
1005/* Function: xstormy16_gdbarch_init
1006 Initializer function for the xstormy16 gdbarch vector.
1007 Called by gdbarch. Sets up the gdbarch vector(s) for this target. */
1008
1009static struct gdbarch *
1010xstormy16_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1011{
1012 static LONGEST call_dummy_words[1] = { 0 };
1013 struct gdbarch_tdep *tdep = NULL;
1014 struct gdbarch *gdbarch;
1015
1016 /* find a candidate among the list of pre-declared architectures. */
1017 arches = gdbarch_list_lookup_by_info (arches, &info);
1018 if (arches != NULL)
1019 return (arches->gdbarch);
1020
1021#if 0
1022 tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
1023#endif
1024
1025 gdbarch = gdbarch_alloc (&info, 0);
1026
a5afb99f
AC
1027 /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
1028 ready to unwind the PC first (see frame.c:get_prev_frame()). */
1029 set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_default);
1030
0c884e17
CV
1031 /*
1032 * Basic register fields and methods.
1033 */
1034
1035 set_gdbarch_num_regs (gdbarch, E_NUM_REGS);
1036 set_gdbarch_num_pseudo_regs (gdbarch, 0);
1037 set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
0ba6dca9 1038 set_gdbarch_deprecated_fp_regnum (gdbarch, E_FP_REGNUM);
0c884e17
CV
1039 set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
1040 set_gdbarch_register_name (gdbarch, xstormy16_register_name);
b1e29e33 1041 set_gdbarch_deprecated_register_size (gdbarch, xstormy16_reg_size);
b8b527c5 1042 set_gdbarch_deprecated_register_bytes (gdbarch, E_ALL_REGS_SIZE);
9c04cab7
AC
1043 set_gdbarch_deprecated_register_byte (gdbarch, xstormy16_register_byte);
1044 set_gdbarch_deprecated_register_raw_size (gdbarch, xstormy16_register_raw_size);
a0ed5532 1045 set_gdbarch_deprecated_max_register_raw_size (gdbarch, xstormy16_pc_size);
9c04cab7 1046 set_gdbarch_deprecated_register_virtual_size (gdbarch, xstormy16_register_raw_size);
a0ed5532 1047 set_gdbarch_deprecated_max_register_virtual_size (gdbarch, 4);
9c04cab7 1048 set_gdbarch_deprecated_register_virtual_type (gdbarch, xstormy16_reg_virtual_type);
0c884e17
CV
1049
1050 /*
1051 * Frame Info
1052 */
e9582e71 1053 set_gdbarch_deprecated_init_extra_frame_info (gdbarch,
0c884e17 1054 xstormy16_init_extra_frame_info);
f30ee0bc 1055 set_gdbarch_deprecated_frame_init_saved_regs (gdbarch,
0c884e17 1056 xstormy16_frame_init_saved_regs);
618ce49f 1057 set_gdbarch_deprecated_frame_chain (gdbarch, xstormy16_frame_chain);
129c1cd6 1058 set_gdbarch_deprecated_get_saved_register (gdbarch, xstormy16_get_saved_register);
6913c89a 1059 set_gdbarch_deprecated_saved_pc_after_call (gdbarch, xstormy16_saved_pc_after_call);
8bedc050 1060 set_gdbarch_deprecated_frame_saved_pc (gdbarch, xstormy16_frame_saved_pc);
0c884e17 1061 set_gdbarch_skip_prologue (gdbarch, xstormy16_skip_prologue);
618ce49f 1062 set_gdbarch_deprecated_frame_chain_valid (gdbarch, xstormy16_frame_chain_valid);
0c884e17
CV
1063
1064 set_gdbarch_in_function_epilogue_p (gdbarch,
1065 xstormy16_in_function_epilogue_p);
1066
1067 /*
1068 * Miscelany
1069 */
1070 /* Stack grows up. */
1071 set_gdbarch_inner_than (gdbarch, core_addr_greaterthan);
1072 /* PC stops zero byte after a trap instruction
1073 (which means: exactly on trap instruction). */
1074 set_gdbarch_decr_pc_after_break (gdbarch, 0);
1075 /* This value is almost never non-zero... */
1076 set_gdbarch_function_start_offset (gdbarch, 0);
1077 /* This value is almost never non-zero... */
1078 set_gdbarch_frame_args_skip (gdbarch, 0);
0c884e17 1079
0c884e17
CV
1080 /*
1081 * Call Dummies
1082 *
1083 * These values and methods are used when gdb calls a target function. */
28f617b3 1084 set_gdbarch_deprecated_push_return_address (gdbarch, xstormy16_push_return_address);
26e9b323 1085 set_gdbarch_deprecated_extract_return_value (gdbarch, xstormy16_extract_return_value);
b81774d8 1086 set_gdbarch_deprecated_push_arguments (gdbarch, xstormy16_push_arguments);
749b82f6 1087 set_gdbarch_deprecated_pop_frame (gdbarch, xstormy16_pop_frame);
4183d812 1088 set_gdbarch_deprecated_store_struct_return (gdbarch, xstormy16_store_struct_return);
ebba8386 1089 set_gdbarch_deprecated_store_return_value (gdbarch, xstormy16_store_return_value);
26e9b323 1090 set_gdbarch_deprecated_extract_struct_value_address (gdbarch, xstormy16_extract_struct_value_address);
0c884e17
CV
1091 set_gdbarch_use_struct_convention (gdbarch,
1092 xstormy16_use_struct_convention);
b1e29e33
AC
1093 set_gdbarch_deprecated_call_dummy_words (gdbarch, call_dummy_words);
1094 set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, 0);
0c884e17
CV
1095 set_gdbarch_breakpoint_from_pc (gdbarch, xstormy16_breakpoint_from_pc);
1096
71c08af0 1097 set_gdbarch_char_signed (gdbarch, 0);
0c884e17
CV
1098 set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1099 set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1100 set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1101 set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
1102
1103 set_gdbarch_address_to_pointer (gdbarch, xstormy16_address_to_pointer);
1104 set_gdbarch_pointer_to_address (gdbarch, xstormy16_pointer_to_address);
1105
f27dd7fd 1106 set_gdbarch_deprecated_stack_align (gdbarch, xstormy16_stack_align);
0c884e17 1107
a59fe496 1108 set_gdbarch_deprecated_save_dummy_frame_tos (gdbarch, xstormy16_save_dummy_frame_tos);
0c884e17
CV
1109
1110 set_gdbarch_skip_trampoline_code (gdbarch, xstormy16_skip_trampoline_code);
1111
1112 set_gdbarch_in_solib_call_trampoline (gdbarch,
1113 xstormy16_in_solib_call_trampoline);
1114
6c0e89ed 1115 /* Should be using push_dummy_call. */
b46e02f6 1116 set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
6c0e89ed 1117
36482093
AC
1118 set_gdbarch_print_insn (gdbarch, print_insn_xstormy16);
1119
0c884e17
CV
1120 return gdbarch;
1121}
1122
1123/* Function: _initialize_xstormy16_tdep
1124 Initializer function for the Sanyo Xstormy16a module.
1125 Called by gdb at start-up. */
1126
a78f21af
AC
1127extern initialize_file_ftype _initialize_xstormy16_tdep; /* -Wmissing-prototypes */
1128
0c884e17
CV
1129void
1130_initialize_xstormy16_tdep (void)
1131{
0c884e17 1132 register_gdbarch_init (bfd_arch_xstormy16, xstormy16_gdbarch_init);
0c884e17 1133}
This page took 0.278259 seconds and 4 git commands to generate.