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