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