|
|
Sponsor |
Re: [rfc/rfa:arm] rewrite arm_push_arguments() as a single two pass loop: msg#01029gdb.patches
Hello, Hmm, with patch ... 2002-05-29 Andrew Cagney <ac131313@xxxxxxxxxx> * arm-tdep.c (arm_push_arguments): Rewrite using a two-pass loop. (arm_debug): New static variable. (_initialize_arm_tdep): Add ``set debug arm'' command. Index: arm-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/arm-tdep.c,v retrieving revision 1.62 diff -p -r1.62 arm-tdep.c *** arm-tdep.c 21 May 2002 15:36:02 -0000 1.62 --- arm-tdep.c 30 May 2002 02:30:47 -0000 *************** *** 41,46 **** --- 41,48 ---- #include "coff/internal.h" #include "elf/arm.h" + static int arm_debug; + /* Each OS has a different mechanism for accessing the various registers stored in the sigcontext structure. *************** static CORE_ADDR *** 1407,1510 **** arm_push_arguments (int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { ! char *fp; ! int argnum, argreg, nstack_size; /* Walk through the list of args and determine how large a temporary stack is required. Need to take care here as structs may be ! passed on the stack, and we have to to push them. */ ! nstack_size = -4 * REGISTER_SIZE; /* Some arguments go into A1-A4. */ ! if (struct_return) /* The struct address goes in A1. */ ! nstack_size += REGISTER_SIZE; ! ! /* Walk through the arguments and add their size to nstack_size. */ ! for (argnum = 0; argnum < nargs; argnum++) ! { ! int len; ! struct type *arg_type; ! ! arg_type = check_typedef (VALUE_TYPE (args[argnum])); ! len = TYPE_LENGTH (arg_type); ! ! nstack_size += len; ! } ! ! /* Allocate room on the stack, and initialize our stack frame ! pointer. */ ! fp = NULL; ! if (nstack_size > 0) ! { ! sp -= nstack_size; ! fp = (char *) sp; ! } ! ! /* Initialize the integer argument register pointer. */ ! argreg = ARM_A1_REGNUM; ! ! /* The struct_return pointer occupies the first parameter passing ! register. */ ! if (struct_return) ! write_register (argreg++, struct_addr); ! ! /* Process arguments from left to right. Store as many as allowed ! in the parameter passing registers (A1-A4), and save the rest on ! the temporary stack. */ ! for (argnum = 0; argnum < nargs; argnum++) ! { ! int len; ! char *val; ! CORE_ADDR regval; ! enum type_code typecode; ! struct type *arg_type, *target_type; ! ! arg_type = check_typedef (VALUE_TYPE (args[argnum])); ! target_type = TYPE_TARGET_TYPE (arg_type); ! len = TYPE_LENGTH (arg_type); ! typecode = TYPE_CODE (arg_type); ! val = (char *) VALUE_CONTENTS (args[argnum]); ! ! #if 1 ! /* I don't know why this code was disable. The only logical use ! for a function pointer is to call that function, so setting ! the mode bit is perfectly fine. FN */ ! /* If the argument is a pointer to a function, and it is a Thumb ! function, set the low bit of the pointer. */ ! if (TYPE_CODE_PTR == typecode ! && NULL != target_type ! && TYPE_CODE_FUNC == TYPE_CODE (target_type)) ! { ! CORE_ADDR regval = extract_address (val, len); ! if (arm_pc_is_thumb (regval)) ! store_address (val, len, MAKE_THUMB_ADDR (regval)); ! } ! #endif ! /* Copy the argument to general registers or the stack in ! register-sized pieces. Large arguments are split between ! registers and stack. */ ! while (len > 0) { ! int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE; ! if (argreg <= ARM_LAST_ARG_REGNUM) { ! /* It's an argument being passed in a general register. */ ! regval = extract_address (val, partial_len); ! write_register (argreg++, regval); } ! else { ! /* Push the arguments onto the stack. */ ! write_memory ((CORE_ADDR) fp, val, REGISTER_SIZE); ! fp += REGISTER_SIZE; } - len -= partial_len; - val += partial_len; } } ! /* Return adjusted stack pointer. */ ! return sp; } /* Pop the current frame. So long as the frame info has been --- 1409,1533 ---- arm_push_arguments (int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { ! CORE_ADDR fp; ! int argnum; ! int argreg; ! int nstack; ! int simd_argreg; ! int second_pass; ! struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); /* Walk through the list of args and determine how large a temporary stack is required. Need to take care here as structs may be ! passed on the stack, and we have to to push them. On the second ! pass, do the store. */ ! nstack = 0; ! fp = sp; ! for (second_pass = 0; second_pass < 2; second_pass++) ! { ! /* Compute the FP using the information computed during the ! first pass. */ ! if (second_pass) ! fp = sp - nstack; ! ! simd_argreg = 0; ! argreg = ARM_A1_REGNUM; ! nstack = 0; ! ! /* The struct_return pointer occupies the first parameter ! passing register. */ ! if (struct_return) { ! if (second_pass) ! { ! if (arm_debug) ! fprintf_unfiltered (gdb_stdlog, ! "struct return in %s = 0x%s\n", ! REGISTER_NAME (argreg), ! paddr (struct_addr)); ! write_register (argreg, struct_addr); ! } ! argreg++; ! } ! for (argnum = 0; argnum < nargs; argnum++) ! { ! int len; ! struct type *arg_type; ! struct type *target_type; ! enum type_code typecode; ! char *val; ! ! arg_type = check_typedef (VALUE_TYPE (args[argnum])); ! len = TYPE_LENGTH (arg_type); ! target_type = TYPE_TARGET_TYPE (arg_type); ! typecode = TYPE_CODE (arg_type); ! val = VALUE_CONTENTS (args[argnum]); ! ! /* If the argument is a pointer to a function, and it is a ! Thumb function, create a LOCAL copy of the value and set ! the THUMB bit in it. */ ! if (second_pass ! && TYPE_CODE_PTR == typecode ! && target_type != NULL ! && TYPE_CODE_FUNC == TYPE_CODE (target_type)) { ! CORE_ADDR regval = extract_address (val, len); ! if (arm_pc_is_thumb (regval)) ! { ! val = alloca (len); ! store_address (val, len, MAKE_THUMB_ADDR (regval)); ! } } ! ! /* Copy the argument to general registers or the stack in ! register-sized pieces. Large arguments are split between ! registers and stack. */ ! while (len > 0) { ! int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE; ! ! if (argreg <= ARM_LAST_ARG_REGNUM) ! { ! /* The argument is being passed in a general purpose ! register. */ ! if (second_pass) ! { ! CORE_ADDR regval = extract_address (val, ! partial_len); ! if (arm_debug) ! fprintf_unfiltered (gdb_stdlog, ! "arg %d in %s = 0x%s\n", ! argnum, ! REGISTER_NAME (argreg), ! phex (regval, REGISTER_SIZE)); ! write_register (argreg, regval); ! } ! argreg++; ! } ! else ! { ! if (second_pass) ! { ! /* Push the arguments onto the stack. */ ! if (arm_debug) ! fprintf_unfiltered (gdb_stdlog, ! "arg %d @ 0x%s + %d\n", ! argnum, paddr (fp), nstack); ! write_memory (fp + nstack, val, REGISTER_SIZE); ! } ! nstack += REGISTER_SIZE; ! } ! ! len -= partial_len; ! val += partial_len; } } } ! /* Return the botom of the argument list (pointed to by fp). */ ! return fp; } /* Pop the current frame. So long as the frame info has been *************** The valid values are:\n"); *** 3076,3079 **** --- 3099,3108 ---- prologue_cache.saved_regs = NULL; prologue_cache.extra_info = (struct frame_extra_info *) xcalloc (1, sizeof (struct frame_extra_info)); + + /* Debugging flag. */ + add_show_from_set (add_set_cmd ("arm", class_maintenance, var_zinteger, + &arm_debug, "Set arm debugging.\n\ + When non-zero, arm specific debugging is enabled.", &setdebuglist), + &showdebuglist); }
|
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | Re: ppc/sim multiline strings, Andrew Cagney |
|---|---|
| Next by Date: | Re: ppc/sim multiline strings, DJ Delorie |
| Previous by Thread: | [rfc/rfa:arm] rewrite arm_push_arguments() as a single two pass loop, Andrew Cagney |
| Next by Thread: | Re: [rfc/rfa:arm] rewrite arm_push_arguments() as a single two pass loop, Kevin Buettner |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
Free MagazinesCisco NewsReceive a free quarterly e-newsletter with exclusive articles on how Cisco IT uses its own products and solutions to enable the business. subscribe Systems Management News, the newspaper for IT systems administration and data center managers! Each issue of Systems Management News is chock-full of news and analysis to help you understand what's happening in your field. subscribe The Enterprise Newsweekly eWeek is the essential technology information source for builders of e-business. subscribe Oracle Magazine Oracle Magazine contains technology strategy articles, sample code, tips, Oracle and partner news, how to articles for developers and DBAs, and more. Oracle (NASDAQ: ORCL) is the world's largest enterprise software company. subscribe Total Telecom Total Telecom is "The Economist of the communications industry". subscribe |
Home | sitemap
| advertise | OSDir is
an inevitable website.
|