daily update
[deliverable/binutils-gdb.git] / gdb / moxie-tdep.c
CommitLineData
d7066cce
AG
1/* Target-dependent code for Moxie.
2
3 Copyright (C) 2009 Free Software Foundation, Inc.
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 3 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, see <http://www.gnu.org/licenses/>. */
19
20#include "defs.h"
21#include "frame.h"
22#include "frame-unwind.h"
23#include "frame-base.h"
24#include "symtab.h"
25#include "gdbtypes.h"
26#include "gdbcmd.h"
27#include "gdbcore.h"
28#include "gdb_string.h"
29#include "value.h"
30#include "inferior.h"
31#include "symfile.h"
32#include "objfiles.h"
33#include "osabi.h"
34#include "language.h"
35#include "arch-utils.h"
36#include "regcache.h"
37#include "trad-frame.h"
38#include "dis-asm.h"
39
40#include "gdb_assert.h"
41
42#include "moxie-tdep.h"
43
44/* Local functions. */
45
46extern void _initialize_moxie_tdep (void);
47
48/* Use an invalid address value as 'not available' marker. */
49enum { REG_UNAVAIL = (CORE_ADDR) -1 };
50
51struct moxie_frame_cache
52{
53 /* Base address. */
54 CORE_ADDR base;
55 CORE_ADDR pc;
56 LONGEST framesize;
57 CORE_ADDR saved_regs[MOXIE_NUM_REGS];
58 CORE_ADDR saved_sp;
59};
60
61/* Implement the "frame_align" gdbarch method. */
62
63static CORE_ADDR
64moxie_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
65{
66 /* Align to the size of an instruction (so that they can safely be
67 pushed onto the stack. */
68 return sp & ~1;
69}
70
71/* Implement the "breakpoint_from_pc" gdbarch method. */
72
73const static unsigned char *
74moxie_breakpoint_from_pc (struct gdbarch *gdbarch,
75 CORE_ADDR *pcptr, int *lenptr)
76{
77 static unsigned char breakpoint[] = { 0x35, 0x00 };
78
79 *lenptr = sizeof (breakpoint);
80 return breakpoint;
81}
82
83/* Moxie register names. */
84
85char *moxie_register_names[] = {
86 "$fp", "$sp", "$r0", "$r1", "$r2",
87 "$r3", "$r4", "$r5", "$r6", "$r7",
88 "$r8", "$r9", "$r10", "$r11", "$r12",
89 "$r13", "$pc", "$cc" };
90
91/* Implement the "register_name" gdbarch method. */
92
93static const char *
94moxie_register_name (struct gdbarch *gdbarch, int reg_nr)
95{
96 if (reg_nr < 0)
97 return NULL;
98 if (reg_nr >= MOXIE_NUM_REGS)
99 return NULL;
100 return moxie_register_names[reg_nr];
101}
102
103/* Implement the "register_type" gdbarch method. */
104
105static struct type *
106moxie_register_type (struct gdbarch *gdbarch, int reg_nr)
107{
108 if (reg_nr == MOXIE_PC_REGNUM)
109 return builtin_type (gdbarch)->builtin_func_ptr;
110 else if (reg_nr == MOXIE_SP_REGNUM || reg_nr == MOXIE_FP_REGNUM)
111 return builtin_type (gdbarch)->builtin_data_ptr;
112 else
df4df182 113 return builtin_type (gdbarch)->builtin_int32;
d7066cce
AG
114}
115
116/* Write into appropriate registers a function return value
117 of type TYPE, given in virtual format. */
118
119static void
120moxie_store_return_value (struct type *type, struct regcache *regcache,
121 const void *valbuf)
122{
e17a4113
UW
123 struct gdbarch *gdbarch = get_regcache_arch (regcache);
124 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
d7066cce
AG
125 CORE_ADDR regval;
126 int len = TYPE_LENGTH (type);
127
128 /* Things always get returned in RET1_REGNUM, RET2_REGNUM. */
e17a4113 129 regval = extract_unsigned_integer (valbuf, len > 4 ? 4 : len, byte_order);
d7066cce
AG
130 regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval);
131 if (len > 4)
132 {
e17a4113
UW
133 regval = extract_unsigned_integer ((gdb_byte *) valbuf + 4,
134 len - 4, byte_order);
d7066cce
AG
135 regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);
136 }
137}
138
139/* Decode the instructions within the given address range. Decide
140 when we must have reached the end of the function prologue. If a
141 frame_info pointer is provided, fill in its saved_regs etc.
142
143 Returns the address of the first instruction after the prologue. */
144
145static CORE_ADDR
146moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
147 struct moxie_frame_cache *cache,
148 struct frame_info *this_frame)
149{
e17a4113
UW
150 struct gdbarch *gdbarch = get_frame_arch (this_frame);
151 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
d7066cce
AG
152 CORE_ADDR next_addr;
153 ULONGEST inst, inst2;
154 LONGEST offset;
155 int regnum;
156
157 /* Record where the jsra instruction saves the PC and FP. */
158 cache->saved_regs[MOXIE_PC_REGNUM] = -4;
159 cache->saved_regs[MOXIE_FP_REGNUM] = 0;
160 cache->framesize = 0;
161
162 if (start_addr >= end_addr)
163 return end_addr;
164
165 for (next_addr = start_addr; next_addr < end_addr; )
166 {
e17a4113 167 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
d7066cce
AG
168
169 /* Match "push $rN" where N is between 2 and 13 inclusive. */
170 if (inst >= 0x0614 && inst <= 0x061f)
171 {
172 regnum = inst & 0x000f;
173 cache->framesize += 4;
174 cache->saved_regs[regnum] = cache->framesize;
175 next_addr += 2;
176 }
177
178 /* Optional stack allocation for args and local vars <= 4
179 byte. */
180 else if (inst == 0x01f0) /* ldi.l $r12, X */
181 {
e17a4113
UW
182 offset = read_memory_integer (next_addr + 2, 4, byte_order);
183 inst2 = read_memory_unsigned_integer (next_addr + 6, 2, byte_order);
d7066cce
AG
184
185 if (inst2 == 0x051f) /* add.l $sp, $r12 */
186 {
187 cache->framesize += offset;
188 }
189
190 return (next_addr + 8);
191 }
192 else /* This is not a prologue instruction. */
193 break;
194 }
195
196 return next_addr;
197}
198
199/* Find the end of function prologue. */
200
201static CORE_ADDR
202moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
203{
204 CORE_ADDR func_addr = 0, func_end = 0;
205 char *func_name;
206
207 /* See if we can determine the end of the prologue via the symbol table.
208 If so, then return either PC, or the PC after the prologue, whichever
209 is greater. */
210 if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
211 {
d80b854b
UW
212 CORE_ADDR post_prologue_pc
213 = skip_prologue_using_sal (gdbarch, func_addr);
d7066cce
AG
214 if (post_prologue_pc != 0)
215 return max (pc, post_prologue_pc);
216 else
217 {
218 /* Can't determine prologue from the symbol table, need to examine
219 instructions. */
220 struct symtab_and_line sal;
221 struct symbol *sym;
222 struct moxie_frame_cache cache;
223 CORE_ADDR plg_end;
224
225 memset (&cache, 0, sizeof cache);
226
227 plg_end = moxie_analyze_prologue (func_addr,
228 func_end, &cache, NULL);
229 /* Found a function. */
230 sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL);
231 /* Don't use line number debug info for assembly source
232 files. */
233 if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
234 {
235 sal = find_pc_line (func_addr, 0);
236 if (sal.end && sal.end < func_end)
237 {
238 /* Found a line number, use it as end of
239 prologue. */
240 return sal.end;
241 }
242 }
243 /* No useable line symbol. Use result of prologue parsing
244 method. */
245 return plg_end;
246 }
247 }
248
249 /* No function symbol -- just return the PC. */
250 return (CORE_ADDR) pc;
251}
252
253struct moxie_unwind_cache
254{
255 /* The previous frame's inner most stack address. Used as this
256 frame ID's stack_addr. */
257 CORE_ADDR prev_sp;
258 /* The frame's base, optionally used by the high-level debug info. */
259 CORE_ADDR base;
260 int size;
261 /* How far the SP and r13 (FP) have been offset from the start of
262 the stack frame (as defined by the previous frame's stack
263 pointer). */
264 LONGEST sp_offset;
265 LONGEST r13_offset;
266 int uses_frame;
267 /* Table indicating the location of each and every register. */
268 struct trad_frame_saved_reg *saved_regs;
269};
270
271/* Implement the "read_pc" gdbarch method. */
272
273static CORE_ADDR
274moxie_read_pc (struct regcache *regcache)
275{
276 ULONGEST pc;
277
278 regcache_cooked_read_unsigned (regcache, MOXIE_PC_REGNUM, &pc);
279 return pc;
280}
281
282/* Implement the "write_pc" gdbarch method. */
283
284static void
285moxie_write_pc (struct regcache *regcache, CORE_ADDR val)
286{
287 regcache_cooked_write_unsigned (regcache, MOXIE_PC_REGNUM, val);
288}
289
290/* Implement the "unwind_pc" gdbarch method. */
291
292static CORE_ADDR
293moxie_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
294{
295 return frame_unwind_register_unsigned (next_frame, MOXIE_SP_REGNUM);
296}
297
298/* Given a return value in `regbuf' with a type `valtype',
299 extract and copy its value into `valbuf'. */
300
301static void
302moxie_extract_return_value (struct type *type, struct regcache *regcache,
303 void *dst)
304{
e17a4113
UW
305 struct gdbarch *gdbarch = get_regcache_arch (regcache);
306 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
d7066cce
AG
307 bfd_byte *valbuf = dst;
308 int len = TYPE_LENGTH (type);
309 ULONGEST tmp;
310
311 /* By using store_unsigned_integer we avoid having to do
312 anything special for small big-endian values. */
313 regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp);
e17a4113 314 store_unsigned_integer (valbuf, (len > 4 ? len - 4 : len), byte_order, tmp);
d7066cce
AG
315
316 /* Ignore return values more than 8 bytes in size because the moxie
317 returns anything more than 8 bytes in the stack. */
318 if (len > 4)
319 {
320 regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);
e17a4113 321 store_unsigned_integer (valbuf + len - 4, 4, byte_order, tmp);
d7066cce
AG
322 }
323}
324
325/* Implement the "return_value" gdbarch method. */
326
327static enum return_value_convention
328moxie_return_value (struct gdbarch *gdbarch, struct type *func_type,
329 struct type *valtype, struct regcache *regcache,
330 gdb_byte *readbuf, const gdb_byte *writebuf)
331{
332 if (TYPE_LENGTH (valtype) > 8)
333 return RETURN_VALUE_STRUCT_CONVENTION;
334 else
335 {
336 if (readbuf != NULL)
337 moxie_extract_return_value (valtype, regcache, readbuf);
338 if (writebuf != NULL)
339 moxie_store_return_value (valtype, regcache, writebuf);
340 return RETURN_VALUE_REGISTER_CONVENTION;
341 }
342}
343
344/* Allocate and initialize a moxie_frame_cache object. */
345
346static struct moxie_frame_cache *
347moxie_alloc_frame_cache (void)
348{
349 struct moxie_frame_cache *cache;
350 int i;
351
352 cache = FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache);
353
354 cache->base = 0;
355 cache->saved_sp = 0;
356 cache->pc = 0;
357 cache->framesize = 0;
358 for (i = 0; i < MOXIE_NUM_REGS; ++i)
359 cache->saved_regs[i] = REG_UNAVAIL;
360
361 return cache;
362}
363
364/* Populate a moxie_frame_cache object for this_frame. */
365
366static struct moxie_frame_cache *
367moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
368{
369 struct moxie_frame_cache *cache;
370 CORE_ADDR current_pc;
371 int i;
372
373 if (*this_cache)
374 return *this_cache;
375
376 cache = moxie_alloc_frame_cache ();
377 *this_cache = cache;
378
379 cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM);
380 if (cache->base == 0)
381 return cache;
382
383 cache->pc = get_frame_func (this_frame);
384 current_pc = get_frame_pc (this_frame);
385 if (cache->pc)
386 moxie_analyze_prologue (cache->pc, current_pc, cache, this_frame);
387
388 cache->saved_sp = cache->base - cache->framesize;
389
390 for (i = 0; i < MOXIE_NUM_REGS; ++i)
391 if (cache->saved_regs[i] != REG_UNAVAIL)
392 cache->saved_regs[i] = cache->base - cache->saved_regs[i];
393
394 return cache;
395}
396
397/* Implement the "unwind_pc" gdbarch method. */
398
399static CORE_ADDR
400moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
401{
402 return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM);
403}
404
405/* Given a GDB frame, determine the address of the calling function's
406 frame. This will be used to create a new GDB frame struct. */
407
408static void
409moxie_frame_this_id (struct frame_info *this_frame,
410 void **this_prologue_cache, struct frame_id *this_id)
411{
412 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
413 this_prologue_cache);
414
415 /* This marks the outermost frame. */
416 if (cache->base == 0)
417 return;
418
419 *this_id = frame_id_build (cache->saved_sp, cache->pc);
420}
421
422/* Get the value of register regnum in the previous stack frame. */
423
424static struct value *
425moxie_frame_prev_register (struct frame_info *this_frame,
426 void **this_prologue_cache, int regnum)
427{
428 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
429 this_prologue_cache);
430
431 gdb_assert (regnum >= 0);
432
433 if (regnum == MOXIE_SP_REGNUM && cache->saved_sp)
434 return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
435
436 if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
437 return frame_unwind_got_memory (this_frame, regnum,
438 cache->saved_regs[regnum]);
439
440 return frame_unwind_got_register (this_frame, regnum, regnum);
441}
442
443static const struct frame_unwind moxie_frame_unwind = {
444 NORMAL_FRAME,
445 moxie_frame_this_id,
446 moxie_frame_prev_register,
447 NULL,
448 default_frame_sniffer
449};
450
451/* Return the base address of this_frame. */
452
453static CORE_ADDR
454moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
455{
456 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
457 this_cache);
458
459 return cache->base;
460}
461
462static const struct frame_base moxie_frame_base = {
463 &moxie_frame_unwind,
464 moxie_frame_base_address,
465 moxie_frame_base_address,
466 moxie_frame_base_address
467};
468
469static struct frame_id
470moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
471{
472 CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM);
473
474 return frame_id_build (sp, get_frame_pc (this_frame));
475}
476
477/* Allocate and initialize the moxie gdbarch object. */
478
479static struct gdbarch *
480moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
481{
482 struct gdbarch *gdbarch;
483 struct gdbarch_tdep *tdep;
484
485 /* If there is already a candidate, use it. */
486 arches = gdbarch_list_lookup_by_info (arches, &info);
487 if (arches != NULL)
488 return arches->gdbarch;
489
490 /* Allocate space for the new architecture. */
491 tdep = XMALLOC (struct gdbarch_tdep);
492 gdbarch = gdbarch_alloc (&info, tdep);
493
494 set_gdbarch_read_pc (gdbarch, moxie_read_pc);
495 set_gdbarch_write_pc (gdbarch, moxie_write_pc);
496 set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp);
497
498 set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS);
499 set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM);
500 set_gdbarch_register_name (gdbarch, moxie_register_name);
501 set_gdbarch_register_type (gdbarch, moxie_register_type);
502
503 set_gdbarch_return_value (gdbarch, moxie_return_value);
504
505 set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue);
506 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
507 set_gdbarch_breakpoint_from_pc (gdbarch, moxie_breakpoint_from_pc);
508 set_gdbarch_frame_align (gdbarch, moxie_frame_align);
509
510 frame_base_set_default (gdbarch, &moxie_frame_base);
511
512 /* Methods for saving / extracting a dummy frame's ID. The ID's
513 stack address must match the SP value returned by
514 PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
515 set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);
516
517 set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);
518
519 set_gdbarch_print_insn (gdbarch, print_insn_moxie);
520
521 /* Hook in ABI-specific overrides, if they have been registered. */
522 gdbarch_init_osabi (info, gdbarch);
523
524 /* Hook in the default unwinders. */
525 frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind);
526
527 /* Support simple overlay manager. */
528 set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
529
530 return gdbarch;
531}
532
533/* Register this machine's init routine. */
534
535void
536_initialize_moxie_tdep (void)
537{
538 register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init);
539}
This page took 0.090972 seconds and 4 git commands to generate.