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