binutils/
[external/binutils.git] / gdb / moxie-tdep.c
1 /* Target-dependent code for Moxie.
2
3    Copyright (C) 2009, 2010, 2011 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 #include "record.h"
40
41 #include "gdb_assert.h"
42
43 #include "moxie-tdep.h"
44
45 /* Local functions.  */
46
47 extern void _initialize_moxie_tdep (void);
48
49 /* Use an invalid address value as 'not available' marker.  */
50 enum { REG_UNAVAIL = (CORE_ADDR) -1 };
51
52 struct moxie_frame_cache
53 {
54   /* Base address.  */
55   CORE_ADDR base;
56   CORE_ADDR pc;
57   LONGEST framesize;
58   CORE_ADDR saved_regs[MOXIE_NUM_REGS];
59   CORE_ADDR saved_sp;
60 };
61
62 /* Implement the "frame_align" gdbarch method.  */
63
64 static CORE_ADDR
65 moxie_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
66 {
67   /* Align to the size of an instruction (so that they can safely be
68      pushed onto the stack.  */
69   return sp & ~1;
70 }
71
72 /* Implement the "breakpoint_from_pc" gdbarch method.  */
73
74 const static unsigned char *
75 moxie_breakpoint_from_pc (struct gdbarch *gdbarch,
76                           CORE_ADDR *pcptr, int *lenptr)
77 {
78   static unsigned char breakpoint[] = { 0x35, 0x00 };
79
80   *lenptr = sizeof (breakpoint);
81   return breakpoint;
82 }
83
84 /* Moxie register names.  */
85
86 char *moxie_register_names[] = {
87   "$fp",  "$sp",  "$r0",  "$r1",  "$r2",
88   "$r3",  "$r4",  "$r5", "$r6", "$r7",
89   "$r8", "$r9", "$r10", "$r11", "$r12",
90   "$r13", "$pc", "$cc" };
91
92 /* Implement the "register_name" gdbarch method.  */
93
94 static const char *
95 moxie_register_name (struct gdbarch *gdbarch, int reg_nr)
96 {
97   if (reg_nr < 0)
98     return NULL;
99   if (reg_nr >= MOXIE_NUM_REGS)
100     return NULL;
101   return moxie_register_names[reg_nr];
102 }
103
104 /* Implement the "register_type" gdbarch method.  */
105
106 static struct type *
107 moxie_register_type (struct gdbarch *gdbarch, int reg_nr)
108 {
109   if (reg_nr == MOXIE_PC_REGNUM)
110     return  builtin_type (gdbarch)->builtin_func_ptr;
111   else if (reg_nr == MOXIE_SP_REGNUM || reg_nr == MOXIE_FP_REGNUM)
112     return builtin_type (gdbarch)->builtin_data_ptr;
113   else
114     return builtin_type (gdbarch)->builtin_int32;
115 }
116
117 /* Write into appropriate registers a function return value
118    of type TYPE, given in virtual format.  */
119
120 static void
121 moxie_store_return_value (struct type *type, struct regcache *regcache,
122                          const void *valbuf)
123 {
124   struct gdbarch *gdbarch = get_regcache_arch (regcache);
125   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
126   CORE_ADDR regval;
127   int len = TYPE_LENGTH (type);
128
129   /* Things always get returned in RET1_REGNUM, RET2_REGNUM.  */
130   regval = extract_unsigned_integer (valbuf, len > 4 ? 4 : len, byte_order);
131   regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval);
132   if (len > 4)
133     {
134       regval = extract_unsigned_integer ((gdb_byte *) valbuf + 4,
135                                          len - 4, byte_order);
136       regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);
137     }
138 }
139
140 /* Decode the instructions within the given address range.  Decide
141    when we must have reached the end of the function prologue.  If a
142    frame_info pointer is provided, fill in its saved_regs etc.
143
144    Returns the address of the first instruction after the prologue.  */
145
146 static CORE_ADDR
147 moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
148                         struct moxie_frame_cache *cache,
149                         struct gdbarch *gdbarch)
150 {
151   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
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     {
167       inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
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       else
178         break;
179     }
180
181   inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
182
183   /* Optional stack allocation for args and local vars <= 4
184      byte.  */
185   if (inst == 0x0170)           /* ldi.l $r5, X */
186     {
187       offset = read_memory_integer (next_addr + 2, 4, byte_order);
188       inst2 = read_memory_unsigned_integer (next_addr + 6, 2, byte_order);
189       
190       if (inst2 == 0x0517)           /* add.l $sp, $r5 */
191         {
192           cache->framesize += offset;
193         }
194       
195       return (next_addr + 8);
196     }
197   else if ((inst & 0xff00) == 0x91)   /* dec $sp, X */
198     {
199       cache->framesize += (inst & 0x00ff);
200       next_addr += 2;
201
202       while (next_addr < end_addr)
203         {
204           inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
205           if ((inst & 0xff00) != 0x91) /* no more dec $sp, X */
206             break;
207           cache->framesize += (inst & 0x00ff);
208           next_addr += 2;
209         }
210     }
211
212   return next_addr;
213 }
214
215 /* Find the end of function prologue.  */
216
217 static CORE_ADDR
218 moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
219 {
220   CORE_ADDR func_addr = 0, func_end = 0;
221   char *func_name;
222
223   /* See if we can determine the end of the prologue via the symbol table.
224      If so, then return either PC, or the PC after the prologue, whichever
225      is greater.  */
226   if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
227     {
228       CORE_ADDR post_prologue_pc
229         = skip_prologue_using_sal (gdbarch, func_addr);
230       if (post_prologue_pc != 0)
231         return max (pc, post_prologue_pc);
232       else
233         {
234           /* Can't determine prologue from the symbol table, need to examine
235              instructions.  */
236           struct symtab_and_line sal;
237           struct symbol *sym;
238           struct moxie_frame_cache cache;
239           CORE_ADDR plg_end;
240           
241           memset (&cache, 0, sizeof cache);
242           
243           plg_end = moxie_analyze_prologue (func_addr, 
244                                             func_end, &cache, gdbarch);
245           /* Found a function.  */
246           sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL);
247           /* Don't use line number debug info for assembly source
248              files.  */
249           if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
250             {
251               sal = find_pc_line (func_addr, 0);
252               if (sal.end && sal.end < func_end)
253                 {
254                   /* Found a line number, use it as end of
255                      prologue.  */
256                   return sal.end;
257                 }
258             }
259           /* No useable line symbol.  Use result of prologue parsing
260              method.  */
261           return plg_end;
262         }
263     }
264
265   /* No function symbol -- just return the PC.  */
266   return (CORE_ADDR) pc;
267 }
268
269 struct moxie_unwind_cache
270 {
271   /* The previous frame's inner most stack address.  Used as this
272      frame ID's stack_addr.  */
273   CORE_ADDR prev_sp;
274   /* The frame's base, optionally used by the high-level debug info.  */
275   CORE_ADDR base;
276   int size;
277   /* How far the SP and r13 (FP) have been offset from the start of
278      the stack frame (as defined by the previous frame's stack
279      pointer).  */
280   LONGEST sp_offset;
281   LONGEST r13_offset;
282   int uses_frame;
283   /* Table indicating the location of each and every register.  */
284   struct trad_frame_saved_reg *saved_regs;
285 };
286
287 /* Implement the "read_pc" gdbarch method.  */
288
289 static CORE_ADDR
290 moxie_read_pc (struct regcache *regcache)
291 {
292   ULONGEST pc;
293
294   regcache_cooked_read_unsigned (regcache, MOXIE_PC_REGNUM, &pc);
295   return pc;
296 }
297
298 /* Implement the "write_pc" gdbarch method.  */
299
300 static void
301 moxie_write_pc (struct regcache *regcache, CORE_ADDR val)
302 {
303   regcache_cooked_write_unsigned (regcache, MOXIE_PC_REGNUM, val);
304 }
305
306 /* Implement the "unwind_sp" gdbarch method.  */
307
308 static CORE_ADDR
309 moxie_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
310 {
311   return frame_unwind_register_unsigned (next_frame, MOXIE_SP_REGNUM);
312 }
313
314 /* Given a return value in `regbuf' with a type `valtype', 
315    extract and copy its value into `valbuf'.  */
316
317 static void
318 moxie_extract_return_value (struct type *type, struct regcache *regcache,
319                            void *dst)
320 {
321   struct gdbarch *gdbarch = get_regcache_arch (regcache);
322   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
323   bfd_byte *valbuf = dst;
324   int len = TYPE_LENGTH (type);
325   ULONGEST tmp;
326
327   /* By using store_unsigned_integer we avoid having to do
328      anything special for small big-endian values.  */
329   regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp);
330   store_unsigned_integer (valbuf, (len > 4 ? len - 4 : len), byte_order, tmp);
331
332   /* Ignore return values more than 8 bytes in size because the moxie
333      returns anything more than 8 bytes in the stack.  */
334   if (len > 4)
335     {
336       regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);
337       store_unsigned_integer (valbuf + len - 4, 4, byte_order, tmp);
338     }
339 }
340
341 /* Implement the "return_value" gdbarch method.  */
342
343 static enum return_value_convention
344 moxie_return_value (struct gdbarch *gdbarch, struct type *func_type,
345                    struct type *valtype, struct regcache *regcache,
346                    gdb_byte *readbuf, const gdb_byte *writebuf)
347 {
348   if (TYPE_LENGTH (valtype) > 8)
349     return RETURN_VALUE_STRUCT_CONVENTION;
350   else
351     {
352       if (readbuf != NULL)
353         moxie_extract_return_value (valtype, regcache, readbuf);
354       if (writebuf != NULL)
355         moxie_store_return_value (valtype, regcache, writebuf);
356       return RETURN_VALUE_REGISTER_CONVENTION;
357     }
358 }
359
360 /* Allocate and initialize a moxie_frame_cache object.  */
361
362 static struct moxie_frame_cache *
363 moxie_alloc_frame_cache (void)
364 {
365   struct moxie_frame_cache *cache;
366   int i;
367
368   cache = FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache);
369
370   cache->base = 0;
371   cache->saved_sp = 0;
372   cache->pc = 0;
373   cache->framesize = 0;
374   for (i = 0; i < MOXIE_NUM_REGS; ++i)
375     cache->saved_regs[i] = REG_UNAVAIL;
376
377   return cache;
378 }
379
380 /* Populate a moxie_frame_cache object for this_frame.  */
381
382 static struct moxie_frame_cache *
383 moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
384 {
385   struct moxie_frame_cache *cache;
386   CORE_ADDR current_pc;
387   int i;
388
389   if (*this_cache)
390     return *this_cache;
391
392   cache = moxie_alloc_frame_cache ();
393   *this_cache = cache;
394
395   cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM);
396   if (cache->base == 0)
397     return cache;
398
399   cache->pc = get_frame_func (this_frame);
400   current_pc = get_frame_pc (this_frame);
401   if (cache->pc)
402     {
403       struct gdbarch *gdbarch = get_frame_arch (this_frame);
404       moxie_analyze_prologue (cache->pc, current_pc, cache, gdbarch);
405     }
406
407   cache->saved_sp = cache->base - cache->framesize;
408
409   for (i = 0; i < MOXIE_NUM_REGS; ++i)
410     if (cache->saved_regs[i] != REG_UNAVAIL)
411       cache->saved_regs[i] = cache->base - cache->saved_regs[i];
412
413   return cache;
414 }
415
416 /* Implement the "unwind_pc" gdbarch method.  */
417
418 static CORE_ADDR
419 moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
420 {
421   return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM);
422 }
423
424 /* Given a GDB frame, determine the address of the calling function's
425    frame.  This will be used to create a new GDB frame struct.  */
426
427 static void
428 moxie_frame_this_id (struct frame_info *this_frame,
429                     void **this_prologue_cache, struct frame_id *this_id)
430 {
431   struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
432                                                    this_prologue_cache);
433
434   /* This marks the outermost frame.  */
435   if (cache->base == 0)
436     return;
437
438   *this_id = frame_id_build (cache->saved_sp, cache->pc);
439 }
440
441 /* Get the value of register regnum in the previous stack frame.  */
442
443 static struct value *
444 moxie_frame_prev_register (struct frame_info *this_frame,
445                           void **this_prologue_cache, int regnum)
446 {
447   struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
448                                                    this_prologue_cache);
449
450   gdb_assert (regnum >= 0);
451
452   if (regnum == MOXIE_SP_REGNUM && cache->saved_sp)
453     return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
454
455   if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
456     return frame_unwind_got_memory (this_frame, regnum,
457                                     cache->saved_regs[regnum]);
458
459   return frame_unwind_got_register (this_frame, regnum, regnum);
460 }
461
462 static const struct frame_unwind moxie_frame_unwind = {
463   NORMAL_FRAME,
464   default_frame_unwind_stop_reason,
465   moxie_frame_this_id,
466   moxie_frame_prev_register,
467   NULL,
468   default_frame_sniffer
469 };
470
471 /* Return the base address of this_frame.  */
472
473 static CORE_ADDR
474 moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
475 {
476   struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
477                                                        this_cache);
478
479   return cache->base;
480 }
481
482 static const struct frame_base moxie_frame_base = {
483   &moxie_frame_unwind,
484   moxie_frame_base_address,
485   moxie_frame_base_address,
486   moxie_frame_base_address
487 };
488
489 static struct frame_id
490 moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
491 {
492   CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM);
493
494   return frame_id_build (sp, get_frame_pc (this_frame));
495 }
496
497 /* Read an unsigned integer from the inferior, and adjust
498    endianess.  */
499 static ULONGEST
500 moxie_process_readu (CORE_ADDR addr, char *buf, 
501                      int length, enum bfd_endian byte_order)
502 {
503   if (target_read_memory (addr, buf, length))
504     {
505       if (record_debug)
506         printf_unfiltered (_("Process record: error reading memory at "
507                              "addr 0x%s len = %d.\n"),
508                            paddress (target_gdbarch, addr), length);
509       return -1;
510     }
511
512   return extract_unsigned_integer (buf, length, byte_order);
513 }
514
515 /* Parse the current instruction and record the values of the registers and
516    memory that will be changed in current instruction to "record_arch_list".
517    Return -1 if something wrong.  */
518
519 int
520 moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
521                       CORE_ADDR addr)
522 {
523   gdb_byte buf[4];
524   uint16_t inst;
525   uint32_t tmpu32;
526   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
527
528   if (record_debug > 1)
529     fprintf_unfiltered (gdb_stdlog, "Process record: moxie_process_record "
530                                     "addr = 0x%s\n",
531                         paddress (target_gdbarch, addr));
532
533   inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
534
535   /* Decode instruction.  */
536   if (inst & (1 << 15))
537     {
538       if (inst & (1 << 14))
539         {
540           /* This is a Form 3 instruction.  */
541           int opcode = (inst >> 10 & 0xf);
542           
543           switch (opcode)
544             {
545             case 0x00: /* beq */
546             case 0x01: /* bne */
547             case 0x02: /* blt */
548             case 0x03: /* bgt */
549             case 0x04: /* bltu */
550             case 0x05: /* bgtu */
551             case 0x06: /* bge */
552             case 0x07: /* ble */
553             case 0x08: /* bgeu */
554             case 0x09: /* bleu */
555               /* Do nothing.  */
556               break;
557             default:
558               {
559                 /* Do nothing.  */
560                 break;
561               }
562             }
563         }
564       else
565         {
566           /* This is a Form 2 instruction.  */
567           int opcode = (inst >> 12 & 0x3);
568           switch (opcode)
569             {
570             case 0x00: /* inc */
571             case 0x01: /* dec */
572             case 0x02: /* gsr */
573               {
574                 int reg = (inst >> 8) & 0xf;
575                 if (record_arch_list_add_reg (regcache, reg))
576                   return -1;
577               }
578               break;
579             case 0x03: /* ssr */
580               {
581                 /* Do nothing until GDB learns about moxie's special
582                    registers.  */
583               }
584               break;
585             default:
586               /* Do nothing.  */
587               break;
588             }
589         }
590     }
591   else
592     {
593       /* This is a Form 1 instruction.  */
594       int opcode = inst >> 8;
595
596       switch (opcode)
597         {
598         case 0x00: /* nop */
599           /* Do nothing.  */
600           break;
601         case 0x01: /* ldi.l (immediate) */
602         case 0x02: /* mov (register-to-register) */
603           {
604             int reg = (inst >> 4) & 0xf;
605             if (record_arch_list_add_reg (regcache, reg))
606               return -1;
607           }
608           break;
609         case 0x03: /* jsra */
610           {
611             regcache_raw_read (regcache, 
612                                MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
613             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
614                                                4, byte_order);
615             if (record_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
616                 || (record_arch_list_add_reg (regcache, 
617                                               MOXIE_SP_REGNUM))
618                 || record_arch_list_add_mem (tmpu32 - 12, 12))
619               return -1;
620           }
621           break;
622         case 0x04: /* ret */
623           {
624             if (record_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
625                 || (record_arch_list_add_reg (regcache, 
626                                               MOXIE_SP_REGNUM)))
627               return -1;
628           }
629           break;
630         case 0x05: /* add.l */
631           {
632             int reg = (inst >> 4) & 0xf;
633             if (record_arch_list_add_reg (regcache, reg))
634               return -1;
635           }
636           break;
637         case 0x06: /* push */
638           {
639             int reg = (inst >> 4) & 0xf;
640             regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
641             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
642                                                4, byte_order);
643             if (record_arch_list_add_reg (regcache, reg)
644                 || record_arch_list_add_mem (tmpu32 - 4, 4))
645               return -1;
646           }
647           break;
648         case 0x07: /* pop */
649           {
650             int a = (inst >> 4) & 0xf;
651             int b = inst & 0xf;
652             if (record_arch_list_add_reg (regcache, a)
653                 || record_arch_list_add_reg (regcache, b))
654               return -1;
655           }
656           break;
657         case 0x08: /* lda.l */
658           {
659             int reg = (inst >> 4) & 0xf;
660             if (record_arch_list_add_reg (regcache, reg))
661               return -1;
662           }
663           break;
664         case 0x09: /* sta.l */
665           {
666             tmpu32 = (uint32_t) moxie_process_readu (addr+2, buf, 
667                                                      4, byte_order);
668             if (record_arch_list_add_mem (tmpu32, 4))
669               return -1;
670           }
671           break;
672         case 0x0a: /* ld.l (register indirect) */
673           {
674             int reg = (inst >> 4) & 0xf;
675             if (record_arch_list_add_reg (regcache, reg))
676               return -1;
677           }
678           break;
679         case 0x0b: /* st.l */
680           {
681             int reg = (inst >> 4) & 0xf;
682             regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
683             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
684                                                4, byte_order);
685             if (record_arch_list_add_mem (tmpu32, 4))
686               return -1;
687           }
688           break;
689         case 0x0c: /* ldo.l */
690           {
691             int reg = (inst >> 4) & 0xf;
692             if (record_arch_list_add_reg (regcache, reg))
693               return -1;
694           }
695           break;
696         case 0x0d: /* sto.l */
697           {
698             int reg = (inst >> 4) & 0xf;
699             uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
700                                                               byte_order);
701             regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
702             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
703                                                4, byte_order);
704             tmpu32 += offset;
705             if (record_arch_list_add_mem (tmpu32, 4))
706               return -1;
707           }
708           break;
709         case 0x0e: /* cmp */
710           {
711             if (record_arch_list_add_reg (regcache, MOXIE_CC_REGNUM))
712               return -1;
713           }
714           break;
715         case 0x0f:
716         case 0x10:
717         case 0x11:
718         case 0x12:
719         case 0x13:
720         case 0x14:
721         case 0x15:
722         case 0x16:
723         case 0x17:
724         case 0x18:
725           {
726             /* Do nothing.  */
727             break;
728           }
729         case 0x19: /* jsr */
730           {
731             regcache_raw_read (regcache, 
732                                MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
733             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
734                                                4, byte_order);
735             if (record_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
736                 || (record_arch_list_add_reg (regcache, 
737                                               MOXIE_SP_REGNUM))
738                 || record_arch_list_add_mem (tmpu32 - 12, 12))
739               return -1;
740           }
741           break;
742         case 0x1a: /* jmpa */
743           {
744             /* Do nothing.  */
745           }
746           break;
747         case 0x1b: /* ldi.b (immediate) */
748         case 0x1c: /* ld.b (register indirect) */
749         case 0x1d: /* lda.b */
750           {
751             int reg = (inst >> 4) & 0xf;
752             if (record_arch_list_add_reg (regcache, reg))
753               return -1;
754           }
755           break;
756         case 0x1e: /* st.b */
757           {
758             int reg = (inst >> 4) & 0xf;
759             regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
760             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
761                                                4, byte_order);
762             if (record_arch_list_add_mem (tmpu32, 1))
763               return -1;
764           }
765           break;
766         case 0x1f: /* sta.b */
767           {
768             tmpu32 = moxie_process_readu (addr+2, (char *) buf, 
769                                           4, byte_order);
770             if (record_arch_list_add_mem (tmpu32, 1))
771               return -1;
772           }
773           break;
774         case 0x20: /* ldi.s (immediate) */
775         case 0x21: /* ld.s (register indirect) */
776         case 0x22: /* lda.s */
777           {
778             int reg = (inst >> 4) & 0xf;
779             if (record_arch_list_add_reg (regcache, reg))
780               return -1;
781           }
782           break;
783         case 0x23: /* st.s */
784           {
785             int reg = (inst >> 4) & 0xf;
786             regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
787             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
788                                                4, byte_order);
789             if (record_arch_list_add_mem (tmpu32, 2))
790               return -1;
791           }
792           break;
793         case 0x24: /* sta.s */
794           {
795             tmpu32 = moxie_process_readu (addr+2, (char *) buf, 
796                                           4, byte_order);
797             if (record_arch_list_add_mem (tmpu32, 2))
798               return -1;
799           }
800           break;
801         case 0x25: /* jmp */
802           {
803             /* Do nothing.  */
804           }
805           break;
806         case 0x26: /* and */
807         case 0x27: /* lshr */
808         case 0x28: /* ashl */
809         case 0x29: /* sub.l */
810         case 0x2a: /* neg */
811         case 0x2b: /* or */
812         case 0x2c: /* not */
813         case 0x2d: /* ashr */
814         case 0x2e: /* xor */
815         case 0x2f: /* mul.l */
816           {
817             int reg = (inst >> 4) & 0xf;
818             if (record_arch_list_add_reg (regcache, reg))
819               return -1;
820           }
821           break;
822         case 0x30: /* swi */
823           {
824             /* We currently implement support for libgloss' 
825                system calls.  */
826
827             int inum = moxie_process_readu (addr+2, (char *) buf, 
828                                             4, byte_order);
829
830             switch (inum)
831               {
832               case 0x1: /* SYS_exit */
833                 {
834                   /* Do nothing.  */
835                 }
836                 break;
837               case 0x2: /* SYS_open */
838                 {
839                   if (record_arch_list_add_reg (regcache, RET1_REGNUM))
840                     return -1;
841                 }
842                 break;
843               case 0x4: /* SYS_read */
844                 {
845                   uint32_t length, ptr;
846
847                   /* Read buffer pointer is in $r1.  */
848                   regcache_raw_read (regcache, 3, (gdb_byte *) & ptr);
849                   ptr = extract_unsigned_integer ((gdb_byte *) & ptr, 
850                                                   4, byte_order);
851
852                   /* String length is at 0x12($fp).  */
853                   regcache_raw_read (regcache, 
854                                      MOXIE_FP_REGNUM, (gdb_byte *) & tmpu32);
855                   tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
856                                                      4, byte_order);
857                   length = moxie_process_readu (tmpu32+20, (char *) buf, 
858                                                 4, byte_order);
859
860                   if (record_arch_list_add_mem (ptr, length))
861                     return -1;
862                 }
863                 break;
864               case 0x5: /* SYS_write */
865                 {
866                   if (record_arch_list_add_reg (regcache, RET1_REGNUM))
867                     return -1;
868                 }
869                 break;
870               default:
871                 break;
872               }
873           }
874           break;
875         case 0x31: /* div.l */
876         case 0x32: /* udiv.l */
877         case 0x33: /* mod.l */
878         case 0x34: /* umod.l */
879           {
880             int reg = (inst >> 4) & 0xf;
881             if (record_arch_list_add_reg (regcache, reg))
882               return -1;
883           }
884           break;
885         case 0x35: /* brk */
886           /* Do nothing.  */
887           break;
888         case 0x36: /* ldo.b */
889           {
890             int reg = (inst >> 4) & 0xf;
891             if (record_arch_list_add_reg (regcache, reg))
892               return -1;
893           }
894           break;
895         case 0x37: /* sto.b */
896           {
897             int reg = (inst >> 4) & 0xf;
898             uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
899                                                               byte_order);
900             regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
901             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
902                                                4, byte_order);
903             tmpu32 += offset;
904             if (record_arch_list_add_mem (tmpu32, 1))
905               return -1;
906           }
907           break;
908         case 0x38: /* ldo.s */
909           {
910             int reg = (inst >> 4) & 0xf;
911             if (record_arch_list_add_reg (regcache, reg))
912               return -1;
913           }
914           break;
915         case 0x39: /* sto.s */
916           {
917             int reg = (inst >> 4) & 0xf;
918             uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
919                                                               byte_order);
920             regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
921             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
922                                                4, byte_order);
923             tmpu32 += offset;
924             if (record_arch_list_add_mem (tmpu32, 2))
925               return -1;
926           }
927           break;
928         default:
929           /* Do nothing.  */
930           break;
931         }
932     }
933
934   if (record_arch_list_add_reg (regcache, MOXIE_PC_REGNUM))
935     return -1;
936   if (record_arch_list_add_end ())
937     return -1;
938   return 0;
939 }
940
941 /* Allocate and initialize the moxie gdbarch object.  */
942
943 static struct gdbarch *
944 moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
945 {
946   struct gdbarch *gdbarch;
947   struct gdbarch_tdep *tdep;
948
949   /* If there is already a candidate, use it.  */
950   arches = gdbarch_list_lookup_by_info (arches, &info);
951   if (arches != NULL)
952     return arches->gdbarch;
953
954   /* Allocate space for the new architecture.  */
955   tdep = XMALLOC (struct gdbarch_tdep);
956   gdbarch = gdbarch_alloc (&info, tdep);
957
958   set_gdbarch_read_pc (gdbarch, moxie_read_pc);
959   set_gdbarch_write_pc (gdbarch, moxie_write_pc);
960   set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp);
961
962   set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS);
963   set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM);
964   set_gdbarch_pc_regnum (gdbarch, MOXIE_PC_REGNUM);
965   set_gdbarch_register_name (gdbarch, moxie_register_name);
966   set_gdbarch_register_type (gdbarch, moxie_register_type);
967
968   set_gdbarch_return_value (gdbarch, moxie_return_value);
969
970   set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue);
971   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
972   set_gdbarch_breakpoint_from_pc (gdbarch, moxie_breakpoint_from_pc);
973   set_gdbarch_frame_align (gdbarch, moxie_frame_align);
974
975   frame_base_set_default (gdbarch, &moxie_frame_base);
976
977   /* Methods for saving / extracting a dummy frame's ID.  The ID's
978      stack address must match the SP value returned by
979      PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
980   set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);
981
982   set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);
983
984   set_gdbarch_print_insn (gdbarch, print_insn_moxie);
985
986   /* Hook in ABI-specific overrides, if they have been registered.  */
987   gdbarch_init_osabi (info, gdbarch);
988
989   /* Hook in the default unwinders.  */
990   frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind);
991
992   /* Support simple overlay manager.  */
993   set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
994
995   /* Support reverse debugging.  */
996   set_gdbarch_process_record (gdbarch, moxie_process_record);
997
998   return gdbarch;
999 }
1000
1001 /* Register this machine's init routine.  */
1002
1003 void
1004 _initialize_moxie_tdep (void)
1005 {
1006   register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init);
1007 }