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