aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meissner <meissner@cygnus.com>1999-09-22 21:37:20 +0000
committerMichael Meissner <meissner@gcc.gnu.org>1999-09-22 21:37:20 +0000
commit405f63da1c335254a9f4c27bde94d7be7340524c (patch)
tree57b94d994167c688cb82c4a1fe633296abed1717
parentf9bd8d8e45377edd96155bc38295f483c67a973a (diff)
downloadgcc-405f63da1c335254a9f4c27bde94d7be7340524c.zip
gcc-405f63da1c335254a9f4c27bde94d7be7340524c.tar.gz
gcc-405f63da1c335254a9f4c27bde94d7be7340524c.tar.bz2
Fix complex-5.c problem
From-SVN: r29604
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/dwarf2out.c19
-rw-r--r--gcc/expr.c49
-rw-r--r--gcc/tree.c34
4 files changed, 114 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dcca8b9..da95ab5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index a79339c..43d1eaa 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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:
diff --git a/gcc/expr.c b/gcc/expr.c
index 39bfb49..fc08068 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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. */
diff --git a/gcc/tree.c b/gcc/tree.c
index 81942ce..ec85e92 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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;
}