This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


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

fix for complex-5.c


I just installed the following as a bandaid fix for the complex-5
problem, until it is fixed better by providing a way for structures
and complex to live in registers as outlined in the discussion between
Greg McGary <gkm@eng.ascend.com> and myself.

Wed Sep 22 17:35:55 1999  Michael Meissner  <meissner@cygnus.com>

	* dwarf2out.c (base_type_die): Use the name __unknown__ if there
	is no name for the base type, rather than segfault.  If we are
	writing out a complex integer type, use DW_ATE_lo_user.

	* expr.c (emit_move_insn_1): If we are copying a complex that fits
	in one word or less (complex char, complex short, or on 64 bit
	systems complex float) to/from a hard register, copy it through
	memory instead of dying in gen_{real,imag}part.  If we have a
	short complex type, prevent inlining since it allocates stack
	memory.

	* tree.c (build_complex_type): If we are writing dwarf2 output,
	generate a name for complex integer types.

Index: dwarf2out.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/dwarf2out.c,v
retrieving revision 1.114
diff -p -c -r1.114 dwarf2out.c
*** dwarf2out.c	1999/09/09 21:36:19	1.114
--- dwarf2out.c	1999/09/22 21:34:35
*************** base_type_die (type)
*** 6248,6256 ****
        || TREE_CODE (type) == VOID_TYPE)
      return 0;
  
!   if (TREE_CODE (name) == TYPE_DECL)
!     name = DECL_NAME (name);
!   type_name = IDENTIFIER_POINTER (name);
  
    switch (TREE_CODE (type))
      {
--- 6248,6262 ----
        || TREE_CODE (type) == VOID_TYPE)
      return 0;
  
!   if (name)
!     {
!       if (TREE_CODE (name) == TYPE_DECL)
! 	name = DECL_NAME (name);
! 
!       type_name = IDENTIFIER_POINTER (name);
!     }
!   else
!     type_name = "__unknown__";
  
    switch (TREE_CODE (type))
      {
*************** base_type_die (type)
*** 6284,6291 ****
        encoding = DW_ATE_float;
        break;
  
      case COMPLEX_TYPE:
!       encoding = DW_ATE_complex_float;
        break;
  
      case BOOLEAN_TYPE:
--- 6290,6302 ----
        encoding = DW_ATE_float;
        break;
  
+       /* Dwarf2 doesn't know anything about complex ints, so use
+ 	 a user defined type for it.  */
      case COMPLEX_TYPE:
!       if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)
! 	encoding = DW_ATE_complex_float;
!       else
! 	encoding = DW_ATE_lo_user;
        break;
  
      case BOOLEAN_TYPE:
Index: expr.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/expr.c,v
retrieving revision 1.172
diff -p -c -r1.172 expr.c
*** expr.c	1999/09/20 09:59:44	1.172
--- expr.c	1999/09/22 21:34:41
*************** emit_move_insn_1 (x, y)
*** 2630,2635 ****
--- 2630,2684 ----
  	}
        else
  	{
+ 	  /* If this is a complex value with each part being smaller than a
+ 	     word, the usual calling sequence will likely pack the pieces into
+ 	     a single register.  Unfortunately, SUBREG of hard registers only
+ 	     deals in terms of words, so we have a problem converting input
+ 	     arguments to the CONCAT of two registers that is used elsewhere
+ 	     for complex values.  If this is before reload, we can copy it into
+ 	     memory and reload.  FIXME, we should see about using extract and
+ 	     insert on integer registers, but complex short and complex char
+ 	     variables should be rarely used.  */
+ 	  if (GET_MODE_BITSIZE (mode) < 2*BITS_PER_WORD
+ 	      && (reload_in_progress | reload_completed) == 0)
+ 	    {
+ 	      int packed_dest_p = (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER);
+ 	      int packed_src_p  = (REG_P (y) && REGNO (y) < FIRST_PSEUDO_REGISTER);
+ 
+ 	      if (packed_dest_p || packed_src_p)
+ 		{
+ 		  enum mode_class reg_class = ((class == MODE_COMPLEX_FLOAT)
+ 					       ? MODE_FLOAT : MODE_INT);
+ 
+ 		  enum machine_mode reg_mode = 
+ 		    mode_for_size (GET_MODE_BITSIZE (mode), reg_class, 1);
+ 
+ 		  if (reg_mode != BLKmode)
+ 		    {
+ 		      rtx mem = assign_stack_temp (reg_mode,
+ 						   GET_MODE_SIZE (mode), 0);
+ 
+ 		      rtx cmem = change_address (mem, mode, NULL_RTX);
+ 
+ 		      current_function->cannot_inline
+ 			= "function uses short complex types";
+ 
+ 		      if (packed_dest_p)
+ 			{
+ 			  rtx sreg = gen_rtx_SUBREG (reg_mode, x, 0);
+ 			  emit_move_insn_1 (cmem, y);
+ 			  return emit_move_insn_1 (sreg, mem);
+ 			}
+ 		      else
+ 			{
+ 			  rtx sreg = gen_rtx_SUBREG (reg_mode, y, 0);
+ 			  emit_move_insn_1 (mem, sreg);
+ 			  return emit_move_insn_1 (x, cmem);
+ 			}
+ 		    }
+ 		}
+ 	    }
+ 
  	  /* Show the output dies here.  This is necessary for pseudos;
  	     hard regs shouldn't appear here except as return values.
  	     We never want to emit such a clobber after reload.  */
Index: tree.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/tree.c,v
retrieving revision 1.92
diff -p -c -r1.92 tree.c
*** tree.c	1999/09/21 18:09:54	1.92
--- tree.c	1999/09/22 21:34:44
*************** build_complex_type (component_type)
*** 4449,4454 ****
--- 4449,4488 ----
    if (TYPE_SIZE (t) == 0)
      layout_type (t);
  
+   /* If we are writing Dwarf2 output we need to create a name,
+      since complex is a fundamental type.  */
+   if (write_symbols == DWARF2_DEBUG && ! TYPE_NAME (t))
+     {
+       char *name;
+       if (component_type == char_type_node)
+ 	name = "complex char";
+       else if (component_type == signed_char_type_node)
+ 	name = "complex signed char";
+       else if (component_type == unsigned_char_type_node)
+ 	name = "complex unsigned char";
+       else if (component_type == short_integer_type_node)
+ 	name = "complex short int";
+       else if (component_type == short_unsigned_type_node)
+ 	name = "complex short unsigned int";
+       else if (component_type == integer_type_node)
+ 	name = "complex int";
+       else if (component_type == unsigned_type_node)
+ 	name = "complex unsigned int";
+       else if (component_type == long_integer_type_node)
+ 	name = "complex long int";
+       else if (component_type == long_unsigned_type_node)
+ 	name = "complex long unsigned int";
+       else if (component_type == long_long_integer_type_node)
+ 	name = "complex long long int";
+       else if (component_type == long_long_unsigned_type_node)
+ 	name = "complex long long unsigned int";
+       else
+ 	name = (char *)0;
+ 
+       if (name)
+ 	TYPE_NAME (t) = get_identifier (name);
+     }
+ 
    return t;
  }
  


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