diff options
author | Richard Stallman <rms@gnu.org> | 1993-07-15 02:20:05 +0000 |
---|---|---|
committer | Richard Stallman <rms@gnu.org> | 1993-07-15 02:20:05 +0000 |
commit | fc84e8a81c6e02906f467755cca9789200251d36 (patch) | |
tree | 8bf097593aff382e9978b4983cf88e0e078f0ee0 /gcc | |
parent | 5998c7dcc3c8f1c1825d3c8dc61aec0279bb540c (diff) | |
download | gcc-fc84e8a81c6e02906f467755cca9789200251d36.zip gcc-fc84e8a81c6e02906f467755cca9789200251d36.tar.gz gcc-fc84e8a81c6e02906f467755cca9789200251d36.tar.bz2 |
(gen_lowpart_common, gen_highpart): Handle CONCAT.
(operand_subword): Likewise.
(gen_reg_rtx): For complex mode, return a CONCAT of two pseudos.
From-SVN: r4923
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/emit-rtl.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 3bc0889..04b9069 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -402,6 +402,27 @@ gen_reg_rtx (mode) if (reload_in_progress || reload_completed) 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); + } + /* Make sure regno_pointer_flag and regno_reg_rtx are large enough to have an element for this pseudo reg number. */ @@ -542,7 +563,12 @@ gen_lowpart_common (mode, x) else return gen_rtx (SUBREG, mode, x, word); } - + else if (GET_CODE (x) == CONCAT) + { + if (GET_MODE (XEXP (x, 0)) != mode) + abort (); + return XEXP (x, 0); + } /* If X is a CONST_INT or a CONST_DOUBLE, extract the appropriate bits from the low-order part of the constant. */ else if ((GET_MODE_CLASS (mode) == MODE_INT @@ -831,6 +857,12 @@ gen_highpart (mode, x) else return gen_rtx (SUBREG, mode, x, word); } + else if (GET_CODE (x) == CONCAT) + { + if (GET_MODE (XEXP (x, 1)) != mode) + abort (); + return XEXP (x, 1); + } else abort (); } @@ -924,6 +956,14 @@ operand_subword (op, i, validate_address, mode) } 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) + { + 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); + } /* Form a new MEM at the requested address. */ if (GET_CODE (op) == MEM) |