Building glibc for powerpc-linux-gnuspe --enable-e500-double, given the patch <https://gcc.gnu.org/ml/gcc-patches/2016-11/msg02404.html> applied, fails with errors such as:
../sysdeps/ieee754/ldbl-128ibm/s_modfl.c: In function '__modfl': ../sysdeps/ieee754/ldbl-128ibm/s_modfl.c:91:1: error: unrecognizable insn: } ^ (insn 31 30 32 2 (set (reg:DF 203) (subreg:DF (reg:TI 202) 8)) "../sysdeps/ieee754/ldbl-128ibm/s_modfl.c":44 -1 (nil)) ../sysdeps/ieee754/ldbl-128ibm/s_modfl.c:91:1: internal compiler error: in extract_insn, at recog.c:2311 This patch adds an insn pattern similar to various patterns already present to handle extracting such a subreg. This allows the glibc build to get further, until it runs into an assembler error for which I have another patch. OK to commit? gcc: 2016-11-23 Joseph Myers <jos...@codesourcery.com> * config/rs6000/spe.md (*frob_<SPE64:mode>_ti_8): New insn pattern. gcc/testsuite: 2016-11-23 Joseph Myers <jos...@codesourcery.com> * gcc.c-torture/compile/20161123-1.c: New test. Index: gcc/config/rs6000/spe.md =================================================================== --- gcc/config/rs6000/spe.md (revision 242751) +++ gcc/config/rs6000/spe.md (working copy) @@ -2314,6 +2314,18 @@ } }) +(define_insn "*frob_<SPE64:mode>_ti_8" + [(set (match_operand:SPE64 0 "nonimmediate_operand" "=r") + (subreg:SPE64 (match_operand:TI 1 "input_operand" "r") 8))] + "(TARGET_E500_DOUBLE && <SPE64:MODE>mode == DFmode) + || (TARGET_SPE && <SPE64:MODE>mode != DFmode)" +{ + if (WORDS_BIG_ENDIAN) + return "evmergelo %0,%Y1,%Z1"; + else + return "evmergelo %0,%Z1,%Y1"; +}) + (define_insn "*frob_tf_ti" [(set (match_operand:TF 0 "gpc_reg_operand" "=r") (subreg:TF (match_operand:TI 1 "gpc_reg_operand" "r") 0))] Index: gcc/testsuite/gcc.c-torture/compile/20161123-1.c =================================================================== --- gcc/testsuite/gcc.c-torture/compile/20161123-1.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/compile/20161123-1.c (working copy) @@ -0,0 +1,7 @@ +double +f (long double x) +{ + union { long double ld; double d[2]; } u; + u.ld = x; + return u.d[1]; +} -- Joseph S. Myers jos...@codesourcery.com