In backporting the power8 changes to the 4.8 branch, one of the testers of these patches noticed that libgcc cannot be built on a linux SPE target. The reason was the _Decimal64 type did not have a proper move insn in the SPE environment. This patch fixes that issue. In looking at the patch, I discovered two other thinkos that are fixed in this patch.
The first problem is the movdf/movdd insns for 32-bit without hardware floating point, checked whether we had hardware single precision support, when it should have been checking that we had hardware double precision support. The second problem was that some of the types believed they could use the floating point registers in a SPE or software emulation enviornment. So I added additional code to turn off the use of the FPRs in this case. I have done bootstraps and make check on 64-bit PowerPC linux systems with no regression. In addition, I tested the code generated using cross compilers to the Linux SPE system. Is this patch acceptible to be checked in the trunk (and to the 4.8 branch when the other patches are approved)? 2014-04-01 Michael Meissner <meiss...@linux.vnet.ibm.com> PR target/60735 * config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): If we have software floating point or no floating point registers, do not allow any type in the FPRs. Eliminate a test for SPE SIMD types in GPRs that occurs after we tested for GPRs that would never be true. * config/rs6000/rs6000.md (mov<mode>_softfloat32, FMOVE64): Rewrite tests to use TARGET_DOUBLE_FLOAT and TARGET_E500_DOUBLE, since the FMOVE64 type is DFmode/DDmode. If TARGET_E500_DOUBLE, specifically allow DDmode, since that does not use the SPE SIMD instructions. -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 208989) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -1752,6 +1752,9 @@ rs6000_hard_regno_mode_ok (int regno, en modes and DImode. */ if (FP_REGNO_P (regno)) { + if (TARGET_SOFT_FLOAT || !TARGET_FPRS) + return 0; + if (SCALAR_FLOAT_MODE_P (mode) && (mode != TDmode || (regno % 2) == 0) && FP_REGNO_P (last_regno)) @@ -1780,10 +1783,6 @@ rs6000_hard_regno_mode_ok (int regno, en return (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode) || mode == V1TImode); - /* ...but GPRs can hold SIMD data on the SPE in one register. */ - if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode)) - return 1; - /* We cannot put non-VSX TImode or PTImode anywhere except general register and it must be able to fit within the register set. */ Index: gcc/config/rs6000/rs6000.md =================================================================== --- gcc/config/rs6000/rs6000.md (revision 208989) +++ gcc/config/rs6000/rs6000.md (working copy) @@ -9394,8 +9394,9 @@ (define_insn "*mov<mode>_softfloat32" [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r") (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))] "! TARGET_POWERPC64 - && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) - || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE) + && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) + || TARGET_SOFT_FLOAT + || (<MODE>mode == DDmode && TARGET_E500_DOUBLE)) && (gpc_reg_operand (operands[0], <MODE>mode) || gpc_reg_operand (operands[1], <MODE>mode))" "#"