PATCH: Replace CONCAT with RECORD_REGS (revised)
Greg McGary
gkm@eng.ascend.com
Sun Oct 31 23:33:00 GMT 1999
graham <grahams@rcp.co.uk> writes:
> In the following code I have highlighted (<<<<) 2 calls to tree_int_cst_equal ()
> which are being passed incorrect parameters, int's rather the tree nodes.
> ...
> + && tree_int_cst_equal (TYPE_ALIGN (t1), TYPE_ALIGN (t2))) <<<<
> ...
> + || !tree_int_cst_equal (DECL_FIELD_SIZE (f1),
> + DECL_FIELD_SIZE (f2)))) <<<<
> ...
> I suspect these should be replaced by "TYPE_ALIGN (t1) == TYPE_ALIGN
> (t2)" and "DECL_FIELD_SIZE (f1) != DECL_FILD_SIZE (f2)" respectively
Yes.
> The follow extract from your patch contains suspect code which I
> have highlighted (<<<<). The code is comparing a int (bytelen)
> with a tree node (TYPE_SIZE_UNIT).
>
> + && TYPE_SIZE_UNIT (TREE_TYPE (field_decl)) == bytelen) <<<<
Right again.
Thanks very much, Graham.
All of these were catchable from warnings. I had fallen into the
habit of ignoring warnings because of the many unused variable &
unused arg warnings that diluted the signal/noise. I would have done
better to filter out the unused warnings, or pass -Wno-unused, or at
least make special effort to look for warnings about pointer/int
clashes.
Here's a revised patch. ChangeLogs are the same as in the original
patch.
Index: c-common.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-common.c,v
retrieving revision 1.72
diff -u -p -r1.72 c-common.c
--- c-common.c 1999/09/24 10:06:48 1.72
+++ c-common.c 1999/10/03 20:57:09
@@ -2247,6 +2247,21 @@ type_for_mode (mode, unsignedp)
if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
return build_pointer_type (integer_type_node);
+ if (mode == TYPE_MODE (complex_integer_type_node))
+ return complex_integer_type_node;
+
+ if (mode == TYPE_MODE (complex_float_type_node))
+ return complex_float_type_node;
+
+ if (mode == TYPE_MODE (complex_double_type_node))
+ return complex_double_type_node;
+
+ if (mode == TYPE_MODE (complex_long_double_type_node))
+ return complex_long_double_type_node;
+
+ if (COMPLEX_MODE_P (mode))
+ return build_complex_type (type_for_mode (GET_MODE_UNIT_MODE (mode), 0));
+
return 0;
}
Index: c-typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-typeck.c,v
retrieving revision 1.40
diff -u -p -r1.40 c-typeck.c
--- c-typeck.c 1999/09/30 06:19:54 1.40
+++ c-typeck.c 1999/10/03 20:57:24
@@ -1,5 +1,5 @@
/* Build expressions with type checking for C compiler.
- Copyright (C) 1987, 88, 91-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 91-97, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -216,13 +216,13 @@ common_type (t1, t2)
required type. */
if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
{
- tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
- tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
+ tree subtype1 = code1 == COMPLEX_TYPE ? TYPE_COMPLEX_SUBTYPE (t1) : t1;
+ tree subtype2 = code2 == COMPLEX_TYPE ? TYPE_COMPLEX_SUBTYPE (t2) : t2;
tree subtype = common_type (subtype1, subtype2);
- if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
+ if (code1 == COMPLEX_TYPE && TYPE_COMPLEX_SUBTYPE (t1) == subtype)
return build_type_attribute_variant (t1, attributes);
- else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
+ else if (code2 == COMPLEX_TYPE && TYPE_COMPLEX_SUBTYPE (t2) == subtype)
return build_type_attribute_variant (t2, attributes);
else
return build_type_attribute_variant (build_complex_type (subtype),
@@ -2765,7 +2765,7 @@ build_unary_op (code, xarg, noconvert)
if (TREE_CODE (arg) == COMPLEX_CST)
return TREE_REALPART (arg);
else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
- return fold (build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
+ return fold (build1 (REALPART_EXPR, TYPE_COMPLEX_SUBTYPE (TREE_TYPE (arg)), arg));
else
return arg;
@@ -2773,7 +2773,7 @@ build_unary_op (code, xarg, noconvert)
if (TREE_CODE (arg) == COMPLEX_CST)
return TREE_IMAGPART (arg);
else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
- return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
+ return fold (build1 (IMAGPART_EXPR, TYPE_COMPLEX_SUBTYPE (TREE_TYPE (arg)), arg));
else
return convert (TREE_TYPE (arg), integer_zero_node);
Index: convert.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/convert.c,v
retrieving revision 1.7
diff -u -p -r1.7 convert.c
--- convert.c 1999/09/07 05:47:39 1.7
+++ convert.c 1999/10/03 20:57:25
@@ -1,5 +1,5 @@
/* Utility routines for data type conversion for GNU C.
- Copyright (C) 1987, 88, 91-95, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 91-95, 97, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU C.
@@ -92,7 +92,7 @@ convert_to_real (type, expr)
case COMPLEX_TYPE:
return convert (type,
fold (build1 (REALPART_EXPR,
- TREE_TYPE (TREE_TYPE (expr)), expr)));
+ TYPE_COMPLEX_SUBTYPE (TREE_TYPE (expr)), expr)));
case POINTER_TYPE:
case REFERENCE_TYPE:
@@ -380,7 +380,7 @@ convert_to_integer (type, expr)
case COMPLEX_TYPE:
return convert (type,
fold (build1 (REALPART_EXPR,
- TREE_TYPE (TREE_TYPE (expr)), expr)));
+ TYPE_COMPLEX_SUBTYPE (TREE_TYPE (expr)), expr)));
default:
error ("aggregate value used where an integer was expected");
@@ -394,7 +394,7 @@ tree
convert_to_complex (type, expr)
tree type, expr;
{
- tree subtype = TREE_TYPE (type);
+ tree subtype = TYPE_COMPLEX_SUBTYPE (type);
switch (TREE_CODE (TREE_TYPE (expr)))
{
@@ -408,28 +408,25 @@ convert_to_complex (type, expr)
case COMPLEX_TYPE:
{
- tree elt_type = TREE_TYPE (TREE_TYPE (expr));
+ tree elt_type = TYPE_COMPLEX_SUBTYPE (TREE_TYPE (expr));
if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
return expr;
else if (TREE_CODE (expr) == COMPLEX_EXPR)
- return fold (build (COMPLEX_EXPR,
- type,
+ return fold (build (COMPLEX_EXPR, type,
convert (subtype, TREE_OPERAND (expr, 0)),
convert (subtype, TREE_OPERAND (expr, 1))));
else
{
expr = save_expr (expr);
- return
- fold (build (COMPLEX_EXPR,
- type, convert (subtype,
- fold (build1 (REALPART_EXPR,
- TREE_TYPE (TREE_TYPE (expr)),
- expr))),
- convert (subtype,
- fold (build1 (IMAGPART_EXPR,
- TREE_TYPE (TREE_TYPE (expr)),
- expr)))));
+ elt_type = TYPE_COMPLEX_SUBTYPE (TREE_TYPE (expr));
+ return fold (build (COMPLEX_EXPR, type,
+ convert (subtype,
+ fold (build1 (REALPART_EXPR,
+ elt_type, expr))),
+ convert (subtype,
+ fold (build1 (IMAGPART_EXPR,
+ elt_type, expr)))));
}
}
Index: dbxout.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/dbxout.c,v
retrieving revision 1.38
diff -u -p -r1.38 dbxout.c
--- dbxout.c 1999/09/23 12:36:04 1.38
+++ dbxout.c 1999/10/03 20:57:32
@@ -1,5 +1,5 @@
/* Output dbx-format symbol table information from GNU compiler.
- Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-97, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -1228,13 +1228,13 @@ dbxout_type (type, full, show_arg_types)
case COMPLEX_TYPE:
/* Differs from the REAL_TYPE by its new data type number */
- if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)
+ if (TREE_CODE (TYPE_COMPLEX_SUBTYPE (type)) == REAL_TYPE)
{
fprintf (asmfile, "r");
dbxout_type_index (type);
fputc (';', asmfile);
fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
- int_size_in_bytes (TREE_TYPE (type)));
+ int_size_in_bytes (TYPE_COMPLEX_SUBTYPE (type)));
fputs (";0;", asmfile);
CHARS (12); /* The number is probably incorrect here. */
}
@@ -2119,27 +2119,26 @@ dbxout_symbol_location (decl, type, suff
letter = 'V';
current_sym_addr = XEXP (XEXP (home, 0), 0);
}
- else if (GET_CODE (home) == CONCAT)
+ else if (GET_CODE (home) == RECORD_REGS)
{
- tree subtype = TREE_TYPE (type);
-
- /* If the variable's storage is in two parts,
- output each as a separate stab with a modified name. */
- if (WORDS_BIG_ENDIAN)
- dbxout_symbol_location (decl, subtype, "$imag", XEXP (home, 0));
- else
- dbxout_symbol_location (decl, subtype, "$real", XEXP (home, 0));
-
- /* Cast avoids warning in old compilers. */
- current_sym_code = (STAB_CODE_TYPE) 0;
- current_sym_value = 0;
- current_sym_addr = 0;
- dbxout_prepare_symbol (decl);
+ int fi;
+ for (fi = 0; fi < RECORD_REGS_NUM_FIELDS (home); fi++)
+ {
+ rtx field = RECORD_REGS_FIELD (home, fi);
+ tree field_decl = FIELD_REG_DECL (field);
- if (WORDS_BIG_ENDIAN)
- dbxout_symbol_location (decl, subtype, "$real", XEXP (home, 1));
- else
- dbxout_symbol_location (decl, subtype, "$imag", XEXP (home, 1));
+ if (fi > 0)
+ {
+ /* Cast avoids warning in old compilers. */
+ current_sym_code = (STAB_CODE_TYPE) 0;
+ current_sym_value = 0;
+ current_sym_addr = 0;
+ dbxout_prepare_symbol (decl);
+ }
+ dbxout_symbol_location (decl, TREE_TYPE (field_decl),
+ IDENTIFIER_POINTER (DECL_NAME (field_decl)),
+ FIELD_REG_RTX (field));
+ }
return;
}
else
@@ -2180,10 +2179,24 @@ dbxout_symbol_name (decl, suffix, letter
char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
if (name == 0)
name = "(anon)";
- fprintf (asmfile, "%s \"%s%s:", ASM_STABS_OP, name,
- (suffix ? suffix : ""));
-
- if (letter) putc (letter, asmfile);
+ fprintf (asmfile, "%s \"%s", ASM_STABS_OP, name);
+ if (suffix)
+ {
+ /* We should always use '.' to separate decl name and suffix,
+ and gdb should be fixed to look for symbol names of the form
+ `foo.bar', after finding that struct foo is not stored in
+ memory, but rather has its fields in registers, and that
+ `bar' is the name of such a field. */
+#ifndef NO_DOLLAR_IN_LABEL
+ putc ('$', asmfile);
+#else
+ putc ('.', asmfile);
+#endif
+ fputs (suffix, asmfile);
+ }
+ putc (':', asmfile);
+ if (letter)
+ putc (letter, asmfile);
}
static void
@@ -2502,7 +2515,7 @@ dbxout_reg_parms (parms)
&& REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
dbxout_symbol_location (parms, TREE_TYPE (parms),
0, DECL_RTL (parms));
- else if (GET_CODE (DECL_RTL (parms)) == CONCAT)
+ else if (RECORD_REGS_COMPLEX_P (DECL_RTL (parms)))
dbxout_symbol_location (parms, TREE_TYPE (parms),
0, DECL_RTL (parms));
/* Report parms that live in memory but not where they were passed. */
Index: dwarf2out.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/dwarf2out.c,v
retrieving revision 1.118
diff -u -p -r1.118 dwarf2out.c
--- dwarf2out.c 1999/09/30 13:40:41 1.118
+++ dwarf2out.c 1999/10/03 20:57:59
@@ -2467,7 +2467,7 @@ static dw_loc_descr_ref reg_loc_descript
static dw_loc_descr_ref based_loc_descr PROTO((unsigned, long));
static int is_based_loc PROTO((rtx));
static dw_loc_descr_ref mem_loc_descriptor PROTO((rtx, enum machine_mode mode));
-static dw_loc_descr_ref concat_loc_descriptor PROTO((rtx, rtx));
+static dw_loc_descr_ref record_regs_loc_descriptor PROTO((rtx));
static dw_loc_descr_ref loc_descriptor PROTO((rtx));
static unsigned ceiling PROTO((unsigned, unsigned));
static tree field_type PROTO((tree));
@@ -6218,7 +6218,7 @@ base_type_die (type)
/* 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)
+ if (TREE_CODE (TYPE_COMPLEX_SUBTYPE (type)) == REAL_TYPE)
encoding = DW_ATE_complex_float;
else
encoding = DW_ATE_lo_user;
@@ -6610,23 +6610,21 @@ mem_loc_descriptor (rtl, mode)
This is typically a complex variable. */
static dw_loc_descr_ref
-concat_loc_descriptor (x0, x1)
- register rtx x0, x1;
+record_regs_loc_descriptor (strux)
+ register rtx strux;
{
dw_loc_descr_ref cc_loc_result = NULL;
+ int fi;
- if (!is_pseudo_reg (x0)
- && (GET_CODE (x0) != MEM || !is_pseudo_reg (XEXP (x0, 0))))
- add_loc_descr (&cc_loc_result, loc_descriptor (x0));
- add_loc_descr (&cc_loc_result,
- new_loc_descr (DW_OP_piece, GET_MODE_SIZE (GET_MODE (x0)), 0));
-
- if (!is_pseudo_reg (x1)
- && (GET_CODE (x1) != MEM || !is_pseudo_reg (XEXP (x1, 0))))
- add_loc_descr (&cc_loc_result, loc_descriptor (x1));
- add_loc_descr (&cc_loc_result,
- new_loc_descr (DW_OP_piece, GET_MODE_SIZE (GET_MODE (x1)), 0));
-
+ for (fi = 0; fi < RECORD_REGS_NUM_FIELDS (strux); fi++)
+ {
+ rtx x = FIELD_REG_RTX (RECORD_REGS_FIELD (strux, fi));
+ if (!is_pseudo_reg (x)
+ && (GET_CODE (x) != MEM || !is_pseudo_reg (XEXP (x, 0))))
+ add_loc_descr (&cc_loc_result, loc_descriptor (x));
+ add_loc_descr (&cc_loc_result,
+ new_loc_descr (DW_OP_piece, GET_MODE_SIZE (GET_MODE (x)), 0));
+ }
return cc_loc_result;
}
@@ -6661,8 +6659,8 @@ loc_descriptor (rtl)
loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl));
break;
- case CONCAT:
- loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1));
+ case RECORD_REGS:
+ loc_result = record_regs_loc_descriptor (rtl);
break;
default:
@@ -6872,11 +6870,17 @@ add_AT_location_description (die, attr_k
if (is_pseudo_reg (rtl)
|| (GET_CODE (rtl) == MEM
- && is_pseudo_reg (XEXP (rtl, 0)))
- || (GET_CODE (rtl) == CONCAT
- && is_pseudo_reg (XEXP (rtl, 0))
- && is_pseudo_reg (XEXP (rtl, 1))))
+ && is_pseudo_reg (XEXP (rtl, 0))))
return;
+ if (GET_CODE (rtl) == RECORD_REGS)
+ {
+ int fi;
+ for (fi = 0; fi < RECORD_REGS_NUM_FIELDS (rtl); fi++)
+ if (!is_pseudo_reg (FIELD_REG_RTX (RECORD_REGS_FIELD (rtl, fi))))
+ break;
+ if (fi == RECORD_REGS_NUM_FIELDS (rtl))
+ return;
+ }
add_AT_loc (die, attr_kind, loc_descriptor (rtl));
}
@@ -7211,7 +7215,7 @@ add_location_or_const_value_attribute (d
case MEM:
case REG:
case SUBREG:
- case CONCAT:
+ case RECORD_REGS:
add_AT_location_description (die, DW_AT_location, rtl);
break;
Index: dwarfout.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/dwarfout.c,v
retrieving revision 1.42
diff -u -p -r1.42 dwarfout.c
--- dwarfout.c 1999/09/07 02:36:27 1.42
+++ dwarfout.c 1999/10/03 20:58:13
@@ -2151,7 +2151,8 @@ sibling_attribute ()
/* Output the form of location attributes suitable for whole variables and
whole parameters. Note that the location attributes for struct fields
- are generated by the routine `data_member_location_attribute' below. */
+ stored in memory are generated by the routine
+ `data_member_location_attribute' below. */
static void
location_attribute (rtl)
@@ -2473,13 +2474,13 @@ location_or_const_value_attribute (decl)
location_attribute (rtl);
break;
- case CONCAT:
- /* ??? CONCAT is used for complex variables, which may have the real
- part stored in one place and the imag part stored somewhere else.
- DWARF1 has no way to describe a variable that lives in two different
- places, so we just describe where the first part lives, and hope that
- the second part is stored after it. */
- location_attribute (XEXP (rtl, 0));
+ case RECORD_REGS:
+ /* A RECORD_REGS rtx (e.g., complex variables) may have one part stored
+ in one place and other parts stored elsewhere. DWARF1 has no way to
+ describe a variable that lives in mulitiple different places, so we
+ just describe where the first part lives, and hope that subsequent
+ parts are stored after it. */
+ location_attribute (FIELD_REG_RTX (RECORD_REGS_FIELD (rtl, 0)));
break;
default:
Index: emit-rtl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/emit-rtl.c,v
retrieving revision 1.90
diff -u -p -r1.90 emit-rtl.c
--- emit-rtl.c 1999/09/23 20:34:19 1.90
+++ emit-rtl.c 1999/10/03 20:58:22
@@ -162,10 +162,12 @@ static rtx free_insn;
#define last_filename (current_function->emit->x_last_filename)
#define first_label_num (current_function->emit->x_first_label_num)
+static rtx gen_record_regs_rtx PROTO((tree));
static rtx make_jump_insn_raw PROTO((rtx));
static rtx make_call_insn_raw PROTO((rtx));
static rtx find_line_note PROTO((rtx));
static void mark_sequence_stack PROTO((struct sequence_stack *));
+
/* There are some RTL codes that require special attention; the generation
functions do the raw handling. If you add to this list, modify
@@ -457,26 +459,13 @@ gen_reg_rtx (mode)
if (no_new_pseudos)
abort ();
- if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
- || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
- {
- /* For complex modes, don't make a single pseudo.
- Instead, make a CONCAT of two pseudos.
- This allows noncontiguous allocation of the real and imaginary parts,
- which makes much better code. Besides, allocating DCmode
- pseudos overstrains reload on some machines like the 386. */
- rtx realpart, imagpart;
- int size = GET_MODE_UNIT_SIZE (mode);
- enum machine_mode partmode
- = mode_for_size (size * BITS_PER_UNIT,
- (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
- ? MODE_FLOAT : MODE_INT),
- 0);
-
- realpart = gen_reg_rtx (partmode);
- imagpart = gen_reg_rtx (partmode);
- return gen_rtx_CONCAT (mode, realpart, imagpart);
- }
+ /* For complex modes, don't make a single pseudo. Instead, make
+ a RECORD_REGS of two FIELD_REGs containing the pseudos. This allows
+ noncontiguous allocation of the real and imaginary parts,
+ which makes much better code. Besides, allocating DCmode
+ pseudos overstrains reload on some machines like the 386. */
+ if (COMPLEX_MODE_P (mode))
+ return gen_record_regs_rtx (TREE_TYPE (type_for_mode (mode, 0)));
/* Make sure regno_pointer_flag and regno_reg_rtx are large
enough to have an element for this pseudo reg number. */
@@ -507,16 +496,50 @@ gen_reg_rtx (mode)
return val;
}
-/* Identify REG (which may be a CONCAT) as a user register. */
+/* Generate a RECORD_REGS rtx containing fields of REG rtxes whose modes
+ match those of the fields in the record type TYPE. This process is
+ not (yet) recursive: the record type should not contain fields that
+ are record types. Only field decls with integral or floating modes
+ are recognized. */
+
+static rtx
+gen_record_regs_rtx (type)
+ tree type;
+{
+ tree field;
+ int n = list_length (TYPE_FIELDS (type));
+ rtx *vector0 = (rtx *) alloca (n * sizeof (rtx));
+ rtx *vector = vector0;
+
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) == FIELD_DECL)
+ {
+ enum machine_mode mode = DECL_MODE (field);
+ if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
+ abort ();
+ if (!INTEGRAL_MODE_P (mode) && !FLOAT_MODE_P (mode))
+ abort ();
+ *vector++ = gen_rtx_FIELD_REG (mode, gen_reg_rtx (mode), field);
+ }
+ }
+ if (vector == vector0)
+ abort ();
+ return gen_rtx_RECORD_REGS (TYPE_MODE (type),
+ gen_rtvec_v (vector - vector0, vector0), type);
+}
+/* Identify REG (which may be a RECORD_REGS) as a user register. */
+
void
mark_user_reg (reg)
rtx reg;
{
- if (GET_CODE (reg) == CONCAT)
+ if (GET_CODE (reg) == RECORD_REGS)
{
- REG_USERVAR_P (XEXP (reg, 0)) = 1;
- REG_USERVAR_P (XEXP (reg, 1)) = 1;
+ int fi;
+ for (fi = 0; fi < RECORD_REGS_NUM_FIELDS (reg); fi++)
+ REG_USERVAR_P (FIELD_REG_RTX (RECORD_REGS_FIELD (reg, fi))) = 1;
}
else if (GET_CODE (reg) == REG)
REG_USERVAR_P (reg) = 1;
@@ -872,8 +895,9 @@ gen_realpart (mode, x)
enum machine_mode mode;
register rtx x;
{
- if (GET_CODE (x) == CONCAT && GET_MODE (XEXP (x, 0)) == mode)
- return XEXP (x, 0);
+ if (RECORD_REGS_COMPLEX_P (x)
+ && GET_MODE (FIELD_REG_RTX (RECORD_REGS_COMPLEX_REAL (x))) == mode)
+ return FIELD_REG_RTX (RECORD_REGS_COMPLEX_REAL (x));
else if (WORDS_BIG_ENDIAN
&& GET_MODE_BITSIZE (mode) < BITS_PER_WORD
&& REG_P (x)
@@ -893,8 +917,9 @@ gen_imagpart (mode, x)
enum machine_mode mode;
register rtx x;
{
- if (GET_CODE (x) == CONCAT && GET_MODE (XEXP (x, 0)) == mode)
- return XEXP (x, 1);
+ if (RECORD_REGS_COMPLEX_P (x)
+ && GET_MODE (FIELD_REG_RTX (RECORD_REGS_COMPLEX_IMAG (x))) == mode)
+ return FIELD_REG_RTX (RECORD_REGS_COMPLEX_IMAG (x));
else if (WORDS_BIG_ENDIAN)
return gen_lowpart (mode, x);
else if (!WORDS_BIG_ENDIAN
@@ -1173,14 +1198,17 @@ operand_subword (op, i, validate_address
}
else if (GET_CODE (op) == SUBREG)
return gen_rtx_SUBREG (word_mode, SUBREG_REG (op), i + SUBREG_WORD (op));
- else if (GET_CODE (op) == CONCAT)
+ else if (RECORD_REGS_COMPLEX_P (op))
{
int partwords = GET_MODE_UNIT_SIZE (GET_MODE (op)) / UNITS_PER_WORD;
if (i < partwords)
- return operand_subword (XEXP (op, 0), i, validate_address, mode);
- return operand_subword (XEXP (op, 1), i - partwords,
- validate_address, mode);
+ return operand_subword (FIELD_REG_RTX (RECORD_REGS_COMPLEX_REAL (op)),
+ i, validate_address, mode);
+ return operand_subword (FIELD_REG_RTX (RECORD_REGS_COMPLEX_IMAG (op)),
+ i - partwords, validate_address, mode);
}
+ else if (GET_CODE (op) == RECORD_REGS)
+ abort ();
/* Form a new MEM at the requested address. */
if (GET_CODE (op) == MEM)
Index: expr.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/expr.c,v
retrieving revision 1.174
diff -u -p -r1.174 expr.c
--- expr.c 1999/09/23 11:34:48 1.174
+++ expr.c 1999/10/03 20:58:52
@@ -1936,15 +1936,22 @@ emit_group_load (dst, orig_src, ssize, a
plus_constant (XEXP (src, 0),
bytepos)));
}
- else if (GET_CODE (src) == CONCAT)
+ else if (GET_CODE (src) == RECORD_REGS)
{
- if (bytepos == 0
- && bytelen == GET_MODE_SIZE (GET_MODE (XEXP (src, 0))))
- tmps[i] = XEXP (src, 0);
- else if (bytepos == GET_MODE_SIZE (GET_MODE (XEXP (src, 0)))
- && bytelen == GET_MODE_SIZE (GET_MODE (XEXP (src, 1))))
- tmps[i] = XEXP (src, 1);
- else
+ int fi;
+ for (fi = 0; fi < RECORD_REGS_NUM_FIELDS (src); fi++)
+ {
+ rtx field = RECORD_REGS_FIELD (src, fi);
+ tree field_decl = FIELD_REG_DECL (field);
+ if (FIELD_REG_BYTE_OFFSET (field_decl) == bytepos
+ && (TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (field_decl)))
+ == bytelen))
+ {
+ tmps[i] = FIELD_REG_RTX (field);
+ break;
+ }
+ }
+ if (fi == RECORD_REGS_NUM_FIELDS (src))
abort ();
}
else
@@ -2592,11 +2599,7 @@ emit_move_insn_1 (x, y)
/* Expand complex moves by moving real part and imag part, if possible. */
else if ((class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
- && BLKmode != (submode = mode_for_size ((GET_MODE_UNIT_SIZE (mode)
- * BITS_PER_UNIT),
- (class == MODE_COMPLEX_INT
- ? MODE_INT : MODE_FLOAT),
- 0))
+ && BLKmode != (submode = GET_MODE_UNIT_MODE (mode))
&& (mov_optab->handlers[(int) submode].insn_code
!= CODE_FOR_nothing))
{
@@ -8077,7 +8080,7 @@ expand_expr (exp, target, tmode, modifie
}
else if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG
- || GET_CODE (op0) == CONCAT || GET_CODE (op0) == ADDRESSOF)
+ || GET_CODE (op0) == RECORD_REGS || GET_CODE (op0) == ADDRESSOF)
{
/* If this object is in a register, it must be not
be BLKmode. */
@@ -8132,7 +8135,7 @@ expand_expr (exp, target, tmode, modifie
/* COMPLEX type for Extended Pascal & Fortran */
case COMPLEX_EXPR:
{
- enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
+ enum machine_mode mode = TYPE_MODE (TYPE_COMPLEX_SUBTYPE (TREE_TYPE (exp)));
rtx insns;
/* Get the rtx code of the operands. */
@@ -8152,10 +8155,10 @@ expand_expr (exp, target, tmode, modifie
end_sequence ();
/* Complex construction should appear as a single unit. */
- /* If TARGET is a CONCAT, we got insns like RD = RS, ID = IS,
+ /* If TARGET is a RECORD_REGS, we got insns like RD = RS, ID = IS,
each with a separate pseudo as destination.
It's not correct for flow to treat them as a unit. */
- if (GET_CODE (target) != CONCAT)
+ if (GET_CODE (target) != RECORD_REGS)
emit_no_conflict_block (insns, target, op0, op1, NULL_RTX);
else
emit_insns (insns);
@@ -8173,7 +8176,7 @@ expand_expr (exp, target, tmode, modifie
case CONJ_EXPR:
{
- enum machine_mode partmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
+ enum machine_mode partmode = TYPE_MODE (TYPE_COMPLEX_SUBTYPE (TREE_TYPE (exp)));
rtx imag_t;
rtx insns;
@@ -8198,10 +8201,10 @@ expand_expr (exp, target, tmode, modifie
end_sequence ();
/* Conjugate should appear as a single unit
- If TARGET is a CONCAT, we got insns like RD = RS, ID = - IS,
+ If TARGET is a RECORD_REGS, we got insns like RD = RS, ID = - IS,
each with a separate pseudo as destination.
It's not correct for flow to treat them as a unit. */
- if (GET_CODE (target) != CONCAT)
+ if (GET_CODE (target) != RECORD_REGS)
emit_no_conflict_block (insns, target, op0, NULL_RTX, NULL_RTX);
else
emit_insns (insns);
@@ -8919,17 +8922,17 @@ do_jump (exp, if_false_label, if_true_la
(build (TRUTH_ANDIF_EXPR, TREE_TYPE (exp),
fold (build (EQ_EXPR, TREE_TYPE (exp),
fold (build1 (REALPART_EXPR,
- TREE_TYPE (inner_type),
+ TYPE_COMPLEX_SUBTYPE (inner_type),
exp0)),
fold (build1 (REALPART_EXPR,
- TREE_TYPE (inner_type),
+ TYPE_COMPLEX_SUBTYPE (inner_type),
exp1)))),
fold (build (EQ_EXPR, TREE_TYPE (exp),
fold (build1 (IMAGPART_EXPR,
- TREE_TYPE (inner_type),
+ TYPE_COMPLEX_SUBTYPE (inner_type),
exp0)),
fold (build1 (IMAGPART_EXPR,
- TREE_TYPE (inner_type),
+ TYPE_COMPLEX_SUBTYPE (inner_type),
exp1)))))),
if_false_label, if_true_label);
}
@@ -8959,17 +8962,17 @@ do_jump (exp, if_false_label, if_true_la
(build (TRUTH_ORIF_EXPR, TREE_TYPE (exp),
fold (build (NE_EXPR, TREE_TYPE (exp),
fold (build1 (REALPART_EXPR,
- TREE_TYPE (inner_type),
+ TYPE_COMPLEX_SUBTYPE (inner_type),
exp0)),
fold (build1 (REALPART_EXPR,
- TREE_TYPE (inner_type),
+ TYPE_COMPLEX_SUBTYPE (inner_type),
exp1)))),
fold (build (NE_EXPR, TREE_TYPE (exp),
fold (build1 (IMAGPART_EXPR,
- TREE_TYPE (inner_type),
+ TYPE_COMPLEX_SUBTYPE (inner_type),
exp0)),
fold (build1 (IMAGPART_EXPR,
- TREE_TYPE (inner_type),
+ TYPE_COMPLEX_SUBTYPE (inner_type),
exp1)))))),
if_false_label, if_true_label);
}
Index: fold-const.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/fold-const.c,v
retrieving revision 1.76
diff -u -p -r1.76 fold-const.c
--- fold-const.c 1999/09/20 17:12:03 1.76
+++ fold-const.c 1999/10/03 20:59:11
@@ -4714,12 +4714,12 @@ fold (expr)
return build (COMPLEX_EXPR, TREE_TYPE (arg0),
TREE_OPERAND (arg0, 0),
fold (build1 (NEGATE_EXPR,
- TREE_TYPE (TREE_TYPE (arg0)),
+ TYPE_COMPLEX_SUBTYPE (TREE_TYPE (arg0)),
TREE_OPERAND (arg0, 1))));
else if (TREE_CODE (arg0) == COMPLEX_CST)
return build_complex (type, TREE_OPERAND (arg0, 0),
fold (build1 (NEGATE_EXPR,
- TREE_TYPE (TREE_TYPE (arg0)),
+ TYPE_COMPLEX_SUBTYPE (TREE_TYPE (arg0)),
TREE_OPERAND (arg0, 1))));
else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
return fold (build (TREE_CODE (arg0), type,
@@ -6130,7 +6130,7 @@ fold (expr)
|| TREE_CODE (arg0) == COMPLEX_CST
|| TREE_CODE (arg1) == COMPLEX_CST))
{
- tree subtype = TREE_TYPE (TREE_TYPE (arg0));
+ tree subtype = TYPE_COMPLEX_SUBTYPE (TREE_TYPE (arg0));
tree real0, imag0, real1, imag1;
arg0 = save_expr (arg0);
Index: function.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/function.c,v
retrieving revision 1.118
diff -u -p -r1.118 function.c
--- function.c 1999/09/20 09:59:47 1.118
+++ function.c 1999/10/03 20:59:31
@@ -241,6 +241,7 @@ static struct fixup_replacement
*find_fixup_replacement PROTO((struct fixup_replacement **, rtx));
static void fixup_var_refs_insns PROTO((rtx, enum machine_mode, int,
rtx, int, struct hash_table *));
+static int field_rtx_matches_var (rtx, rtx);
static void fixup_var_refs_1 PROTO((rtx, enum machine_mode, rtx *, rtx,
struct fixup_replacement **));
static rtx fixup_memory_subreg PROTO((rtx, rtx, int));
@@ -1292,41 +1293,40 @@ put_var_into_stack (decl)
TREE_USED (decl) || DECL_INITIAL (decl) != 0,
0);
}
- else if (GET_CODE (reg) == CONCAT)
+ else if (GET_CODE (reg) == RECORD_REGS)
{
- /* A CONCAT contains two pseudos; put them both in the stack.
- We do it so they end up consecutive. */
- enum machine_mode part_mode = GET_MODE (XEXP (reg, 0));
- tree part_type = TREE_TYPE (TREE_TYPE (decl));
+ /* ??? Putting a RECORD_REGS onto the stack piecemeal works for
+ simple structures with uniform word alignment. For anything
+ hairier, we should allocate stack space for the entire RECORD_REGS
+ first, then compute stack addresses for moves using the
+ RECORD_TYPE's FIELD_DECL offsets. */
+ int fi;
+ rtx field0_rtx;
#ifdef FRAME_GROWS_DOWNWARD
- /* Since part 0 should have a lower address, do it second. */
- put_reg_into_stack (function, XEXP (reg, 1), part_type, part_mode,
- part_mode, TREE_SIDE_EFFECTS (decl), 0,
- TREE_USED (decl) || DECL_INITIAL (decl) != 0,
- 0);
- put_reg_into_stack (function, XEXP (reg, 0), part_type, part_mode,
- part_mode, TREE_SIDE_EFFECTS (decl), 0,
- TREE_USED (decl) || DECL_INITIAL (decl) != 0,
- 0);
+ for (fi = RECORD_REGS_NUM_FIELDS (reg) - 1; fi >= 0; fi--)
#else
- put_reg_into_stack (function, XEXP (reg, 0), part_type, part_mode,
- part_mode, TREE_SIDE_EFFECTS (decl), 0,
- TREE_USED (decl) || DECL_INITIAL (decl) != 0,
- 0);
- put_reg_into_stack (function, XEXP (reg, 1), part_type, part_mode,
- part_mode, TREE_SIDE_EFFECTS (decl), 0,
- TREE_USED (decl) || DECL_INITIAL (decl) != 0,
- 0);
+ for (fi = 0; fi < RECORD_REGS_NUM_FIELDS (reg); fi++)
#endif
+ {
+ rtx field = RECORD_REGS_FIELD (reg, fi);
+ tree field_decl = FIELD_REG_DECL (field);
+ rtx field_rtx = FIELD_REG_RTX (field);
+ put_reg_into_stack (function, field_rtx, TREE_TYPE (field_decl),
+ GET_MODE (field_rtx), DECL_MODE (field_decl),
+ TREE_SIDE_EFFECTS (decl), 0,
+ TREE_USED (decl) || DECL_INITIAL (decl) != 0,
+ 0);
+ }
- /* Change the CONCAT into a combined MEM for both parts. */
+ /* Change the RECORD_REGS into a combined MEM for both parts. */
+ field0_rtx = FIELD_REG_RTX (RECORD_REGS_FIELD (reg, 0));
PUT_CODE (reg, MEM);
- MEM_VOLATILE_P (reg) = MEM_VOLATILE_P (XEXP (reg, 0));
+ MEM_VOLATILE_P (reg) = MEM_VOLATILE_P (field0_rtx);
MEM_ALIAS_SET (reg) = get_alias_set (decl);
- /* The two parts are in memory order already.
- Use the lower parts address as ours. */
- XEXP (reg, 0) = XEXP (XEXP (reg, 0), 0);
+ /* All parts are in memory order already.
+ Use the lowest part's address as ours. */
+ XEXP (reg, 0) = XEXP (field0_rtx, 0);
/* Prevent sharing of rtl that might lose. */
if (GET_CODE (XEXP (reg, 0)) == PLUS)
XEXP (reg, 0) = copy_rtx (XEXP (reg, 0));
@@ -1530,9 +1530,8 @@ fixup_var_refs_insns (var, promoted_mode
and REG_RETVAL notes too. */
if (GET_CODE (PATTERN (insn)) == CLOBBER
&& (XEXP (PATTERN (insn), 0) == var
- || (GET_CODE (XEXP (PATTERN (insn), 0)) == CONCAT
- && (XEXP (XEXP (PATTERN (insn), 0), 0) == var
- || XEXP (XEXP (PATTERN (insn), 0), 1) == var))))
+ || (GET_CODE (XEXP (PATTERN (insn), 0)) == RECORD_REGS
+ && field_rtx_matches_var (XEXP (PATTERN (insn), 0), var))))
{
if ((note = find_reg_note (insn, REG_LIBCALL, NULL_RTX)) != 0)
/* The REG_LIBCALL note will go away since we are going to
@@ -1702,6 +1701,21 @@ fixup_var_refs_insns (var, promoted_mode
insn = NULL_RTX;
}
}
+
+/* return nonzero of VAR is the rtx of any field in STRUX. */
+
+static int
+field_rtx_matches_var (strux, var)
+ rtx strux;
+ rtx var;
+{
+ int i;
+ for (i = 0; i < RECORD_REGS_NUM_FIELDS (strux); i++)
+ if (FIELD_REG_RTX (RECORD_REGS_FIELD (strux, i)) == var)
+ return 1;
+ return 0;
+}
+
/* VAR is a MEM that used to be a pseudo register with mode PROMOTED_MODE.
See if the rtx expression at *LOC in INSN needs to be changed.
@@ -4412,7 +4426,7 @@ assign_parms (fndecl)
may need to do it in a wider mode. */
register rtx parmreg;
- int regno, regnoi = 0, regnor = 0;
+ int regno;
unsignedp = TREE_UNSIGNED (TREE_TYPE (parm));
@@ -4554,11 +4568,20 @@ assign_parms (fndecl)
/* In any case, record the parm's desired stack location
in case we later discover it must live in the stack.
- If it is a COMPLEX value, store the stack location for both
- halves. */
+ If it is a RECORD_REGS value, store the stack location for
+ all fields. */
- if (GET_CODE (parmreg) == CONCAT)
- regno = MAX (REGNO (XEXP (parmreg, 0)), REGNO (XEXP (parmreg, 1)));
+ if (GET_CODE (parmreg) == RECORD_REGS)
+ {
+ int fi;
+ regno = 0;
+ for (fi = 0; fi < RECORD_REGS_NUM_FIELDS (parmreg); fi++)
+ {
+ int regnox = REGNO (FIELD_REG_RTX (RECORD_REGS_FIELD (parmreg, fi)));
+ if (regnox > regno)
+ regno = regnox;
+ }
+ }
else
regno = REGNO (parmreg);
@@ -4578,24 +4601,25 @@ assign_parms (fndecl)
parm_reg_stack_loc = new;
}
- if (GET_CODE (parmreg) == CONCAT)
+ if (GET_CODE (parmreg) == RECORD_REGS)
{
- enum machine_mode submode = GET_MODE (XEXP (parmreg, 0));
-
- regnor = REGNO (gen_realpart (submode, parmreg));
- regnoi = REGNO (gen_imagpart (submode, parmreg));
-
- if (stack_parm != 0)
- {
- parm_reg_stack_loc[regnor]
- = gen_realpart (submode, stack_parm);
- parm_reg_stack_loc[regnoi]
- = gen_imagpart (submode, stack_parm);
- }
- else
+ int fi;
+ for (fi = 0; fi < RECORD_REGS_NUM_FIELDS (parmreg); fi++)
{
- parm_reg_stack_loc[regnor] = 0;
- parm_reg_stack_loc[regnoi] = 0;
+ rtx field = RECORD_REGS_FIELD (parmreg, fi);
+ int regnox = REGNO (FIELD_REG_RTX (field));
+ if (GET_CODE (stack_parm) != MEM)
+ abort ();
+ if (stack_parm)
+ {
+ tree field_decl = FIELD_REG_DECL (field);
+ parm_reg_stack_loc[regnox]
+ = change_address (stack_parm, DECL_MODE (field_decl),
+ plus_constant (XEXP (stack_parm, 0),
+ FIELD_REG_BYTE_OFFSET (field_decl)));
+ }
+ else
+ parm_reg_stack_loc[regnox] = 0;
}
}
else
@@ -4619,25 +4643,26 @@ assign_parms (fndecl)
rtx sinsn, set;
/* Mark complex types separately. */
- if (GET_CODE (parmreg) == CONCAT)
+ if (GET_CODE (parmreg) == RECORD_REGS)
/* Scan backwards for the set of the real and
imaginary parts. */
for (sinsn = linsn; sinsn != 0;
sinsn = prev_nonnote_insn (sinsn))
{
set = single_set (sinsn);
- if (set != 0
- && SET_DEST (set) == regno_reg_rtx [regnoi])
- REG_NOTES (sinsn)
- = gen_rtx_EXPR_LIST (REG_EQUIV,
- parm_reg_stack_loc[regnoi],
- REG_NOTES (sinsn));
- else if (set != 0
- && SET_DEST (set) == regno_reg_rtx [regnor])
- REG_NOTES (sinsn)
- = gen_rtx_EXPR_LIST (REG_EQUIV,
- parm_reg_stack_loc[regnor],
- REG_NOTES (sinsn));
+ if (set)
+ {
+ int fi;
+ for (fi = 0; fi < RECORD_REGS_NUM_FIELDS (parmreg); fi++)
+ {
+ int regnox = REGNO (FIELD_REG_RTX (RECORD_REGS_FIELD (parmreg, fi)));
+ if (SET_DEST (set) == regno_reg_rtx [regnox])
+ REG_NOTES (sinsn)
+ = gen_rtx_EXPR_LIST (REG_EQUIV,
+ parm_reg_stack_loc[regnox],
+ REG_NOTES (sinsn));
+ }
+ }
}
else if ((set = single_set (linsn)) != 0
&& SET_DEST (set) == parmreg)
Index: integrate.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/integrate.c,v
retrieving revision 1.69
diff -u -p -r1.69 integrate.c
--- integrate.c 1999/09/20 09:59:48 1.69
+++ integrate.c 1999/10/03 20:59:39
@@ -272,15 +272,15 @@ initialize_for_inline (fndecl)
if (GET_CODE (p) == REG)
parmdecl_map[REGNO (p)] = parms;
- else if (GET_CODE (p) == CONCAT)
+ else if (GET_CODE (p) == RECORD_REGS)
{
- rtx preal = gen_realpart (GET_MODE (XEXP (p, 0)), p);
- rtx pimag = gen_imagpart (GET_MODE (preal), p);
-
- if (GET_CODE (preal) == REG)
- parmdecl_map[REGNO (preal)] = parms;
- if (GET_CODE (pimag) == REG)
- parmdecl_map[REGNO (pimag)] = parms;
+ int fi;
+ for (fi = 0; fi < RECORD_REGS_NUM_FIELDS (p); fi++)
+ {
+ rtx field = FIELD_REG_RTX (RECORD_REGS_FIELD (p, fi));
+ if (GET_CODE (field) == REG)
+ parmdecl_map[REGNO (field)] = parms;
+ }
}
/* This flag is cleared later
@@ -796,10 +796,10 @@ expand_inline_function (fndecl, parms, t
}
else if (GET_CODE (loc) == REG)
process_reg_param (map, loc, copy);
- else if (GET_CODE (loc) == CONCAT)
+ else if (RECORD_REGS_COMPLEX_P (loc))
{
- rtx locreal = gen_realpart (GET_MODE (XEXP (loc, 0)), loc);
- rtx locimag = gen_imagpart (GET_MODE (XEXP (loc, 0)), loc);
+ rtx locreal = FIELD_REG_RTX (RECORD_REGS_COMPLEX_REAL (loc));
+ rtx locimag = FIELD_REG_RTX (RECORD_REGS_COMPLEX_IMAG (loc));
rtx copyreal = gen_realpart (GET_MODE (locreal), copy);
rtx copyimag = gen_imagpart (GET_MODE (locimag), copy);
@@ -1605,10 +1605,11 @@ copy_rtx_and_substitute (orig, map)
if (GET_CODE (copy) == SUBREG)
return gen_rtx_SUBREG (GET_MODE (orig), SUBREG_REG (copy),
SUBREG_WORD (orig) + SUBREG_WORD (copy));
- else if (GET_CODE (copy) == CONCAT)
+ else if (RECORD_REGS_COMPLEX_P (copy))
{
- rtx retval = subreg_realpart_p (orig) ? XEXP (copy, 0) : XEXP (copy, 1);
-
+ rtx retval = (subreg_realpart_p (orig)
+ ? FIELD_REG_RTX (RECORD_REGS_COMPLEX_REAL (copy))
+ : FIELD_REG_RTX (RECORD_REGS_COMPLEX_IMAG (copy)));
if (GET_MODE (retval) == GET_MODE (orig))
return retval;
else
@@ -1617,6 +1618,8 @@ copy_rtx_and_substitute (orig, map)
(GET_MODE_UNIT_SIZE (GET_MODE (SUBREG_REG (orig)))
/ (unsigned) UNITS_PER_WORD)));
}
+ else if (GET_CODE (copy) == RECORD_REGS)
+ abort ();
else
return gen_rtx_SUBREG (GET_MODE (orig), copy,
SUBREG_WORD (orig));
Index: machmode.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/machmode.h,v
retrieving revision 1.16
diff -u -p -r1.16 machmode.h
--- machmode.h 1999/09/21 22:31:29 1.16
+++ machmode.h 1999/10/03 20:59:40
@@ -1,5 +1,5 @@
/* Machine mode definitions for GNU C-Compiler; included by rtl.h and tree.h.
- Copyright (C) 1991, 1993, 1994, 1996, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1993, 1994, 1996, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -80,6 +80,11 @@ extern const int mode_unit_size[];
#define GET_MODE_NUNITS(MODE) \
((GET_MODE_UNIT_SIZE ((MODE)) == 0) ? 0 \
: (GET_MODE_SIZE ((MODE)) / GET_MODE_UNIT_SIZE ((MODE))))
+
+#define GET_MODE_UNIT_MODE(MODE) \
+ mode_for_size (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT, \
+ (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
+ ? MODE_FLOAT : MODE_INT), 0)
/* Get the size in bits of an object of mode MODE. */
Index: optabs.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/optabs.c,v
retrieving revision 1.53
diff -u -p -r1.53 optabs.c
--- optabs.c 1999/09/24 08:40:11 1.53
+++ optabs.c 1999/10/03 20:59:50
@@ -1433,10 +1433,7 @@ expand_binop (mode, binoptab, op0, op1,
int ok = 0;
/* Find the correct mode for the real and imaginary parts */
- enum machine_mode submode
- = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
- class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
- 0);
+ enum machine_mode submode = GET_MODE_UNIT_MODE (mode);
if (submode == BLKmode)
abort ();
@@ -2125,10 +2122,7 @@ expand_unop (mode, unoptab, op0, target,
rtx seq;
/* Find the correct mode for the real and imaginary parts */
- enum machine_mode submode
- = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
- class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
- 0);
+ enum machine_mode submode = GET_MODE_UNIT_MODE (mode);
if (submode == BLKmode)
abort ();
@@ -2343,10 +2337,7 @@ expand_complex_abs (mode, op0, target, u
rtx pat;
/* Find the correct mode for the real and imaginary parts. */
- enum machine_mode submode
- = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
- class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
- 0);
+ enum machine_mode submode = GET_MODE_UNIT_MODE (mode);
if (submode == BLKmode)
abort ();
Index: rtl.def
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/rtl.def,v
retrieving revision 1.24
diff -u -p -r1.24 rtl.def
--- rtl.def 1999/09/15 03:28:12 1.24
+++ rtl.def 1999/10/03 20:59:54
@@ -573,11 +573,16 @@ DEF_RTL_EXPR(SUBREG, "subreg", "ei", 'x'
DEF_RTL_EXPR(STRICT_LOW_PART, "strict_low_part", "e", 'x')
-/* (CONCAT a b) represents the virtual concatenation of a and b
- to make a value that has as many bits as a and b put together.
- This is used for complex values. Normally it appears only
- in DECL_RTLs and during RTL generation, but not in the insn chain. */
-DEF_RTL_EXPR(CONCAT, "concat", "ee", 'o')
+/* Represent a record type as a collection of pseudo registers
+ representing individual fields.
+ operand 0: a vector of FIELD_REGs.
+ operand 1: the RECORD_TYPE tree. */
+DEF_RTL_EXPR (RECORD_REGS, "record_regs", "Et", 'o')
+
+/* A record field.
+ operand 0: a pseudo register, or a MEM if the field's address is taken.
+ operand 1: the field's FIELD_DECL */
+DEF_RTL_EXPR (FIELD_REG, "field_reg", "et", 'o')
/* A memory location; operand is the address. Can be nested inside a
VOLATILE. The second operand is the alias set to which this MEM
Index: rtl.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/rtl.h,v
retrieving revision 1.139
diff -u -p -r1.139 rtl.h
--- rtl.h 1999/09/28 06:28:33 1.139
+++ rtl.h 1999/10/03 21:00:02
@@ -675,6 +675,24 @@ extern const char * const note_insn_name
#define ASM_OPERANDS_SOURCE_FILE(RTX) XCSTR ((RTX), 5, ASM_OPERANDS)
#define ASM_OPERANDS_SOURCE_LINE(RTX) XCINT ((RTX), 6, ASM_OPERANDS)
+/* Macros to access the slots of a RECORD_REGS rtx. */
+#define RECORD_REGS_FIELD_VEC(RTX) XCVEC ((RTX), 0, RECORD_REGS)
+#define RECORD_REGS_FIELD(RTX, I) RTVEC_ELT (RECORD_REGS_FIELD_VEC (RTX), (I))
+#define RECORD_REGS_NUM_FIELDS(RTX) GET_NUM_ELEM (RECORD_REGS_FIELD_VEC (RTX))
+#define RECORD_REGS_TYPE(RTX) XCTREE (RTX, 1, RECORD_REGS)
+
+/* Macros to access a RECORD_REGS complex rtx, which
+ replaces the old CONCAT rtx. */
+#define RECORD_REGS_COMPLEX_REAL(RTX) RECORD_REGS_FIELD (RTX, 0)
+#define RECORD_REGS_COMPLEX_IMAG(RTX) RECORD_REGS_FIELD (RTX, 1)
+#define RECORD_REGS_COMPLEX_P(RTX) (GET_CODE (RTX) == RECORD_REGS \
+ && COMPLEX_MODE_P (GET_MODE (RTX)))
+
+/* Macros to access the slots of a FIELD rtx. */
+#define FIELD_REG_RTX(RTX) XCEXP ((RTX), 0, FIELD_REG)
+#define FIELD_REG_DECL(RTX) XCTREE ((RTX), 1, FIELD_REG)
+#define FIELD_REG_BYTE_OFFSET(RTX) (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (RTX)) / BITS_PER_UNIT)
+
/* For a MEM rtx, 1 if it's a volatile reference.
Also in an ASM_OPERANDS rtx. */
#define MEM_VOLATILE_P(RTX) ((RTX)->volatil)
Index: stmt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/stmt.c,v
retrieving revision 1.99
diff -u -p -r1.99 stmt.c
--- stmt.c 1999/09/24 01:14:54 1.99
+++ stmt.c 1999/10/03 21:00:20
@@ -1690,7 +1690,7 @@ expand_asm_operands (string, outputs, in
op);
else if (GET_CODE (op) == REG
|| GET_CODE (op) == SUBREG
- || GET_CODE (op) == CONCAT)
+ || GET_CODE (op) == RECORD_REGS)
{
tree type = TREE_TYPE (TREE_VALUE (tail));
rtx memloc = assign_temp (type, 1, 1, 1);
Index: stor-layout.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/stor-layout.c,v
retrieving revision 1.33
diff -u -p -r1.33 stor-layout.c
--- stor-layout.c 1999/09/26 18:13:28 1.33
+++ stor-layout.c 1999/10/03 21:00:24
@@ -1,5 +1,5 @@
/* C-compiler utilities for types and variables storage layout
- Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-97, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -757,10 +757,10 @@ layout_type (type)
break;
case COMPLEX_TYPE:
- TREE_UNSIGNED (type) = TREE_UNSIGNED (TREE_TYPE (type));
+ TREE_UNSIGNED (type) = TREE_UNSIGNED (TYPE_COMPLEX_SUBTYPE (type));
TYPE_MODE (type)
- = mode_for_size (2 * TYPE_PRECISION (TREE_TYPE (type)),
- (TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
+ = mode_for_size (2 * TYPE_PRECISION (TYPE_COMPLEX_SUBTYPE (type)),
+ (TREE_CODE (TYPE_COMPLEX_SUBTYPE (type)) == INTEGER_TYPE
? MODE_COMPLEX_INT : MODE_COMPLEX_FLOAT),
0);
TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)), 0L);
Index: tree.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/tree.c,v
retrieving revision 1.93
diff -u -p -r1.93 tree.c
--- tree.c 1999/09/22 21:37:20 1.93
+++ tree.c 1999/10/03 21:00:35
@@ -273,6 +273,7 @@ static void set_type_quals PROTO((tree,
static void append_random_chars PROTO((char *));
static void build_real_from_int_cst_1 PROTO((PTR));
static void mark_type_hash PROTO ((void *));
+static int record_types_equal PROTO ((tree, tree));
static void fix_sizetype PROTO ((tree));
/* If non-null, a language specific helper for unsave_expr_now. */
@@ -3693,7 +3694,8 @@ type_hash_lookup (hashcode, type)
for (h = type_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next)
if (h->hashcode == hashcode
&& TREE_CODE (h->type) == TREE_CODE (type)
- && TREE_TYPE (h->type) == TREE_TYPE (type)
+ && (TREE_TYPE (h->type) == TREE_TYPE (type)
+ || record_types_equal (TREE_TYPE (h->type), TREE_TYPE (type)))
&& attribute_list_equal (TYPE_ATTRIBUTES (h->type),
TYPE_ATTRIBUTES (type))
&& TYPE_ALIGN (h->type) == TYPE_ALIGN (type)
@@ -4427,31 +4429,65 @@ build_offset_type (basetype, type)
return t;
}
+/* Compare two record types for structural equivalence. This function
+ is purpose-built for the RECORD_TYPE associated with COMPLEX_TYPE. */
+
+static int
+record_types_equal (t1, t2)
+ tree t1, t2;
+{
+ if (TREE_CODE (t1) == RECORD_TYPE
+ && TREE_CODE (t2) == RECORD_TYPE
+ && TYPE_MODE (t1) == TYPE_MODE (t2)
+ && TYPE_ALIGN (t1) == TYPE_ALIGN (t2)
+ && tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2)))
+ {
+ tree f1 = TYPE_FIELDS (t1);
+ tree f2 = TYPE_FIELDS (t2);
+ for (; f1 && f2; f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
+ if (f1 != f2 && (TREE_TYPE (f1) != TREE_TYPE (f2)
+ || DECL_NAME (f1) != DECL_NAME (f2)
+ || DECL_FIELD_SIZE (f1) != DECL_FIELD_SIZE (f2)
+ || !tree_int_cst_equal (DECL_FIELD_BITPOS (f1),
+ DECL_FIELD_BITPOS (f2))))
+ return 0;
+ return 1;
+ }
+
+ return 0;
+}
+
/* Create a complex type whose components are COMPONENT_TYPE. */
tree
build_complex_type (component_type)
tree component_type;
{
- register tree t;
+ register tree type;
+ register tree rectype;
int hashcode;
/* Make a node of the sort we want. */
- t = make_node (COMPLEX_TYPE);
-
- TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type);
- set_type_quals (t, TYPE_QUALS (component_type));
+ type = make_node (COMPLEX_TYPE);
+ rectype = make_node (RECORD_TYPE);
+ TYPE_FIELDS (rectype)
+ = chainon (build_decl (FIELD_DECL, get_identifier ("real"),
+ TYPE_MAIN_VARIANT (component_type)),
+ build_decl (FIELD_DECL, get_identifier ("imag"),
+ TYPE_MAIN_VARIANT (component_type)));
+ layout_type (rectype);
+ TREE_TYPE (type) = rectype;
+ set_type_quals (type, TYPE_QUALS (component_type));
+ layout_type (type);
+ TYPE_MODE (rectype) = TYPE_MODE (type);
/* If we already have such a type, use the old one and free this one. */
hashcode = TYPE_HASH (component_type);
- t = type_hash_canon (hashcode, t);
+ type = type_hash_canon (hashcode, 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))
+ if (write_symbols == DWARF2_DEBUG && ! TYPE_NAME (type))
{
char *name;
if (component_type == char_type_node)
@@ -4480,10 +4516,10 @@ build_complex_type (component_type)
name = (char *)0;
if (name)
- TYPE_NAME (t) = get_identifier (name);
+ TYPE_NAME (type) = get_identifier (name);
}
- return t;
+ return type;
}
/* Return OP, stripped of any conversions to wider types as much as is safe.
@@ -5284,21 +5320,10 @@ build_common_tree_nodes_2 (short_double)
TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE;
layout_type (long_double_type_node);
- complex_integer_type_node = make_node (COMPLEX_TYPE);
- TREE_TYPE (complex_integer_type_node) = integer_type_node;
- layout_type (complex_integer_type_node);
-
- complex_float_type_node = make_node (COMPLEX_TYPE);
- TREE_TYPE (complex_float_type_node) = float_type_node;
- layout_type (complex_float_type_node);
-
- complex_double_type_node = make_node (COMPLEX_TYPE);
- TREE_TYPE (complex_double_type_node) = double_type_node;
- layout_type (complex_double_type_node);
-
- complex_long_double_type_node = make_node (COMPLEX_TYPE);
- TREE_TYPE (complex_long_double_type_node) = long_double_type_node;
- layout_type (complex_long_double_type_node);
+ complex_integer_type_node = build_complex_type (integer_type_node);
+ complex_float_type_node = build_complex_type (float_type_node);
+ complex_double_type_node = build_complex_type (double_type_node);
+ complex_long_double_type_node = build_complex_type (long_double_type_node);
#ifdef BUILD_VA_LIST_TYPE
BUILD_VA_LIST_TYPE(va_list_type_node);
Index: tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/tree.h,v
retrieving revision 1.95
diff -u -p -r1.95 tree.h
--- tree.h 1999/09/30 13:40:40 1.95
+++ tree.h 1999/10/03 21:00:42
@@ -917,6 +917,9 @@ struct tree_block
compact a way as possible. */
#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->type.packed_flag)
+/* Component type of a complex type */
+#define TYPE_COMPLEX_SUBTYPE(NODE) (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (NODE))))
+
struct tree_type
{
char common[sizeof (struct tree_common)];
Index: config/sh/sh.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/sh/sh.c,v
retrieving revision 1.35
diff -u -p -r1.35 sh.c
--- sh.c 1999/09/14 23:29:48 1.35
+++ sh.c 1999/10/03 21:00:55
@@ -4122,7 +4122,7 @@ sh_va_arg (valist, type)
{
pass_as_float = ((TREE_CODE (type) == REAL_TYPE && size <= 8)
|| (TREE_CODE (type) == COMPLEX_TYPE
- && TREE_CODE (TREE_TYPE (type)) == REAL_TYPE
+ && TREE_CODE (TYPE_COMPLEX_SUBTYPE (type)) == REAL_TYPE
&& size <= 16));
}
else
Index: cp/method.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/method.c,v
retrieving revision 1.120
diff -u -p -r1.120 method.c
--- method.c 1999/10/01 04:34:24 1.120
+++ method.c 1999/10/03 21:01:01
@@ -1465,7 +1465,7 @@ process_overload_item (parmtype, extra_G
case COMPLEX_TYPE:
OB_PUTC ('J');
- build_mangled_name_for_type (TREE_TYPE (parmtype));
+ build_mangled_name_for_type (TYPE_COMPLEX_SUBTYPE (parmtype));
break;
case VOID_TYPE:
Index: cp/typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck.c,v
retrieving revision 1.219
diff -u -p -r1.219 typeck.c
--- typeck.c 1999/09/30 06:15:53 1.219
+++ typeck.c 1999/10/03 21:01:18
@@ -555,13 +555,13 @@ common_type (t1, t2)
required type. */
if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
{
- tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
- tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
+ tree subtype1 = code1 == COMPLEX_TYPE ? TYPE_COMPLEX_SUBTYPE (t1) : t1;
+ tree subtype2 = code2 == COMPLEX_TYPE ? TYPE_COMPLEX_SUBTYPE (t2) : t2;
tree subtype = common_type (subtype1, subtype2);
- if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
+ if (code1 == COMPLEX_TYPE && TYPE_COMPLEX_SUBTYPE (t1) == subtype)
return build_type_attribute_variant (t1, attributes);
- else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
+ else if (code2 == COMPLEX_TYPE && TYPE_COMPLEX_SUBTYPE (t2) == subtype)
return build_type_attribute_variant (t2, attributes);
else
return build_type_attribute_variant (build_complex_type (subtype),
@@ -1076,7 +1076,7 @@ comptypes (t1, t2, strict)
return same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2));
case COMPLEX_TYPE:
- return same_type_p (TREE_TYPE (t1), TREE_TYPE (t2));
+ return same_type_p (TYPE_COMPLEX_SUBTYPE (t1), TYPE_COMPLEX_SUBTYPE (t2));
default:
break;
@@ -4440,7 +4440,7 @@ build_unary_op (code, xarg, noconvert)
if (TREE_CODE (arg) == COMPLEX_CST)
return TREE_REALPART (arg);
else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
- return fold (build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
+ return fold (build1 (REALPART_EXPR, TYPE_COMPLEX_SUBTYPE (TREE_TYPE (arg)), arg));
else
return arg;
@@ -4448,7 +4448,7 @@ build_unary_op (code, xarg, noconvert)
if (TREE_CODE (arg) == COMPLEX_CST)
return TREE_IMAGPART (arg);
else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
- return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
+ return fold (build1 (IMAGPART_EXPR, TYPE_COMPLEX_SUBTYPE (TREE_TYPE (arg)), arg));
else
return cp_convert (TREE_TYPE (arg), integer_zero_node);
Index: f/com.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/f/com.c,v
retrieving revision 1.68
diff -u -p -r1.68 com.c
--- com.c 1999/09/24 10:07:01 1.68
+++ com.c 1999/10/03 21:01:51
@@ -1,5 +1,5 @@
/* com.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995-1998 Free Software Foundation, Inc.
+ Copyright (C) 1995-1999 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -1220,7 +1220,8 @@ ffecom_convert_narrow_ (type, expr)
if (code == COMPLEX_TYPE)
{
assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
- assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
+ assert (TYPE_PRECISION (TYPE_COMPLEX_SUBTYPE (type))
+ <= TYPE_PRECISION (TYPE_COMPLEX_SUBTYPE (TREE_TYPE (e))));
return fold (convert_to_complex (type, e));
}
if (code == RECORD_TYPE)
@@ -1293,7 +1294,8 @@ ffecom_convert_widen_ (type, expr)
if (code == COMPLEX_TYPE)
{
assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
- assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
+ assert (TYPE_PRECISION (TYPE_COMPLEX_SUBTYPE (type))
+ >= TYPE_PRECISION (TYPE_COMPLEX_SUBTYPE (TREE_TYPE (e))));
return fold (convert_to_complex (type, e));
}
if (code == RECORD_TYPE)
@@ -1323,26 +1325,27 @@ ffecom_convert_widen_ (type, expr)
static tree
ffecom_make_complex_type_ (tree subtype)
{
- tree type;
- tree realfield;
- tree imagfield;
-
+ tree rec_type;
+ tree real_field;
+ tree imag_field;
+
+ rec_type = make_node (RECORD_TYPE);
+ real_field = ffecom_decl_field (rec_type, NULL_TREE, "r", subtype);
+ imag_field = ffecom_decl_field (rec_type, real_field, "i", subtype);
+ TYPE_FIELDS (rec_type) = real_field;
+ layout_type (rec_type);
+
if (ffe_is_emulate_complex ())
- {
- type = make_node (RECORD_TYPE);
- realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
- imagfield = ffecom_decl_field (type, realfield, "i", subtype);
- TYPE_FIELDS (type) = realfield;
- layout_type (type);
- }
+ return rec_type;
else
{
- type = make_node (COMPLEX_TYPE);
- TREE_TYPE (type) = subtype;
- layout_type (type);
+ tree complex_type = make_node (COMPLEX_TYPE);
+ TREE_TYPE (rec_type) = subtype;
+ TREE_TYPE (complex_type) = rec_type;
+ layout_type (complex_type);
+ TYPE_MODE (rec_type) = TYPE_MODE (complex_type);
+ return complex_type;
}
-
- return type;
}
#endif
@@ -2610,10 +2613,13 @@ ffecom_debug_kludge_ (tree aggr, const c
break;
case ARRAY_TYPE:
- case COMPLEX_TYPE:
type_id = TREE_TYPE (type_id);
break;
+ case COMPLEX_TYPE:
+ type_id = TYPE_COMPLEX_SUBTYPE (type_id);
+ break;
+
default:
assert ("no IDENTIFIER_NODE for type!" == NULL);
type_id = error_mark_node;
@@ -3755,8 +3761,8 @@ ffecom_expr_ (ffebld expr, tree dest_tre
if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
{
- real_type = TREE_TYPE (TREE_TYPE (arg1));
- assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
+ real_type = TYPE_COMPLEX_SUBTYPE (TREE_TYPE (arg1));
+ assert (real_type == TYPE_COMPLEX_SUBTYPE (TREE_TYPE (arg2)));
}
else
{
@@ -4044,7 +4050,7 @@ ffecom_expr_intrinsic_ (ffebld expr, tre
case FFEINTRIN_impDIMAG:
case FFEINTRIN_impIMAGPART:
if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
- arg1_type = TREE_TYPE (arg1_type);
+ arg1_type = TYPE_COMPLEX_SUBTYPE (arg1_type);
else
arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
@@ -4497,7 +4503,7 @@ ffecom_expr_intrinsic_ (ffebld expr, tre
case FFEINTRIN_impREALPART:
if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
- arg1_type = TREE_TYPE (arg1_type);
+ arg1_type = TYPE_COMPLEX_SUBTYPE (arg1_type);
else
arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
@@ -9353,7 +9359,7 @@ ffecom_tree_divide_ (tree tree_type, tre
{
ffecomGfrt ix;
- if (TREE_TYPE (tree_type)
+ if (TYPE_COMPLEX_SUBTYPE (tree_type)
== ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
else
@@ -15661,10 +15667,10 @@ truthvalue_conversion (expr)
? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
integer_type_node,
truthvalue_conversion (ffecom_1 (REALPART_EXPR,
- TREE_TYPE (TREE_TYPE (expr)),
+ TYPE_COMPLEX_SUBTYPE (TREE_TYPE (expr)),
expr)),
truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
- TREE_TYPE (TREE_TYPE (expr)),
+ TYPE_COMPLEX_SUBTYPE (TREE_TYPE (expr)),
expr))));
return ffecom_2 (NE_EXPR, integer_type_node,
More information about the Gcc-patches
mailing list