diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 25 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/test_mffsl.c | 12 |
4 files changed, 34 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9c94729..b7ec138 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-04-28 Alexandre Oliva <oliva@adacore.com> + + PR target/94812 + * gcc/config/rs6000/rs6000.md (rs6000_mffsl): Copy result to + output operand in emulation. Don't overwrite pseudos. + 2020-04-28 Jeff Law <law@redhat.com> * config/h8300/h8300.md (H8/SX mult patterns): All H8/SX specific diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 11ab745..6173994 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -13620,18 +13620,19 @@ if (!TARGET_P9_MISC) { - rtx tmp_di = gen_reg_rtx (DImode); - rtx tmp_df = gen_reg_rtx (DFmode); - - /* The mffs instruction reads the entire FPSCR. Emulate the mffsl - instruction using the mffs instruction and masking off the bits - the mmsl instruciton actually reads. */ - emit_insn (gen_rs6000_mffs (tmp_df)); - tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); - emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL))); - - operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0); - DONE; + rtx tmp1 = gen_reg_rtx (DFmode); + + /* The mffs instruction reads the entire FPSCR. Emulate the mffsl + instruction using the mffs instruction and masking the result. */ + emit_insn (gen_rs6000_mffs (tmp1)); + + rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0); + rtx tmp2 = gen_reg_rtx (DImode); + emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL))); + + rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0); + emit_move_insn (operands[0], tmp2df); + DONE; } emit_insn (gen_rs6000_mffsl_hw (operands[0])); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 74755cb..d20308b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2020-04-28 Alexandre Oliva <oliva@adacore.com> + + PR target/94812 + * gcc.target/powerpc/test_mffsl.c: Call mffsl only once. + Reinterpret the doubles as long longs for compares. Mask out + mffs bits that are not expected from mffsl. + 2020-04-28 David Malcolm <dmalcolm@redhat.com> PR analyzer/94816 diff --git a/gcc/testsuite/gcc.target/powerpc/test_mffsl.c b/gcc/testsuite/gcc.target/powerpc/test_mffsl.c index 93a8ec2..41377ef 100644 --- a/gcc/testsuite/gcc.target/powerpc/test_mffsl.c +++ b/gcc/testsuite/gcc.target/powerpc/test_mffsl.c @@ -14,17 +14,21 @@ int main () union blah { double d; unsigned long long ll; - } conv_val; + } mffs_val, mffsl_val; /* Test reading the FPSCR register. */ __asm __volatile ("mffs %0" : "=f"(f14)); - conv_val.d = f14; + mffs_val.d = f14; + /* Select the same bits as mffsl. */ + mffs_val.ll &= 0x70007f0ffLL; - if (conv_val.d != __builtin_mffsl()) + mffsl_val.d = __builtin_mffsl (); + + if (mffs_val.ll != mffsl_val.ll) { #ifdef DEBUG printf("ERROR, __builtin_mffsl() returned 0x%llx, not the expecected value 0x%llx\n", - __builtin_mffsl(), conv_val.d); + mffsl_val.ll, mffs_val.ll); #else abort(); #endif |