Add moxie-elf port.
[external/binutils.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 }