2002-08-01 Michael Snyder * mips-tdep.c (mips_eabi_reg_struct_has_addr, mips_newabi_reg_struct_has_addr, mips_oldabi_reg_struct_has_addr): New gdbarch functions. (mips_push_argument): Don't convert struct args to pointers, leave it to REG_STRUCT_HAS_ADDR. (mips_gdbarch_init): Set gdbarch_reg_struct_has_addr. Index: mips-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/mips-tdep.c,v retrieving revision 1.87 diff -c -3 -p -r1.87 mips-tdep.c *** mips-tdep.c 1 Aug 2002 21:36:27 -0000 1.87 --- mips-tdep.c 2 Aug 2002 02:01:01 -0000 *************** mips_use_struct_convention (int gcc_p, s *** 567,572 **** --- 567,606 ---- return 1; /* Structures are returned by ref in extra arg0 */ } + /* Should call_function pass struct by reference? + For each architecture, structs are passed either by + value or by reference, depending on their size. */ + + static int + mips_eabi_reg_struct_has_addr (int gcc_p, struct type *type) + { + enum type_code typecode = TYPE_CODE (check_typedef (type)); + int len = TYPE_LENGTH (check_typedef (type)); + + if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION) + return (len > MIPS_SAVED_REGSIZE); + + return 0; + } + + static int + mips_newabi_reg_struct_has_addr (int gcc_p, struct type *type) + { + enum type_code typecode = TYPE_CODE (check_typedef (type)); + int len = TYPE_LENGTH (check_typedef (type)); + + if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION) + return (len > MIPS_SAVED_REGSIZE && len % MIPS_SAVED_REGSIZE != 0); + + return 0; + } + + int + mips_oldabi_reg_struct_has_addr (int gcc_p, struct type *type) + { + return 0; /* FIXME: what should we do for old abi? */ + } + /* Tell if the program counter value in MEMADDR is in a MIPS16 function. */ static int *************** mips_push_arguments (int nargs, *** 2428,2448 **** "mips_push_arguments: %d len=%d type=%d", argnum + 1, len, (int) typecode); ! /* The EABI passes structures that do not fit in a register by ! reference. In all other cases, pass the structure by value. */ ! if (MIPS_EABI ! && len > MIPS_SAVED_REGSIZE ! && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)) ! { ! store_address (valbuf, MIPS_SAVED_REGSIZE, VALUE_ADDRESS (arg)); ! typecode = TYPE_CODE_PTR; ! len = MIPS_SAVED_REGSIZE; ! val = valbuf; ! if (mips_debug) ! fprintf_unfiltered (gdb_stdlog, " push"); ! } ! else ! val = (char *) VALUE_CONTENTS (arg); /* 32-bit ABIs always start floating point arguments in an even-numbered floating point register. Round the FP register --- 2462,2468 ---- "mips_push_arguments: %d len=%d type=%d", argnum + 1, len, (int) typecode); ! val = (char *) VALUE_CONTENTS (arg); /* 32-bit ABIs always start floating point arguments in an even-numbered floating point register. Round the FP register *************** mips_gdbarch_init (struct gdbarch_info i *** 4472,4477 **** --- 4492,4500 ---- set_gdbarch_long_bit (gdbarch, 32); set_gdbarch_ptr_bit (gdbarch, 32); set_gdbarch_long_long_bit (gdbarch, 64); + /* Set up reg_struct_has_addr. */ + set_gdbarch_reg_struct_has_addr (gdbarch, + mips_oldabi_reg_struct_has_addr); break; case MIPS_ABI_O64: tdep->mips_default_saved_regsize = 8; *************** mips_gdbarch_init (struct gdbarch_info i *** 4485,4490 **** --- 4508,4516 ---- set_gdbarch_long_bit (gdbarch, 32); set_gdbarch_ptr_bit (gdbarch, 32); set_gdbarch_long_long_bit (gdbarch, 64); + /* Set up reg_struct_has_addr. */ + set_gdbarch_reg_struct_has_addr (gdbarch, + mips_oldabi_reg_struct_has_addr); break; case MIPS_ABI_EABI32: tdep->mips_default_saved_regsize = 4; *************** mips_gdbarch_init (struct gdbarch_info i *** 4498,4503 **** --- 4524,4532 ---- set_gdbarch_long_bit (gdbarch, 32); set_gdbarch_ptr_bit (gdbarch, 32); set_gdbarch_long_long_bit (gdbarch, 64); + /* Set up reg_struct_has_addr. */ + set_gdbarch_reg_struct_has_addr (gdbarch, + mips_eabi_reg_struct_has_addr); break; case MIPS_ABI_EABI64: tdep->mips_default_saved_regsize = 8; *************** mips_gdbarch_init (struct gdbarch_info i *** 4511,4516 **** --- 4540,4548 ---- set_gdbarch_long_bit (gdbarch, 64); set_gdbarch_ptr_bit (gdbarch, 64); set_gdbarch_long_long_bit (gdbarch, 64); + /* Set up reg_struct_has_addr. */ + set_gdbarch_reg_struct_has_addr (gdbarch, + mips_eabi_reg_struct_has_addr); break; case MIPS_ABI_N32: tdep->mips_default_saved_regsize = 4; *************** mips_gdbarch_init (struct gdbarch_info i *** 4535,4540 **** --- 4567,4575 ---- tm_print_insn_info.mach = info.bfd_arch_info->mach; else tm_print_insn_info.mach = bfd_mach_mips8000; + /* Set up reg_struct_has_addr. */ + set_gdbarch_reg_struct_has_addr (gdbarch, + mips_newabi_reg_struct_has_addr); break; case MIPS_ABI_N64: tdep->mips_default_saved_regsize = 8; *************** mips_gdbarch_init (struct gdbarch_info i *** 4559,4564 **** --- 4594,4602 ---- tm_print_insn_info.mach = info.bfd_arch_info->mach; else tm_print_insn_info.mach = bfd_mach_mips8000; + /* Set up reg_struct_has_addr. */ + set_gdbarch_reg_struct_has_addr (gdbarch, + mips_newabi_reg_struct_has_addr); break; default: internal_error (__FILE__, __LINE__,