| /* Target dependent code for CRIS, for GDB, the GNU debugger. | 
 |  | 
 |    Copyright (C) 2001-2023 Free Software Foundation, Inc. | 
 |  | 
 |    Contributed by Axis Communications AB. | 
 |    Written by Hendrik Ruijter, Stefan Andersson, and Orjan Friberg. | 
 |  | 
 |    This file is part of GDB. | 
 |  | 
 |    This program is free software; you can redistribute it and/or modify | 
 |    it under the terms of the GNU General Public License as published by | 
 |    the Free Software Foundation; either version 3 of the License, or | 
 |    (at your option) any later version. | 
 |  | 
 |    This program is distributed in the hope that it will be useful, | 
 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 |    GNU General Public License for more details. | 
 |  | 
 |    You should have received a copy of the GNU General Public License | 
 |    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | 
 |  | 
 | #include "defs.h" | 
 | #include "frame.h" | 
 | #include "frame-unwind.h" | 
 | #include "frame-base.h" | 
 | #include "trad-frame.h" | 
 | #include "dwarf2/frame.h" | 
 | #include "symtab.h" | 
 | #include "inferior.h" | 
 | #include "gdbtypes.h" | 
 | #include "gdbcore.h" | 
 | #include "gdbcmd.h" | 
 | #include "target.h" | 
 | #include "value.h" | 
 | #include "opcode/cris.h" | 
 | #include "osabi.h" | 
 | #include "arch-utils.h" | 
 | #include "regcache.h" | 
 | #include "regset.h" | 
 |  | 
 | #include "objfiles.h" | 
 |  | 
 | #include "solib.h"              /* Support for shared libraries.  */ | 
 | #include "solib-svr4.h" | 
 | #include "dis-asm.h" | 
 |  | 
 | #include "cris-tdep.h" | 
 |  | 
 | enum cris_num_regs | 
 | { | 
 |   /* There are no floating point registers.  Used in gdbserver low-linux.c.  */ | 
 |   NUM_FREGS = 0, | 
 |    | 
 |   /* There are 16 general registers.  */ | 
 |   NUM_GENREGS = 16, | 
 |    | 
 |   /* There are 16 special registers.  */ | 
 |   NUM_SPECREGS = 16, | 
 |  | 
 |   /* CRISv32 has a pseudo PC register, not noted here.  */ | 
 |    | 
 |   /* CRISv32 has 16 support registers.  */ | 
 |   NUM_SUPPREGS = 16 | 
 | }; | 
 |  | 
 | /* Register numbers of various important registers. | 
 |    CRIS_FP_REGNUM   Contains address of executing stack frame. | 
 |    STR_REGNUM  Contains the address of structure return values. | 
 |    RET_REGNUM  Contains the return value when shorter than or equal to 32 bits | 
 |    ARG1_REGNUM Contains the first parameter to a function. | 
 |    ARG2_REGNUM Contains the second parameter to a function. | 
 |    ARG3_REGNUM Contains the third parameter to a function. | 
 |    ARG4_REGNUM Contains the fourth parameter to a function.  Rest on stack. | 
 |    gdbarch_sp_regnum Contains address of top of stack. | 
 |    gdbarch_pc_regnum Contains address of next instruction. | 
 |    SRP_REGNUM  Subroutine return pointer register. | 
 |    BRP_REGNUM  Breakpoint return pointer register.  */ | 
 |  | 
 | enum cris_regnums | 
 | { | 
 |   /* Enums with respect to the general registers, valid for all  | 
 |      CRIS versions.  The frame pointer is always in R8.  */ | 
 |   CRIS_FP_REGNUM = 8, | 
 |   /* ABI related registers.  */ | 
 |   STR_REGNUM  = 9, | 
 |   RET_REGNUM  = 10, | 
 |   ARG1_REGNUM = 10, | 
 |   ARG2_REGNUM = 11, | 
 |   ARG3_REGNUM = 12, | 
 |   ARG4_REGNUM = 13, | 
 |    | 
 |   /* Registers which happen to be common.  */ | 
 |   VR_REGNUM   = 17, | 
 |   MOF_REGNUM  = 23, | 
 |   SRP_REGNUM  = 27, | 
 |  | 
 |   /* CRISv10 et al. specific registers.  */ | 
 |   P0_REGNUM   = 16, | 
 |   P4_REGNUM   = 20, | 
 |   CCR_REGNUM  = 21, | 
 |   P8_REGNUM   = 24, | 
 |   IBR_REGNUM  = 25, | 
 |   IRP_REGNUM  = 26, | 
 |   BAR_REGNUM  = 28, | 
 |   DCCR_REGNUM = 29, | 
 |   BRP_REGNUM  = 30, | 
 |   USP_REGNUM  = 31, | 
 |  | 
 |   /* CRISv32 specific registers.  */ | 
 |   ACR_REGNUM  = 15, | 
 |   BZ_REGNUM   = 16, | 
 |   PID_REGNUM  = 18, | 
 |   SRS_REGNUM  = 19, | 
 |   WZ_REGNUM   = 20, | 
 |   EXS_REGNUM  = 21, | 
 |   EDA_REGNUM  = 22, | 
 |   DZ_REGNUM   = 24, | 
 |   EBP_REGNUM  = 25, | 
 |   ERP_REGNUM  = 26, | 
 |   NRP_REGNUM  = 28, | 
 |   CCS_REGNUM  = 29, | 
 |   CRISV32USP_REGNUM  = 30, /* Shares name but not number with CRISv10.  */ | 
 |   SPC_REGNUM  = 31, | 
 |   CRISV32PC_REGNUM   = 32, /* Shares name but not number with CRISv10.  */ | 
 |  | 
 |   S0_REGNUM = 33, | 
 |   S1_REGNUM = 34, | 
 |   S2_REGNUM = 35, | 
 |   S3_REGNUM = 36, | 
 |   S4_REGNUM = 37, | 
 |   S5_REGNUM = 38, | 
 |   S6_REGNUM = 39, | 
 |   S7_REGNUM = 40, | 
 |   S8_REGNUM = 41, | 
 |   S9_REGNUM = 42, | 
 |   S10_REGNUM = 43, | 
 |   S11_REGNUM = 44, | 
 |   S12_REGNUM = 45, | 
 |   S13_REGNUM = 46, | 
 |   S14_REGNUM = 47, | 
 |   S15_REGNUM = 48, | 
 | }; | 
 |  | 
 | extern const struct cris_spec_reg cris_spec_regs[]; | 
 |  | 
 | /* CRIS version, set via the user command 'set cris-version'.  Affects | 
 |    register names and sizes.  */ | 
 | static unsigned int usr_cmd_cris_version; | 
 |  | 
 | /* Indicates whether to trust the above variable.  */ | 
 | static bool usr_cmd_cris_version_valid = false; | 
 |  | 
 | static const char cris_mode_normal[] = "normal"; | 
 | static const char cris_mode_guru[] = "guru"; | 
 | static const char *const cris_modes[] = { | 
 |   cris_mode_normal, | 
 |   cris_mode_guru, | 
 |   0 | 
 | }; | 
 |  | 
 | /* CRIS mode, set via the user command 'set cris-mode'.  Affects | 
 |    type of break instruction among other things.  */ | 
 | static const char *usr_cmd_cris_mode = cris_mode_normal; | 
 |  | 
 | /* Whether to make use of Dwarf-2 CFI (default on).  */ | 
 | static bool usr_cmd_cris_dwarf2_cfi = true; | 
 |  | 
 | /* Sigtramp identification code copied from i386-linux-tdep.c.  */ | 
 |  | 
 | #define SIGTRAMP_INSN0    0x9c5f  /* movu.w 0xXX, $r9 */ | 
 | #define SIGTRAMP_OFFSET0  0 | 
 | #define SIGTRAMP_INSN1    0xe93d  /* break 13 */ | 
 | #define SIGTRAMP_OFFSET1  4 | 
 |  | 
 | static const unsigned short sigtramp_code[] = | 
 | { | 
 |   SIGTRAMP_INSN0, 0x0077,  /* movu.w $0x77, $r9 */ | 
 |   SIGTRAMP_INSN1           /* break 13 */ | 
 | }; | 
 |  | 
 | #define SIGTRAMP_LEN (sizeof sigtramp_code) | 
 |  | 
 | /* Note: same length as normal sigtramp code.  */ | 
 |  | 
 | static const unsigned short rt_sigtramp_code[] = | 
 | { | 
 |   SIGTRAMP_INSN0, 0x00ad,  /* movu.w $0xad, $r9 */ | 
 |   SIGTRAMP_INSN1           /* break 13 */ | 
 | }; | 
 |  | 
 | /* If PC is in a sigtramp routine, return the address of the start of | 
 |    the routine.  Otherwise, return 0.  */ | 
 |  | 
 | static CORE_ADDR | 
 | cris_sigtramp_start (frame_info_ptr this_frame) | 
 | { | 
 |   CORE_ADDR pc = get_frame_pc (this_frame); | 
 |   gdb_byte buf[SIGTRAMP_LEN]; | 
 |  | 
 |   if (!safe_frame_unwind_memory (this_frame, pc, buf)) | 
 |     return 0; | 
 |  | 
 |   if (((buf[1] << 8) + buf[0]) != SIGTRAMP_INSN0) | 
 |     { | 
 |       if (((buf[1] << 8) + buf[0]) != SIGTRAMP_INSN1) | 
 | 	return 0; | 
 |  | 
 |       pc -= SIGTRAMP_OFFSET1; | 
 |       if (!safe_frame_unwind_memory (this_frame, pc, buf)) | 
 | 	return 0; | 
 |     } | 
 |  | 
 |   if (memcmp (buf, sigtramp_code, SIGTRAMP_LEN) != 0) | 
 |     return 0; | 
 |  | 
 |   return pc; | 
 | } | 
 |  | 
 | /* If PC is in a RT sigtramp routine, return the address of the start of | 
 |    the routine.  Otherwise, return 0.  */ | 
 |  | 
 | static CORE_ADDR | 
 | cris_rt_sigtramp_start (frame_info_ptr this_frame) | 
 | { | 
 |   CORE_ADDR pc = get_frame_pc (this_frame); | 
 |   gdb_byte buf[SIGTRAMP_LEN]; | 
 |  | 
 |   if (!safe_frame_unwind_memory (this_frame, pc, buf)) | 
 |     return 0; | 
 |  | 
 |   if (((buf[1] << 8) + buf[0]) != SIGTRAMP_INSN0) | 
 |     { | 
 |       if (((buf[1] << 8) + buf[0]) != SIGTRAMP_INSN1) | 
 | 	return 0; | 
 |  | 
 |       pc -= SIGTRAMP_OFFSET1; | 
 |       if (!safe_frame_unwind_memory (this_frame, pc, buf)) | 
 | 	return 0; | 
 |     } | 
 |  | 
 |   if (memcmp (buf, rt_sigtramp_code, SIGTRAMP_LEN) != 0) | 
 |     return 0; | 
 |  | 
 |   return pc; | 
 | } | 
 |  | 
 | /* Assuming THIS_FRAME is a frame for a GNU/Linux sigtramp routine, | 
 |    return the address of the associated sigcontext structure.  */ | 
 |  | 
 | static CORE_ADDR | 
 | cris_sigcontext_addr (frame_info_ptr this_frame) | 
 | { | 
 |   struct gdbarch *gdbarch = get_frame_arch (this_frame); | 
 |   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | 
 |   CORE_ADDR pc; | 
 |   CORE_ADDR sp; | 
 |   gdb_byte buf[4]; | 
 |  | 
 |   get_frame_register (this_frame, gdbarch_sp_regnum (gdbarch), buf); | 
 |   sp = extract_unsigned_integer (buf, 4, byte_order); | 
 |  | 
 |   /* Look for normal sigtramp frame first.  */ | 
 |   pc = cris_sigtramp_start (this_frame); | 
 |   if (pc) | 
 |     { | 
 |       /* struct signal_frame (arch/cris/kernel/signal.c) contains | 
 | 	 struct sigcontext as its first member, meaning the SP points to | 
 | 	 it already.  */ | 
 |       return sp; | 
 |     } | 
 |  | 
 |   pc = cris_rt_sigtramp_start (this_frame); | 
 |   if (pc) | 
 |     { | 
 |       /* struct rt_signal_frame (arch/cris/kernel/signal.c) contains | 
 | 	 a struct ucontext, which in turn contains a struct sigcontext. | 
 | 	 Magic digging: | 
 | 	 4 + 4 + 128 to struct ucontext, then | 
 | 	 4 + 4 + 12 to struct sigcontext.  */ | 
 |       return (sp + 156); | 
 |     } | 
 |  | 
 |   error (_("Couldn't recognize signal trampoline.")); | 
 |   return 0; | 
 | } | 
 |  | 
 | struct cris_unwind_cache | 
 | { | 
 |   /* The previous frame's inner most stack address.  Used as this | 
 |      frame ID's stack_addr.  */ | 
 |   CORE_ADDR prev_sp; | 
 |   /* The frame's base, optionally used by the high-level debug info.  */ | 
 |   CORE_ADDR base; | 
 |   int size; | 
 |   /* How far the SP and r8 (FP) have been offset from the start of | 
 |      the stack frame (as defined by the previous frame's stack | 
 |      pointer).  */ | 
 |   LONGEST sp_offset; | 
 |   LONGEST r8_offset; | 
 |   int uses_frame; | 
 |  | 
 |   /* From old frame_extra_info struct.  */ | 
 |   CORE_ADDR return_pc; | 
 |   int leaf_function; | 
 |  | 
 |   /* Table indicating the location of each and every register.  */ | 
 |   trad_frame_saved_reg *saved_regs; | 
 | }; | 
 |  | 
 | static struct cris_unwind_cache * | 
 | cris_sigtramp_frame_unwind_cache (frame_info_ptr this_frame, | 
 | 				  void **this_cache) | 
 | { | 
 |   struct gdbarch *gdbarch = get_frame_arch (this_frame); | 
 |   cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch); | 
 |   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | 
 |   struct cris_unwind_cache *info; | 
 |   CORE_ADDR addr; | 
 |   gdb_byte buf[4]; | 
 |   int i; | 
 |  | 
 |   if ((*this_cache)) | 
 |     return (struct cris_unwind_cache *) (*this_cache); | 
 |  | 
 |   info = FRAME_OBSTACK_ZALLOC (struct cris_unwind_cache); | 
 |   (*this_cache) = info; | 
 |   info->saved_regs = trad_frame_alloc_saved_regs (this_frame); | 
 |  | 
 |   /* Zero all fields.  */ | 
 |   info->prev_sp = 0; | 
 |   info->base = 0; | 
 |   info->size = 0; | 
 |   info->sp_offset = 0; | 
 |   info->r8_offset = 0; | 
 |   info->uses_frame = 0; | 
 |   info->return_pc = 0; | 
 |   info->leaf_function = 0; | 
 |  | 
 |   get_frame_register (this_frame, gdbarch_sp_regnum (gdbarch), buf); | 
 |   info->base = extract_unsigned_integer (buf, 4, byte_order); | 
 |  | 
 |   addr = cris_sigcontext_addr (this_frame); | 
 |    | 
 |   /* Layout of the sigcontext struct: | 
 |      struct sigcontext { | 
 | 	struct pt_regs regs; | 
 | 	unsigned long oldmask; | 
 | 	unsigned long usp; | 
 |      }; */ | 
 |    | 
 |   if (tdep->cris_version == 10) | 
 |     { | 
 |       /* R0 to R13 are stored in reverse order at offset (2 * 4) in  | 
 | 	 struct pt_regs.  */ | 
 |       for (i = 0; i <= 13; i++) | 
 | 	info->saved_regs[i].set_addr (addr + ((15 - i) * 4)); | 
 |  | 
 |       info->saved_regs[MOF_REGNUM].set_addr (addr + (16 * 4)); | 
 |       info->saved_regs[DCCR_REGNUM].set_addr (addr + (17 * 4)); | 
 |       info->saved_regs[SRP_REGNUM].set_addr (addr + (18 * 4)); | 
 |       /* Note: IRP is off by 2 at this point.  There's no point in correcting | 
 | 	 it though since that will mean that the backtrace will show a PC  | 
 | 	 different from what is shown when stopped.  */ | 
 |       info->saved_regs[IRP_REGNUM].set_addr (addr + (19 * 4)); | 
 |       info->saved_regs[gdbarch_pc_regnum (gdbarch)] | 
 | 	= info->saved_regs[IRP_REGNUM]; | 
 |       info->saved_regs[gdbarch_sp_regnum (gdbarch)].set_addr (addr + (24 * 4)); | 
 |     } | 
 |   else | 
 |     { | 
 |       /* CRISv32.  */ | 
 |       /* R0 to R13 are stored in order at offset (1 * 4) in  | 
 | 	 struct pt_regs.  */ | 
 |       for (i = 0; i <= 13; i++) | 
 | 	info->saved_regs[i].set_addr (addr + ((i + 1) * 4)); | 
 |  | 
 |       info->saved_regs[ACR_REGNUM].set_addr (addr + (15 * 4)); | 
 |       info->saved_regs[SRS_REGNUM].set_addr (addr + (16 * 4)); | 
 |       info->saved_regs[MOF_REGNUM].set_addr (addr + (17 * 4)); | 
 |       info->saved_regs[SPC_REGNUM].set_addr (addr + (18 * 4)); | 
 |       info->saved_regs[CCS_REGNUM].set_addr (addr + (19 * 4)); | 
 |       info->saved_regs[SRP_REGNUM].set_addr (addr + (20 * 4)); | 
 |       info->saved_regs[ERP_REGNUM].set_addr (addr + (21 * 4)); | 
 |       info->saved_regs[EXS_REGNUM].set_addr (addr + (22 * 4)); | 
 |       info->saved_regs[EDA_REGNUM].set_addr (addr + (23 * 4)); | 
 |  | 
 |       /* FIXME: If ERP is in a delay slot at this point then the PC will | 
 | 	 be wrong at this point.  This problem manifests itself in the | 
 | 	 sigaltstack.exp test case, which occasionally generates FAILs when | 
 | 	 the signal is received while in a delay slot. | 
 | 	  | 
 | 	 This could be solved by a couple of read_memory_unsigned_integer and a | 
 | 	 trad_frame_set_value.  */ | 
 |       info->saved_regs[gdbarch_pc_regnum (gdbarch)] | 
 | 	= info->saved_regs[ERP_REGNUM]; | 
 |  | 
 |       info->saved_regs[gdbarch_sp_regnum (gdbarch)].set_addr (addr + (25 * 4)); | 
 |     } | 
 |    | 
 |   return info; | 
 | } | 
 |  | 
 | static void | 
 | cris_sigtramp_frame_this_id (frame_info_ptr this_frame, void **this_cache, | 
 | 			     struct frame_id *this_id) | 
 | { | 
 |   struct cris_unwind_cache *cache = | 
 |     cris_sigtramp_frame_unwind_cache (this_frame, this_cache); | 
 |   (*this_id) = frame_id_build (cache->base, get_frame_pc (this_frame)); | 
 | } | 
 |  | 
 | /* Forward declaration.  */ | 
 |  | 
 | static struct value *cris_frame_prev_register (frame_info_ptr this_frame, | 
 | 					       void **this_cache, int regnum); | 
 | static struct value * | 
 | cris_sigtramp_frame_prev_register (frame_info_ptr this_frame, | 
 | 				   void **this_cache, int regnum) | 
 | { | 
 |   /* Make sure we've initialized the cache.  */ | 
 |   cris_sigtramp_frame_unwind_cache (this_frame, this_cache); | 
 |   return cris_frame_prev_register (this_frame, this_cache, regnum); | 
 | } | 
 |  | 
 | static int | 
 | cris_sigtramp_frame_sniffer (const struct frame_unwind *self, | 
 | 			     frame_info_ptr this_frame, | 
 | 			     void **this_cache) | 
 | { | 
 |   if (cris_sigtramp_start (this_frame)  | 
 |       || cris_rt_sigtramp_start (this_frame)) | 
 |     return 1; | 
 |  | 
 |   return 0; | 
 | } | 
 |  | 
 | static const struct frame_unwind cris_sigtramp_frame_unwind = | 
 | { | 
 |   "cris sigtramp", | 
 |   SIGTRAMP_FRAME, | 
 |   default_frame_unwind_stop_reason, | 
 |   cris_sigtramp_frame_this_id, | 
 |   cris_sigtramp_frame_prev_register, | 
 |   NULL, | 
 |   cris_sigtramp_frame_sniffer | 
 | }; | 
 |  | 
 | static int | 
 | crisv32_single_step_through_delay (struct gdbarch *gdbarch, | 
 | 				   frame_info_ptr this_frame) | 
 | { | 
 |   cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch); | 
 |   ULONGEST erp; | 
 |   int ret = 0; | 
 |  | 
 |   if (tdep->cris_mode == cris_mode_guru) | 
 |     erp = get_frame_register_unsigned (this_frame, NRP_REGNUM); | 
 |   else | 
 |     erp = get_frame_register_unsigned (this_frame, ERP_REGNUM); | 
 |  | 
 |   if (erp & 0x1) | 
 |     { | 
 |       /* In delay slot - check if there's a breakpoint at the preceding | 
 | 	 instruction.  */ | 
 |       if (breakpoint_here_p (get_frame_address_space (this_frame), erp & ~0x1)) | 
 | 	ret = 1; | 
 |     } | 
 |   return ret; | 
 | } | 
 |  | 
 | /* The instruction environment needed to find single-step breakpoints.  */ | 
 |  | 
 | typedef  | 
 | struct instruction_environment | 
 | { | 
 |   unsigned long reg[NUM_GENREGS]; | 
 |   unsigned long preg[NUM_SPECREGS]; | 
 |   unsigned long branch_break_address; | 
 |   unsigned long delay_slot_pc; | 
 |   unsigned long prefix_value; | 
 |   int   branch_found; | 
 |   int   prefix_found; | 
 |   int   invalid; | 
 |   int   slot_needed; | 
 |   int   delay_slot_pc_active; | 
 |   int   xflag_found; | 
 |   int   disable_interrupt; | 
 |   enum bfd_endian byte_order; | 
 | } inst_env_type; | 
 |  | 
 | /* Machine-dependencies in CRIS for opcodes.  */ | 
 |  | 
 | /* Instruction sizes.  */ | 
 | enum cris_instruction_sizes | 
 | { | 
 |   INST_BYTE_SIZE  = 0, | 
 |   INST_WORD_SIZE  = 1, | 
 |   INST_DWORD_SIZE = 2 | 
 | }; | 
 |  | 
 | /* Addressing modes.  */ | 
 | enum cris_addressing_modes | 
 | { | 
 |   REGISTER_MODE = 1, | 
 |   INDIRECT_MODE = 2, | 
 |   AUTOINC_MODE  = 3 | 
 | }; | 
 |  | 
 | /* Prefix addressing modes.  */ | 
 | enum cris_prefix_addressing_modes | 
 | { | 
 |   PREFIX_INDEX_MODE  = 2, | 
 |   PREFIX_ASSIGN_MODE = 3, | 
 |  | 
 |   /* Handle immediate byte offset addressing mode prefix format.  */ | 
 |   PREFIX_OFFSET_MODE = 2 | 
 | }; | 
 |  | 
 | /* Masks for opcodes.  */ | 
 | enum cris_opcode_masks | 
 | { | 
 |   BRANCH_SIGNED_SHORT_OFFSET_MASK = 0x1, | 
 |   SIGNED_EXTEND_BIT_MASK          = 0x2, | 
 |   SIGNED_BYTE_MASK                = 0x80, | 
 |   SIGNED_BYTE_EXTEND_MASK         = 0xFFFFFF00, | 
 |   SIGNED_WORD_MASK                = 0x8000, | 
 |   SIGNED_WORD_EXTEND_MASK         = 0xFFFF0000, | 
 |   SIGNED_DWORD_MASK               = 0x80000000, | 
 |   SIGNED_QUICK_VALUE_MASK         = 0x20, | 
 |   SIGNED_QUICK_VALUE_EXTEND_MASK  = 0xFFFFFFC0 | 
 | }; | 
 |  | 
 | /* Functions for opcodes.  The general form of the ETRAX 16-bit instruction: | 
 |    Bit 15 - 12   Operand2 | 
 |        11 - 10   Mode | 
 | 	9 -  6   Opcode | 
 | 	5 -  4   Size | 
 | 	3 -  0   Operand1  */ | 
 |  | 
 | static int  | 
 | cris_get_operand2 (unsigned short insn) | 
 | { | 
 |   return ((insn & 0xF000) >> 12); | 
 | } | 
 |  | 
 | static int | 
 | cris_get_mode (unsigned short insn) | 
 | { | 
 |   return ((insn & 0x0C00) >> 10); | 
 | } | 
 |  | 
 | static int | 
 | cris_get_opcode (unsigned short insn) | 
 | { | 
 |   return ((insn & 0x03C0) >> 6); | 
 | } | 
 |  | 
 | static int | 
 | cris_get_size (unsigned short insn) | 
 | { | 
 |   return ((insn & 0x0030) >> 4); | 
 | } | 
 |  | 
 | static int | 
 | cris_get_operand1 (unsigned short insn) | 
 | { | 
 |   return (insn & 0x000F); | 
 | } | 
 |  | 
 | /* Additional functions in order to handle opcodes.  */ | 
 |  | 
 | static int | 
 | cris_get_quick_value (unsigned short insn) | 
 | { | 
 |   return (insn & 0x003F); | 
 | } | 
 |  | 
 | static int | 
 | cris_get_bdap_quick_offset (unsigned short insn) | 
 | { | 
 |   return (insn & 0x00FF); | 
 | } | 
 |  | 
 | static int | 
 | cris_get_branch_short_offset (unsigned short insn) | 
 | { | 
 |   return (insn & 0x00FF); | 
 | } | 
 |  | 
 | static int | 
 | cris_get_asr_shift_steps (unsigned long value) | 
 | { | 
 |   return (value & 0x3F); | 
 | } | 
 |  | 
 | static int | 
 | cris_get_clear_size (unsigned short insn) | 
 | { | 
 |   return ((insn) & 0xC000); | 
 | } | 
 |  | 
 | static int | 
 | cris_is_signed_extend_bit_on (unsigned short insn) | 
 | { | 
 |   return (((insn) & 0x20) == 0x20); | 
 | } | 
 |  | 
 | static int | 
 | cris_is_xflag_bit_on (unsigned short insn) | 
 | { | 
 |   return (((insn) & 0x1000) == 0x1000); | 
 | } | 
 |  | 
 | static void | 
 | cris_set_size_to_dword (unsigned short *insn) | 
 | { | 
 |   *insn &= 0xFFCF;  | 
 |   *insn |= 0x20;  | 
 | } | 
 |  | 
 | static signed char | 
 | cris_get_signed_offset (unsigned short insn) | 
 | { | 
 |   return ((signed char) (insn & 0x00FF)); | 
 | } | 
 |  | 
 | /* Calls an op function given the op-type, working on the insn and the | 
 |    inst_env.  */ | 
 | static void cris_gdb_func (struct gdbarch *, enum cris_op_type, unsigned short, | 
 | 			   inst_env_type *); | 
 |  | 
 | static struct gdbarch *cris_gdbarch_init (struct gdbarch_info, | 
 | 					  struct gdbarch_list *); | 
 |  | 
 | static void cris_dump_tdep (struct gdbarch *, struct ui_file *); | 
 |  | 
 | static void set_cris_version (const char *ignore_args, int from_tty,  | 
 | 			      struct cmd_list_element *c); | 
 |  | 
 | static void set_cris_mode (const char *ignore_args, int from_tty,  | 
 | 			   struct cmd_list_element *c); | 
 |  | 
 | static void set_cris_dwarf2_cfi (const char *ignore_args, int from_tty,  | 
 | 				 struct cmd_list_element *c); | 
 |  | 
 | static CORE_ADDR cris_scan_prologue (CORE_ADDR pc,  | 
 | 				     frame_info_ptr this_frame, | 
 | 				     struct cris_unwind_cache *info); | 
 |  | 
 | static CORE_ADDR crisv32_scan_prologue (CORE_ADDR pc,  | 
 | 					frame_info_ptr this_frame, | 
 | 					struct cris_unwind_cache *info); | 
 |  | 
 | /* When arguments must be pushed onto the stack, they go on in reverse | 
 |    order.  The below implements a FILO (stack) to do this. | 
 |    Copied from d10v-tdep.c.  */ | 
 |  | 
 | struct cris_stack_item | 
 | { | 
 |   int len; | 
 |   struct cris_stack_item *prev; | 
 |   gdb_byte *data; | 
 | }; | 
 |  | 
 | static struct cris_stack_item * | 
 | push_stack_item (struct cris_stack_item *prev, const gdb_byte *contents, | 
 | 		 int len) | 
 | { | 
 |   struct cris_stack_item *si = XNEW (struct cris_stack_item); | 
 |   si->data = (gdb_byte *) xmalloc (len); | 
 |   si->len = len; | 
 |   si->prev = prev; | 
 |   memcpy (si->data, contents, len); | 
 |   return si; | 
 | } | 
 |  | 
 | static struct cris_stack_item * | 
 | pop_stack_item (struct cris_stack_item *si) | 
 | { | 
 |   struct cris_stack_item *dead = si; | 
 |   si = si->prev; | 
 |   xfree (dead->data); | 
 |   xfree (dead); | 
 |   return si; | 
 | } | 
 |  | 
 | /* Put here the code to store, into fi->saved_regs, the addresses of | 
 |    the saved registers of frame described by FRAME_INFO.  This | 
 |    includes special registers such as pc and fp saved in special ways | 
 |    in the stack frame.  sp is even more special: the address we return | 
 |    for it IS the sp for the next frame.  */ | 
 |  | 
 | static struct cris_unwind_cache * | 
 | cris_frame_unwind_cache (frame_info_ptr this_frame, | 
 | 			 void **this_prologue_cache) | 
 | { | 
 |   struct gdbarch *gdbarch = get_frame_arch (this_frame); | 
 |   cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch); | 
 |   struct cris_unwind_cache *info; | 
 |  | 
 |   if ((*this_prologue_cache)) | 
 |     return (struct cris_unwind_cache *) (*this_prologue_cache); | 
 |  | 
 |   info = FRAME_OBSTACK_ZALLOC (struct cris_unwind_cache); | 
 |   (*this_prologue_cache) = info; | 
 |   info->saved_regs = trad_frame_alloc_saved_regs (this_frame); | 
 |  | 
 |   /* Zero all fields.  */ | 
 |   info->prev_sp = 0; | 
 |   info->base = 0; | 
 |   info->size = 0; | 
 |   info->sp_offset = 0; | 
 |   info->r8_offset = 0; | 
 |   info->uses_frame = 0; | 
 |   info->return_pc = 0; | 
 |   info->leaf_function = 0; | 
 |  | 
 |   /* Prologue analysis does the rest...  */ | 
 |   if (tdep->cris_version == 32) | 
 |     crisv32_scan_prologue (get_frame_func (this_frame), this_frame, info); | 
 |   else | 
 |     cris_scan_prologue (get_frame_func (this_frame), this_frame, info); | 
 |  | 
 |   return info; | 
 | } | 
 |  | 
 | /* Given a GDB frame, determine the address of the calling function's | 
 |    frame.  This will be used to create a new GDB frame struct.  */ | 
 |  | 
 | static void | 
 | cris_frame_this_id (frame_info_ptr this_frame, | 
 | 		    void **this_prologue_cache, | 
 | 		    struct frame_id *this_id) | 
 | { | 
 |   struct cris_unwind_cache *info | 
 |     = cris_frame_unwind_cache (this_frame, this_prologue_cache); | 
 |   CORE_ADDR base; | 
 |   CORE_ADDR func; | 
 |   struct frame_id id; | 
 |  | 
 |   /* The FUNC is easy.  */ | 
 |   func = get_frame_func (this_frame); | 
 |  | 
 |   /* Hopefully the prologue analysis either correctly determined the | 
 |      frame's base (which is the SP from the previous frame), or set | 
 |      that base to "NULL".  */ | 
 |   base = info->prev_sp; | 
 |   if (base == 0) | 
 |     return; | 
 |  | 
 |   id = frame_id_build (base, func); | 
 |  | 
 |   (*this_id) = id; | 
 | } | 
 |  | 
 | static struct value * | 
 | cris_frame_prev_register (frame_info_ptr this_frame, | 
 | 			  void **this_prologue_cache, int regnum) | 
 | { | 
 |   struct cris_unwind_cache *info | 
 |     = cris_frame_unwind_cache (this_frame, this_prologue_cache); | 
 |   return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); | 
 | } | 
 |  | 
 | static CORE_ADDR | 
 | cris_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp) | 
 | { | 
 |   /* Align to the size of an instruction (so that they can safely be | 
 |      pushed onto the stack).  */ | 
 |   return sp & ~3; | 
 | } | 
 |  | 
 | static CORE_ADDR | 
 | cris_push_dummy_code (struct gdbarch *gdbarch, | 
 | 		      CORE_ADDR sp, CORE_ADDR funaddr, | 
 | 		      struct value **args, int nargs, | 
 | 		      struct type *value_type, | 
 | 		      CORE_ADDR *real_pc, CORE_ADDR *bp_addr, | 
 | 		      struct regcache *regcache) | 
 | { | 
 |   /* Allocate space sufficient for a breakpoint.  */ | 
 |   sp = (sp - 4) & ~3; | 
 |   /* Store the address of that breakpoint */ | 
 |   *bp_addr = sp; | 
 |   /* CRIS always starts the call at the callee's entry point.  */ | 
 |   *real_pc = funaddr; | 
 |   return sp; | 
 | } | 
 |  | 
 | static CORE_ADDR | 
 | cris_push_dummy_call (struct gdbarch *gdbarch, struct value *function, | 
 | 		      struct regcache *regcache, CORE_ADDR bp_addr, | 
 | 		      int nargs, struct value **args, CORE_ADDR sp, | 
 | 		      function_call_return_method return_method, | 
 | 		      CORE_ADDR struct_addr) | 
 | { | 
 |   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | 
 |   int argreg; | 
 |   int argnum; | 
 |  | 
 |   struct cris_stack_item *si = NULL; | 
 |  | 
 |   /* Push the return address.  */ | 
 |   regcache_cooked_write_unsigned (regcache, SRP_REGNUM, bp_addr); | 
 |  | 
 |   /* Are we returning a value using a structure return or a normal value | 
 |      return?  struct_addr is the address of the reserved space for the return | 
 |      structure to be written on the stack.  */ | 
 |   if (return_method == return_method_struct) | 
 |     regcache_cooked_write_unsigned (regcache, STR_REGNUM, struct_addr); | 
 |  | 
 |   /* Now load as many as possible of the first arguments into registers, | 
 |      and push the rest onto the stack.  */ | 
 |   argreg = ARG1_REGNUM; | 
 |  | 
 |   for (argnum = 0; argnum < nargs; argnum++) | 
 |     { | 
 |       int len; | 
 |       const gdb_byte *val; | 
 |       int reg_demand; | 
 |       int i; | 
 |        | 
 |       len = args[argnum]->type ()->length (); | 
 |       val = args[argnum]->contents ().data (); | 
 |        | 
 |       /* How may registers worth of storage do we need for this argument?  */ | 
 |       reg_demand = (len / 4) + (len % 4 != 0 ? 1 : 0); | 
 | 	 | 
 |       if (len <= (2 * 4) && (argreg + reg_demand - 1 <= ARG4_REGNUM)) | 
 | 	{ | 
 | 	  /* Data passed by value.  Fits in available register(s).  */ | 
 | 	  for (i = 0; i < reg_demand; i++) | 
 | 	    { | 
 | 	      regcache->cooked_write (argreg, val); | 
 | 	      argreg++; | 
 | 	      val += 4; | 
 | 	    } | 
 | 	} | 
 |       else if (len <= (2 * 4) && argreg <= ARG4_REGNUM) | 
 | 	{ | 
 | 	  /* Data passed by value. Does not fit in available register(s). | 
 | 	     Use the register(s) first, then the stack.  */ | 
 | 	  for (i = 0; i < reg_demand; i++) | 
 | 	    { | 
 | 	      if (argreg <= ARG4_REGNUM) | 
 | 		{ | 
 | 		  regcache->cooked_write (argreg, val); | 
 | 		  argreg++; | 
 | 		  val += 4; | 
 | 		} | 
 | 	      else | 
 | 		{ | 
 | 		  /* Push item for later so that pushed arguments | 
 | 		     come in the right order.  */ | 
 | 		  si = push_stack_item (si, val, 4); | 
 | 		  val += 4; | 
 | 		} | 
 | 	    } | 
 | 	} | 
 |       else if (len > (2 * 4)) | 
 | 	{ | 
 | 	  /* Data passed by reference.  Push copy of data onto stack | 
 | 	     and pass pointer to this copy as argument.  */ | 
 | 	  sp = (sp - len) & ~3; | 
 | 	  write_memory (sp, val, len); | 
 |  | 
 | 	  if (argreg <= ARG4_REGNUM) | 
 | 	    { | 
 | 	      regcache_cooked_write_unsigned (regcache, argreg, sp); | 
 | 	      argreg++; | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      gdb_byte buf[4]; | 
 | 	      store_unsigned_integer (buf, 4, byte_order, sp); | 
 | 	      si = push_stack_item (si, buf, 4); | 
 | 	    } | 
 | 	} | 
 |       else | 
 | 	{ | 
 | 	  /* Data passed by value.  No available registers.  Put it on | 
 | 	     the stack.  */ | 
 | 	   si = push_stack_item (si, val, len); | 
 | 	} | 
 |     } | 
 |  | 
 |   while (si) | 
 |     { | 
 |       /* fp_arg must be word-aligned (i.e., don't += len) to match | 
 | 	 the function prologue.  */ | 
 |       sp = (sp - si->len) & ~3; | 
 |       write_memory (sp, si->data, si->len); | 
 |       si = pop_stack_item (si); | 
 |     } | 
 |  | 
 |   /* Finally, update the SP register.  */ | 
 |   regcache_cooked_write_unsigned (regcache, gdbarch_sp_regnum (gdbarch), sp); | 
 |  | 
 |   return sp; | 
 | } | 
 |  | 
 | static const struct frame_unwind cris_frame_unwind =  | 
 | { | 
 |   "cris prologue", | 
 |   NORMAL_FRAME, | 
 |   default_frame_unwind_stop_reason, | 
 |   cris_frame_this_id, | 
 |   cris_frame_prev_register, | 
 |   NULL, | 
 |   default_frame_sniffer | 
 | }; | 
 |  | 
 | static CORE_ADDR | 
 | cris_frame_base_address (frame_info_ptr this_frame, void **this_cache) | 
 | { | 
 |   struct cris_unwind_cache *info | 
 |     = cris_frame_unwind_cache (this_frame, this_cache); | 
 |   return info->base; | 
 | } | 
 |  | 
 | static const struct frame_base cris_frame_base =  | 
 | { | 
 |   &cris_frame_unwind, | 
 |   cris_frame_base_address, | 
 |   cris_frame_base_address, | 
 |   cris_frame_base_address | 
 | }; | 
 |  | 
 | /* Frames information. The definition of the struct frame_info is | 
 |  | 
 |    CORE_ADDR frame | 
 |    CORE_ADDR pc | 
 |    enum frame_type type; | 
 |    CORE_ADDR return_pc | 
 |    int leaf_function | 
 |  | 
 |    If the compilation option -fno-omit-frame-pointer is present the | 
 |    variable frame will be set to the content of R8 which is the frame | 
 |    pointer register. | 
 |  | 
 |    The variable pc contains the address where execution is performed | 
 |    in the present frame.  The innermost frame contains the current content | 
 |    of the register PC.  All other frames contain the content of the | 
 |    register PC in the next frame. | 
 |  | 
 |    The variable `type' indicates the frame's type: normal, SIGTRAMP | 
 |    (associated with a signal handler), dummy (associated with a dummy | 
 |    frame). | 
 |  | 
 |    The variable return_pc contains the address where execution should be | 
 |    resumed when the present frame has finished, the return address. | 
 |  | 
 |    The variable leaf_function is 1 if the return address is in the register | 
 |    SRP, and 0 if it is on the stack. | 
 |  | 
 |    Prologue instructions C-code. | 
 |    The prologue may consist of (-fno-omit-frame-pointer) | 
 |    1)                2) | 
 |    push   srp | 
 |    push   r8         push   r8 | 
 |    move.d sp,r8      move.d sp,r8 | 
 |    subq   X,sp       subq   X,sp | 
 |    movem  rY,[sp]    movem  rY,[sp] | 
 |    move.S rZ,[r8-U]  move.S rZ,[r8-U] | 
 |  | 
 |    where 1 is a non-terminal function, and 2 is a leaf-function. | 
 |  | 
 |    Note that this assumption is extremely brittle, and will break at the | 
 |    slightest change in GCC's prologue. | 
 |  | 
 |    If local variables are declared or register contents are saved on stack | 
 |    the subq-instruction will be present with X as the number of bytes | 
 |    needed for storage.  The reshuffle with respect to r8 may be performed | 
 |    with any size S (b, w, d) and any of the general registers Z={0..13}.  | 
 |    The offset U should be representable by a signed 8-bit value in all cases. | 
 |    Thus, the prefix word is assumed to be immediate byte offset mode followed | 
 |    by another word containing the instruction. | 
 |  | 
 |    Degenerate cases: | 
 |    3) | 
 |    push   r8 | 
 |    move.d sp,r8 | 
 |    move.d r8,sp | 
 |    pop    r8    | 
 |  | 
 |    Prologue instructions C++-code. | 
 |    Case 1) and 2) in the C-code may be followed by | 
 |  | 
 |    move.d r10,rS    ; this | 
 |    move.d r11,rT    ; P1 | 
 |    move.d r12,rU    ; P2 | 
 |    move.d r13,rV    ; P3 | 
 |    move.S [r8+U],rZ ; P4 | 
 |  | 
 |    if any of the call parameters are stored.  The host expects these  | 
 |    instructions to be executed in order to get the call parameters right.  */ | 
 |  | 
 | /* Examine the prologue of a function.  The variable ip is the address of  | 
 |    the first instruction of the prologue.  The variable limit is the address  | 
 |    of the first instruction after the prologue.  The variable fi contains the  | 
 |    information in struct frame_info.  The variable frameless_p controls whether | 
 |    the entire prologue is examined (0) or just enough instructions to  | 
 |    determine that it is a prologue (1).  */ | 
 |  | 
 | static CORE_ADDR  | 
 | cris_scan_prologue (CORE_ADDR pc, frame_info_ptr this_frame, | 
 | 		    struct cris_unwind_cache *info) | 
 | { | 
 |   struct gdbarch *gdbarch = get_frame_arch (this_frame); | 
 |   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | 
 |  | 
 |   /* Present instruction.  */ | 
 |   unsigned short insn; | 
 |  | 
 |   /* Next instruction, lookahead.  */ | 
 |   unsigned short insn_next;  | 
 |   int regno; | 
 |  | 
 |   /* Number of byte on stack used for local variables and movem.  */ | 
 |   int val;  | 
 |  | 
 |   /* Highest register number in a movem.  */ | 
 |   int regsave; | 
 |  | 
 |   /* move.d r<source_register>,rS */ | 
 |   short source_register;  | 
 |  | 
 |   /* Scan limit.  */ | 
 |   int limit; | 
 |  | 
 |   /* This frame is with respect to a leaf until a push srp is found.  */ | 
 |   if (info) | 
 |     { | 
 |       info->leaf_function = 1; | 
 |     } | 
 |  | 
 |   /* Assume nothing on stack.  */ | 
 |   val = 0; | 
 |   regsave = -1; | 
 |  | 
 |   /* If we were called without a this_frame, that means we were called | 
 |      from cris_skip_prologue which already tried to find the end of the | 
 |      prologue through the symbol information.  64 instructions past current | 
 |      pc is arbitrarily chosen, but at least it means we'll stop eventually.  */ | 
 |   limit = this_frame ? get_frame_pc (this_frame) : pc + 64; | 
 |  | 
 |   /* Find the prologue instructions.  */ | 
 |   while (pc > 0 && pc < limit) | 
 |     { | 
 |       insn = read_memory_unsigned_integer (pc, 2, byte_order); | 
 |       pc += 2; | 
 |       if (insn == 0xE1FC) | 
 | 	{ | 
 | 	  /* push <reg> 32 bit instruction.  */ | 
 | 	  insn_next = read_memory_unsigned_integer (pc, 2, byte_order); | 
 | 	  pc += 2; | 
 | 	  regno = cris_get_operand2 (insn_next); | 
 | 	  if (info) | 
 | 	    { | 
 | 	      info->sp_offset += 4; | 
 | 	    } | 
 | 	  /* This check, meant to recognize srp, used to be regno ==  | 
 | 	     (SRP_REGNUM - NUM_GENREGS), but that covers r11 also.  */ | 
 | 	  if (insn_next == 0xBE7E) | 
 | 	    { | 
 | 	      if (info) | 
 | 		{ | 
 | 		  info->leaf_function = 0; | 
 | 		} | 
 | 	    } | 
 | 	  else if (insn_next == 0x8FEE) | 
 | 	    { | 
 | 	      /* push $r8 */ | 
 | 	      if (info) | 
 | 		{ | 
 | 		  info->r8_offset = info->sp_offset; | 
 | 		} | 
 | 	    } | 
 | 	} | 
 |       else if (insn == 0x866E) | 
 | 	{ | 
 | 	  /* move.d sp,r8 */ | 
 | 	  if (info) | 
 | 	    { | 
 | 	      info->uses_frame = 1; | 
 | 	    } | 
 | 	  continue; | 
 | 	} | 
 |       else if (cris_get_operand2 (insn) == gdbarch_sp_regnum (gdbarch) | 
 | 	       && cris_get_mode (insn) == 0x0000 | 
 | 	       && cris_get_opcode (insn) == 0x000A) | 
 | 	{ | 
 | 	  /* subq <val>,sp */ | 
 | 	  if (info) | 
 | 	    { | 
 | 	      info->sp_offset += cris_get_quick_value (insn); | 
 | 	    } | 
 | 	} | 
 |       else if (cris_get_mode (insn) == 0x0002  | 
 | 	       && cris_get_opcode (insn) == 0x000F | 
 | 	       && cris_get_size (insn) == 0x0003 | 
 | 	       && cris_get_operand1 (insn) == gdbarch_sp_regnum (gdbarch)) | 
 | 	{ | 
 | 	  /* movem r<regsave>,[sp] */ | 
 | 	  regsave = cris_get_operand2 (insn); | 
 | 	} | 
 |       else if (cris_get_operand2 (insn) == gdbarch_sp_regnum (gdbarch) | 
 | 	       && ((insn & 0x0F00) >> 8) == 0x0001 | 
 | 	       && (cris_get_signed_offset (insn) < 0)) | 
 | 	{ | 
 | 	  /* Immediate byte offset addressing prefix word with sp as base  | 
 | 	     register.  Used for CRIS v8 i.e. ETRAX 100 and newer if <val>  | 
 | 	     is between 64 and 128.  | 
 | 	     movem r<regsave>,[sp=sp-<val>] */ | 
 | 	  if (info) | 
 | 	    { | 
 | 	      info->sp_offset += -cris_get_signed_offset (insn); | 
 | 	    } | 
 | 	  insn_next = read_memory_unsigned_integer (pc, 2, byte_order); | 
 | 	  pc += 2; | 
 | 	  if (cris_get_mode (insn_next) == PREFIX_ASSIGN_MODE | 
 | 	      && cris_get_opcode (insn_next) == 0x000F | 
 | 	      && cris_get_size (insn_next) == 0x0003 | 
 | 	      && cris_get_operand1 (insn_next) == gdbarch_sp_regnum | 
 | 						  (gdbarch)) | 
 | 	    { | 
 | 	      regsave = cris_get_operand2 (insn_next); | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      /* The prologue ended before the limit was reached.  */ | 
 | 	      pc -= 4; | 
 | 	      break; | 
 | 	    } | 
 | 	} | 
 |       else if (cris_get_mode (insn) == 0x0001 | 
 | 	       && cris_get_opcode (insn) == 0x0009 | 
 | 	       && cris_get_size (insn) == 0x0002) | 
 | 	{ | 
 | 	  /* move.d r<10..13>,r<0..15> */ | 
 | 	  source_register = cris_get_operand1 (insn); | 
 |  | 
 | 	  /* FIXME?  In the glibc solibs, the prologue might contain something | 
 | 	     like (this example taken from relocate_doit): | 
 | 	     move.d $pc,$r0 | 
 | 	     sub.d 0xfffef426,$r0 | 
 | 	     which isn't covered by the source_register check below.  Question | 
 | 	     is whether to add a check for this combo, or make better use of | 
 | 	     the limit variable instead.  */ | 
 | 	  if (source_register < ARG1_REGNUM || source_register > ARG4_REGNUM) | 
 | 	    { | 
 | 	      /* The prologue ended before the limit was reached.  */ | 
 | 	      pc -= 2; | 
 | 	      break; | 
 | 	    } | 
 | 	} | 
 |       else if (cris_get_operand2 (insn) == CRIS_FP_REGNUM  | 
 | 	       /* The size is a fixed-size.  */ | 
 | 	       && ((insn & 0x0F00) >> 8) == 0x0001  | 
 | 	       /* A negative offset.  */ | 
 | 	       && (cris_get_signed_offset (insn) < 0))   | 
 | 	{ | 
 | 	  /* move.S rZ,[r8-U] (?) */ | 
 | 	  insn_next = read_memory_unsigned_integer (pc, 2, byte_order); | 
 | 	  pc += 2; | 
 | 	  regno = cris_get_operand2 (insn_next); | 
 | 	  if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch)) | 
 | 	      && cris_get_mode (insn_next) == PREFIX_OFFSET_MODE | 
 | 	      && cris_get_opcode (insn_next) == 0x000F) | 
 | 	    { | 
 | 	      /* move.S rZ,[r8-U] */ | 
 | 	      continue; | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      /* The prologue ended before the limit was reached.  */ | 
 | 	      pc -= 4; | 
 | 	      break; | 
 | 	    } | 
 | 	} | 
 |       else if (cris_get_operand2 (insn) == CRIS_FP_REGNUM  | 
 | 	       /* The size is a fixed-size.  */ | 
 | 	       && ((insn & 0x0F00) >> 8) == 0x0001  | 
 | 	       /* A positive offset.  */ | 
 | 	       && (cris_get_signed_offset (insn) > 0))   | 
 | 	{ | 
 | 	  /* move.S [r8+U],rZ (?) */ | 
 | 	  insn_next = read_memory_unsigned_integer (pc, 2, byte_order); | 
 | 	  pc += 2; | 
 | 	  regno = cris_get_operand2 (insn_next); | 
 | 	  if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch)) | 
 | 	      && cris_get_mode (insn_next) == PREFIX_OFFSET_MODE | 
 | 	      && cris_get_opcode (insn_next) == 0x0009 | 
 | 	      && cris_get_operand1 (insn_next) == regno) | 
 | 	    { | 
 | 	      /* move.S [r8+U],rZ */ | 
 | 	      continue; | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      /* The prologue ended before the limit was reached.  */ | 
 | 	      pc -= 4; | 
 | 	      break; | 
 | 	    } | 
 | 	} | 
 |       else | 
 | 	{ | 
 | 	  /* The prologue ended before the limit was reached.  */ | 
 | 	  pc -= 2; | 
 | 	  break; | 
 | 	} | 
 |     } | 
 |  | 
 |   /* We only want to know the end of the prologue when this_frame and info | 
 |      are NULL (called from cris_skip_prologue i.e.).  */ | 
 |   if (this_frame == NULL && info == NULL) | 
 |     { | 
 |       return pc; | 
 |     } | 
 |  | 
 |   info->size = info->sp_offset; | 
 |  | 
 |   /* Compute the previous frame's stack pointer (which is also the | 
 |      frame's ID's stack address), and this frame's base pointer.  */ | 
 |   if (info->uses_frame) | 
 |     { | 
 |       ULONGEST this_base; | 
 |       /* The SP was moved to the FP.  This indicates that a new frame | 
 | 	 was created.  Get THIS frame's FP value by unwinding it from | 
 | 	 the next frame.  */ | 
 |       this_base = get_frame_register_unsigned (this_frame, CRIS_FP_REGNUM); | 
 |       info->base = this_base; | 
 |       info->saved_regs[CRIS_FP_REGNUM].set_addr (info->base); | 
 |    | 
 |       /* The FP points at the last saved register.  Adjust the FP back | 
 | 	 to before the first saved register giving the SP.  */ | 
 |       info->prev_sp = info->base + info->r8_offset; | 
 |     } | 
 |   else | 
 |     { | 
 |       ULONGEST this_base;       | 
 |       /* Assume that the FP is this frame's SP but with that pushed | 
 | 	 stack space added back.  */ | 
 |       this_base = get_frame_register_unsigned (this_frame, | 
 | 					       gdbarch_sp_regnum (gdbarch)); | 
 |       info->base = this_base; | 
 |       info->prev_sp = info->base + info->size; | 
 |     } | 
 |        | 
 |   /* Calculate the addresses for the saved registers on the stack.  */ | 
 |   /* FIXME: The address calculation should really be done on the fly while | 
 |      we're analyzing the prologue (we only hold one regsave value as it is  | 
 |      now).  */ | 
 |   val = info->sp_offset; | 
 |  | 
 |   for (regno = regsave; regno >= 0; regno--) | 
 |     { | 
 |       info->saved_regs[regno].set_addr (info->base + info->r8_offset - val); | 
 |       val -= 4; | 
 |     } | 
 |  | 
 |   /* The previous frame's SP needed to be computed.  Save the computed | 
 |      value.  */ | 
 |   info->saved_regs[gdbarch_sp_regnum (gdbarch)].set_value (info->prev_sp); | 
 |  | 
 |   if (!info->leaf_function) | 
 |     { | 
 |       /* SRP saved on the stack.  But where?  */ | 
 |       if (info->r8_offset == 0) | 
 | 	{ | 
 | 	  /* R8 not pushed yet.  */ | 
 | 	  info->saved_regs[SRP_REGNUM].set_addr (info->base); | 
 | 	} | 
 |       else | 
 | 	{ | 
 | 	  /* R8 pushed, but SP may or may not be moved to R8 yet.  */ | 
 | 	  info->saved_regs[SRP_REGNUM].set_addr (info->base + 4); | 
 | 	} | 
 |     } | 
 |  | 
 |   /* The PC is found in SRP (the actual register or located on the stack).  */ | 
 |   info->saved_regs[gdbarch_pc_regnum (gdbarch)] | 
 |     = info->saved_regs[SRP_REGNUM]; | 
 |  | 
 |   return pc; | 
 | } | 
 |  | 
 | static CORE_ADDR  | 
 | crisv32_scan_prologue (CORE_ADDR pc, frame_info_ptr this_frame, | 
 | 		    struct cris_unwind_cache *info) | 
 | { | 
 |   struct gdbarch *gdbarch = get_frame_arch (this_frame); | 
 |   ULONGEST this_base; | 
 |  | 
 |   /* Unlike the CRISv10 prologue scanner (cris_scan_prologue), this is not | 
 |      meant to be a full-fledged prologue scanner.  It is only needed for  | 
 |      the cases where we end up in code always lacking DWARF-2 CFI, notably: | 
 |  | 
 |        * PLT stubs (library calls) | 
 |        * call dummys | 
 |        * signal trampolines | 
 |  | 
 |      For those cases, it is assumed that there is no actual prologue; that  | 
 |      the stack pointer is not adjusted, and (as a consequence) the return | 
 |      address is not pushed onto the stack.  */ | 
 |  | 
 |   /* We only want to know the end of the prologue when this_frame and info | 
 |      are NULL (called from cris_skip_prologue i.e.).  */ | 
 |   if (this_frame == NULL && info == NULL) | 
 |     { | 
 |       return pc; | 
 |     } | 
 |  | 
 |   /* The SP is assumed to be unaltered.  */ | 
 |   this_base = get_frame_register_unsigned (this_frame, | 
 | 					   gdbarch_sp_regnum (gdbarch)); | 
 |   info->base = this_base; | 
 |   info->prev_sp = this_base; | 
 |        | 
 |   /* The PC is assumed to be found in SRP.  */ | 
 |   info->saved_regs[gdbarch_pc_regnum (gdbarch)] | 
 |     = info->saved_regs[SRP_REGNUM]; | 
 |  | 
 |   return pc; | 
 | } | 
 |  | 
 | /* Advance pc beyond any function entry prologue instructions at pc | 
 |    to reach some "real" code.  */ | 
 |  | 
 | /* Given a PC value corresponding to the start of a function, return the PC | 
 |    of the first instruction after the function prologue.  */ | 
 |  | 
 | static CORE_ADDR | 
 | cris_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) | 
 | { | 
 |   cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch); | 
 |   CORE_ADDR func_addr, func_end; | 
 |   struct symtab_and_line sal; | 
 |   CORE_ADDR pc_after_prologue; | 
 |    | 
 |   /* If we have line debugging information, then the end of the prologue | 
 |      should the first assembly instruction of the first source line.  */ | 
 |   if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) | 
 |     { | 
 |       sal = find_pc_line (func_addr, 0); | 
 |       if (sal.end > 0 && sal.end < func_end) | 
 | 	return sal.end; | 
 |     } | 
 |  | 
 |   if (tdep->cris_version == 32) | 
 |     pc_after_prologue = crisv32_scan_prologue (pc, NULL, NULL); | 
 |   else | 
 |     pc_after_prologue = cris_scan_prologue (pc, NULL, NULL); | 
 |  | 
 |   return pc_after_prologue; | 
 | } | 
 |  | 
 | /* Implement the breakpoint_kind_from_pc gdbarch method.  */ | 
 |  | 
 | static int | 
 | cris_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr) | 
 | { | 
 |   return 2; | 
 | } | 
 |  | 
 | /* Implement the sw_breakpoint_from_kind gdbarch method.  */ | 
 |  | 
 | static const gdb_byte * | 
 | cris_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size) | 
 | { | 
 |   cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch); | 
 |   static unsigned char break8_insn[] = {0x38, 0xe9}; | 
 |   static unsigned char break15_insn[] = {0x3f, 0xe9}; | 
 |  | 
 |   *size = kind; | 
 |  | 
 |   if (tdep->cris_mode == cris_mode_guru) | 
 |     return break15_insn; | 
 |   else | 
 |     return break8_insn; | 
 | } | 
 |  | 
 | /* Returns 1 if spec_reg is applicable to the current gdbarch's CRIS version, | 
 |    0 otherwise.  */ | 
 |  | 
 | static int | 
 | cris_spec_reg_applicable (struct gdbarch *gdbarch, | 
 | 			  struct cris_spec_reg spec_reg) | 
 | { | 
 |   cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch); | 
 |   unsigned int version = tdep->cris_version; | 
 |    | 
 |   switch (spec_reg.applicable_version) | 
 |     { | 
 |     case cris_ver_version_all: | 
 |       return 1; | 
 |     case cris_ver_warning: | 
 |       /* Indeterminate/obsolete.  */ | 
 |       return 0; | 
 |     case cris_ver_v0_3: | 
 |       return in_inclusive_range (version, 0U, 3U); | 
 |     case cris_ver_v3p: | 
 |       return (version >= 3); | 
 |     case cris_ver_v8: | 
 |       return in_inclusive_range (version, 8U, 9U); | 
 |     case cris_ver_v8p: | 
 |       return (version >= 8); | 
 |     case cris_ver_v0_10: | 
 |       return in_inclusive_range (version, 0U, 10U); | 
 |     case cris_ver_v3_10: | 
 |       return in_inclusive_range (version, 3U, 10U); | 
 |     case cris_ver_v8_10: | 
 |       return in_inclusive_range (version, 8U, 10U); | 
 |     case cris_ver_v10: | 
 |       return (version == 10); | 
 |     case cris_ver_v10p: | 
 |       return (version >= 10); | 
 |     case cris_ver_v32p: | 
 |       return (version >= 32); | 
 |     default: | 
 |       /* Invalid cris version.  */ | 
 |       return 0; | 
 |     } | 
 | } | 
 |  | 
 | /* Returns the register size in unit byte.  Returns 0 for an unimplemented | 
 |    register, -1 for an invalid register.  */ | 
 |  | 
 | static int | 
 | cris_register_size (struct gdbarch *gdbarch, int regno) | 
 | { | 
 |   int i; | 
 |   int spec_regno; | 
 |    | 
 |   if (regno >= 0 && regno < NUM_GENREGS) | 
 |     { | 
 |       /* General registers (R0 - R15) are 32 bits.  */ | 
 |       return 4; | 
 |     } | 
 |   else if (regno >= NUM_GENREGS && regno < (NUM_GENREGS + NUM_SPECREGS)) | 
 |     { | 
 |       /* Special register (R16 - R31).  cris_spec_regs is zero-based.  | 
 | 	 Adjust regno accordingly.  */ | 
 |       spec_regno = regno - NUM_GENREGS; | 
 |        | 
 |       for (i = 0; cris_spec_regs[i].name != NULL; i++) | 
 | 	{ | 
 | 	  if (cris_spec_regs[i].number == spec_regno  | 
 | 	      && cris_spec_reg_applicable (gdbarch, cris_spec_regs[i])) | 
 | 	    /* Go with the first applicable register.  */ | 
 | 	    return cris_spec_regs[i].reg_size; | 
 | 	} | 
 |       /* Special register not applicable to this CRIS version.  */ | 
 |       return 0; | 
 |     } | 
 |   else if (regno >= gdbarch_pc_regnum (gdbarch) | 
 | 	   && regno < gdbarch_num_regs (gdbarch)) | 
 |     { | 
 |       /* This will apply to CRISv32 only where there are additional registers | 
 | 	 after the special registers (pseudo PC and support registers).  */ | 
 |       return 4; | 
 |     } | 
 |  | 
 |    | 
 |   return -1; | 
 | } | 
 |  | 
 | /* Nonzero if regno should not be fetched from the target.  This is the case | 
 |    for unimplemented (size 0) and non-existant registers.  */ | 
 |  | 
 | static int | 
 | cris_cannot_fetch_register (struct gdbarch *gdbarch, int regno) | 
 | { | 
 |   return ((regno < 0 || regno >= gdbarch_num_regs (gdbarch)) | 
 | 	  || (cris_register_size (gdbarch, regno) == 0)); | 
 | } | 
 |  | 
 | /* Nonzero if regno should not be written to the target, for various  | 
 |    reasons.  */ | 
 |  | 
 | static int | 
 | cris_cannot_store_register (struct gdbarch *gdbarch, int regno) | 
 | { | 
 |   /* There are three kinds of registers we refuse to write to. | 
 |      1. Those that not implemented. | 
 |      2. Those that are read-only (depends on the processor mode). | 
 |      3. Those registers to which a write has no effect.  */ | 
 |  | 
 |   if (regno < 0 | 
 |       || regno >= gdbarch_num_regs (gdbarch) | 
 |       || cris_register_size (gdbarch, regno) == 0) | 
 |     /* Not implemented.  */ | 
 |     return 1; | 
 |  | 
 |   else if  (regno == VR_REGNUM) | 
 |     /* Read-only.  */ | 
 |     return 1; | 
 |  | 
 |   else if  (regno == P0_REGNUM || regno == P4_REGNUM || regno == P8_REGNUM) | 
 |     /* Writing has no effect.  */ | 
 |     return 1; | 
 |  | 
 |   /* IBR, BAR, BRP and IRP are read-only in user mode.  Let the debug | 
 |      agent decide whether they are writable.  */ | 
 |    | 
 |   return 0; | 
 | } | 
 |  | 
 | /* Nonzero if regno should not be fetched from the target.  This is the case | 
 |    for unimplemented (size 0) and non-existant registers.  */ | 
 |  | 
 | static int | 
 | crisv32_cannot_fetch_register (struct gdbarch *gdbarch, int regno) | 
 | { | 
 |   return ((regno < 0 || regno >= gdbarch_num_regs (gdbarch)) | 
 | 	  || (cris_register_size (gdbarch, regno) == 0)); | 
 | } | 
 |  | 
 | /* Nonzero if regno should not be written to the target, for various  | 
 |    reasons.  */ | 
 |  | 
 | static int | 
 | crisv32_cannot_store_register (struct gdbarch *gdbarch, int regno) | 
 | { | 
 |   /* There are three kinds of registers we refuse to write to. | 
 |      1. Those that not implemented. | 
 |      2. Those that are read-only (depends on the processor mode). | 
 |      3. Those registers to which a write has no effect.  */ | 
 |  | 
 |   if (regno < 0 | 
 |       || regno >= gdbarch_num_regs (gdbarch) | 
 |       || cris_register_size (gdbarch, regno) == 0) | 
 |     /* Not implemented.  */ | 
 |     return 1; | 
 |  | 
 |   else if  (regno == VR_REGNUM) | 
 |     /* Read-only.  */ | 
 |     return 1; | 
 |  | 
 |   else if  (regno == BZ_REGNUM || regno == WZ_REGNUM || regno == DZ_REGNUM) | 
 |     /* Writing has no effect.  */ | 
 |     return 1; | 
 |  | 
 |   /* Many special registers are read-only in user mode.  Let the debug | 
 |      agent decide whether they are writable.  */ | 
 |    | 
 |   return 0; | 
 | } | 
 |  | 
 | /* Return the GDB type (defined in gdbtypes.c) for the "standard" data type | 
 |    of data in register regno.  */ | 
 |  | 
 | static struct type * | 
 | cris_register_type (struct gdbarch *gdbarch, int regno) | 
 | { | 
 |   if (regno == gdbarch_pc_regnum (gdbarch)) | 
 |     return builtin_type (gdbarch)->builtin_func_ptr; | 
 |   else if (regno == gdbarch_sp_regnum (gdbarch) | 
 | 	   || regno == CRIS_FP_REGNUM) | 
 |     return builtin_type (gdbarch)->builtin_data_ptr; | 
 |   else if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch)) | 
 | 	   || (regno >= MOF_REGNUM && regno <= USP_REGNUM)) | 
 |     /* Note: R8 taken care of previous clause.  */ | 
 |     return builtin_type (gdbarch)->builtin_uint32; | 
 |   else if (regno >= P4_REGNUM && regno <= CCR_REGNUM) | 
 |       return builtin_type (gdbarch)->builtin_uint16; | 
 |   else if (regno >= P0_REGNUM && regno <= VR_REGNUM) | 
 |       return builtin_type (gdbarch)->builtin_uint8; | 
 |   else | 
 |       /* Invalid (unimplemented) register.  */ | 
 |       return builtin_type (gdbarch)->builtin_int0; | 
 | } | 
 |  | 
 | static struct type * | 
 | crisv32_register_type (struct gdbarch *gdbarch, int regno) | 
 | { | 
 |   if (regno == gdbarch_pc_regnum (gdbarch)) | 
 |     return builtin_type (gdbarch)->builtin_func_ptr; | 
 |   else if (regno == gdbarch_sp_regnum (gdbarch) | 
 | 	   || regno == CRIS_FP_REGNUM) | 
 |     return builtin_type (gdbarch)->builtin_data_ptr; | 
 |   else if ((regno >= 0 && regno <= ACR_REGNUM) | 
 | 	   || (regno >= EXS_REGNUM && regno <= SPC_REGNUM) | 
 | 	   || (regno == PID_REGNUM) | 
 | 	   || (regno >= S0_REGNUM && regno <= S15_REGNUM)) | 
 |     /* Note: R8 and SP taken care of by previous clause.  */ | 
 |     return builtin_type (gdbarch)->builtin_uint32; | 
 |   else if (regno == WZ_REGNUM) | 
 |       return builtin_type (gdbarch)->builtin_uint16; | 
 |   else if (regno == BZ_REGNUM || regno == VR_REGNUM || regno == SRS_REGNUM) | 
 |       return builtin_type (gdbarch)->builtin_uint8; | 
 |   else | 
 |     { | 
 |       /* Invalid (unimplemented) register.  Should not happen as there are | 
 | 	 no unimplemented CRISv32 registers.  */ | 
 |       warning (_("crisv32_register_type: unknown regno %d"), regno); | 
 |       return builtin_type (gdbarch)->builtin_int0; | 
 |     } | 
 | } | 
 |  | 
 | /* Stores a function return value of type type, where valbuf is the address  | 
 |    of the value to be stored.  */ | 
 |  | 
 | /* In the CRIS ABI, R10 and R11 are used to store return values.  */ | 
 |  | 
 | static void | 
 | cris_store_return_value (struct type *type, struct regcache *regcache, | 
 | 			 const gdb_byte *valbuf) | 
 | { | 
 |   struct gdbarch *gdbarch = regcache->arch (); | 
 |   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | 
 |   ULONGEST val; | 
 |   int len = type->length (); | 
 |    | 
 |   if (len <= 4) | 
 |     { | 
 |       /* Put the return value in R10.  */ | 
 |       val = extract_unsigned_integer (valbuf, len, byte_order); | 
 |       regcache_cooked_write_unsigned (regcache, ARG1_REGNUM, val); | 
 |     } | 
 |   else if (len <= 8) | 
 |     { | 
 |       /* Put the return value in R10 and R11.  */ | 
 |       val = extract_unsigned_integer (valbuf, 4, byte_order); | 
 |       regcache_cooked_write_unsigned (regcache, ARG1_REGNUM, val); | 
 |       val = extract_unsigned_integer (valbuf + 4, len - 4, byte_order); | 
 |       regcache_cooked_write_unsigned (regcache, ARG2_REGNUM, val); | 
 |     } | 
 |   else | 
 |     error (_("cris_store_return_value: type length too large.")); | 
 | } | 
 |  | 
 | /* Return the name of register regno as a string.  Return NULL for an | 
 |    invalid or unimplemented register.  */ | 
 |  | 
 | static const char * | 
 | cris_special_register_name (struct gdbarch *gdbarch, int regno) | 
 | { | 
 |   int spec_regno; | 
 |   int i; | 
 |  | 
 |   /* Special register (R16 - R31).  cris_spec_regs is zero-based.  | 
 |      Adjust regno accordingly.  */ | 
 |   spec_regno = regno - NUM_GENREGS; | 
 |    | 
 |   /* Assume nothing about the layout of the cris_spec_regs struct | 
 |      when searching.  */ | 
 |   for (i = 0; cris_spec_regs[i].name != NULL; i++) | 
 |     { | 
 |       if (cris_spec_regs[i].number == spec_regno  | 
 | 	  && cris_spec_reg_applicable (gdbarch, cris_spec_regs[i])) | 
 | 	/* Go with the first applicable register.  */ | 
 | 	return cris_spec_regs[i].name; | 
 |     } | 
 |   /* Special register not applicable to this CRIS version.  */ | 
 |   return ""; | 
 | } | 
 |  | 
 | static const char * | 
 | cris_register_name (struct gdbarch *gdbarch, int regno) | 
 | { | 
 |   static const char *cris_genreg_names[] = | 
 |   { "r0",  "r1",  "r2",  "r3", \ | 
 |     "r4",  "r5",  "r6",  "r7", \ | 
 |     "r8",  "r9",  "r10", "r11", \ | 
 |     "r12", "r13", "sp",  "pc" }; | 
 |  | 
 |   if (regno < NUM_GENREGS) | 
 |     { | 
 |       /* General register.  */ | 
 |       gdb_static_assert (ARRAY_SIZE (cris_genreg_names) == NUM_GENREGS); | 
 |       return cris_genreg_names[regno]; | 
 |     } | 
 |   else if (regno >= NUM_GENREGS && regno < gdbarch_num_regs (gdbarch)) | 
 |     { | 
 |       return cris_special_register_name (gdbarch, regno); | 
 |     } | 
 |   else | 
 |     { | 
 |       /* Invalid register.  */ | 
 |       return ""; | 
 |     } | 
 | } | 
 |  | 
 | static const char * | 
 | crisv32_register_name (struct gdbarch *gdbarch, int regno) | 
 | { | 
 |   static const char *crisv32_genreg_names[] = | 
 |     { "r0",  "r1",  "r2",  "r3", \ | 
 |       "r4",  "r5",  "r6",  "r7", \ | 
 |       "r8",  "r9",  "r10", "r11", \ | 
 |       "r12", "r13", "sp",  "acr" | 
 |     }; | 
 |  | 
 |   static const char *crisv32_sreg_names[] = | 
 |     { "s0",  "s1",  "s2",  "s3", \ | 
 |       "s4",  "s5",  "s6",  "s7", \ | 
 |       "s8",  "s9",  "s10", "s11", \ | 
 |       "s12", "s13", "s14",  "s15" | 
 |     }; | 
 |  | 
 |   if (regno >= 0 && regno < NUM_GENREGS) | 
 |     { | 
 |       /* General register.  */ | 
 |       return crisv32_genreg_names[regno]; | 
 |     } | 
 |   else if (regno >= NUM_GENREGS && regno < (NUM_GENREGS + NUM_SPECREGS)) | 
 |     { | 
 |       return cris_special_register_name (gdbarch, regno); | 
 |     } | 
 |   else if (regno == gdbarch_pc_regnum (gdbarch)) | 
 |     { | 
 |       return "pc"; | 
 |     } | 
 |   else if (regno >= S0_REGNUM && regno <= S15_REGNUM) | 
 |     { | 
 |       return crisv32_sreg_names[regno - S0_REGNUM]; | 
 |     } | 
 |   else | 
 |     { | 
 |       /* Invalid register.  */ | 
 |       return NULL; | 
 |     } | 
 | } | 
 |  | 
 | /* Convert DWARF register number REG to the appropriate register | 
 |    number used by GDB.  */ | 
 |  | 
 | static int | 
 | cris_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg) | 
 | { | 
 |   /* We need to re-map a couple of registers (SRP is 16 in Dwarf-2 register | 
 |      numbering, MOF is 18). | 
 |      Adapted from gcc/config/cris/cris.h.  */ | 
 |   static int cris_dwarf_regmap[] = { | 
 |     0,  1,  2,  3, | 
 |     4,  5,  6,  7, | 
 |     8,  9,  10, 11, | 
 |     12, 13, 14, 15, | 
 |     27, -1, -1, -1, | 
 |     -1, -1, -1, 23, | 
 |     -1, -1, -1, 27, | 
 |     -1, -1, -1, -1 | 
 |   }; | 
 |   int regnum = -1; | 
 |  | 
 |   if (reg >= 0 && reg < ARRAY_SIZE (cris_dwarf_regmap)) | 
 |     regnum = cris_dwarf_regmap[reg]; | 
 |  | 
 |   return regnum; | 
 | } | 
 |  | 
 | /* DWARF-2 frame support.  */ | 
 |  | 
 | static void | 
 | cris_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, | 
 | 			    struct dwarf2_frame_state_reg *reg, | 
 | 			    frame_info_ptr this_frame) | 
 | { | 
 |   /* The return address column.  */ | 
 |   if (regnum == gdbarch_pc_regnum (gdbarch)) | 
 |     reg->how = DWARF2_FRAME_REG_RA; | 
 |  | 
 |   /* The call frame address.  */ | 
 |   else if (regnum == gdbarch_sp_regnum (gdbarch)) | 
 |     reg->how = DWARF2_FRAME_REG_CFA; | 
 | } | 
 |  | 
 | /* Extract from an array regbuf containing the raw register state a function | 
 |    return value of type type, and copy that, in virtual format, into  | 
 |    valbuf.  */ | 
 |  | 
 | /* In the CRIS ABI, R10 and R11 are used to store return values.  */ | 
 |  | 
 | static void | 
 | cris_extract_return_value (struct type *type, struct regcache *regcache, | 
 | 			   gdb_byte *valbuf) | 
 | { | 
 |   struct gdbarch *gdbarch = regcache->arch (); | 
 |   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | 
 |   ULONGEST val; | 
 |   int len = type->length (); | 
 |    | 
 |   if (len <= 4) | 
 |     { | 
 |       /* Get the return value from R10.  */ | 
 |       regcache_cooked_read_unsigned (regcache, ARG1_REGNUM, &val); | 
 |       store_unsigned_integer (valbuf, len, byte_order, val); | 
 |     } | 
 |   else if (len <= 8) | 
 |     { | 
 |       /* Get the return value from R10 and R11.  */ | 
 |       regcache_cooked_read_unsigned (regcache, ARG1_REGNUM, &val); | 
 |       store_unsigned_integer (valbuf, 4, byte_order, val); | 
 |       regcache_cooked_read_unsigned (regcache, ARG2_REGNUM, &val); | 
 |       store_unsigned_integer (valbuf + 4, len - 4, byte_order, val); | 
 |     } | 
 |   else | 
 |     error (_("cris_extract_return_value: type length too large")); | 
 | } | 
 |  | 
 | /* Handle the CRIS return value convention.  */ | 
 |  | 
 | static enum return_value_convention | 
 | cris_return_value (struct gdbarch *gdbarch, struct value *function, | 
 | 		   struct type *type, struct regcache *regcache, | 
 | 		   gdb_byte *readbuf, const gdb_byte *writebuf) | 
 | { | 
 |   if (type->code () == TYPE_CODE_STRUCT | 
 |       || type->code () == TYPE_CODE_UNION | 
 |       || type->length () > 8) | 
 |     /* Structs, unions, and anything larger than 8 bytes (2 registers) | 
 |        goes on the stack.  */ | 
 |     return RETURN_VALUE_STRUCT_CONVENTION; | 
 |  | 
 |   if (readbuf) | 
 |     cris_extract_return_value (type, regcache, readbuf); | 
 |   if (writebuf) | 
 |     cris_store_return_value (type, regcache, writebuf); | 
 |  | 
 |   return RETURN_VALUE_REGISTER_CONVENTION; | 
 | } | 
 |  | 
 | /* Calculates a value that measures how good inst_args constraints an  | 
 |    instruction.  It stems from cris_constraint, found in cris-dis.c.  */ | 
 |  | 
 | static int | 
 | constraint (unsigned int insn, const char *inst_args, | 
 | 	    inst_env_type *inst_env) | 
 | { | 
 |   int retval = 0; | 
 |   int tmp, i; | 
 |  | 
 |   const gdb_byte *s = (const gdb_byte *) inst_args; | 
 |  | 
 |   for (; *s; s++) | 
 |     switch (*s)  | 
 |       { | 
 |       case 'm': | 
 | 	if ((insn & 0x30) == 0x30) | 
 | 	  return -1; | 
 | 	break; | 
 | 	 | 
 |       case 'S': | 
 | 	/* A prefix operand.  */ | 
 | 	if (inst_env->prefix_found) | 
 | 	  break; | 
 | 	else | 
 | 	  return -1; | 
 |  | 
 |       case 'B': | 
 | 	/* A "push" prefix.  (This check was REMOVED by san 970921.)  Check for | 
 | 	   valid "push" size.  In case of special register, it may be != 4.  */ | 
 | 	if (inst_env->prefix_found) | 
 | 	  break; | 
 | 	else | 
 | 	  return -1; | 
 |  | 
 |       case 'D': | 
 | 	retval = (((insn >> 0xC) & 0xF) == (insn & 0xF)); | 
 | 	if (!retval) | 
 | 	  return -1; | 
 | 	else  | 
 | 	  retval += 4; | 
 | 	break; | 
 |  | 
 |       case 'P': | 
 | 	tmp = (insn >> 0xC) & 0xF; | 
 |  | 
 | 	for (i = 0; cris_spec_regs[i].name != NULL; i++) | 
 | 	  { | 
 | 	    /* Since we match four bits, we will give a value of | 
 | 	       4 - 1 = 3 in a match.  If there is a corresponding | 
 | 	       exact match of a special register in another pattern, it | 
 | 	       will get a value of 4, which will be higher.  This should | 
 | 	       be correct in that an exact pattern would match better that | 
 | 	       a general pattern. | 
 | 	       Note that there is a reason for not returning zero; the | 
 | 	       pattern for "clear" is partly  matched in the bit-pattern | 
 | 	       (the two lower bits must be zero), while the bit-pattern | 
 | 	       for a move from a special register is matched in the | 
 | 	       register constraint. | 
 | 	       This also means we will will have a race condition if | 
 | 	       there is a partly match in three bits in the bit pattern.  */ | 
 | 	    if (tmp == cris_spec_regs[i].number) | 
 | 	      { | 
 | 		retval += 3; | 
 | 		break; | 
 | 	      } | 
 | 	  } | 
 | 	 | 
 | 	if (cris_spec_regs[i].name == NULL) | 
 | 	  return -1; | 
 | 	break; | 
 |       } | 
 |   return retval; | 
 | } | 
 |  | 
 | /* Returns the number of bits set in the variable value.  */ | 
 |  | 
 | static int | 
 | number_of_bits (unsigned int value) | 
 | { | 
 |   int number_of_bits = 0; | 
 |    | 
 |   while (value != 0) | 
 |     { | 
 |       number_of_bits += 1; | 
 |       value &= (value - 1); | 
 |     } | 
 |   return number_of_bits; | 
 | } | 
 |  | 
 | /* Finds the address that should contain the single step breakpoint(s).  | 
 |    It stems from code in cris-dis.c.  */ | 
 |  | 
 | static int | 
 | find_cris_op (unsigned short insn, inst_env_type *inst_env) | 
 | { | 
 |   int i; | 
 |   int max_level_of_match = -1; | 
 |   int max_matched = -1; | 
 |   int level_of_match; | 
 |  | 
 |   for (i = 0; cris_opcodes[i].name != NULL; i++) | 
 |     { | 
 |       if (((cris_opcodes[i].match & insn) == cris_opcodes[i].match)  | 
 | 	  && ((cris_opcodes[i].lose & insn) == 0) | 
 | 	  /* Only CRISv10 instructions, please.  */ | 
 | 	  && (cris_opcodes[i].applicable_version != cris_ver_v32p)) | 
 | 	{ | 
 | 	  level_of_match = constraint (insn, cris_opcodes[i].args, inst_env); | 
 | 	  if (level_of_match >= 0) | 
 | 	    { | 
 | 	      level_of_match += | 
 | 		number_of_bits (cris_opcodes[i].match | cris_opcodes[i].lose); | 
 | 	      if (level_of_match > max_level_of_match) | 
 | 		{ | 
 | 		  max_matched = i; | 
 | 		  max_level_of_match = level_of_match; | 
 | 		  if (level_of_match == 16) | 
 | 		    { | 
 | 		      /* All bits matched, cannot find better.  */ | 
 | 		      break; | 
 | 		    } | 
 | 		} | 
 | 	    } | 
 | 	} | 
 |     } | 
 |   return max_matched; | 
 | } | 
 |  | 
 | /* Attempts to find single-step breakpoints.  Returns -1 on failure which is | 
 |    actually an internal error.  */ | 
 |  | 
 | static int | 
 | find_step_target (struct regcache *regcache, inst_env_type *inst_env) | 
 | { | 
 |   int i; | 
 |   int offset; | 
 |   unsigned short insn; | 
 |   struct gdbarch *gdbarch = regcache->arch (); | 
 |   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | 
 |  | 
 |   /* Create a local register image and set the initial state.  */ | 
 |   for (i = 0; i < NUM_GENREGS; i++) | 
 |     { | 
 |       inst_env->reg[i] =  | 
 | 	(unsigned long) regcache_raw_get_unsigned (regcache, i); | 
 |     } | 
 |   offset = NUM_GENREGS; | 
 |   for (i = 0; i < NUM_SPECREGS; i++) | 
 |     { | 
 |       inst_env->preg[i] =  | 
 | 	(unsigned long) regcache_raw_get_unsigned (regcache, offset + i); | 
 |     } | 
 |   inst_env->branch_found = 0; | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->delay_slot_pc_active = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->invalid = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 |   inst_env->byte_order = byte_order; | 
 |  | 
 |   /* Look for a step target.  */ | 
 |   do | 
 |     { | 
 |       /* Read an instruction from the client.  */ | 
 |       insn = read_memory_unsigned_integer | 
 | 	     (inst_env->reg[gdbarch_pc_regnum (gdbarch)], 2, byte_order); | 
 |  | 
 |       /* If the instruction is not in a delay slot the new content of the | 
 | 	 PC is [PC] + 2.  If the instruction is in a delay slot it is not | 
 | 	 that simple.  Since a instruction in a delay slot cannot change  | 
 | 	 the content of the PC, it does not matter what value PC will have.  | 
 | 	 Just make sure it is a valid instruction.  */ | 
 |       if (!inst_env->delay_slot_pc_active) | 
 | 	{ | 
 | 	  inst_env->reg[gdbarch_pc_regnum (gdbarch)] += 2; | 
 | 	} | 
 |       else | 
 | 	{ | 
 | 	  inst_env->delay_slot_pc_active = 0; | 
 | 	  inst_env->reg[gdbarch_pc_regnum (gdbarch)] | 
 | 	    = inst_env->delay_slot_pc; | 
 | 	} | 
 |       /* Analyse the present instruction.  */ | 
 |       i = find_cris_op (insn, inst_env); | 
 |       if (i == -1) | 
 | 	{ | 
 | 	  inst_env->invalid = 1; | 
 | 	} | 
 |       else | 
 | 	{ | 
 | 	  cris_gdb_func (gdbarch, cris_opcodes[i].op, insn, inst_env); | 
 | 	} | 
 |     } while (!inst_env->invalid  | 
 | 	     && (inst_env->prefix_found || inst_env->xflag_found  | 
 | 		 || inst_env->slot_needed)); | 
 |   return i; | 
 | } | 
 |  | 
 | /* There is no hardware single-step support.  The function find_step_target | 
 |    digs through the opcodes in order to find all possible targets. | 
 |    Either one ordinary target or two targets for branches may be found.  */ | 
 |  | 
 | static std::vector<CORE_ADDR> | 
 | cris_software_single_step (struct regcache *regcache) | 
 | { | 
 |   struct gdbarch *gdbarch = regcache->arch (); | 
 |   inst_env_type inst_env; | 
 |   std::vector<CORE_ADDR> next_pcs; | 
 |  | 
 |   /* Analyse the present instruction environment and insert  | 
 |      breakpoints.  */ | 
 |   int status = find_step_target (regcache, &inst_env); | 
 |   if (status == -1) | 
 |     { | 
 |       /* Could not find a target.  Things are likely to go downhill  | 
 | 	 from here.  */ | 
 |       warning (_("CRIS software single step could not find a step target.")); | 
 |     } | 
 |   else | 
 |     { | 
 |       /* Insert at most two breakpoints.  One for the next PC content | 
 | 	 and possibly another one for a branch, jump, etc.  */ | 
 |       CORE_ADDR next_pc | 
 | 	= (CORE_ADDR) inst_env.reg[gdbarch_pc_regnum (gdbarch)]; | 
 |  | 
 |       next_pcs.push_back (next_pc); | 
 |       if (inst_env.branch_found  | 
 | 	  && (CORE_ADDR) inst_env.branch_break_address != next_pc) | 
 | 	{ | 
 | 	  CORE_ADDR branch_target_address | 
 | 		= (CORE_ADDR) inst_env.branch_break_address; | 
 |  | 
 | 	  next_pcs.push_back (branch_target_address); | 
 | 	} | 
 |     } | 
 |  | 
 |   return next_pcs; | 
 | } | 
 |  | 
 | /* Calculates the prefix value for quick offset addressing mode.  */ | 
 |  | 
 | static void | 
 | quick_mode_bdap_prefix (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* It's invalid to be in a delay slot.  You can't have a prefix to this | 
 |      instruction (not 100% sure).  */ | 
 |   if (inst_env->slot_needed || inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return;  | 
 |     } | 
 |   | 
 |   inst_env->prefix_value = inst_env->reg[cris_get_operand2 (inst)]; | 
 |   inst_env->prefix_value += cris_get_bdap_quick_offset (inst); | 
 |  | 
 |   /* A prefix doesn't change the xflag_found.  But the rest of the flags | 
 |      need updating.  */ | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 1; | 
 | } | 
 |  | 
 | /* Updates the autoincrement register.  The size of the increment is derived  | 
 |    from the size of the operation.  The PC is always kept aligned on even | 
 |    word addresses.  */ | 
 |  | 
 | static void  | 
 | process_autoincrement (int size, unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   if (size == INST_BYTE_SIZE) | 
 |     { | 
 |       inst_env->reg[cris_get_operand1 (inst)] += 1; | 
 |  | 
 |       /* The PC must be word aligned, so increase the PC with one | 
 | 	 word even if the size is byte.  */ | 
 |       if (cris_get_operand1 (inst) == REG_PC) | 
 | 	{ | 
 | 	  inst_env->reg[REG_PC] += 1; | 
 | 	} | 
 |     } | 
 |   else if (size == INST_WORD_SIZE) | 
 |     { | 
 |       inst_env->reg[cris_get_operand1 (inst)] += 2; | 
 |     } | 
 |   else if (size == INST_DWORD_SIZE) | 
 |     { | 
 |       inst_env->reg[cris_get_operand1 (inst)] += 4; | 
 |     } | 
 |   else | 
 |     { | 
 |       /* Invalid size.  */ | 
 |       inst_env->invalid = 1; | 
 |     } | 
 | } | 
 |  | 
 | /* Just a forward declaration.  */ | 
 |  | 
 | static unsigned long get_data_from_address (unsigned short *inst, | 
 | 					    CORE_ADDR address, | 
 | 					    enum bfd_endian byte_order); | 
 |  | 
 | /* Calculates the prefix value for the general case of offset addressing  | 
 |    mode.  */ | 
 |  | 
 | static void | 
 | bdap_prefix (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* It's invalid to be in a delay slot.  */ | 
 |   if (inst_env->slot_needed || inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return;  | 
 |     } | 
 |  | 
 |   /* The calculation of prefix_value used to be after process_autoincrement, | 
 |      but that fails for an instruction such as jsr [$r0+12] which is encoded | 
 |      as 5f0d 0c00 30b9 when compiled with -fpic.  Since PC is operand1 it | 
 |      mustn't be incremented until we have read it and what it points at.  */ | 
 |   inst_env->prefix_value = inst_env->reg[cris_get_operand2 (inst)]; | 
 |  | 
 |   /* The offset is an indirection of the contents of the operand1 register.  */ | 
 |   inst_env->prefix_value +=  | 
 |     get_data_from_address (&inst, inst_env->reg[cris_get_operand1 (inst)], | 
 | 			   inst_env->byte_order); | 
 |    | 
 |   if (cris_get_mode (inst) == AUTOINC_MODE) | 
 |     { | 
 |       process_autoincrement (cris_get_size (inst), inst, inst_env);  | 
 |     } | 
 |     | 
 |   /* A prefix doesn't change the xflag_found.  But the rest of the flags | 
 |      need updating.  */ | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 1; | 
 | } | 
 |  | 
 | /* Calculates the prefix value for the index addressing mode.  */ | 
 |  | 
 | static void | 
 | biap_prefix (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* It's invalid to be in a delay slot.  I can't see that it's possible to | 
 |      have a prefix to this instruction.  So I will treat this as invalid.  */ | 
 |   if (inst_env->slot_needed || inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |    | 
 |   inst_env->prefix_value = inst_env->reg[cris_get_operand1 (inst)]; | 
 |  | 
 |   /* The offset is the operand2 value shifted the size of the instruction  | 
 |      to the left.  */ | 
 |   inst_env->prefix_value +=  | 
 |     inst_env->reg[cris_get_operand2 (inst)] << cris_get_size (inst); | 
 |    | 
 |   /* If the PC is operand1 (base) the address used is the address after  | 
 |      the main instruction, i.e. address + 2 (the PC is already compensated | 
 |      for the prefix operation).  */ | 
 |   if (cris_get_operand1 (inst) == REG_PC) | 
 |     { | 
 |       inst_env->prefix_value += 2; | 
 |     } | 
 |  | 
 |   /* A prefix doesn't change the xflag_found.  But the rest of the flags | 
 |      need updating.  */ | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->prefix_found = 1; | 
 | } | 
 |  | 
 | /* Calculates the prefix value for the double indirect addressing mode.  */ | 
 |  | 
 | static void  | 
 | dip_prefix (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |  | 
 |   CORE_ADDR address; | 
 |  | 
 |   /* It's invalid to be in a delay slot.  */ | 
 |   if (inst_env->slot_needed || inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |    | 
 |   /* The prefix value is one dereference of the contents of the operand1 | 
 |      register.  */ | 
 |   address = (CORE_ADDR) inst_env->reg[cris_get_operand1 (inst)]; | 
 |   inst_env->prefix_value | 
 |     = read_memory_unsigned_integer (address, 4, inst_env->byte_order); | 
 |      | 
 |   /* Check if the mode is autoincrement.  */ | 
 |   if (cris_get_mode (inst) == AUTOINC_MODE) | 
 |     { | 
 |       inst_env->reg[cris_get_operand1 (inst)] += 4; | 
 |     } | 
 |  | 
 |   /* A prefix doesn't change the xflag_found.  But the rest of the flags | 
 |      need updating.  */ | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->prefix_found = 1; | 
 | } | 
 |  | 
 | /* Finds the destination for a branch with 8-bits offset.  */ | 
 |  | 
 | static void | 
 | eight_bit_offset_branch_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |  | 
 |   short offset; | 
 |  | 
 |   /* If we have a prefix or are in a delay slot it's bad.  */ | 
 |   if (inst_env->slot_needed || inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |    | 
 |   /* We have a branch, find out where the branch will land.  */ | 
 |   offset = cris_get_branch_short_offset (inst); | 
 |  | 
 |   /* Check if the offset is signed.  */ | 
 |   if (offset & BRANCH_SIGNED_SHORT_OFFSET_MASK) | 
 |     { | 
 |       offset |= 0xFF00; | 
 |     } | 
 |    | 
 |   /* The offset ends with the sign bit, set it to zero.  The address | 
 |      should always be word aligned.  */ | 
 |   offset &= ~BRANCH_SIGNED_SHORT_OFFSET_MASK; | 
 |    | 
 |   inst_env->branch_found = 1; | 
 |   inst_env->branch_break_address = inst_env->reg[REG_PC] + offset; | 
 |  | 
 |   inst_env->slot_needed = 1; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 1; | 
 | } | 
 |  | 
 | /* Finds the destination for a branch with 16-bits offset.  */ | 
 |  | 
 | static void  | 
 | sixteen_bit_offset_branch_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   short offset; | 
 |  | 
 |   /* If we have a prefix or is in a delay slot it's bad.  */ | 
 |   if (inst_env->slot_needed || inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   /* We have a branch, find out the offset for the branch.  */ | 
 |   offset = read_memory_integer (inst_env->reg[REG_PC], 2, | 
 | 				inst_env->byte_order); | 
 |  | 
 |   /* The instruction is one word longer than normal, so add one word | 
 |      to the PC.  */ | 
 |   inst_env->reg[REG_PC] += 2; | 
 |  | 
 |   inst_env->branch_found = 1; | 
 |   inst_env->branch_break_address = inst_env->reg[REG_PC] + offset; | 
 |  | 
 |  | 
 |   inst_env->slot_needed = 1; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 1; | 
 | } | 
 |  | 
 | /* Handles the ABS instruction.  */ | 
 |  | 
 | static void  | 
 | abs_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |  | 
 |   long value; | 
 |    | 
 |   /* ABS can't have a prefix, so it's bad if it does.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   /* Check if the operation affects the PC.  */ | 
 |   if (cris_get_operand2 (inst) == REG_PC) | 
 |     { | 
 |      | 
 |       /* It's invalid to change to the PC if we are in a delay slot.  */ | 
 |       if (inst_env->slot_needed) | 
 | 	{ | 
 | 	  inst_env->invalid = 1; | 
 | 	  return; | 
 | 	} | 
 |  | 
 |       value = (long) inst_env->reg[REG_PC]; | 
 |  | 
 |       /* The value of abs (SIGNED_DWORD_MASK) is SIGNED_DWORD_MASK.  */ | 
 |       if (value != SIGNED_DWORD_MASK) | 
 | 	{ | 
 | 	  value = -value; | 
 | 	  inst_env->reg[REG_PC] = (long) value; | 
 | 	} | 
 |     } | 
 |  | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the ADDI instruction.  */ | 
 |  | 
 | static void  | 
 | addi_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* It's invalid to have the PC as base register.  And ADDI can't have | 
 |      a prefix.  */ | 
 |   if (inst_env->prefix_found || (cris_get_operand1 (inst) == REG_PC)) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the ASR instruction.  */ | 
 |  | 
 | static void  | 
 | asr_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   int shift_steps; | 
 |   unsigned long value; | 
 |   unsigned long signed_extend_mask = 0; | 
 |  | 
 |   /* ASR can't have a prefix, so check that it doesn't.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   /* Check if the PC is the target register.  */ | 
 |   if (cris_get_operand2 (inst) == REG_PC) | 
 |     { | 
 |       /* It's invalid to change the PC in a delay slot.  */ | 
 |       if (inst_env->slot_needed) | 
 | 	{ | 
 | 	  inst_env->invalid = 1; | 
 | 	  return; | 
 | 	} | 
 |       /* Get the number of bits to shift.  */ | 
 |       shift_steps | 
 | 	= cris_get_asr_shift_steps (inst_env->reg[cris_get_operand1 (inst)]); | 
 |       value = inst_env->reg[REG_PC]; | 
 |  | 
 |       /* Find out how many bits the operation should apply to.  */ | 
 |       if (cris_get_size (inst) == INST_BYTE_SIZE) | 
 | 	{ | 
 | 	  if (value & SIGNED_BYTE_MASK) | 
 | 	    { | 
 | 	      signed_extend_mask = 0xFF; | 
 | 	      signed_extend_mask = signed_extend_mask >> shift_steps; | 
 | 	      signed_extend_mask = ~signed_extend_mask; | 
 | 	    } | 
 | 	  value = value >> shift_steps; | 
 | 	  value |= signed_extend_mask; | 
 | 	  value &= 0xFF; | 
 | 	  inst_env->reg[REG_PC] &= 0xFFFFFF00; | 
 | 	  inst_env->reg[REG_PC] |= value; | 
 | 	} | 
 |       else if (cris_get_size (inst) == INST_WORD_SIZE) | 
 | 	{ | 
 | 	  if (value & SIGNED_WORD_MASK) | 
 | 	    { | 
 | 	      signed_extend_mask = 0xFFFF; | 
 | 	      signed_extend_mask = signed_extend_mask >> shift_steps; | 
 | 	      signed_extend_mask = ~signed_extend_mask; | 
 | 	    } | 
 | 	  value = value >> shift_steps; | 
 | 	  value |= signed_extend_mask; | 
 | 	  value &= 0xFFFF; | 
 | 	  inst_env->reg[REG_PC] &= 0xFFFF0000; | 
 | 	  inst_env->reg[REG_PC] |= value; | 
 | 	} | 
 |       else if (cris_get_size (inst) == INST_DWORD_SIZE) | 
 | 	{ | 
 | 	  if (value & SIGNED_DWORD_MASK) | 
 | 	    { | 
 | 	      signed_extend_mask = 0xFFFFFFFF; | 
 | 	      signed_extend_mask = signed_extend_mask >> shift_steps; | 
 | 	      signed_extend_mask = ~signed_extend_mask; | 
 | 	    } | 
 | 	  value = value >> shift_steps; | 
 | 	  value |= signed_extend_mask; | 
 | 	  inst_env->reg[REG_PC]  = value; | 
 | 	} | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the ASRQ instruction.  */ | 
 |  | 
 | static void  | 
 | asrq_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |  | 
 |   int shift_steps; | 
 |   unsigned long value; | 
 |   unsigned long signed_extend_mask = 0; | 
 |    | 
 |   /* ASRQ can't have a prefix, so check that it doesn't.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   /* Check if the PC is the target register.  */ | 
 |   if (cris_get_operand2 (inst) == REG_PC) | 
 |     { | 
 |  | 
 |       /* It's invalid to change the PC in a delay slot.  */ | 
 |       if (inst_env->slot_needed) | 
 | 	{ | 
 | 	  inst_env->invalid = 1; | 
 | 	  return; | 
 | 	} | 
 |       /* The shift size is given as a 5 bit quick value, i.e. we don't | 
 | 	 want the sign bit of the quick value.  */ | 
 |       shift_steps = cris_get_asr_shift_steps (inst); | 
 |       value = inst_env->reg[REG_PC]; | 
 |       if (value & SIGNED_DWORD_MASK) | 
 | 	{ | 
 | 	  signed_extend_mask = 0xFFFFFFFF; | 
 | 	  signed_extend_mask = signed_extend_mask >> shift_steps; | 
 | 	  signed_extend_mask = ~signed_extend_mask; | 
 | 	} | 
 |       value = value >> shift_steps; | 
 |       value |= signed_extend_mask; | 
 |       inst_env->reg[REG_PC]  = value; | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the AX, EI and SETF instruction.  */ | 
 |  | 
 | static void  | 
 | ax_ei_setf_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |   /* Check if the instruction is setting the X flag.  */ | 
 |   if (cris_is_xflag_bit_on (inst)) | 
 |     { | 
 |       inst_env->xflag_found = 1; | 
 |     } | 
 |   else | 
 |     { | 
 |       inst_env->xflag_found = 0; | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->disable_interrupt = 1; | 
 | } | 
 |  | 
 | /* Checks if the instruction is in assign mode.  If so, it updates the assign  | 
 |    register.  Note that check_assign assumes that the caller has checked that | 
 |    there is a prefix to this instruction.  The mode check depends on this.  */ | 
 |  | 
 | static void  | 
 | check_assign (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* Check if it's an assign addressing mode.  */ | 
 |   if (cris_get_mode (inst) == PREFIX_ASSIGN_MODE) | 
 |     { | 
 |       /* Assign the prefix value to operand 1.  */ | 
 |       inst_env->reg[cris_get_operand1 (inst)] = inst_env->prefix_value; | 
 |     } | 
 | } | 
 |  | 
 | /* Handles the 2-operand BOUND instruction.  */ | 
 |  | 
 | static void  | 
 | two_operand_bound_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* It's invalid to have the PC as the index operand.  */ | 
 |   if (cris_get_operand2 (inst) == REG_PC) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |   /* Check if we have a prefix.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       check_assign (inst, inst_env); | 
 |     } | 
 |   /* Check if this is an autoincrement mode.  */ | 
 |   else if (cris_get_mode (inst) == AUTOINC_MODE) | 
 |     { | 
 |       /* It's invalid to change the PC in a delay slot.  */ | 
 |       if (inst_env->slot_needed) | 
 | 	{ | 
 | 	  inst_env->invalid = 1; | 
 | 	  return; | 
 | 	} | 
 |       process_autoincrement (cris_get_size (inst), inst, inst_env); | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the 3-operand BOUND instruction.  */ | 
 |  | 
 | static void  | 
 | three_operand_bound_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* It's an error if we haven't got a prefix.  And it's also an error | 
 |      if the PC is the destination register.  */ | 
 |   if ((!inst_env->prefix_found) || (cris_get_operand1 (inst) == REG_PC)) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Clears the status flags in inst_env.  */ | 
 |  | 
 | static void  | 
 | btst_nop_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* It's an error if we have got a prefix.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Clears the status flags in inst_env.  */ | 
 |  | 
 | static void  | 
 | clearf_di_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* It's an error if we have got a prefix.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 1; | 
 | } | 
 |  | 
 | /* Handles the CLEAR instruction if it's in register mode.  */ | 
 |  | 
 | static void  | 
 | reg_mode_clear_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* Check if the target is the PC.  */ | 
 |   if (cris_get_operand2 (inst) == REG_PC) | 
 |     { | 
 |       /* The instruction will clear the instruction's size bits.  */ | 
 |       int clear_size = cris_get_clear_size (inst); | 
 |       if (clear_size == INST_BYTE_SIZE) | 
 | 	{ | 
 | 	  inst_env->delay_slot_pc = inst_env->reg[REG_PC] & 0xFFFFFF00; | 
 | 	} | 
 |       if (clear_size == INST_WORD_SIZE) | 
 | 	{ | 
 | 	  inst_env->delay_slot_pc = inst_env->reg[REG_PC] & 0xFFFF0000; | 
 | 	} | 
 |       if (clear_size == INST_DWORD_SIZE) | 
 | 	{ | 
 | 	  inst_env->delay_slot_pc = 0x0; | 
 | 	} | 
 |       /* The jump will be delayed with one delay slot.  So we need a delay  | 
 | 	 slot.  */ | 
 |       inst_env->slot_needed = 1; | 
 |       inst_env->delay_slot_pc_active = 1; | 
 |     } | 
 |   else | 
 |     { | 
 |       /* The PC will not change => no delay slot.  */ | 
 |       inst_env->slot_needed = 0; | 
 |     } | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the TEST instruction if it's in register mode.  */ | 
 |  | 
 | static void | 
 | reg_mode_test_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* It's an error if we have got a prefix.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 |  | 
 | } | 
 |  | 
 | /* Handles the CLEAR and TEST instruction if the instruction isn't  | 
 |    in register mode.  */ | 
 |  | 
 | static void  | 
 | none_reg_mode_clear_test_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* Check if we are in a prefix mode.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       /* The only way the PC can change is if this instruction is in | 
 | 	 assign addressing mode.  */ | 
 |       check_assign (inst, inst_env); | 
 |     } | 
 |   /* Indirect mode can't change the PC so just check if the mode is | 
 |      autoincrement.  */ | 
 |   else if (cris_get_mode (inst) == AUTOINC_MODE) | 
 |     { | 
 |       process_autoincrement (cris_get_size (inst), inst, inst_env); | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Checks that the PC isn't the destination register or the instructions has | 
 |    a prefix.  */ | 
 |  | 
 | static void  | 
 | dstep_logshift_mstep_neg_not_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* It's invalid to have the PC as the destination.  The instruction can't | 
 |      have a prefix.  */ | 
 |   if ((cris_get_operand2 (inst) == REG_PC) || inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Checks that the instruction doesn't have a prefix.  */ | 
 |  | 
 | static void | 
 | break_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* The instruction can't have a prefix.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 1; | 
 | } | 
 |  | 
 | /* Checks that the PC isn't the destination register and that the instruction | 
 |    doesn't have a prefix.  */ | 
 |  | 
 | static void | 
 | scc_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* It's invalid to have the PC as the destination.  The instruction can't | 
 |      have a prefix.  */ | 
 |   if ((cris_get_operand2 (inst) == REG_PC) || inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 1; | 
 | } | 
 |  | 
 | /* Handles the register mode JUMP instruction.  */ | 
 |  | 
 | static void  | 
 | reg_mode_jump_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* It's invalid to do a JUMP in a delay slot.  The mode is register, so  | 
 |      you can't have a prefix.  */ | 
 |   if ((inst_env->slot_needed) || (inst_env->prefix_found)) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |    | 
 |   /* Just change the PC.  */ | 
 |   inst_env->reg[REG_PC] = inst_env->reg[cris_get_operand1 (inst)]; | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 1; | 
 | } | 
 |  | 
 | /* Handles the JUMP instruction for all modes except register.  */ | 
 |  | 
 | static void | 
 | none_reg_mode_jump_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   unsigned long newpc; | 
 |   CORE_ADDR address; | 
 |  | 
 |   /* It's invalid to do a JUMP in a delay slot.  */ | 
 |   if (inst_env->slot_needed) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |     } | 
 |   else | 
 |     { | 
 |       /* Check if we have a prefix.  */ | 
 |       if (inst_env->prefix_found) | 
 | 	{ | 
 | 	  check_assign (inst, inst_env); | 
 |  | 
 | 	  /* Get the new value for the PC.  */ | 
 | 	  newpc =  | 
 | 	    read_memory_unsigned_integer ((CORE_ADDR) inst_env->prefix_value, | 
 | 					  4, inst_env->byte_order); | 
 | 	} | 
 |       else | 
 | 	{ | 
 | 	  /* Get the new value for the PC.  */ | 
 | 	  address = (CORE_ADDR) inst_env->reg[cris_get_operand1 (inst)]; | 
 | 	  newpc = read_memory_unsigned_integer (address, | 
 | 						4, inst_env->byte_order); | 
 |  | 
 | 	  /* Check if we should increment a register.  */ | 
 | 	  if (cris_get_mode (inst) == AUTOINC_MODE) | 
 | 	    { | 
 | 	      inst_env->reg[cris_get_operand1 (inst)] += 4; | 
 | 	    } | 
 | 	} | 
 |       inst_env->reg[REG_PC] = newpc; | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 1; | 
 | } | 
 |  | 
 | /* Handles moves to special registers (aka P-register) for all modes.  */ | 
 |  | 
 | static void  | 
 | move_to_preg_op (struct gdbarch *gdbarch, unsigned short inst, | 
 | 		 inst_env_type *inst_env) | 
 | { | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       /* The instruction has a prefix that means we are only interested if | 
 | 	 the instruction is in assign mode.  */ | 
 |       if (cris_get_mode (inst) == PREFIX_ASSIGN_MODE) | 
 | 	{ | 
 | 	  /* The prefix handles the problem if we are in a delay slot.  */ | 
 | 	  if (cris_get_operand1 (inst) == REG_PC) | 
 | 	    { | 
 | 	      /* Just take care of the assign.  */ | 
 | 	      check_assign (inst, inst_env); | 
 | 	    } | 
 | 	} | 
 |     } | 
 |   else if (cris_get_mode (inst) == AUTOINC_MODE) | 
 |     { | 
 |       /* The instruction doesn't have a prefix, the only case left that we | 
 | 	 are interested in is the autoincrement mode.  */ | 
 |       if (cris_get_operand1 (inst) == REG_PC) | 
 | 	{ | 
 | 	  /* If the PC is to be incremented it's invalid to be in a  | 
 | 	     delay slot.  */ | 
 | 	  if (inst_env->slot_needed) | 
 | 	    { | 
 | 	      inst_env->invalid = 1; | 
 | 	      return; | 
 | 	    } | 
 |  | 
 | 	  /* The increment depends on the size of the special register.  */ | 
 | 	  if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 1) | 
 | 	    { | 
 | 	      process_autoincrement (INST_BYTE_SIZE, inst, inst_env); | 
 | 	    } | 
 | 	  else if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 2) | 
 | 	    { | 
 | 	      process_autoincrement (INST_WORD_SIZE, inst, inst_env); | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      process_autoincrement (INST_DWORD_SIZE, inst, inst_env); | 
 | 	    } | 
 | 	} | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 1; | 
 | } | 
 |  | 
 | /* Handles moves from special registers (aka P-register) for all modes | 
 |    except register.  */ | 
 |  | 
 | static void  | 
 | none_reg_mode_move_from_preg_op (struct gdbarch *gdbarch, unsigned short inst, | 
 | 				 inst_env_type *inst_env) | 
 | { | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       /* The instruction has a prefix that means we are only interested if | 
 | 	 the instruction is in assign mode.  */ | 
 |       if (cris_get_mode (inst) == PREFIX_ASSIGN_MODE) | 
 | 	{ | 
 | 	  /* The prefix handles the problem if we are in a delay slot.  */ | 
 | 	  if (cris_get_operand1 (inst) == REG_PC) | 
 | 	    { | 
 | 	      /* Just take care of the assign.  */ | 
 | 	      check_assign (inst, inst_env); | 
 | 	    } | 
 | 	} | 
 |     }     | 
 |   /* The instruction doesn't have a prefix, the only case left that we | 
 |      are interested in is the autoincrement mode.  */ | 
 |   else if (cris_get_mode (inst) == AUTOINC_MODE) | 
 |     { | 
 |       if (cris_get_operand1 (inst) == REG_PC) | 
 | 	{ | 
 | 	  /* If the PC is to be incremented it's invalid to be in a  | 
 | 	     delay slot.  */ | 
 | 	  if (inst_env->slot_needed) | 
 | 	    { | 
 | 	      inst_env->invalid = 1; | 
 | 	      return; | 
 | 	    } | 
 | 	   | 
 | 	  /* The increment depends on the size of the special register.  */ | 
 | 	  if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 1) | 
 | 	    { | 
 | 	      process_autoincrement (INST_BYTE_SIZE, inst, inst_env); | 
 | 	    } | 
 | 	  else if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 2) | 
 | 	    { | 
 | 	      process_autoincrement (INST_WORD_SIZE, inst, inst_env); | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      process_autoincrement (INST_DWORD_SIZE, inst, inst_env); | 
 | 	    } | 
 | 	} | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 1; | 
 | } | 
 |  | 
 | /* Handles moves from special registers (aka P-register) when the mode | 
 |    is register.  */ | 
 |  | 
 | static void  | 
 | reg_mode_move_from_preg_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* Register mode move from special register can't have a prefix.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   if (cris_get_operand1 (inst) == REG_PC) | 
 |     { | 
 |       /* It's invalid to change the PC in a delay slot.  */ | 
 |       if (inst_env->slot_needed) | 
 | 	{ | 
 | 	  inst_env->invalid = 1; | 
 | 	  return; | 
 | 	} | 
 |       /* The destination is the PC, the jump will have a delay slot.  */ | 
 |       inst_env->delay_slot_pc = inst_env->preg[cris_get_operand2 (inst)]; | 
 |       inst_env->slot_needed = 1; | 
 |       inst_env->delay_slot_pc_active = 1; | 
 |     } | 
 |   else | 
 |     { | 
 |       /* If the destination isn't PC, there will be no jump.  */ | 
 |       inst_env->slot_needed = 0; | 
 |     } | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 1; | 
 | } | 
 |  | 
 | /* Handles the MOVEM from memory to general register instruction.  */ | 
 |  | 
 | static void  | 
 | move_mem_to_reg_movem_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       /* The prefix handles the problem if we are in a delay slot.  Is the | 
 | 	 MOVEM instruction going to change the PC?  */ | 
 |       if (cris_get_operand2 (inst) >= REG_PC) | 
 | 	{ | 
 | 	  inst_env->reg[REG_PC] =  | 
 | 	    read_memory_unsigned_integer (inst_env->prefix_value, | 
 | 					  4, inst_env->byte_order); | 
 | 	} | 
 |       /* The assign value is the value after the increment.  Normally, the    | 
 | 	 assign value is the value before the increment.  */ | 
 |       if ((cris_get_operand1 (inst) == REG_PC)  | 
 | 	  && (cris_get_mode (inst) == PREFIX_ASSIGN_MODE)) | 
 | 	{ | 
 | 	  inst_env->reg[REG_PC] = inst_env->prefix_value; | 
 | 	  inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1); | 
 | 	} | 
 |     } | 
 |   else | 
 |     { | 
 |       /* Is the MOVEM instruction going to change the PC?  */ | 
 |       if (cris_get_operand2 (inst) == REG_PC) | 
 | 	{ | 
 | 	  /* It's invalid to change the PC in a delay slot.  */ | 
 | 	  if (inst_env->slot_needed) | 
 | 	    { | 
 | 	      inst_env->invalid = 1; | 
 | 	      return; | 
 | 	    } | 
 | 	  inst_env->reg[REG_PC] = | 
 | 	    read_memory_unsigned_integer (inst_env->reg[cris_get_operand1 (inst)],  | 
 | 					  4, inst_env->byte_order); | 
 | 	} | 
 |       /* The increment is not depending on the size, instead it's depending | 
 | 	 on the number of registers loaded from memory.  */ | 
 |       if ((cris_get_operand1 (inst) == REG_PC) | 
 | 	  && (cris_get_mode (inst) == AUTOINC_MODE)) | 
 | 	{ | 
 | 	  /* It's invalid to change the PC in a delay slot.  */ | 
 | 	  if (inst_env->slot_needed) | 
 | 	    { | 
 | 	      inst_env->invalid = 1; | 
 | 	      return; | 
 | 	    } | 
 | 	  inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);  | 
 | 	} | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the MOVEM to memory from general register instruction.  */ | 
 |  | 
 | static void  | 
 | move_reg_to_mem_movem_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       /* The assign value is the value after the increment.  Normally, the | 
 | 	 assign value is the value before the increment.  */ | 
 |       if ((cris_get_operand1 (inst) == REG_PC) | 
 | 	  && (cris_get_mode (inst) == PREFIX_ASSIGN_MODE)) | 
 | 	{ | 
 | 	  /* The prefix handles the problem if we are in a delay slot.  */ | 
 | 	  inst_env->reg[REG_PC] = inst_env->prefix_value; | 
 | 	  inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1); | 
 | 	} | 
 |     } | 
 |   else | 
 |     { | 
 |       /* The increment is not depending on the size, instead it's depending | 
 | 	 on the number of registers loaded to memory.  */ | 
 |       if ((cris_get_operand1 (inst) == REG_PC) | 
 | 	  && (cris_get_mode (inst) == AUTOINC_MODE)) | 
 | 	{ | 
 | 	  /* It's invalid to change the PC in a delay slot.  */ | 
 | 	  if (inst_env->slot_needed) | 
 | 	    { | 
 | 	      inst_env->invalid = 1; | 
 | 	      return; | 
 | 	    } | 
 | 	  inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1); | 
 | 	} | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the instructions that's not yet implemented, by setting | 
 |    inst_env->invalid to true.  */ | 
 |  | 
 | static void  | 
 | not_implemented_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   inst_env->invalid = 1; | 
 | } | 
 |  | 
 | /* Handles the XOR instruction.  */ | 
 |  | 
 | static void  | 
 | xor_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* XOR can't have a prefix.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   /* Check if the PC is the target.  */ | 
 |   if (cris_get_operand2 (inst) == REG_PC) | 
 |     { | 
 |       /* It's invalid to change the PC in a delay slot.  */ | 
 |       if (inst_env->slot_needed) | 
 | 	{ | 
 | 	  inst_env->invalid = 1; | 
 | 	  return; | 
 | 	} | 
 |       inst_env->reg[REG_PC] ^= inst_env->reg[cris_get_operand1 (inst)]; | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the MULS instruction.  */ | 
 |  | 
 | static void  | 
 | muls_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* MULS/U can't have a prefix.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   /* Consider it invalid if the PC is the target.  */ | 
 |   if (cris_get_operand2 (inst) == REG_PC) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the MULU instruction.  */ | 
 |  | 
 | static void  | 
 | mulu_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   /* MULS/U can't have a prefix.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   /* Consider it invalid if the PC is the target.  */ | 
 |   if (cris_get_operand2 (inst) == REG_PC) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Calculate the result of the instruction for ADD, SUB, CMP AND, OR and MOVE. | 
 |    The MOVE instruction is the move from source to register.  */ | 
 |  | 
 | static void  | 
 | add_sub_cmp_and_or_move_action (unsigned short inst, inst_env_type *inst_env,  | 
 | 				unsigned long source1, unsigned long source2) | 
 | { | 
 |   unsigned long pc_mask; | 
 |   unsigned long operation_mask; | 
 |    | 
 |   /* Find out how many bits the operation should apply to.  */ | 
 |   if (cris_get_size (inst) == INST_BYTE_SIZE) | 
 |     { | 
 |       pc_mask = 0xFFFFFF00;  | 
 |       operation_mask = 0xFF; | 
 |     } | 
 |   else if (cris_get_size (inst) == INST_WORD_SIZE) | 
 |     { | 
 |       pc_mask = 0xFFFF0000; | 
 |       operation_mask = 0xFFFF; | 
 |     } | 
 |   else if (cris_get_size (inst) == INST_DWORD_SIZE) | 
 |     { | 
 |       pc_mask = 0x0; | 
 |       operation_mask = 0xFFFFFFFF; | 
 |     } | 
 |   else | 
 |     { | 
 |       /* The size is out of range.  */ | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   /* The instruction just works on uw_operation_mask bits.  */ | 
 |   source2 &= operation_mask; | 
 |   source1 &= operation_mask; | 
 |  | 
 |   /* Now calculate the result.  The opcode's 3 first bits separates | 
 |      the different actions.  */ | 
 |   switch (cris_get_opcode (inst) & 7) | 
 |     { | 
 |     case 0:  /* add */ | 
 |       source1 += source2; | 
 |       break; | 
 |  | 
 |     case 1:  /* move */ | 
 |       source1 = source2; | 
 |       break; | 
 |  | 
 |     case 2:  /* subtract */ | 
 |       source1 -= source2; | 
 |       break; | 
 |  | 
 |     case 3:  /* compare */ | 
 |       break; | 
 |  | 
 |     case 4:  /* and */ | 
 |       source1 &= source2; | 
 |       break; | 
 |  | 
 |     case 5:  /* or */ | 
 |       source1 |= source2; | 
 |       break; | 
 |  | 
 |     default: | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |  | 
 |       break; | 
 |     } | 
 |  | 
 |   /* Make sure that the result doesn't contain more than the instruction | 
 |      size bits.  */ | 
 |   source2 &= operation_mask; | 
 |  | 
 |   /* Calculate the new breakpoint address.  */ | 
 |   inst_env->reg[REG_PC] &= pc_mask; | 
 |   inst_env->reg[REG_PC] |= source1; | 
 |  | 
 | } | 
 |  | 
 | /* Extends the value from either byte or word size to a dword.  If the mode | 
 |    is zero extend then the value is extended with zero.  If instead the mode | 
 |    is signed extend the sign bit of the value is taken into consideration.  */ | 
 |  | 
 | static unsigned long  | 
 | do_sign_or_zero_extend (unsigned long value, unsigned short *inst) | 
 | { | 
 |   /* The size can be either byte or word, check which one it is.  | 
 |      Don't check the highest bit, it's indicating if it's a zero | 
 |      or sign extend.  */ | 
 |   if (cris_get_size (*inst) & INST_WORD_SIZE) | 
 |     { | 
 |       /* Word size.  */ | 
 |       value &= 0xFFFF; | 
 |  | 
 |       /* Check if the instruction is signed extend.  If so, check if value has | 
 | 	 the sign bit on.  */ | 
 |       if (cris_is_signed_extend_bit_on (*inst) && (value & SIGNED_WORD_MASK)) | 
 | 	{ | 
 | 	  value |= SIGNED_WORD_EXTEND_MASK; | 
 | 	}  | 
 |     } | 
 |   else | 
 |     { | 
 |       /* Byte size.  */ | 
 |       value &= 0xFF; | 
 |  | 
 |       /* Check if the instruction is signed extend.  If so, check if value has | 
 | 	 the sign bit on.  */ | 
 |       if (cris_is_signed_extend_bit_on (*inst) && (value & SIGNED_BYTE_MASK)) | 
 | 	{ | 
 | 	  value |= SIGNED_BYTE_EXTEND_MASK; | 
 | 	} | 
 |     } | 
 |   /* The size should now be dword.  */ | 
 |   cris_set_size_to_dword (inst); | 
 |   return value; | 
 | } | 
 |  | 
 | /* Handles the register mode for the ADD, SUB, CMP, AND, OR and MOVE | 
 |    instruction.  The MOVE instruction is the move from source to register.  */ | 
 |  | 
 | static void  | 
 | reg_mode_add_sub_cmp_and_or_move_op (unsigned short inst, | 
 | 				     inst_env_type *inst_env) | 
 | { | 
 |   unsigned long operand1; | 
 |   unsigned long operand2; | 
 |  | 
 |   /* It's invalid to have a prefix to the instruction.  This is a register  | 
 |      mode instruction and can't have a prefix.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |   /* Check if the instruction has PC as its target.  */ | 
 |   if (cris_get_operand2 (inst) == REG_PC) | 
 |     { | 
 |       if (inst_env->slot_needed) | 
 | 	{ | 
 | 	  inst_env->invalid = 1; | 
 | 	  return; | 
 | 	} | 
 |       /* The instruction has the PC as its target register.  */ | 
 |       operand1 = inst_env->reg[cris_get_operand1 (inst)];  | 
 |       operand2 = inst_env->reg[REG_PC]; | 
 |  | 
 |       /* Check if it's a extend, signed or zero instruction.  */ | 
 |       if (cris_get_opcode (inst) < 4) | 
 | 	{ | 
 | 	  operand1 = do_sign_or_zero_extend (operand1, &inst); | 
 | 	} | 
 |       /* Calculate the PC value after the instruction, i.e. where the | 
 | 	 breakpoint should be.  The order of the udw_operands is vital.  */ | 
 |       add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand1);  | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Returns the data contained at address.  The size of the data is derived from | 
 |    the size of the operation.  If the instruction is a zero or signed | 
 |    extend instruction, the size field is changed in instruction.  */ | 
 |  | 
 | static unsigned long  | 
 | get_data_from_address (unsigned short *inst, CORE_ADDR address, | 
 | 		       enum bfd_endian byte_order) | 
 | { | 
 |   int size = cris_get_size (*inst); | 
 |   unsigned long value; | 
 |  | 
 |   /* If it's an extend instruction we don't want the signed extend bit, | 
 |      because it influences the size.  */ | 
 |   if (cris_get_opcode (*inst) < 4) | 
 |     { | 
 |       size &= ~SIGNED_EXTEND_BIT_MASK; | 
 |     } | 
 |   /* Is there a need for checking the size?  Size should contain the number of | 
 |      bytes to read.  */ | 
 |   size = 1 << size; | 
 |   value = read_memory_unsigned_integer (address, size, byte_order); | 
 |  | 
 |   /* Check if it's an extend, signed or zero instruction.  */ | 
 |   if (cris_get_opcode (*inst) < 4) | 
 |     { | 
 |       value = do_sign_or_zero_extend (value, inst); | 
 |     } | 
 |   return value; | 
 | } | 
 |  | 
 | /* Handles the assign addresing mode for the ADD, SUB, CMP, AND, OR and MOVE  | 
 |    instructions.  The MOVE instruction is the move from source to register.  */ | 
 |  | 
 | static void  | 
 | handle_prefix_assign_mode_for_aritm_op (unsigned short inst,  | 
 | 					inst_env_type *inst_env) | 
 | { | 
 |   unsigned long operand2; | 
 |   unsigned long operand3; | 
 |  | 
 |   check_assign (inst, inst_env); | 
 |   if (cris_get_operand2 (inst) == REG_PC) | 
 |     { | 
 |       operand2 = inst_env->reg[REG_PC]; | 
 |  | 
 |       /* Get the value of the third operand.  */ | 
 |       operand3 = get_data_from_address (&inst, inst_env->prefix_value, | 
 | 					inst_env->byte_order); | 
 |  | 
 |       /* Calculate the PC value after the instruction, i.e. where the | 
 | 	 breakpoint should be.  The order of the udw_operands is vital.  */ | 
 |       add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand3); | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the three-operand addressing mode for the ADD, SUB, CMP, AND and | 
 |    OR instructions.  Note that for this to work as expected, the calling | 
 |    function must have made sure that there is a prefix to this instruction.  */ | 
 |  | 
 | static void  | 
 | three_operand_add_sub_cmp_and_or_op (unsigned short inst,  | 
 | 				     inst_env_type *inst_env) | 
 | { | 
 |   unsigned long operand2; | 
 |   unsigned long operand3; | 
 |  | 
 |   if (cris_get_operand1 (inst) == REG_PC) | 
 |     { | 
 |       /* The PC will be changed by the instruction.  */ | 
 |       operand2 = inst_env->reg[cris_get_operand2 (inst)]; | 
 |  | 
 |       /* Get the value of the third operand.  */ | 
 |       operand3 = get_data_from_address (&inst, inst_env->prefix_value, | 
 | 					inst_env->byte_order); | 
 |  | 
 |       /* Calculate the PC value after the instruction, i.e. where the | 
 | 	 breakpoint should be.  */ | 
 |       add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand3); | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the index addresing mode for the ADD, SUB, CMP, AND, OR and MOVE | 
 |    instructions.  The MOVE instruction is the move from source to register.  */ | 
 |  | 
 | static void  | 
 | handle_prefix_index_mode_for_aritm_op (unsigned short inst,  | 
 | 				       inst_env_type *inst_env) | 
 | { | 
 |   if (cris_get_operand1 (inst) != cris_get_operand2 (inst)) | 
 |     { | 
 |       /* If the instruction is MOVE it's invalid.  If the instruction is ADD, | 
 | 	 SUB, AND or OR something weird is going on (if everything works these | 
 | 	 instructions should end up in the three operand version).  */ | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |   else | 
 |     { | 
 |       /* three_operand_add_sub_cmp_and_or does the same as we should do here | 
 | 	 so use it.  */ | 
 |       three_operand_add_sub_cmp_and_or_op (inst, inst_env); | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the autoincrement and indirect addresing mode for the ADD, SUB, | 
 |    CMP, AND OR and MOVE instruction.  The MOVE instruction is the move from | 
 |    source to register.  */ | 
 |  | 
 | static void  | 
 | handle_inc_and_index_mode_for_aritm_op (unsigned short inst,  | 
 | 					inst_env_type *inst_env) | 
 | { | 
 |   unsigned long operand1; | 
 |   unsigned long operand2; | 
 |   unsigned long operand3; | 
 |   int size; | 
 |  | 
 |   /* The instruction is either an indirect or autoincrement addressing mode. | 
 |      Check if the destination register is the PC.  */ | 
 |   if (cris_get_operand2 (inst) == REG_PC) | 
 |     { | 
 |       /* Must be done here, get_data_from_address may change the size  | 
 | 	 field.  */ | 
 |       size = cris_get_size (inst); | 
 |       operand2 = inst_env->reg[REG_PC]; | 
 |  | 
 |       /* Get the value of the third operand, i.e. the indirect operand.  */ | 
 |       operand1 = inst_env->reg[cris_get_operand1 (inst)]; | 
 |       operand3 = get_data_from_address (&inst, operand1, inst_env->byte_order); | 
 |  | 
 |       /* Calculate the PC value after the instruction, i.e. where the | 
 | 	 breakpoint should be.  The order of the udw_operands is vital.  */ | 
 |       add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand3);  | 
 |     } | 
 |   /* If this is an autoincrement addressing mode, check if the increment | 
 |      changes the PC.  */ | 
 |   if ((cris_get_operand1 (inst) == REG_PC) | 
 |       && (cris_get_mode (inst) == AUTOINC_MODE)) | 
 |     { | 
 |       /* Get the size field.  */ | 
 |       size = cris_get_size (inst); | 
 |  | 
 |       /* If it's an extend instruction we don't want the signed extend bit, | 
 | 	 because it influences the size.  */ | 
 |       if (cris_get_opcode (inst) < 4) | 
 | 	{ | 
 | 	  size &= ~SIGNED_EXTEND_BIT_MASK; | 
 | 	} | 
 |       process_autoincrement (size, inst, inst_env); | 
 |     }  | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the two-operand addressing mode, all modes except register, for | 
 |    the ADD, SUB CMP, AND and OR instruction.  */ | 
 |  | 
 | static void  | 
 | none_reg_mode_add_sub_cmp_and_or_move_op (unsigned short inst,  | 
 | 					  inst_env_type *inst_env) | 
 | { | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       if (cris_get_mode (inst) == PREFIX_INDEX_MODE) | 
 | 	{ | 
 | 	  handle_prefix_index_mode_for_aritm_op (inst, inst_env); | 
 | 	} | 
 |       else if (cris_get_mode (inst) == PREFIX_ASSIGN_MODE) | 
 | 	{ | 
 | 	  handle_prefix_assign_mode_for_aritm_op (inst, inst_env); | 
 | 	} | 
 |       else | 
 | 	{ | 
 | 	  /* The mode is invalid for a prefixed base instruction.  */ | 
 | 	  inst_env->invalid = 1; | 
 | 	  return; | 
 | 	} | 
 |     } | 
 |   else | 
 |     { | 
 |       handle_inc_and_index_mode_for_aritm_op (inst, inst_env); | 
 |     } | 
 | } | 
 |  | 
 | /* Handles the quick addressing mode for the ADD and SUB instruction.  */ | 
 |  | 
 | static void  | 
 | quick_mode_add_sub_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   unsigned long operand1; | 
 |   unsigned long operand2; | 
 |  | 
 |   /* It's a bad idea to be in a prefix instruction now.  This is a quick mode | 
 |      instruction and can't have a prefix.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |  | 
 |   /* Check if the instruction has PC as its target.  */ | 
 |   if (cris_get_operand2 (inst) == REG_PC) | 
 |     { | 
 |       if (inst_env->slot_needed) | 
 | 	{ | 
 | 	  inst_env->invalid = 1; | 
 | 	  return; | 
 | 	} | 
 |       operand1 = cris_get_quick_value (inst); | 
 |       operand2 = inst_env->reg[REG_PC]; | 
 |  | 
 |       /* The size should now be dword.  */ | 
 |       cris_set_size_to_dword (&inst); | 
 |  | 
 |       /* Calculate the PC value after the instruction, i.e. where the | 
 | 	 breakpoint should be.  */ | 
 |       add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand1); | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Handles the quick addressing mode for the CMP, AND and OR instruction.  */ | 
 |  | 
 | static void  | 
 | quick_mode_and_cmp_move_or_op (unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   unsigned long operand1; | 
 |   unsigned long operand2; | 
 |  | 
 |   /* It's a bad idea to be in a prefix instruction now.  This is a quick mode | 
 |      instruction and can't have a prefix.  */ | 
 |   if (inst_env->prefix_found) | 
 |     { | 
 |       inst_env->invalid = 1; | 
 |       return; | 
 |     } | 
 |   /* Check if the instruction has PC as its target.  */ | 
 |   if (cris_get_operand2 (inst) == REG_PC) | 
 |     { | 
 |       if (inst_env->slot_needed) | 
 | 	{ | 
 | 	  inst_env->invalid = 1; | 
 | 	  return; | 
 | 	} | 
 |       /* The instruction has the PC as its target register.  */ | 
 |       operand1 = cris_get_quick_value (inst); | 
 |       operand2 = inst_env->reg[REG_PC]; | 
 |  | 
 |       /* The quick value is signed, so check if we must do a signed extend.  */ | 
 |       if (operand1 & SIGNED_QUICK_VALUE_MASK) | 
 | 	{ | 
 | 	  /* sign extend  */ | 
 | 	  operand1 |= SIGNED_QUICK_VALUE_EXTEND_MASK; | 
 | 	} | 
 |       /* The size should now be dword.  */ | 
 |       cris_set_size_to_dword (&inst); | 
 |  | 
 |       /* Calculate the PC value after the instruction, i.e. where the | 
 | 	 breakpoint should be.  */ | 
 |       add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand1); | 
 |     } | 
 |   inst_env->slot_needed = 0; | 
 |   inst_env->prefix_found = 0; | 
 |   inst_env->xflag_found = 0; | 
 |   inst_env->disable_interrupt = 0; | 
 | } | 
 |  | 
 | /* Translate op_type to a function and call it.  */ | 
 |  | 
 | static void | 
 | cris_gdb_func (struct gdbarch *gdbarch, enum cris_op_type op_type, | 
 | 	       unsigned short inst, inst_env_type *inst_env) | 
 | { | 
 |   switch (op_type) | 
 |     { | 
 |     case cris_not_implemented_op: | 
 |       not_implemented_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_abs_op: | 
 |       abs_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_addi_op: | 
 |       addi_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_asr_op: | 
 |       asr_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_asrq_op: | 
 |       asrq_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_ax_ei_setf_op: | 
 |       ax_ei_setf_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_bdap_prefix: | 
 |       bdap_prefix (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_biap_prefix: | 
 |       biap_prefix (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_break_op: | 
 |       break_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_btst_nop_op: | 
 |       btst_nop_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_clearf_di_op: | 
 |       clearf_di_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_dip_prefix: | 
 |       dip_prefix (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_dstep_logshift_mstep_neg_not_op: | 
 |       dstep_logshift_mstep_neg_not_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_eight_bit_offset_branch_op: | 
 |       eight_bit_offset_branch_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_move_mem_to_reg_movem_op: | 
 |       move_mem_to_reg_movem_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_move_reg_to_mem_movem_op: | 
 |       move_reg_to_mem_movem_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_move_to_preg_op: | 
 |       move_to_preg_op (gdbarch, inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_muls_op: | 
 |       muls_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_mulu_op: | 
 |       mulu_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_none_reg_mode_add_sub_cmp_and_or_move_op: | 
 |       none_reg_mode_add_sub_cmp_and_or_move_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_none_reg_mode_clear_test_op: | 
 |       none_reg_mode_clear_test_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_none_reg_mode_jump_op: | 
 |       none_reg_mode_jump_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_none_reg_mode_move_from_preg_op: | 
 |       none_reg_mode_move_from_preg_op (gdbarch, inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_quick_mode_add_sub_op: | 
 |       quick_mode_add_sub_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_quick_mode_and_cmp_move_or_op: | 
 |       quick_mode_and_cmp_move_or_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_quick_mode_bdap_prefix: | 
 |       quick_mode_bdap_prefix (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_reg_mode_add_sub_cmp_and_or_move_op: | 
 |       reg_mode_add_sub_cmp_and_or_move_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_reg_mode_clear_op: | 
 |       reg_mode_clear_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_reg_mode_jump_op: | 
 |       reg_mode_jump_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_reg_mode_move_from_preg_op: | 
 |       reg_mode_move_from_preg_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_reg_mode_test_op: | 
 |       reg_mode_test_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_scc_op: | 
 |       scc_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_sixteen_bit_offset_branch_op: | 
 |       sixteen_bit_offset_branch_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_three_operand_add_sub_cmp_and_or_op: | 
 |       three_operand_add_sub_cmp_and_or_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_three_operand_bound_op: | 
 |       three_operand_bound_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_two_operand_bound_op: | 
 |       two_operand_bound_op (inst, inst_env); | 
 |       break; | 
 |  | 
 |     case cris_xor_op: | 
 |       xor_op (inst, inst_env); | 
 |       break; | 
 |     } | 
 | } | 
 |  | 
 | /* Originally from <asm/elf.h>.  */ | 
 | typedef unsigned char cris_elf_greg_t[4]; | 
 |  | 
 | /* Same as user_regs_struct struct in <asm/user.h>.  */ | 
 | #define CRISV10_ELF_NGREG 35 | 
 | typedef cris_elf_greg_t cris_elf_gregset_t[CRISV10_ELF_NGREG]; | 
 |  | 
 | #define CRISV32_ELF_NGREG 32 | 
 | typedef cris_elf_greg_t crisv32_elf_gregset_t[CRISV32_ELF_NGREG]; | 
 |  | 
 | /* Unpack a cris_elf_gregset_t into GDB's register cache.  */ | 
 |  | 
 | static void  | 
 | cris_supply_gregset (const struct regset *regset, struct regcache *regcache, | 
 | 		     int regnum, const void *gregs, size_t len) | 
 | { | 
 |   struct gdbarch *gdbarch = regcache->arch (); | 
 |   cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch); | 
 |   int i; | 
 |   const cris_elf_greg_t *regp = static_cast<const cris_elf_greg_t *>(gregs); | 
 |  | 
 |   if (len != sizeof (cris_elf_gregset_t) | 
 |       && len != sizeof (crisv32_elf_gregset_t)) | 
 |     warning (_("wrong size gregset struct in core file")); | 
 |   gdb_assert (len >= sizeof (crisv32_elf_gregset_t)); | 
 |  | 
 |   /* The kernel dumps all 32 registers as unsigned longs, but supply_register | 
 |      knows about the actual size of each register so that's no problem.  */ | 
 |   for (i = 0; i < NUM_GENREGS + NUM_SPECREGS; i++) | 
 |     { | 
 |       if (regnum == -1 || regnum == i) | 
 | 	regcache->raw_supply (i, (char *)®p[i]); | 
 |     } | 
 |  | 
 |   if (tdep->cris_version == 32 && (regnum == -1 || regnum == ERP_REGNUM)) | 
 |     { | 
 |       /* Needed to set pseudo-register PC for CRISv32.  */ | 
 |       /* FIXME: If ERP is in a delay slot at this point then the PC will | 
 | 	 be wrong.  Issue a warning to alert the user.  */ | 
 |       regcache->raw_supply (gdbarch_pc_regnum (gdbarch), | 
 | 			    (char *)®p[ERP_REGNUM]); | 
 |  | 
 |       if (*(char *)®p[ERP_REGNUM] & 0x1) | 
 | 	gdb_printf (gdb_stderr, "Warning: PC in delay slot\n"); | 
 |     } | 
 | } | 
 |  | 
 | static const struct regset cris_regset = { | 
 |   nullptr, | 
 |   cris_supply_gregset, | 
 |   /* We don't need a collect function because we only use this for core files | 
 |      (via iterate_over_regset_sections).  */ | 
 |   nullptr, | 
 |   REGSET_VARIABLE_SIZE | 
 | }; | 
 |  | 
 | static void cris_iterate_over_regset_sections (struct gdbarch *gdbarch, | 
 | 					       iterate_over_regset_sections_cb *cb, | 
 | 					       void *cb_data, | 
 | 					       const struct regcache *regcache) | 
 | { | 
 |   cb (".reg", sizeof (crisv32_elf_gregset_t), sizeof (crisv32_elf_gregset_t), | 
 |       &cris_regset, NULL, cb_data); | 
 | } | 
 |  | 
 | void _initialize_cris_tdep (); | 
 | void | 
 | _initialize_cris_tdep () | 
 | { | 
 |   gdbarch_register (bfd_arch_cris, cris_gdbarch_init, cris_dump_tdep); | 
 |    | 
 |   /* CRIS-specific user-commands.  */ | 
 |   add_setshow_zuinteger_cmd ("cris-version", class_support, | 
 | 			     &usr_cmd_cris_version, | 
 | 			     _("Set the current CRIS version."), | 
 | 			     _("Show the current CRIS version."), | 
 | 			     _("\ | 
 | Set to 10 for CRISv10 or 32 for CRISv32 if autodetection fails.\n\ | 
 | Defaults to 10. "), | 
 | 			     set_cris_version, | 
 | 			     NULL, /* FIXME: i18n: Current CRIS version | 
 | 				      is %s.  */ | 
 | 			     &setlist, &showlist); | 
 |  | 
 |   add_setshow_enum_cmd ("cris-mode", class_support,  | 
 | 			cris_modes, &usr_cmd_cris_mode,  | 
 | 			_("Set the current CRIS mode."), | 
 | 			_("Show the current CRIS mode."), | 
 | 			_("\ | 
 | Set to CRIS_MODE_GURU when debugging in guru mode.\n\ | 
 | Makes GDB use the NRP register instead of the ERP register in certain cases."), | 
 | 			set_cris_mode, | 
 | 			NULL, /* FIXME: i18n: Current CRIS version is %s.  */ | 
 | 			&setlist, &showlist); | 
 |    | 
 |   add_setshow_boolean_cmd ("cris-dwarf2-cfi", class_support, | 
 | 			   &usr_cmd_cris_dwarf2_cfi, | 
 | 			   _("Set the usage of Dwarf-2 CFI for CRIS."), | 
 | 			   _("Show the usage of Dwarf-2 CFI for CRIS."), | 
 | 			   _("Set this to \"off\" if using gcc-cris < R59."), | 
 | 			   set_cris_dwarf2_cfi, | 
 | 			   NULL, /* FIXME: i18n: Usage of Dwarf-2 CFI | 
 | 				    for CRIS is %d.  */ | 
 | 			   &setlist, &showlist); | 
 | } | 
 |  | 
 | /* Prints out all target specific values.  */ | 
 |  | 
 | static void | 
 | cris_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) | 
 | { | 
 |   cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch); | 
 |   if (tdep != NULL) | 
 |     { | 
 |       gdb_printf (file, "cris_dump_tdep: tdep->cris_version = %i\n", | 
 | 		  tdep->cris_version); | 
 |       gdb_printf (file, "cris_dump_tdep: tdep->cris_mode = %s\n", | 
 | 		  tdep->cris_mode); | 
 |       gdb_printf (file, "cris_dump_tdep: tdep->cris_dwarf2_cfi = %i\n", | 
 | 		  tdep->cris_dwarf2_cfi); | 
 |     } | 
 | } | 
 |  | 
 | static void | 
 | set_cris_version (const char *ignore_args, int from_tty,  | 
 | 		  struct cmd_list_element *c) | 
 | { | 
 |   struct gdbarch_info info; | 
 |  | 
 |   usr_cmd_cris_version_valid = 1; | 
 |    | 
 |   /* Update the current architecture, if needed.  */ | 
 |   if (!gdbarch_update_p (info)) | 
 |     internal_error (_("cris_gdbarch_update: failed to update architecture.")); | 
 | } | 
 |  | 
 | static void | 
 | set_cris_mode (const char *ignore_args, int from_tty,  | 
 | 	       struct cmd_list_element *c) | 
 | { | 
 |   struct gdbarch_info info; | 
 |  | 
 |   /* Update the current architecture, if needed.  */ | 
 |   if (!gdbarch_update_p (info)) | 
 |     internal_error ("cris_gdbarch_update: failed to update architecture."); | 
 | } | 
 |  | 
 | static void | 
 | set_cris_dwarf2_cfi (const char *ignore_args, int from_tty,  | 
 | 		     struct cmd_list_element *c) | 
 | { | 
 |   struct gdbarch_info info; | 
 |  | 
 |   /* Update the current architecture, if needed.  */ | 
 |   if (!gdbarch_update_p (info)) | 
 |     internal_error (_("cris_gdbarch_update: failed to update architecture.")); | 
 | } | 
 |  | 
 | static struct gdbarch * | 
 | cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | 
 | { | 
 |   unsigned int cris_version; | 
 |  | 
 |   if (usr_cmd_cris_version_valid) | 
 |     { | 
 |       /* Trust the user's CRIS version setting.  */  | 
 |       cris_version = usr_cmd_cris_version; | 
 |     } | 
 |   else if (info.abfd && bfd_get_mach (info.abfd) == bfd_mach_cris_v32) | 
 |     { | 
 |       cris_version = 32; | 
 |     } | 
 |   else | 
 |     { | 
 |       /* Assume it's CRIS version 10.  */ | 
 |       cris_version = 10; | 
 |     } | 
 |  | 
 |   /* Make the current settings visible to the user.  */ | 
 |   usr_cmd_cris_version = cris_version; | 
 |    | 
 |   /* Find a candidate among the list of pre-declared architectures.  */ | 
 |   for (arches = gdbarch_list_lookup_by_info (arches, &info);  | 
 |        arches != NULL; | 
 |        arches = gdbarch_list_lookup_by_info (arches->next, &info)) | 
 |     { | 
 |       cris_gdbarch_tdep *tdep | 
 | 	= gdbarch_tdep<cris_gdbarch_tdep> (arches->gdbarch); | 
 |  | 
 |       if (tdep->cris_version == usr_cmd_cris_version | 
 | 	  && tdep->cris_mode == usr_cmd_cris_mode | 
 | 	  && tdep->cris_dwarf2_cfi == usr_cmd_cris_dwarf2_cfi) | 
 | 	return arches->gdbarch; | 
 |     } | 
 |  | 
 |   /* No matching architecture was found.  Create a new one.  */ | 
 |   info.byte_order = BFD_ENDIAN_LITTLE; | 
 |   gdbarch *gdbarch | 
 |     = gdbarch_alloc (&info, gdbarch_tdep_up (new cris_gdbarch_tdep)); | 
 |   cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch); | 
 |  | 
 |   tdep->cris_version = usr_cmd_cris_version; | 
 |   tdep->cris_mode = usr_cmd_cris_mode; | 
 |   tdep->cris_dwarf2_cfi = usr_cmd_cris_dwarf2_cfi; | 
 |  | 
 |   set_gdbarch_return_value (gdbarch, cris_return_value); | 
 |   set_gdbarch_sp_regnum (gdbarch, 14); | 
 |    | 
 |   /* Length of ordinary registers used in push_word and a few other | 
 |      places.  register_size() is the real way to know how big a | 
 |      register is.  */ | 
 |  | 
 |   set_gdbarch_double_bit (gdbarch, 64); | 
 |   /* The default definition of a long double is 2 * gdbarch_double_bit, | 
 |      which means we have to set this explicitly.  */ | 
 |   set_gdbarch_long_double_bit (gdbarch, 64); | 
 |  | 
 |   /* The total amount of space needed to store (in an array called registers) | 
 |      GDB's copy of the machine's register state.  Note: We can not use | 
 |      cris_register_size at this point, since it relies on gdbarch | 
 |      being set.  */ | 
 |   switch (tdep->cris_version) | 
 |     { | 
 |     case 0: | 
 |     case 1: | 
 |     case 2: | 
 |     case 3: | 
 |     case 8: | 
 |     case 9: | 
 |       /* Old versions; not supported.  */ | 
 |       return 0; | 
 |  | 
 |     case 10: | 
 |     case 11:  | 
 |       /* CRIS v10 and v11, a.k.a. ETRAX 100LX.  In addition to ETRAX 100,  | 
 | 	 P7 (32 bits), and P15 (32 bits) have been implemented.  */ | 
 |       set_gdbarch_pc_regnum (gdbarch, 15); | 
 |       set_gdbarch_register_type (gdbarch, cris_register_type); | 
 |       /* There are 32 registers (some of which may not be implemented).  */ | 
 |       set_gdbarch_num_regs (gdbarch, 32); | 
 |       set_gdbarch_register_name (gdbarch, cris_register_name); | 
 |       set_gdbarch_cannot_store_register (gdbarch, cris_cannot_store_register); | 
 |       set_gdbarch_cannot_fetch_register (gdbarch, cris_cannot_fetch_register); | 
 |  | 
 |       set_gdbarch_software_single_step (gdbarch, cris_software_single_step); | 
 |       break; | 
 |  | 
 |     case 32: | 
 |       /* CRIS v32.  General registers R0 - R15 (32 bits), special registers  | 
 | 	 P0 - P15 (32 bits) except P0, P1, P3 (8 bits) and P4 (16 bits) | 
 | 	 and pseudo-register PC (32 bits).  */ | 
 |       set_gdbarch_pc_regnum (gdbarch, 32); | 
 |       set_gdbarch_register_type (gdbarch, crisv32_register_type); | 
 |       /* 32 registers + pseudo-register PC + 16 support registers.  */ | 
 |       set_gdbarch_num_regs (gdbarch, 32 + 1 + 16); | 
 |       set_gdbarch_register_name (gdbarch, crisv32_register_name); | 
 |  | 
 |       set_gdbarch_cannot_store_register  | 
 | 	(gdbarch, crisv32_cannot_store_register); | 
 |       set_gdbarch_cannot_fetch_register | 
 | 	(gdbarch, crisv32_cannot_fetch_register); | 
 |  | 
 |       set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); | 
 |  | 
 |       set_gdbarch_single_step_through_delay  | 
 | 	(gdbarch, crisv32_single_step_through_delay); | 
 |  | 
 |       break; | 
 |  | 
 |     default: | 
 |       /* Unknown version.  */ | 
 |       return 0; | 
 |     } | 
 |  | 
 |   /* Dummy frame functions (shared between CRISv10 and CRISv32 since they | 
 |      have the same ABI).  */ | 
 |   set_gdbarch_push_dummy_code (gdbarch, cris_push_dummy_code); | 
 |   set_gdbarch_push_dummy_call (gdbarch, cris_push_dummy_call); | 
 |   set_gdbarch_frame_align (gdbarch, cris_frame_align); | 
 |   set_gdbarch_skip_prologue (gdbarch, cris_skip_prologue); | 
 |    | 
 |   /* The stack grows downward.  */ | 
 |   set_gdbarch_inner_than (gdbarch, core_addr_lessthan); | 
 |  | 
 |   set_gdbarch_breakpoint_kind_from_pc (gdbarch, cris_breakpoint_kind_from_pc); | 
 |   set_gdbarch_sw_breakpoint_from_kind (gdbarch, cris_sw_breakpoint_from_kind); | 
 |   set_gdbarch_iterate_over_regset_sections (gdbarch, cris_iterate_over_regset_sections); | 
 |    | 
 |   if (tdep->cris_dwarf2_cfi == 1) | 
 |     { | 
 |       /* Hook in the Dwarf-2 frame sniffer.  */ | 
 |       set_gdbarch_dwarf2_reg_to_regnum (gdbarch, cris_dwarf2_reg_to_regnum); | 
 |       dwarf2_frame_set_init_reg (gdbarch, cris_dwarf2_frame_init_reg); | 
 |       dwarf2_append_unwinders (gdbarch); | 
 |     } | 
 |  | 
 |   if (tdep->cris_mode != cris_mode_guru) | 
 |     { | 
 |       frame_unwind_append_unwinder (gdbarch, &cris_sigtramp_frame_unwind); | 
 |     } | 
 |  | 
 |   frame_unwind_append_unwinder (gdbarch, &cris_frame_unwind); | 
 |   frame_base_set_default (gdbarch, &cris_frame_base); | 
 |  | 
 |   /* Hook in ABI-specific overrides, if they have been registered.  */ | 
 |   gdbarch_init_osabi (info, gdbarch); | 
 |  | 
 |   return gdbarch; | 
 | } |