Fix complex-5.c problem
authormeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Sep 1999 21:37:20 +0000 (21:37 +0000)
committermeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Sep 1999 21:37:20 +0000 (21:37 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@29604 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/dwarf2out.c
gcc/expr.c
gcc/tree.c

index dcca8b9..da95ab5 100644 (file)
@@ -1,3 +1,19 @@
+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.
+
 Wed Sep 22 11:34:08 EDT 1999  Andrew MacLeod  <amacleod@cygnus.com>
 
        * basic-block.h (add_noreturn_fake_exit_edges): Use correct name.
index a79339c..43d1eaa 100644 (file)
@@ -6248,9 +6248,15 @@ base_type_die (type)
       || TREE_CODE (type) == VOID_TYPE)
     return 0;
 
-  if (TREE_CODE (name) == TYPE_DECL)
-    name = DECL_NAME (name);
-  type_name = IDENTIFIER_POINTER (name);
+  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))
     {
@@ -6284,8 +6290,13 @@ base_type_die (type)
       encoding = DW_ATE_float;
       break;
 
+      /* Dwarf2 doesn't know anything about complex ints, so use
+        a user defined type for it.  */
     case COMPLEX_TYPE:
-      encoding = DW_ATE_complex_float;
+      if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)
+       encoding = DW_ATE_complex_float;
+      else
+       encoding = DW_ATE_lo_user;
       break;
 
     case BOOLEAN_TYPE:
index 39bfb49..fc08068 100644 (file)
@@ -2630,6 +2630,55 @@ emit_move_insn_1 (x, y)
        }
       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 81942ce..ec85e92 100644 (file)
@@ -4449,6 +4449,40 @@ build_complex_type (component_type)
   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;
 }
 \f