]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/xstormy16-tdep.c
Update years in copyright notice for the GDB files.
[thirdparty/binutils-gdb.git] / gdb / xstormy16-tdep.c
CommitLineData
0c884e17 1/* Target-dependent code for the Sanyo Xstormy16a (LC590000) processor.
f4f9705a 2
8acc9f48 3 Copyright (C) 2001-2013 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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
0c884e17
CV
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0c884e17
CV
19
20#include "defs.h"
b6fcb393
CV
21#include "frame.h"
22#include "frame-base.h"
23#include "frame-unwind.h"
24#include "dwarf2-frame.h"
25#include "symtab.h"
26#include "gdbtypes.h"
27#include "gdbcmd.h"
28#include "gdbcore.h"
0c884e17 29#include "value.h"
b6fcb393 30#include "dis-asm.h"
0c884e17 31#include "inferior.h"
b6fcb393
CV
32#include "gdb_string.h"
33#include "gdb_assert.h"
0c884e17 34#include "arch-utils.h"
b6fcb393 35#include "floatformat.h"
0c884e17 36#include "regcache.h"
b6fcb393
CV
37#include "doublest.h"
38#include "osabi.h"
0c884e17 39#include "objfiles.h"
0c884e17
CV
40
41enum gdb_regnum
42{
43 /* Xstormy16 has 16 general purpose registers (R0-R15) plus PC.
44 Functions will return their values in register R2-R7 as they fit.
45 Otherwise a hidden pointer to an big enough area is given as argument
581e13c1 46 to the function in r2. Further arguments are beginning in r3 then.
0c884e17
CV
47 R13 is used as frame pointer when GCC compiles w/o optimization
48 R14 is used as "PSW", displaying the CPU status.
581e13c1 49 R15 is used implicitely as stack pointer. */
0c884e17
CV
50 E_R0_REGNUM,
51 E_R1_REGNUM,
52 E_R2_REGNUM, E_1ST_ARG_REGNUM = E_R2_REGNUM, E_PTR_RET_REGNUM = E_R2_REGNUM,
53 E_R3_REGNUM,
54 E_R4_REGNUM,
55 E_R5_REGNUM,
56 E_R6_REGNUM,
57 E_R7_REGNUM, E_LST_ARG_REGNUM = E_R7_REGNUM,
58 E_R8_REGNUM,
59 E_R9_REGNUM,
60 E_R10_REGNUM,
61 E_R11_REGNUM,
62 E_R12_REGNUM,
63 E_R13_REGNUM, E_FP_REGNUM = E_R13_REGNUM,
64 E_R14_REGNUM, E_PSW_REGNUM = E_R14_REGNUM,
65 E_R15_REGNUM, E_SP_REGNUM = E_R15_REGNUM,
66 E_PC_REGNUM,
67 E_NUM_REGS
68};
69
b6fcb393
CV
70/* Use an invalid address value as 'not available' marker. */
71enum { REG_UNAVAIL = (CORE_ADDR) -1 };
72
73struct xstormy16_frame_cache
74{
75 /* Base address. */
76 CORE_ADDR base;
77 CORE_ADDR pc;
78 LONGEST framesize;
79 int uses_fp;
80 CORE_ADDR saved_regs[E_NUM_REGS];
81 CORE_ADDR saved_sp;
82};
83
581e13c1 84/* Size of instructions, registers, etc. */
0c884e17
CV
85enum
86{
87 xstormy16_inst_size = 2,
88 xstormy16_reg_size = 2,
89 xstormy16_pc_size = 4
90};
91
581e13c1 92/* Size of return datatype which fits into the remaining return registers. */
0c884e17
CV
93#define E_MAX_RETTYPE_SIZE(regnum) ((E_LST_ARG_REGNUM - (regnum) + 1) \
94 * xstormy16_reg_size)
95
581e13c1 96/* Size of return datatype which fits into all return registers. */
0c884e17
CV
97enum
98{
99 E_MAX_RETTYPE_SIZE_IN_REGS = E_MAX_RETTYPE_SIZE (E_R2_REGNUM)
100};
101
0c884e17 102/* Function: xstormy16_register_name
b6fcb393 103 Returns the name of the standard Xstormy16 register N. */
0c884e17 104
fa88f677 105static const char *
d93859e2 106xstormy16_register_name (struct gdbarch *gdbarch, int regnum)
0c884e17
CV
107{
108 static char *register_names[] = {
109 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
110 "r8", "r9", "r10", "r11", "r12", "r13",
111 "psw", "sp", "pc"
112 };
113
b6fcb393 114 if (regnum < 0 || regnum >= E_NUM_REGS)
0c884e17 115 internal_error (__FILE__, __LINE__,
e2e0b3e5 116 _("xstormy16_register_name: illegal register number %d"),
0c884e17
CV
117 regnum);
118 else
119 return register_names[regnum];
120
121}
122
0c884e17 123static struct type *
b6fcb393 124xstormy16_register_type (struct gdbarch *gdbarch, int regnum)
0c884e17 125{
b6fcb393 126 if (regnum == E_PC_REGNUM)
df4df182 127 return builtin_type (gdbarch)->builtin_uint32;
0c884e17 128 else
df4df182 129 return builtin_type (gdbarch)->builtin_uint16;
0c884e17
CV
130}
131
0c884e17
CV
132/* Function: xstormy16_type_is_scalar
133 Makes the decision if a given type is a scalar types. Scalar
b6fcb393 134 types are returned in the registers r2-r7 as they fit. */
0c884e17
CV
135
136static int
137xstormy16_type_is_scalar (struct type *t)
138{
139 return (TYPE_CODE(t) != TYPE_CODE_STRUCT
140 && TYPE_CODE(t) != TYPE_CODE_UNION
141 && TYPE_CODE(t) != TYPE_CODE_ARRAY);
142}
143
b6fcb393
CV
144/* Function: xstormy16_use_struct_convention
145 Returns non-zero if the given struct type will be returned using
146 a special convention, rather than the normal function return method.
147 7sed in the contexts of the "return" command, and of
148 target function calls from the debugger. */
149
150static int
151xstormy16_use_struct_convention (struct type *type)
152{
153 return !xstormy16_type_is_scalar (type)
154 || TYPE_LENGTH (type) > E_MAX_RETTYPE_SIZE_IN_REGS;
155}
156
0c884e17 157/* Function: xstormy16_extract_return_value
b6fcb393
CV
158 Find a function's return value in the appropriate registers (in
159 regbuf), and copy it into valbuf. */
0c884e17
CV
160
161static void
b6fcb393
CV
162xstormy16_extract_return_value (struct type *type, struct regcache *regcache,
163 void *valbuf)
0c884e17 164{
b6fcb393
CV
165 int len = TYPE_LENGTH (type);
166 int i, regnum = E_1ST_ARG_REGNUM;
0c884e17 167
b6fcb393
CV
168 for (i = 0; i < len; i += xstormy16_reg_size)
169 regcache_raw_read (regcache, regnum++, (char *) valbuf + i);
170}
171
172/* Function: xstormy16_store_return_value
173 Copy the function return value from VALBUF into the
174 proper location for a function return.
175 Called only in the context of the "return" command. */
176
177static void
178xstormy16_store_return_value (struct type *type, struct regcache *regcache,
179 const void *valbuf)
180{
181 if (TYPE_LENGTH (type) == 1)
182 {
581e13c1 183 /* Add leading zeros to the value. */
b6fcb393
CV
184 char buf[xstormy16_reg_size];
185 memset (buf, 0, xstormy16_reg_size);
186 memcpy (buf, valbuf, 1);
187 regcache_raw_write (regcache, E_1ST_ARG_REGNUM, buf);
0c884e17
CV
188 }
189 else
190 {
b6fcb393
CV
191 int len = TYPE_LENGTH (type);
192 int i, regnum = E_1ST_ARG_REGNUM;
0c884e17 193
b6fcb393
CV
194 for (i = 0; i < len; i += xstormy16_reg_size)
195 regcache_raw_write (regcache, regnum++, (char *) valbuf + i);
0c884e17
CV
196 }
197}
198
b6fcb393 199static enum return_value_convention
6a3a010b 200xstormy16_return_value (struct gdbarch *gdbarch, struct value *function,
c055b101 201 struct type *type, struct regcache *regcache,
05c6a9a1 202 gdb_byte *readbuf, const gdb_byte *writebuf)
b6fcb393
CV
203{
204 if (xstormy16_use_struct_convention (type))
205 return RETURN_VALUE_STRUCT_CONVENTION;
206 if (writebuf)
207 xstormy16_store_return_value (type, regcache, writebuf);
208 else if (readbuf)
209 xstormy16_extract_return_value (type, regcache, readbuf);
210 return RETURN_VALUE_REGISTER_CONVENTION;
211}
212
213static CORE_ADDR
214xstormy16_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
215{
216 if (addr & 1)
217 ++addr;
218 return addr;
219}
220
221/* Function: xstormy16_push_dummy_call
0c884e17
CV
222 Setup the function arguments for GDB to call a function in the inferior.
223 Called only in the context of a target function call from the debugger.
b6fcb393 224 Returns the value of the SP register after the args are pushed. */
0c884e17
CV
225
226static CORE_ADDR
b6fcb393
CV
227xstormy16_push_dummy_call (struct gdbarch *gdbarch,
228 struct value *function,
229 struct regcache *regcache,
230 CORE_ADDR bp_addr, int nargs,
231 struct value **args,
232 CORE_ADDR sp, int struct_return,
233 CORE_ADDR struct_addr)
0c884e17 234{
e17a4113 235 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
0c884e17
CV
236 CORE_ADDR stack_dest = sp;
237 int argreg = E_1ST_ARG_REGNUM;
238 int i, j;
239 int typelen, slacklen;
05c6a9a1 240 const gdb_byte *val;
b6fcb393 241 char buf[xstormy16_pc_size];
0c884e17
CV
242
243 /* If struct_return is true, then the struct return address will
244 consume one argument-passing register. */
245 if (struct_return)
b6fcb393
CV
246 {
247 regcache_cooked_write_unsigned (regcache, E_PTR_RET_REGNUM, struct_addr);
248 argreg++;
249 }
0c884e17 250
581e13c1 251 /* Arguments are passed in R2-R7 as they fit. If an argument doesn't
0c884e17
CV
252 fit in the remaining registers we're switching over to the stack.
253 No argument is put on stack partially and as soon as we switched
254 over to stack no further argument is put in a register even if it
b6fcb393 255 would fit in the remaining unused registers. */
0c884e17
CV
256 for (i = 0; i < nargs && argreg <= E_LST_ARG_REGNUM; i++)
257 {
4754a64e 258 typelen = TYPE_LENGTH (value_enclosing_type (args[i]));
0c884e17
CV
259 if (typelen > E_MAX_RETTYPE_SIZE (argreg))
260 break;
261
581e13c1 262 /* Put argument into registers wordwise. */
0fd88904 263 val = value_contents (args[i]);
0c884e17 264 for (j = 0; j < typelen; j += xstormy16_reg_size)
1c6e1b0d
PM
265 {
266 ULONGEST regval;
267 int size = (typelen - j == 1) ? 1 : xstormy16_reg_size;
268
269 regval = extract_unsigned_integer (val + j, size, byte_order);
270 regcache_cooked_write_unsigned (regcache, argreg++, regval);
271 }
0c884e17
CV
272 }
273
274 /* Align SP */
b6fcb393 275 stack_dest = xstormy16_frame_align (gdbarch, stack_dest);
0c884e17
CV
276
277 /* Loop backwards through remaining arguments and push them on the stack,
b6fcb393 278 wordaligned. */
0c884e17
CV
279 for (j = nargs - 1; j >= i; j--)
280 {
05c6a9a1 281 char *val;
ecfb0d68
SP
282 struct cleanup *back_to;
283 const gdb_byte *bytes = value_contents (args[j]);
05c6a9a1 284
4754a64e 285 typelen = TYPE_LENGTH (value_enclosing_type (args[j]));
0c884e17 286 slacklen = typelen & 1;
ecfb0d68
SP
287 val = xmalloc (typelen + slacklen);
288 back_to = make_cleanup (xfree, val);
289 memcpy (val, bytes, typelen);
0c884e17
CV
290 memset (val + typelen, 0, slacklen);
291
581e13c1 292 /* Now write this data to the stack. The stack grows upwards. */
0c884e17
CV
293 write_memory (stack_dest, val, typelen + slacklen);
294 stack_dest += typelen + slacklen;
ecfb0d68 295 do_cleanups (back_to);
0c884e17
CV
296 }
297
e17a4113 298 store_unsigned_integer (buf, xstormy16_pc_size, byte_order, bp_addr);
b6fcb393
CV
299 write_memory (stack_dest, buf, xstormy16_pc_size);
300 stack_dest += xstormy16_pc_size;
0c884e17 301
b6fcb393
CV
302 /* Update stack pointer. */
303 regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, stack_dest);
0c884e17 304
b6fcb393
CV
305 /* Return the new stack pointer minus the return address slot since
306 that's what DWARF2/GCC uses as the frame's CFA. */
307 return stack_dest - xstormy16_pc_size;
0c884e17
CV
308}
309
310/* Function: xstormy16_scan_prologue
311 Decode the instructions within the given address range.
312 Decide when we must have reached the end of the function prologue.
313 If a frame_info pointer is provided, fill in its saved_regs etc.
314
b6fcb393 315 Returns the address of the first instruction after the prologue. */
0c884e17
CV
316
317static CORE_ADDR
e17a4113
UW
318xstormy16_analyze_prologue (struct gdbarch *gdbarch,
319 CORE_ADDR start_addr, CORE_ADDR end_addr,
b6fcb393 320 struct xstormy16_frame_cache *cache,
94afd7a6 321 struct frame_info *this_frame)
0c884e17 322{
e17a4113 323 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
0c884e17
CV
324 CORE_ADDR next_addr;
325 ULONGEST inst, inst2;
326 LONGEST offset;
327 int regnum;
328
581e13c1 329 /* Initialize framesize with size of PC put on stack by CALLF inst. */
b6fcb393
CV
330 cache->saved_regs[E_PC_REGNUM] = 0;
331 cache->framesize = xstormy16_pc_size;
332
333 if (start_addr >= end_addr)
334 return end_addr;
335
0c884e17
CV
336 for (next_addr = start_addr;
337 next_addr < end_addr; next_addr += xstormy16_inst_size)
338 {
e17a4113
UW
339 inst = read_memory_unsigned_integer (next_addr,
340 xstormy16_inst_size, byte_order);
0c884e17 341 inst2 = read_memory_unsigned_integer (next_addr + xstormy16_inst_size,
e17a4113 342 xstormy16_inst_size, byte_order);
0c884e17
CV
343
344 if (inst >= 0x0082 && inst <= 0x008d) /* push r2 .. push r13 */
345 {
b6fcb393
CV
346 regnum = inst & 0x000f;
347 cache->saved_regs[regnum] = cache->framesize;
348 cache->framesize += xstormy16_reg_size;
0c884e17
CV
349 }
350
581e13c1
MS
351 /* Optional stack allocation for args and local vars <= 4 byte. */
352 else if (inst == 0x301f || inst == 0x303f) /* inc r15, #0x1/#0x3 */
0c884e17 353 {
b6fcb393 354 cache->framesize += ((inst & 0x0030) >> 4) + 1;
0c884e17
CV
355 }
356
357 /* optional stack allocation for args and local vars > 4 && < 16 byte */
358 else if ((inst & 0xff0f) == 0x510f) /* 51Hf add r15, #0xH */
359 {
b6fcb393 360 cache->framesize += (inst & 0x00f0) >> 4;
0c884e17
CV
361 }
362
581e13c1
MS
363 /* Optional stack allocation for args and local vars >= 16 byte. */
364 else if (inst == 0x314f && inst2 >= 0x0010) /* 314f HHHH add r15, #0xH */
0c884e17 365 {
b6fcb393 366 cache->framesize += inst2;
0c884e17
CV
367 next_addr += xstormy16_inst_size;
368 }
369
370 else if (inst == 0x46fd) /* mov r13, r15 */
371 {
b6fcb393 372 cache->uses_fp = 1;
0c884e17
CV
373 }
374
581e13c1
MS
375 /* optional copying of args in r2-r7 to r10-r13. */
376 /* Probably only in optimized case but legal action for prologue. */
0c884e17
CV
377 else if ((inst & 0xff00) == 0x4600 /* 46SD mov rD, rS */
378 && (inst & 0x00f0) >= 0x0020 && (inst & 0x00f0) <= 0x0070
379 && (inst & 0x000f) >= 0x00a0 && (inst & 0x000f) <= 0x000d)
380 ;
381
581e13c1
MS
382 /* Optional copying of args in r2-r7 to stack. */
383 /* 72DS HHHH mov.b (rD, 0xHHHH), r(S-8)
384 (bit3 always 1, bit2-0 = reg) */
0c884e17
CV
385 /* 73DS HHHH mov.w (rD, 0xHHHH), r(S-8) */
386 else if ((inst & 0xfed8) == 0x72d8 && (inst & 0x0007) >= 2)
387 {
b6fcb393
CV
388 regnum = inst & 0x0007;
389 /* Only 12 of 16 bits of the argument are used for the
581e13c1 390 signed offset. */
b6fcb393
CV
391 offset = (LONGEST) (inst2 & 0x0fff);
392 if (offset & 0x0800)
393 offset -= 0x1000;
394
395 cache->saved_regs[regnum] = cache->framesize + offset;
0c884e17
CV
396 next_addr += xstormy16_inst_size;
397 }
0c884e17 398
581e13c1 399 else /* Not a prologue instruction. */
0c884e17
CV
400 break;
401 }
402
0c884e17
CV
403 return next_addr;
404}
405
406/* Function: xstormy16_skip_prologue
407 If the input address is in a function prologue,
408 returns the address of the end of the prologue;
409 else returns the input address.
410
411 Note: the input address is likely to be the function start,
412 since this function is mainly used for advancing a breakpoint
413 to the first line, or stepping to the first line when we have
414 stepped into a function call. */
415
416static CORE_ADDR
6093d2eb 417xstormy16_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
0c884e17
CV
418{
419 CORE_ADDR func_addr = 0, func_end = 0;
2c02bd72 420 const char *func_name;
0c884e17
CV
421
422 if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
423 {
424 struct symtab_and_line sal;
425 struct symbol *sym;
b6fcb393 426 struct xstormy16_frame_cache cache;
57fdbbbe 427 CORE_ADDR plg_end;
0c884e17 428
28fe5f6a
KB
429 memset (&cache, 0, sizeof cache);
430
581e13c1 431 /* Don't trust line number debug info in frameless functions. */
e17a4113
UW
432 plg_end = xstormy16_analyze_prologue (gdbarch, func_addr, func_end,
433 &cache, NULL);
b6fcb393 434 if (!cache.uses_fp)
211a4f69
CV
435 return plg_end;
436
0c884e17 437 /* Found a function. */
2570f2b7 438 sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL);
581e13c1 439 /* Don't use line number debug info for assembly source files. */
0c884e17
CV
440 if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
441 {
0c884e17
CV
442 sal = find_pc_line (func_addr, 0);
443 if (sal.end && sal.end < func_end)
444 {
445 /* Found a line number, use it as end of prologue. */
446 return sal.end;
447 }
448 }
581e13c1 449 /* No useable line symbol. Use result of prologue parsing method. */
211a4f69 450 return plg_end;
0c884e17
CV
451 }
452
581e13c1 453 /* No function symbol -- just return the PC. */
0c884e17
CV
454
455 return (CORE_ADDR) pc;
456}
457
458/* The epilogue is defined here as the area at the end of a function,
459 either on the `ret' instruction itself or after an instruction which
581e13c1 460 destroys the function's stack frame. */
0c884e17
CV
461static int
462xstormy16_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
463{
e17a4113 464 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
b6fcb393 465 CORE_ADDR func_addr = 0, func_end = 0;
0c884e17
CV
466
467 if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
468 {
469 ULONGEST inst, inst2;
470 CORE_ADDR addr = func_end - xstormy16_inst_size;
471
581e13c1 472 /* The Xstormy16 epilogue is max. 14 bytes long. */
0c884e17
CV
473 if (pc < func_end - 7 * xstormy16_inst_size)
474 return 0;
475
476 /* Check if we're on a `ret' instruction. Otherwise it's
581e13c1 477 too dangerous to proceed. */
e17a4113
UW
478 inst = read_memory_unsigned_integer (addr,
479 xstormy16_inst_size, byte_order);
0c884e17
CV
480 if (inst != 0x0003)
481 return 0;
482
483 while ((addr -= xstormy16_inst_size) >= func_addr)
484 {
e17a4113 485 inst = read_memory_unsigned_integer (addr,
581e13c1
MS
486 xstormy16_inst_size,
487 byte_order);
0c884e17
CV
488 if (inst >= 0x009a && inst <= 0x009d) /* pop r10...r13 */
489 continue;
490 if (inst == 0x305f || inst == 0x307f) /* dec r15, #0x1/#0x3 */
491 break;
492 inst2 = read_memory_unsigned_integer (addr - xstormy16_inst_size,
581e13c1
MS
493 xstormy16_inst_size,
494 byte_order);
495 if (inst2 == 0x314f && inst >= 0x8000) /* add r15, neg. value */
0c884e17
CV
496 {
497 addr -= xstormy16_inst_size;
498 break;
499 }
500 return 0;
501 }
502 if (pc > addr)
503 return 1;
504 }
505 return 0;
506}
507
f4f9705a 508const static unsigned char *
67d57894
MD
509xstormy16_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
510 int *lenptr)
0c884e17
CV
511{
512 static unsigned char breakpoint[] = { 0x06, 0x0 };
513 *lenptr = sizeof (breakpoint);
514 return breakpoint;
515}
516
517/* Given a pointer to a jump table entry, return the address
581e13c1 518 of the function it jumps to. Return 0 if not found. */
0c884e17 519static CORE_ADDR
e17a4113 520xstormy16_resolve_jmp_table_entry (struct gdbarch *gdbarch, CORE_ADDR faddr)
0c884e17 521{
e17a4113 522 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
0c884e17
CV
523 struct obj_section *faddr_sect = find_pc_section (faddr);
524
525 if (faddr_sect)
526 {
527 LONGEST inst, inst2, addr;
528 char buf[2 * xstormy16_inst_size];
529
581e13c1 530 /* Return faddr if it's not pointing into the jump table. */
0c884e17
CV
531 if (strcmp (faddr_sect->the_bfd_section->name, ".plt"))
532 return faddr;
533
534 if (!target_read_memory (faddr, buf, sizeof buf))
535 {
e17a4113
UW
536 inst = extract_unsigned_integer (buf,
537 xstormy16_inst_size, byte_order);
0c884e17 538 inst2 = extract_unsigned_integer (buf + xstormy16_inst_size,
e17a4113 539 xstormy16_inst_size, byte_order);
0c884e17
CV
540 addr = inst2 << 8 | (inst & 0xff);
541 return addr;
542 }
543 }
544 return 0;
545}
546
547/* Given a function's address, attempt to find (and return) the
548 address of the corresponding jump table entry. Return 0 if
581e13c1 549 not found. */
0c884e17 550static CORE_ADDR
e17a4113 551xstormy16_find_jmp_table_entry (struct gdbarch *gdbarch, CORE_ADDR faddr)
0c884e17 552{
e17a4113 553 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
0c884e17
CV
554 struct obj_section *faddr_sect = find_pc_section (faddr);
555
556 if (faddr_sect)
557 {
558 struct obj_section *osect;
559
581e13c1 560 /* Return faddr if it's already a pointer to a jump table entry. */
0c884e17
CV
561 if (!strcmp (faddr_sect->the_bfd_section->name, ".plt"))
562 return faddr;
563
564 ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
565 {
566 if (!strcmp (osect->the_bfd_section->name, ".plt"))
567 break;
568 }
569
570 if (osect < faddr_sect->objfile->sections_end)
571 {
aded6f54
PA
572 CORE_ADDR addr, endaddr;
573
574 addr = obj_section_addr (osect);
575 endaddr = obj_section_endaddr (osect);
576
577 for (; addr < endaddr; addr += 2 * xstormy16_inst_size)
0c884e17 578 {
0c884e17
CV
579 LONGEST inst, inst2, faddr2;
580 char buf[2 * xstormy16_inst_size];
581
582 if (target_read_memory (addr, buf, sizeof buf))
583 return 0;
e17a4113 584 inst = extract_unsigned_integer (buf,
581e13c1
MS
585 xstormy16_inst_size,
586 byte_order);
0c884e17 587 inst2 = extract_unsigned_integer (buf + xstormy16_inst_size,
581e13c1
MS
588 xstormy16_inst_size,
589 byte_order);
0c884e17
CV
590 faddr2 = inst2 << 8 | (inst & 0xff);
591 if (faddr == faddr2)
592 return addr;
593 }
594 }
595 }
596 return 0;
597}
598
599static CORE_ADDR
52f729a7 600xstormy16_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
0c884e17 601{
e17a4113
UW
602 struct gdbarch *gdbarch = get_frame_arch (frame);
603 CORE_ADDR tmp = xstormy16_resolve_jmp_table_entry (gdbarch, pc);
0c884e17
CV
604
605 if (tmp && tmp != pc)
606 return tmp;
607 return 0;
608}
609
b6fcb393
CV
610/* Function pointers are 16 bit. The address space is 24 bit, using
611 32 bit addresses. Pointers to functions on the XStormy16 are implemented
612 by using 16 bit pointers, which are either direct pointers in case the
613 function begins below 0x10000, or indirect pointers into a jump table.
614 The next two functions convert 16 bit pointers into 24 (32) bit addresses
615 and vice versa. */
616
0c884e17 617static CORE_ADDR
9898f801
UW
618xstormy16_pointer_to_address (struct gdbarch *gdbarch,
619 struct type *type, const gdb_byte *buf)
0c884e17 620{
e17a4113 621 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
0c884e17 622 enum type_code target = TYPE_CODE (TYPE_TARGET_TYPE (type));
e17a4113
UW
623 CORE_ADDR addr
624 = extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);
0c884e17
CV
625
626 if (target == TYPE_CODE_FUNC || target == TYPE_CODE_METHOD)
627 {
e17a4113 628 CORE_ADDR addr2 = xstormy16_resolve_jmp_table_entry (gdbarch, addr);
0c884e17
CV
629 if (addr2)
630 addr = addr2;
631 }
632
633 return addr;
634}
635
636static void
9898f801
UW
637xstormy16_address_to_pointer (struct gdbarch *gdbarch,
638 struct type *type, gdb_byte *buf, CORE_ADDR addr)
0c884e17 639{
e17a4113 640 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
0c884e17
CV
641 enum type_code target = TYPE_CODE (TYPE_TARGET_TYPE (type));
642
643 if (target == TYPE_CODE_FUNC || target == TYPE_CODE_METHOD)
644 {
e17a4113 645 CORE_ADDR addr2 = xstormy16_find_jmp_table_entry (gdbarch, addr);
0c884e17
CV
646 if (addr2)
647 addr = addr2;
648 }
e17a4113 649 store_unsigned_integer (buf, TYPE_LENGTH (type), byte_order, addr);
0c884e17
CV
650}
651
b6fcb393
CV
652static struct xstormy16_frame_cache *
653xstormy16_alloc_frame_cache (void)
0c884e17 654{
b6fcb393
CV
655 struct xstormy16_frame_cache *cache;
656 int i;
657
658 cache = FRAME_OBSTACK_ZALLOC (struct xstormy16_frame_cache);
659
660 cache->base = 0;
661 cache->saved_sp = 0;
662 cache->pc = 0;
663 cache->uses_fp = 0;
664 cache->framesize = 0;
665 for (i = 0; i < E_NUM_REGS; ++i)
666 cache->saved_regs[i] = REG_UNAVAIL;
667
668 return cache;
669}
670
671static struct xstormy16_frame_cache *
94afd7a6 672xstormy16_frame_cache (struct frame_info *this_frame, void **this_cache)
b6fcb393 673{
e17a4113 674 struct gdbarch *gdbarch = get_frame_arch (this_frame);
b6fcb393
CV
675 struct xstormy16_frame_cache *cache;
676 CORE_ADDR current_pc;
677 int i;
678
679 if (*this_cache)
680 return *this_cache;
681
682 cache = xstormy16_alloc_frame_cache ();
683 *this_cache = cache;
684
94afd7a6 685 cache->base = get_frame_register_unsigned (this_frame, E_FP_REGNUM);
b6fcb393
CV
686 if (cache->base == 0)
687 return cache;
688
94afd7a6
UW
689 cache->pc = get_frame_func (this_frame);
690 current_pc = get_frame_pc (this_frame);
b6fcb393 691 if (cache->pc)
e17a4113
UW
692 xstormy16_analyze_prologue (gdbarch, cache->pc, current_pc,
693 cache, this_frame);
b6fcb393
CV
694
695 if (!cache->uses_fp)
94afd7a6 696 cache->base = get_frame_register_unsigned (this_frame, E_SP_REGNUM);
b6fcb393
CV
697
698 cache->saved_sp = cache->base - cache->framesize;
699
700 for (i = 0; i < E_NUM_REGS; ++i)
701 if (cache->saved_regs[i] != REG_UNAVAIL)
702 cache->saved_regs[i] += cache->saved_sp;
703
704 return cache;
0c884e17
CV
705}
706
94afd7a6
UW
707static struct value *
708xstormy16_frame_prev_register (struct frame_info *this_frame,
709 void **this_cache, int regnum)
b6fcb393 710{
94afd7a6 711 struct xstormy16_frame_cache *cache = xstormy16_frame_cache (this_frame,
b6fcb393
CV
712 this_cache);
713 gdb_assert (regnum >= 0);
714
715 if (regnum == E_SP_REGNUM && cache->saved_sp)
94afd7a6 716 return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
b6fcb393
CV
717
718 if (regnum < E_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
94afd7a6
UW
719 return frame_unwind_got_memory (this_frame, regnum,
720 cache->saved_regs[regnum]);
b6fcb393 721
94afd7a6 722 return frame_unwind_got_register (this_frame, regnum, regnum);
b6fcb393
CV
723}
724
725static void
94afd7a6 726xstormy16_frame_this_id (struct frame_info *this_frame, void **this_cache,
b6fcb393
CV
727 struct frame_id *this_id)
728{
94afd7a6 729 struct xstormy16_frame_cache *cache = xstormy16_frame_cache (this_frame,
b6fcb393
CV
730 this_cache);
731
732 /* This marks the outermost frame. */
733 if (cache->base == 0)
734 return;
735
736 *this_id = frame_id_build (cache->saved_sp, cache->pc);
737}
738
739static CORE_ADDR
94afd7a6 740xstormy16_frame_base_address (struct frame_info *this_frame, void **this_cache)
b6fcb393 741{
94afd7a6 742 struct xstormy16_frame_cache *cache = xstormy16_frame_cache (this_frame,
b6fcb393
CV
743 this_cache);
744 return cache->base;
745}
746
747static const struct frame_unwind xstormy16_frame_unwind = {
748 NORMAL_FRAME,
8fbca658 749 default_frame_unwind_stop_reason,
b6fcb393 750 xstormy16_frame_this_id,
94afd7a6
UW
751 xstormy16_frame_prev_register,
752 NULL,
753 default_frame_sniffer
b6fcb393
CV
754};
755
756static const struct frame_base xstormy16_frame_base = {
757 &xstormy16_frame_unwind,
758 xstormy16_frame_base_address,
759 xstormy16_frame_base_address,
760 xstormy16_frame_base_address
761};
762
b6fcb393
CV
763static CORE_ADDR
764xstormy16_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
765{
766 return frame_unwind_register_unsigned (next_frame, E_SP_REGNUM);
767}
768
769static CORE_ADDR
770xstormy16_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
0c884e17 771{
b6fcb393 772 return frame_unwind_register_unsigned (next_frame, E_PC_REGNUM);
0c884e17
CV
773}
774
b6fcb393 775static struct frame_id
94afd7a6 776xstormy16_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
b6fcb393 777{
94afd7a6
UW
778 CORE_ADDR sp = get_frame_register_unsigned (this_frame, E_SP_REGNUM);
779 return frame_id_build (sp, get_frame_pc (this_frame));
b6fcb393
CV
780}
781
782
0c884e17
CV
783/* Function: xstormy16_gdbarch_init
784 Initializer function for the xstormy16 gdbarch vector.
581e13c1 785 Called by gdbarch. Sets up the gdbarch vector(s) for this target. */
0c884e17
CV
786
787static struct gdbarch *
788xstormy16_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
789{
0c884e17
CV
790 struct gdbarch *gdbarch;
791
581e13c1 792 /* find a candidate among the list of pre-declared architectures. */
0c884e17
CV
793 arches = gdbarch_list_lookup_by_info (arches, &info);
794 if (arches != NULL)
795 return (arches->gdbarch);
796
b6fcb393 797 gdbarch = gdbarch_alloc (&info, NULL);
a5afb99f 798
0c884e17 799 /*
b6fcb393 800 * Basic register fields and methods, datatype sizes and stuff.
0c884e17
CV
801 */
802
803 set_gdbarch_num_regs (gdbarch, E_NUM_REGS);
804 set_gdbarch_num_pseudo_regs (gdbarch, 0);
805 set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
0c884e17
CV
806 set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
807 set_gdbarch_register_name (gdbarch, xstormy16_register_name);
b6fcb393 808 set_gdbarch_register_type (gdbarch, xstormy16_register_type);
0c884e17 809
71c08af0 810 set_gdbarch_char_signed (gdbarch, 0);
b6fcb393 811 set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
0c884e17 812 set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
b6fcb393
CV
813 set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
814 set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
815
816 set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
817 set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
818 set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
819
0c884e17
CV
820 set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
821 set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
8da614df 822 set_gdbarch_dwarf2_addr_size (gdbarch, 4);
0c884e17
CV
823
824 set_gdbarch_address_to_pointer (gdbarch, xstormy16_address_to_pointer);
825 set_gdbarch_pointer_to_address (gdbarch, xstormy16_pointer_to_address);
826
581e13c1 827 /* Stack grows up. */
b6fcb393 828 set_gdbarch_inner_than (gdbarch, core_addr_greaterthan);
0c884e17 829
b6fcb393
CV
830 /*
831 * Frame Info
832 */
833 set_gdbarch_unwind_sp (gdbarch, xstormy16_unwind_sp);
834 set_gdbarch_unwind_pc (gdbarch, xstormy16_unwind_pc);
94afd7a6 835 set_gdbarch_dummy_id (gdbarch, xstormy16_dummy_id);
b6fcb393
CV
836 set_gdbarch_frame_align (gdbarch, xstormy16_frame_align);
837 frame_base_set_default (gdbarch, &xstormy16_frame_base);
0c884e17 838
b6fcb393
CV
839 set_gdbarch_skip_prologue (gdbarch, xstormy16_skip_prologue);
840 set_gdbarch_in_function_epilogue_p (gdbarch,
841 xstormy16_in_function_epilogue_p);
842
843 /* These values and methods are used when gdb calls a target function. */
844 set_gdbarch_push_dummy_call (gdbarch, xstormy16_push_dummy_call);
845 set_gdbarch_breakpoint_from_pc (gdbarch, xstormy16_breakpoint_from_pc);
846 set_gdbarch_return_value (gdbarch, xstormy16_return_value);
847
848 set_gdbarch_skip_trampoline_code (gdbarch, xstormy16_skip_trampoline_code);
0c884e17 849
36482093
AC
850 set_gdbarch_print_insn (gdbarch, print_insn_xstormy16);
851
b6fcb393
CV
852 gdbarch_init_osabi (info, gdbarch);
853
94afd7a6
UW
854 dwarf2_append_unwinders (gdbarch);
855 frame_unwind_append_unwinder (gdbarch, &xstormy16_frame_unwind);
b6fcb393 856
0c884e17
CV
857 return gdbarch;
858}
859
860/* Function: _initialize_xstormy16_tdep
861 Initializer function for the Sanyo Xstormy16a module.
581e13c1 862 Called by gdb at start-up. */
0c884e17 863
581e13c1
MS
864/* -Wmissing-prototypes */
865extern initialize_file_ftype _initialize_xstormy16_tdep;
a78f21af 866
0c884e17
CV
867void
868_initialize_xstormy16_tdep (void)
869{
0c884e17 870 register_gdbarch_init (bfd_arch_xstormy16, xstormy16_gdbarch_init);
0c884e17 871}