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