When I made my patches for PR target/60203 (allow use of ISA 2.07 direct move
instructions for long double and _Decimal128), I was not aware that little
endian TDmode has the double words in big endian order, but the bytes within
the double words in little endian order in memory.  This means that normal
SUBREG's of TDmode is not allowed.  That patch broke the little endian build,
and this patch fixes it.  In this patch, I don't allow doing direct move of
TDmode in little endian.

I have done bootstraps and make check on a big endian power7, big endian
power8, and little endian power8 systems.  The two big endian systems introduce
no regressions with the patch applied and without the patch.  The little endian
system now builds, and runs the test suite.  Is this patch ok to apply?

I did not write a test case, as the normal bootstrap on a little endian power8
system will catch regressions in the future.

2014-02-18  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        PR target/60203
        * config/rs6000/rs6000.md (mov<mode>_64bit, TF/TDmode moves):
        Split 64-bit moves into 2 patterns.  Do not allow the use of
        direct move for TDmode in little endian, since the decimal value
        has little endian bytes within a word, but the 64-bit pieces are
        ordered in a big endian fashion, and normal subreg's of TDmode are
        not allowed.

-- 
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.md
===================================================================
--- gcc/config/rs6000/rs6000.md (revision 207853)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -9526,10 +9526,16 @@ (define_expand "mov<mode>"
 ;; It's important to list Y->r and r->Y before r->r because otherwise
 ;; reload, given m->r, will try to pick r->r and reload it, which
 ;; doesn't make progress.
-(define_insn_and_split "*mov<mode>_64bit"
+
+;; We can't split little endian direct moves of TDmode, because the words are
+;; not swapped like they are for TImode or TFmode.  Subregs therefore are
+;; problematical.  Don't allow direct move for this case.
+
+(define_insn_and_split "*mov<mode>_64bit_dm"
   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,Y,r,r,r,wm")
        (match_operand:FMOVE128 1 "input_operand" "d,m,d,r,YGHF,r,wm,r"))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
+   && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
    && (gpc_reg_operand (operands[0], <MODE>mode)
        || gpc_reg_operand (operands[1], <MODE>mode))"
   "#"
@@ -9538,6 +9544,18 @@ (define_insn_and_split "*mov<mode>_64bit
 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
   [(set_attr "length" "8,8,8,12,12,8,8,8")])
 
+(define_insn_and_split "*movtd_64bit_nodm"
+  [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
+       (match_operand:TD 1 "input_operand" "d,m,d,r,YGHF,r"))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
+   && (gpc_reg_operand (operands[0], TDmode)
+       || gpc_reg_operand (operands[1], TDmode))"
+  "#"
+  "&& reload_completed"
+  [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
+  [(set_attr "length" "8,8,8,12,12,8")])
+
 (define_insn_and_split "*mov<mode>_32bit"
   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
        (match_operand:FMOVE128 1 "input_operand" "d,m,d,r,YGHF,r"))]

Reply via email to