From 405f63da1c335254a9f4c27bde94d7be7340524c Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Wed, 22 Sep 1999 21:37:20 +0000 Subject: [PATCH] Fix complex-5.c problem From-SVN: r29604 --- gcc/ChangeLog | 16 ++++++++++++++++ gcc/dwarf2out.c | 19 +++++++++++++++---- gcc/expr.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ gcc/tree.c | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dcca8b978cb9..da95ab576bbb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +Wed Sep 22 17:35:55 1999 Michael Meissner + + * 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 * basic-block.h (add_noreturn_fake_exit_edges): Use correct name. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index a79339c32d1b..43d1eaa76248 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 39bfb4944edc..fc08068e5aa4 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 81942ce8b0f7..ec85e926b6c7 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; } -- 2.43.5