+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,
+ struct frame_info *this_frame,
+ struct cris_unwind_cache *info);
+
+static CORE_ADDR crisv32_scan_prologue (CORE_ADDR pc,
+ struct frame_info *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 stack_item
+{
+ int len;
+ struct stack_item *prev;
+ gdb_byte *data;
+};
+
+static struct stack_item *
+push_stack_item (struct stack_item *prev, const gdb_byte *contents, int len)
+{
+ struct stack_item *si = XNEW (struct stack_item);
+ si->data = (gdb_byte *) xmalloc (len);
+ si->len = len;
+ si->prev = prev;
+ memcpy (si->data, contents, len);
+ return si;
+}
+
+static struct stack_item *
+pop_stack_item (struct stack_item *si)
+{
+ struct 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 (struct frame_info *this_frame,
+ void **this_prologue_cache)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct gdbarch_tdep *tdep = 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 (struct frame_info *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 (struct frame_info *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 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 = TYPE_LENGTH (value_type (args[argnum]));
+ val = value_contents (args[argnum]);
+
+ /* 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;
+}