This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] passing float arguments on SH


The sh4 passes floating point arguments in FP registers.


2003-07-30  Michael Snyder  <msnyder@redhat.com>

	* sh-tdep.h (struct gdbarch_tdep): New member FLOAT_ARGLAST_REG.
	* sh-tdep.c (sh_gdbarch_init): For sh4, set FLOAT_ARG0_REGNUM
	and FLOAT_ARGLAST_REGNUM, to be used for argument passing.
	(sh_push_dummy_call): Use the above to pass floating point
	arguments in floating point registers when called for.

Index: sh-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.c,v
retrieving revision 1.134
diff -p -r1.134 sh-tdep.c
*** sh-tdep.c	16 Jul 2003 09:45:56 -0000	1.134
--- sh-tdep.c	30 Jul 2003 18:32:10 -0000
*************** sh64_pop_frame (void)
*** 2028,2034 ****
    flush_cached_frames ();
  }
  
! /* Function: push_arguments
     Setup the function arguments for calling a function in the inferior.
  
     On the Hitachi SH architecture, there are four registers (R4 to R7)
--- 2028,2034 ----
    flush_cached_frames ();
  }
  
! /* Function: sh_push_dummy_call (formerly push_arguments)
     Setup the function arguments for calling a function in the inferior.
  
     On the Hitachi SH architecture, there are four registers (R4 to R7)
*************** sh_push_dummy_call (struct gdbarch *gdba
*** 2079,2085 ****
  
  {
    int stack_offset, stack_alloc;
!   int argreg;
    int argnum;
    struct type *type;
    CORE_ADDR regval;
--- 2079,2085 ----
  
  {
    int stack_offset, stack_alloc;
!   int argreg, flt_argreg;
    int argnum;
    struct type *type;
    CORE_ADDR regval;
*************** sh_push_dummy_call (struct gdbarch *gdba
*** 2095,2101 ****
    /* The "struct return pointer" pseudo-argument has its own dedicated 
       register */
    if (struct_return)
!     regcache_cooked_write_unsigned (regcache, STRUCT_RETURN_REGNUM, struct_addr);
  
    /* Now make sure there's space on the stack */
    for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
--- 2095,2103 ----
    /* The "struct return pointer" pseudo-argument has its own dedicated 
       register */
    if (struct_return)
!     regcache_cooked_write_unsigned (regcache, 
! 				    STRUCT_RETURN_REGNUM, 
! 				    struct_addr);
  
    /* Now make sure there's space on the stack */
    for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
*************** sh_push_dummy_call (struct gdbarch *gdba
*** 2107,2112 ****
--- 2109,2115 ----
       in four registers available.  Loop thru args from first to last.  */
  
    argreg = tdep->ARG0_REGNUM;
+   flt_argreg = tdep->FLOAT_ARG0_REGNUM;
    for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
      {
        type = VALUE_TYPE (args[argnum]);
*************** sh_push_dummy_call (struct gdbarch *gdba
*** 2131,2137 ****
  	odd_sized_struct = 0;
        while (len > 0)
  	{
! 	  if (argreg > tdep->ARGLAST_REGNUM
  	      || odd_sized_struct)
  	    {			
  	      /* must go on the stack */
--- 2134,2142 ----
  	odd_sized_struct = 0;
        while (len > 0)
  	{
! 	  if ((TYPE_CODE (type) == TYPE_CODE_FLT 
! 	       && flt_argreg > tdep->FLOAT_ARGLAST_REGNUM) 
! 	      || argreg > tdep->ARGLAST_REGNUM
  	      || odd_sized_struct)
  	    {			
  	      /* must go on the stack */
*************** sh_push_dummy_call (struct gdbarch *gdba
*** 2141,2147 ****
  	  /* NOTE WELL!!!!!  This is not an "else if" clause!!!
  	     That's because some *&^%$ things get passed on the stack
  	     AND in the registers!   */
! 	  if (argreg <= tdep->ARGLAST_REGNUM)
  	    {			
  	      /* there's room in a register */
  	      regval = extract_unsigned_integer (val, register_size (gdbarch,
--- 2146,2160 ----
  	  /* NOTE WELL!!!!!  This is not an "else if" clause!!!
  	     That's because some *&^%$ things get passed on the stack
  	     AND in the registers!   */
! 	  if (TYPE_CODE (type) == TYPE_CODE_FLT &&
! 	      flt_argreg > 0 && flt_argreg <= tdep->FLOAT_ARGLAST_REGNUM)
! 	    {
! 	      /* Argument goes in a single-precision fp reg.  */
! 	      regval = extract_unsigned_integer (val, register_size (gdbarch,
! 								     argreg));
! 	      regcache_cooked_write_unsigned (regcache, flt_argreg++, regval);
! 	    }
! 	  else if (argreg <= tdep->ARGLAST_REGNUM)
  	    {			
  	      /* there's room in a register */
  	      regval = extract_unsigned_integer (val, register_size (gdbarch,
*************** sh_gdbarch_init (struct gdbarch_info inf
*** 4523,4528 ****
--- 4536,4543 ----
        tdep->DR_LAST_REGNUM = 66;
        tdep->FV0_REGNUM = 67;
        tdep->FV_LAST_REGNUM = 70;
+       tdep->FLOAT_ARG0_REGNUM = 29;	/* FIXME use constants! */
+       tdep->FLOAT_ARGLAST_REGNUM = 36;	/* FIXME use constants! */
  
        set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_fp_frame_init_saved_regs);
        break;
Index: sh-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.h,v
retrieving revision 1.3
diff -p -r1.3 sh-tdep.h
*** sh-tdep.h	4 Jan 2003 23:38:45 -0000	1.3
--- sh-tdep.h	30 Jul 2003 18:32:10 -0000
*************** struct gdbarch_tdep
*** 85,91 ****
      int FV_LAST_C_REGNUM; /*                            sh5-compact*/
      int ARG0_REGNUM;
      int ARGLAST_REGNUM;
!     int FLOAT_ARGLAST_REGNUM;
      int RETURN_REGNUM;
      enum sh_abi sh_abi;
    };
--- 85,92 ----
      int FV_LAST_C_REGNUM; /*                            sh5-compact*/
      int ARG0_REGNUM;
      int ARGLAST_REGNUM;
!     int FLOAT_ARG0_REGNUM;	/* sh4 */
!     int FLOAT_ARGLAST_REGNUM;	/* sh4, sh5 */
      int RETURN_REGNUM;
      enum sh_abi sh_abi;
    };

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]