+ CORE_ADDR regval;
+
+ /* The function's arguments and memory allocated by gdb for the arguments to
+ point at reside in separate areas on the stack.
+ Both frame pointers grow toward higher addresses. */
+ CORE_ADDR fp_arg;
+ CORE_ADDR fp_mem;
+
+ 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 (struct_return)
+ {
+ 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;
+ stack_offset = 0;
+
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ int len;
+ char *val;
+ int reg_demand;
+ int i;
+
+ len = TYPE_LENGTH (value_type (args[argnum]));
+ val = (char *) 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_unsigned (regcache, argreg,
+ *(unsigned long *) 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_unsigned (regcache, argreg,
+ *(unsigned long *) 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))
+ {
+ /* FIXME */
+ internal_error (__FILE__, __LINE__, "We don't do this");
+ }
+ 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, SP_REGNUM, sp);
+
+ return sp;
+}
+
+static const struct frame_unwind cris_frame_unwind = {
+ NORMAL_FRAME,
+ cris_frame_this_id,
+ cris_frame_prev_register
+};
+
+const struct frame_unwind *
+cris_frame_sniffer (struct frame_info *next_frame)
+{
+ return &cris_frame_unwind;
+}
+
+static CORE_ADDR
+cris_frame_base_address (struct frame_info *next_frame, void **this_cache)
+{
+ struct cris_unwind_cache *info
+ = cris_frame_unwind_cache (next_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, struct frame_info *next_frame,
+ struct cris_unwind_cache *info)
+{
+ /* Present instruction. */
+ unsigned short insn;
+
+ /* Next instruction, lookahead. */
+ unsigned short insn_next;
+ int regno;
+
+ /* Is there a push fp? */
+ int have_fp;
+
+ /* Number of byte on stack used for local variables and movem. */
+ int val;
+
+ /* Highest register number in a movem. */
+ int regsave;