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