- if (len <= DEPRECATED_REGISTER_SIZE)
- deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (RET_REGNUM), valbuf, len);
- else
- internal_error (__FILE__, __LINE__, "cris_abi_original_store_return_value: type length too large.");
-}
-
-/* In the CRIS ABI V2, R10 and R11 are used to store return values. */
-
-static void
-cris_abi_v2_store_return_value (struct type *type, char *valbuf)
-{
- int len = TYPE_LENGTH (type);
-
- if (len <= 2 * DEPRECATED_REGISTER_SIZE)
- {
- /* Note that this works since R10 and R11 are consecutive registers. */
- deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (RET_REGNUM),
- valbuf, len);
- }
- else
- internal_error (__FILE__, __LINE__, "cris_abi_v2_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_register_name (int regno)
-{
- static char *cris_genreg_names[] =
- { "r0", "r1", "r2", "r3", \
- "r4", "r5", "r6", "r7", \
- "r8", "r9", "r10", "r11", \
- "r12", "r13", "sp", "pc" };
-
- int i;
- int spec_regno;
-
- if (regno >= 0 && regno < NUM_GENREGS)
- {
- /* General register. */
- return cris_genreg_names[regno];
- }
- else if (regno >= NUM_GENREGS && regno < NUM_REGS)
- {
- /* Special register (R16 - R31). cris_spec_regs is zero-based.
- Adjust regno accordingly. */
- spec_regno = regno - NUM_GENREGS;
-
- /* The entries in cris_spec_regs are stored in register number order,
- which means we can shortcut into the array when searching it. */
- for (i = spec_regno; cris_spec_regs[i].name != NULL; i++)
- {
- if (cris_spec_regs[i].number == spec_regno
- && cris_spec_reg_applicable (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 NULL;
- }
- else
- {
- /* Invalid register. */
- return NULL;
- }
-}
-
-static int
-cris_register_bytes_ok (long bytes)
-{
- return (bytes == DEPRECATED_REGISTER_BYTES);
-}
-
-/* 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 original CRIS ABI, R10 is used to return values. */
-
-static void
-cris_abi_original_extract_return_value (struct type *type, char *regbuf,
- char *valbuf)
-{
- int len = TYPE_LENGTH (type);
-
- if (len <= DEPRECATED_REGISTER_SIZE)
- memcpy (valbuf, regbuf + DEPRECATED_REGISTER_BYTE (RET_REGNUM), len);
- else
- internal_error (__FILE__, __LINE__, "cris_abi_original_extract_return_value: type length too large");
-}
-
-/* In the CRIS ABI V2, R10 and R11 are used to store return values. */
-
-static void
-cris_abi_v2_extract_return_value (struct type *type, char *regbuf,
- char *valbuf)
-{
- int len = TYPE_LENGTH (type);
-
- if (len <= 2 * DEPRECATED_REGISTER_SIZE)
- memcpy (valbuf, regbuf + DEPRECATED_REGISTER_BYTE (RET_REGNUM), len);
- else
- internal_error (__FILE__, __LINE__, "cris_abi_v2_extract_return_value: type length too large");
-}
-
-/* Store the address of the place in which to copy the structure the
- subroutine will return. In the CRIS ABI, R9 is used in order to pass
- the address of the allocated area where a structure return value must
- be stored. R9 is call-clobbered, which means we must save it here for
- later use. */
-
-static void
-cris_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
-{
- write_register (STR_REGNUM, addr);
- struct_return_address = addr;
-}
-
-/* Extract from regbuf the address where a function should return a
- structure value. It's not there in the CRIS ABI, so we must do it another
- way. */
-
-static CORE_ADDR
-cris_extract_struct_value_address (char *regbuf)
-{
- return struct_return_address;
-}
-
-/* Returns 1 if the given type will be passed by pointer rather than
- directly. */
-
-/* In the original CRIS ABI, arguments shorter than or equal to 32 bits are
- passed by value. */
-
-static int
-cris_abi_original_reg_struct_has_addr (int gcc_p, struct type *type)
-{
- return (TYPE_LENGTH (type) > 4);
-}
-
-/* In the CRIS ABI V2, arguments shorter than or equal to 64 bits are passed
- by value. */
-
-static int
-cris_abi_v2_reg_struct_has_addr (int gcc_p, struct type *type)
-{
- return (TYPE_LENGTH (type) > 8);
-}
-
-/* Returns 1 if the function invocation represented by fi does not have a
- stack frame associated with it. Otherwise return 0. */
-
-static int
-cris_frameless_function_invocation (struct frame_info *fi)
-{
- if ((get_frame_type (fi) == SIGTRAMP_FRAME))
- return 0;
- else
- return frameless_look_for_prologue (fi);
-}
-
-/* See frame.h. Determines the address of all registers in the
- current stack frame storing each in frame->saved_regs. Space for
- frame->saved_regs shall be allocated by
- DEPRECATED_FRAME_INIT_SAVED_REGS using frame_saved_regs_zalloc. */
-
-static void
-cris_frame_init_saved_regs (struct frame_info *fi)
-{
- CORE_ADDR ip;
- struct symtab_and_line sal;
- int best_limit;
- char *dummy_regs = deprecated_generic_find_dummy_frame (get_frame_pc (fi),
- get_frame_base (fi));
-
- /* Examine the entire prologue. */
- int frameless_p = 0;
-
- /* Has this frame's registers already been initialized? */
- if (deprecated_get_frame_saved_regs (fi))
- return;
-
- frame_saved_regs_zalloc (fi);
-
- if (dummy_regs)
- {
- /* I don't see this ever happening, considering the context in which
- cris_frame_init_saved_regs is called (always when we're not in
- a dummy frame). */
- memcpy (deprecated_get_frame_saved_regs (fi), dummy_regs, SIZEOF_FRAME_SAVED_REGS);
- }
- else
- {
- ip = get_frame_func (fi);
- sal = find_pc_line (ip, 0);
-
- /* If there is no symbol information then sal.end == 0, and we end up
- examining only the first instruction in the function prologue.
- Exaggerating the limit seems to be harmless. */
- if (sal.end > 0)
- best_limit = sal.end;
- else
- best_limit = ip + 100;
-
- cris_examine (ip, best_limit, fi, frameless_p);
- }
-}
-
-/* Initialises the extra frame information at the creation of a new frame.
- The inparameter fromleaf is 0 when the call is from create_new_frame.
- When the call is from get_prev_frame_info, fromleaf is determined by
- cris_frameless_function_invocation. */
-
-static void
-cris_init_extra_frame_info (int fromleaf, struct frame_info *fi)
-{
- if (get_next_frame (fi))
- {
- /* Called from get_prev_frame. */
- deprecated_update_frame_pc_hack (fi, DEPRECATED_FRAME_SAVED_PC (get_next_frame (fi)));
- }
-
- frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
-
- get_frame_extra_info (fi)->return_pc = 0;
- get_frame_extra_info (fi)->leaf_function = 0;
-
- if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi),
- get_frame_base (fi),
- get_frame_base (fi)))
- {
- /* We need to setup fi->frame here because call_function_by_hand
- gets it wrong by assuming it's always FP. */
- deprecated_update_frame_base_hack (fi, deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi), SP_REGNUM));
- get_frame_extra_info (fi)->return_pc =
- deprecated_read_register_dummy (get_frame_pc (fi),
- get_frame_base (fi), PC_REGNUM);
-
- /* FIXME: Is this necessarily true? */
- get_frame_extra_info (fi)->leaf_function = 0;
- }
- else
- {
- cris_frame_init_saved_regs (fi);
-
- /* Check fromleaf/frameless_function_invocation. (FIXME) */
-
- if (deprecated_get_frame_saved_regs (fi)[SRP_REGNUM] != 0)
- {
- /* SRP was saved on the stack; non-leaf function. */
- get_frame_extra_info (fi)->return_pc =
- read_memory_integer (deprecated_get_frame_saved_regs (fi)[SRP_REGNUM],
- REGISTER_RAW_SIZE (SRP_REGNUM));
- }
- else
- {
- /* SRP is still in a register; leaf function. */
- get_frame_extra_info (fi)->return_pc = read_register (SRP_REGNUM);
- /* FIXME: Should leaf_function be set to 1 here? */
- get_frame_extra_info (fi)->leaf_function = 1;
- }
- }
-}
-
-/* Return the content of the frame pointer in the present frame. In other
- words, determine the address of the calling function's frame. */
-
-static CORE_ADDR
-cris_frame_chain (struct frame_info *fi)
-{
- if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi),
- get_frame_base (fi),
- get_frame_base (fi)))
- {
- return get_frame_base (fi);
- }
- else if (!deprecated_inside_entry_file (get_frame_pc (fi)))
- {
- return read_memory_unsigned_integer (get_frame_base (fi), 4);
- }
- else
- {
- return 0;
- }
-}
-
-/* Return the saved PC (which equals the return address) of this frame. */
-
-static CORE_ADDR
-cris_frame_saved_pc (struct frame_info *fi)
-{
- return get_frame_extra_info (fi)->return_pc;
-}
-
-/* Setup the function arguments for calling a function in the inferior. */
-
-static CORE_ADDR
-cris_abi_original_push_arguments (int nargs, struct value **args,
- CORE_ADDR sp, int struct_return,
- CORE_ADDR struct_addr)
-{
- int stack_alloc;
- int stack_offset;
- int argreg;
- int argnum;
- struct type *type;
- int len;
- CORE_ADDR regval;
- char *val;
-
- /* Data and parameters reside in different areas on the stack.
- Both frame pointers grow toward higher addresses. */
- CORE_ADDR fp_params;
- CORE_ADDR fp_data;
-
- /* 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)
- {
- write_register (STR_REGNUM, struct_addr);
- }
-
- /* Make sure there's space on the stack. Allocate space for data and a
- parameter to refer to that data. */
- for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
- stack_alloc += (TYPE_LENGTH (VALUE_TYPE (args[argnum])) + DEPRECATED_REGISTER_SIZE);
- sp -= stack_alloc;
- /* We may over-allocate a little here, but that won't hurt anything. */
-
- /* Initialize stack frame pointers. */
- fp_params = sp;
- fp_data = sp + (nargs * DEPRECATED_REGISTER_SIZE);
-
- /* 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++)
- {
- type = VALUE_TYPE (args[argnum]);
- len = TYPE_LENGTH (type);
- val = (char *) VALUE_CONTENTS (args[argnum]);
-
- if (len <= DEPRECATED_REGISTER_SIZE && argreg <= ARG4_REGNUM)
- {
- /* Data fits in a register; put it in the first available
- register. */
- write_register (argreg, *(unsigned long *) val);
- argreg++;
- }
- else if (len > DEPRECATED_REGISTER_SIZE && argreg <= ARG4_REGNUM)
- {
- /* Data does not fit in register; pass it on the stack and
- put its address in the first available register. */
- write_memory (fp_data, val, len);
- write_register (argreg, fp_data);
- fp_data += len;
- argreg++;
- }
- else if (len > DEPRECATED_REGISTER_SIZE)
- {
- /* Data does not fit in register; put both data and
- parameter on the stack. */
- write_memory (fp_data, val, len);
- write_memory (fp_params, (char *) (&fp_data), DEPRECATED_REGISTER_SIZE);
- fp_data += len;
- fp_params += DEPRECATED_REGISTER_SIZE;
- }
- else
- {
- /* Data fits in a register, but we are out of registers;
- put the parameter on the stack. */
- write_memory (fp_params, val, DEPRECATED_REGISTER_SIZE);
- fp_params += DEPRECATED_REGISTER_SIZE;
- }
- }
-
- return sp;
-}
-
-static CORE_ADDR
-cris_abi_v2_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
-{
- int stack_alloc;
- int stack_offset;
- int argreg;
- int argnum;
-
- 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;
-
- /* 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)