OSDN Git Service

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