OSDN Git Service

2011-03-05 Michael Snyder <msnyder@vmware.com>
[pf3gnuchains/sourceware.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   moxie_frame_this_id,
465   moxie_frame_prev_register,
466   NULL,
467   default_frame_sniffer
468 };
469
470 /* Return the base address of this_frame.  */
471
472 static CORE_ADDR
473 moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
474 {
475   struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
476                                                        this_cache);
477
478   return cache->base;
479 }
480
481 static const struct frame_base moxie_frame_base = {
482   &moxie_frame_unwind,
483   moxie_frame_base_address,
484   moxie_frame_base_address,
485   moxie_frame_base_address
486 };
487
488 static struct frame_id
489 moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
490 {
491   CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM);
492
493   return frame_id_build (sp, get_frame_pc (this_frame));
494 }
495
496 /* Read an unsigned integer from the inferior, and adjust
497    endianess.  */
498 static ULONGEST
499 moxie_process_readu (CORE_ADDR addr, char *buf, 
500                      int length, enum bfd_endian byte_order)
501 {
502   if (target_read_memory (addr, buf, length))
503     {
504       if (record_debug)
505         printf_unfiltered (_("Process record: error reading memory at "
506                              "addr 0x%s len = %d.\n"),
507                            paddress (target_gdbarch, addr), length);
508       return -1;
509     }
510
511   return extract_unsigned_integer (buf, length, byte_order);
512 }
513
514 /* Parse the current instruction and record the values of the registers and
515    memory that will be changed in current instruction to "record_arch_list".
516    Return -1 if something wrong.  */
517
518 int
519 moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
520                       CORE_ADDR addr)
521 {
522   gdb_byte buf[4];
523   uint16_t inst;
524   uint32_t tmpu32;
525   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
526
527   if (record_debug > 1)
528     fprintf_unfiltered (gdb_stdlog, "Process record: moxie_process_record "
529                                     "addr = 0x%s\n",
530                         paddress (target_gdbarch, addr));
531
532   inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
533
534   /* Decode instruction.  */
535   if (inst & (1 << 15))
536     {
537       if (inst & (1 << 14))
538         {
539           /* This is a Form 3 instruction.  */
540           int opcode = (inst >> 10 & 0xf);
541           
542           switch (opcode)
543             {
544             case 0x00: /* beq */
545             case 0x01: /* bne */
546             case 0x02: /* blt */
547             case 0x03: /* bgt */
548             case 0x04: /* bltu */
549             case 0x05: /* bgtu */
550             case 0x06: /* bge */
551             case 0x07: /* ble */
552             case 0x08: /* bgeu */
553             case 0x09: /* bleu */
554               /* Do nothing.  */
555               break;
556             default:
557               {
558                 /* Do nothing.  */
559                 break;
560               }
561             }
562         }
563       else
564         {
565           /* This is a Form 2 instruction.  */
566           int opcode = (inst >> 12 & 0x3);
567           switch (opcode)
568             {
569             case 0x00: /* inc */
570             case 0x01: /* dec */
571             case 0x02: /* gsr */
572               {
573                 int reg = (inst >> 8) & 0xf;
574                 if (record_arch_list_add_reg (regcache, reg))
575                   return -1;
576               }
577               break;
578             case 0x03: /* ssr */
579               {
580                 /* Do nothing until GDB learns about moxie's special
581                    registers.  */
582               }
583               break;
584             default:
585               /* Do nothing.  */
586               break;
587             }
588         }
589     }
590   else
591     {
592       /* This is a Form 1 instruction.  */
593       int opcode = inst >> 8;
594
595       switch (opcode)
596         {
597         case 0x00: /* nop */
598           /* Do nothing.  */
599           break;
600         case 0x01: /* ldi.l (immediate) */
601         case 0x02: /* mov (register-to-register) */
602           {
603             int reg = (inst >> 4) & 0xf;
604             if (record_arch_list_add_reg (regcache, reg))
605               return -1;
606           }
607           break;
608         case 0x03: /* jsra */
609           {
610             regcache_raw_read (regcache, 
611                                MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
612             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
613                                                4, byte_order);
614             if (record_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
615                 || (record_arch_list_add_reg (regcache, 
616                                               MOXIE_SP_REGNUM))
617                 || record_arch_list_add_mem (tmpu32 - 12, 12))
618               return -1;
619           }
620           break;
621         case 0x04: /* ret */
622           {
623             if (record_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
624                 || (record_arch_list_add_reg (regcache, 
625                                               MOXIE_SP_REGNUM)))
626               return -1;
627           }
628           break;
629         case 0x05: /* add.l */
630           {
631             int reg = (inst >> 4) & 0xf;
632             if (record_arch_list_add_reg (regcache, reg))
633               return -1;
634           }
635           break;
636         case 0x06: /* push */
637           {
638             int reg = (inst >> 4) & 0xf;
639             regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
640             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
641                                                4, byte_order);
642             if (record_arch_list_add_reg (regcache, reg)
643                 || record_arch_list_add_mem (tmpu32 - 4, 4))
644               return -1;
645           }
646           break;
647         case 0x07: /* pop */
648           {
649             int a = (inst >> 4) & 0xf;
650             int b = inst & 0xf;
651             if (record_arch_list_add_reg (regcache, a)
652                 || record_arch_list_add_reg (regcache, b))
653               return -1;
654           }
655           break;
656         case 0x08: /* lda.l */
657           {
658             int reg = (inst >> 4) & 0xf;
659             if (record_arch_list_add_reg (regcache, reg))
660               return -1;
661           }
662           break;
663         case 0x09: /* sta.l */
664           {
665             tmpu32 = (uint32_t) moxie_process_readu (addr+2, buf, 
666                                                      4, byte_order);
667             if (record_arch_list_add_mem (tmpu32, 4))
668               return -1;
669           }
670           break;
671         case 0x0a: /* ld.l (register indirect) */
672           {
673             int reg = (inst >> 4) & 0xf;
674             if (record_arch_list_add_reg (regcache, reg))
675               return -1;
676           }
677           break;
678         case 0x0b: /* st.l */
679           {
680             int reg = (inst >> 4) & 0xf;
681             regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
682             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
683                                                4, byte_order);
684             if (record_arch_list_add_mem (tmpu32, 4))
685               return -1;
686           }
687           break;
688         case 0x0c: /* ldo.l */
689           {
690             int reg = (inst >> 4) & 0xf;
691             if (record_arch_list_add_reg (regcache, reg))
692               return -1;
693           }
694           break;
695         case 0x0d: /* sto.l */
696           {
697             int reg = (inst >> 4) & 0xf;
698             uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
699                                                               byte_order);
700             regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
701             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
702                                                4, byte_order);
703             tmpu32 += offset;
704             if (record_arch_list_add_mem (tmpu32, 4))
705               return -1;
706           }
707           break;
708         case 0x0e: /* cmp */
709           {
710             if (record_arch_list_add_reg (regcache, MOXIE_CC_REGNUM))
711               return -1;
712           }
713           break;
714         case 0x0f:
715         case 0x10:
716         case 0x11:
717         case 0x12:
718         case 0x13:
719         case 0x14:
720         case 0x15:
721         case 0x16:
722         case 0x17:
723         case 0x18:
724           {
725             /* Do nothing.  */
726             break;
727           }
728         case 0x19: /* jsr */
729           {
730             regcache_raw_read (regcache, 
731                                MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
732             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
733                                                4, byte_order);
734             if (record_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
735                 || (record_arch_list_add_reg (regcache, 
736                                               MOXIE_SP_REGNUM))
737                 || record_arch_list_add_mem (tmpu32 - 12, 12))
738               return -1;
739           }
740           break;
741         case 0x1a: /* jmpa */
742           {
743             /* Do nothing.  */
744           }
745           break;
746         case 0x1b: /* ldi.b (immediate) */
747         case 0x1c: /* ld.b (register indirect) */
748         case 0x1d: /* lda.b */
749           {
750             int reg = (inst >> 4) & 0xf;
751             if (record_arch_list_add_reg (regcache, reg))
752               return -1;
753           }
754           break;
755         case 0x1e: /* st.b */
756           {
757             int reg = (inst >> 4) & 0xf;
758             regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
759             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
760                                                4, byte_order);
761             if (record_arch_list_add_mem (tmpu32, 1))
762               return -1;
763           }
764           break;
765         case 0x1f: /* sta.b */
766           {
767             tmpu32 = moxie_process_readu (addr+2, (char *) buf, 
768                                           4, byte_order);
769             if (record_arch_list_add_mem (tmpu32, 1))
770               return -1;
771           }
772           break;
773         case 0x20: /* ldi.s (immediate) */
774         case 0x21: /* ld.s (register indirect) */
775         case 0x22: /* lda.s */
776           {
777             int reg = (inst >> 4) & 0xf;
778             if (record_arch_list_add_reg (regcache, reg))
779               return -1;
780           }
781           break;
782         case 0x23: /* st.s */
783           {
784             int reg = (inst >> 4) & 0xf;
785             regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
786             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
787                                                4, byte_order);
788             if (record_arch_list_add_mem (tmpu32, 2))
789               return -1;
790           }
791           break;
792         case 0x24: /* sta.s */
793           {
794             tmpu32 = moxie_process_readu (addr+2, (char *) buf, 
795                                           4, byte_order);
796             if (record_arch_list_add_mem (tmpu32, 2))
797               return -1;
798           }
799           break;
800         case 0x25: /* jmp */
801           {
802             /* Do nothing.  */
803           }
804           break;
805         case 0x26: /* and */
806         case 0x27: /* lshr */
807         case 0x28: /* ashl */
808         case 0x29: /* sub.l */
809         case 0x2a: /* neg */
810         case 0x2b: /* or */
811         case 0x2c: /* not */
812         case 0x2d: /* ashr */
813         case 0x2e: /* xor */
814         case 0x2f: /* mul.l */
815           {
816             int reg = (inst >> 4) & 0xf;
817             if (record_arch_list_add_reg (regcache, reg))
818               return -1;
819           }
820           break;
821         case 0x30: /* swi */
822           {
823             /* We currently implement support for libgloss' 
824                system calls.  */
825
826             int inum = moxie_process_readu (addr+2, (char *) buf, 
827                                             4, byte_order);
828
829             switch (inum)
830               {
831               case 0x1: /* SYS_exit */
832                 {
833                   /* Do nothing.  */
834                 }
835                 break;
836               case 0x2: /* SYS_open */
837                 {
838                   if (record_arch_list_add_reg (regcache, RET1_REGNUM))
839                     return -1;
840                 }
841                 break;
842               case 0x4: /* SYS_read */
843                 {
844                   uint32_t length, ptr;
845
846                   /* Read buffer pointer is in $r1.  */
847                   regcache_raw_read (regcache, 3, (gdb_byte *) & ptr);
848                   ptr = extract_unsigned_integer ((gdb_byte *) & ptr, 
849                                                   4, byte_order);
850
851                   /* String length is at 0x12($fp).  */
852                   regcache_raw_read (regcache, 
853                                      MOXIE_FP_REGNUM, (gdb_byte *) & tmpu32);
854                   tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
855                                                      4, byte_order);
856                   length = moxie_process_readu (tmpu32+20, (char *) buf, 
857                                                 4, byte_order);
858
859                   if (record_arch_list_add_mem (ptr, length))
860                     return -1;
861                 }
862                 break;
863               case 0x5: /* SYS_write */
864                 {
865                   if (record_arch_list_add_reg (regcache, RET1_REGNUM))
866                     return -1;
867                 }
868                 break;
869               default:
870                 break;
871               }
872           }
873           break;
874         case 0x31: /* div.l */
875         case 0x32: /* udiv.l */
876         case 0x33: /* mod.l */
877         case 0x34: /* umod.l */
878           {
879             int reg = (inst >> 4) & 0xf;
880             if (record_arch_list_add_reg (regcache, reg))
881               return -1;
882           }
883           break;
884         case 0x35: /* brk */
885           /* Do nothing.  */
886           break;
887         case 0x36: /* ldo.b */
888           {
889             int reg = (inst >> 4) & 0xf;
890             if (record_arch_list_add_reg (regcache, reg))
891               return -1;
892           }
893           break;
894         case 0x37: /* sto.b */
895           {
896             int reg = (inst >> 4) & 0xf;
897             uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
898                                                               byte_order);
899             regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
900             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
901                                                4, byte_order);
902             tmpu32 += offset;
903             if (record_arch_list_add_mem (tmpu32, 1))
904               return -1;
905           }
906           break;
907         case 0x38: /* ldo.s */
908           {
909             int reg = (inst >> 4) & 0xf;
910             if (record_arch_list_add_reg (regcache, reg))
911               return -1;
912           }
913           break;
914         case 0x39: /* sto.s */
915           {
916             int reg = (inst >> 4) & 0xf;
917             uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
918                                                               byte_order);
919             regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
920             tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
921                                                4, byte_order);
922             tmpu32 += offset;
923             if (record_arch_list_add_mem (tmpu32, 2))
924               return -1;
925           }
926           break;
927         default:
928           /* Do nothing.  */
929           break;
930         }
931     }
932
933   if (record_arch_list_add_reg (regcache, MOXIE_PC_REGNUM))
934     return -1;
935   if (record_arch_list_add_end ())
936     return -1;
937   return 0;
938 }
939
940 /* Allocate and initialize the moxie gdbarch object.  */
941
942 static struct gdbarch *
943 moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
944 {
945   struct gdbarch *gdbarch;
946   struct gdbarch_tdep *tdep;
947
948   /* If there is already a candidate, use it.  */
949   arches = gdbarch_list_lookup_by_info (arches, &info);
950   if (arches != NULL)
951     return arches->gdbarch;
952
953   /* Allocate space for the new architecture.  */
954   tdep = XMALLOC (struct gdbarch_tdep);
955   gdbarch = gdbarch_alloc (&info, tdep);
956
957   set_gdbarch_read_pc (gdbarch, moxie_read_pc);
958   set_gdbarch_write_pc (gdbarch, moxie_write_pc);
959   set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp);
960
961   set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS);
962   set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM);
963   set_gdbarch_pc_regnum (gdbarch, MOXIE_PC_REGNUM);
964   set_gdbarch_register_name (gdbarch, moxie_register_name);
965   set_gdbarch_register_type (gdbarch, moxie_register_type);
966
967   set_gdbarch_return_value (gdbarch, moxie_return_value);
968
969   set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue);
970   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
971   set_gdbarch_breakpoint_from_pc (gdbarch, moxie_breakpoint_from_pc);
972   set_gdbarch_frame_align (gdbarch, moxie_frame_align);
973
974   frame_base_set_default (gdbarch, &moxie_frame_base);
975
976   /* Methods for saving / extracting a dummy frame's ID.  The ID's
977      stack address must match the SP value returned by
978      PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
979   set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);
980
981   set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);
982
983   set_gdbarch_print_insn (gdbarch, print_insn_moxie);
984
985   /* Hook in ABI-specific overrides, if they have been registered.  */
986   gdbarch_init_osabi (info, gdbarch);
987
988   /* Hook in the default unwinders.  */
989   frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind);
990
991   /* Support simple overlay manager.  */
992   set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
993
994   /* Support reverse debugging.  */
995   set_gdbarch_process_record (gdbarch, moxie_process_record);
996
997   return gdbarch;
998 }
999
1000 /* Register this machine's init routine.  */
1001
1002 void
1003 _initialize_moxie_tdep (void)
1004 {
1005   register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init);
1006 }