Commit 3ca588d3 by Maciej W. Rozycki Committed by Maciej W. Rozycki

rs6000.c (output_vec_const_move): Handle little-endian code generation.

	gcc/
	* config/rs6000/rs6000.c (output_vec_const_move): Handle
	little-endian code generation.
	* config/rs6000/spe.md (spe_evmergehi): Rename to...
	(vec_perm00_v2si): ... this.  Handle little-endian code 
	generation.
	(spe_evmergehilo): Rename to...
	(vec_perm01_v2si): ... this.  Handle little-endian code
	generation.
	(spe_evmergelo): Rename to...
	(vec_perm11_v2si): ... this.  Handle little-endian code
	generation.
	(spe_evmergelohi): Rename to...
	(vec_perm10_v2si): ... this.  Handle little-endian code
	generation.
	(spe_evmergehi, spe_evmergehilo): New expanders.
	(spe_evmergelo, spe_evmergelohi): Likewise.
	(*frob_<SPE64:mode>_<DITI:mode>): Handle little-endian code
	generation.
	(*frob_tf_ti): Likewise.
	(*frob_<mode>_di_2): Likewise.
	(*frob_tf_di_8_2): Likewise.
	(*frob_di_<mode>): Likewise.
	(*frob_ti_tf): Likewise.
	(*frob_<DITI:mode>_<SPE64:mode>_2): Likewise.
	(*frob_ti_<mode>_8_2): Likewise.
	(*frob_ti_tf_2): Likewise.
	(mov_si<mode>_e500_subreg0): Rename to...
	(mov_si<mode>_e500_subreg0_be): ... this.  Restrict to the big
	endianness only.
	(*mov_si<mode>_e500_subreg0_le): New instruction pattern.
	(*mov_si<mode>_e500_subreg0_elf_low): Rename to...
	(*mov_si<mode>_e500_subreg0_elf_low_be): ... this.  Restrict to 
	the big endianness only.
	(*mov_si<mode>_e500_subreg0_elf_low_le): New instruction pattern.
	(*mov_si<mode>_e500_subreg0_2): Rename to...
	(*mov_si<mode>_e500_subreg0_2_be): ... this.  Restrict to the
	big big endianness only.
	(*mov_si<mode>_e500_subreg0_2_le): New instruction pattern.
	(*mov_si<mode>_e500_subreg4): Rename to...
	(*mov_si<mode>_e500_subreg4_be): ... this.  Restrict to the big
	endianness only.
	(mov_si<mode>_e500_subreg4_le): New instruction pattern.
	(*mov_si<mode>_e500_subreg4_elf_low): Rename to...
	(*mov_si<mode>_e500_subreg4_elf_low_be): ... this.  Restrict to
	the big endianness only.
	(*mov_si<mode>_e500_subreg4_elf_low_le): New instruction/splitter
	pattern.
	(*mov_si<mode>_e500_subreg4_2): Rename to...
	(*mov_si<mode>_e500_subreg4_2_be): ... this.  Restrict to the big
	endianness only.
	(*mov_si<mode>_e500_subreg4_2_le): New instruction pattern.
	(*mov_sitf_e500_subreg8): Rename to...
	(*mov_sitf_e500_subreg8_be): ... this.  Restrict to the big
	endianness only.
	(*mov_sitf_e500_subreg8_le): New instruction pattern.
	(*mov_sitf_e500_subreg8_2): Rename to...
	(*mov_sitf_e500_subreg8_2_be): ... this.  Restrict to the big
	endianness only.
	(*mov_sitf_e500_subreg8_2_le): New instruction pattern.
	(*mov_sitf_e500_subreg12): Rename to...
	(*mov_sitf_e500_subreg12_be): ... this.  Restrict to the big
	endianness only.
	(*mov_sitf_e500_subreg12_le): New instruction pattern.
	(*mov_sitf_e500_subreg12_2): Rename to...
	(*mov_sitf_e500_subreg12_2_be): ... this.  Restrict to the big
	endianness only.
	(*mov_sitf_e500_subreg12_2_le): New instruction pattern.

	gcc/testsuite/
	* gcc.target/powerpc/spe-evmerge.c: New file.

From-SVN: r212335
parent e7623929
2014-07-07 Maciej W. Rozycki <macro@codesourcery.com>
* config/rs6000/rs6000.c (output_vec_const_move): Handle
little-endian code generation.
* config/rs6000/spe.md (spe_evmergehi): Rename to...
(vec_perm00_v2si): ... this. Handle little-endian code
generation.
(spe_evmergehilo): Rename to...
(vec_perm01_v2si): ... this. Handle little-endian code
generation.
(spe_evmergelo): Rename to...
(vec_perm11_v2si): ... this. Handle little-endian code
generation.
(spe_evmergelohi): Rename to...
(vec_perm10_v2si): ... this. Handle little-endian code
generation.
(spe_evmergehi, spe_evmergehilo): New expanders.
(spe_evmergelo, spe_evmergelohi): Likewise.
(*frob_<SPE64:mode>_<DITI:mode>): Handle little-endian code
generation.
(*frob_tf_ti): Likewise.
(*frob_<mode>_di_2): Likewise.
(*frob_tf_di_8_2): Likewise.
(*frob_di_<mode>): Likewise.
(*frob_ti_tf): Likewise.
(*frob_<DITI:mode>_<SPE64:mode>_2): Likewise.
(*frob_ti_<mode>_8_2): Likewise.
(*frob_ti_tf_2): Likewise.
(mov_si<mode>_e500_subreg0): Rename to...
(mov_si<mode>_e500_subreg0_be): ... this. Restrict to the big
endianness only.
(*mov_si<mode>_e500_subreg0_le): New instruction pattern.
(*mov_si<mode>_e500_subreg0_elf_low): Rename to...
(*mov_si<mode>_e500_subreg0_elf_low_be): ... this. Restrict to
the big endianness only.
(*mov_si<mode>_e500_subreg0_elf_low_le): New instruction pattern.
(*mov_si<mode>_e500_subreg0_2): Rename to...
(*mov_si<mode>_e500_subreg0_2_be): ... this. Restrict to the
big big endianness only.
(*mov_si<mode>_e500_subreg0_2_le): New instruction pattern.
(*mov_si<mode>_e500_subreg4): Rename to...
(*mov_si<mode>_e500_subreg4_be): ... this. Restrict to the big
endianness only.
(mov_si<mode>_e500_subreg4_le): New instruction pattern.
(*mov_si<mode>_e500_subreg4_elf_low): Rename to...
(*mov_si<mode>_e500_subreg4_elf_low_be): ... this. Restrict to
the big endianness only.
(*mov_si<mode>_e500_subreg4_elf_low_le): New instruction/splitter
pattern.
(*mov_si<mode>_e500_subreg4_2): Rename to...
(*mov_si<mode>_e500_subreg4_2_be): ... this. Restrict to the big
endianness only.
(*mov_si<mode>_e500_subreg4_2_le): New instruction pattern.
(*mov_sitf_e500_subreg8): Rename to...
(*mov_sitf_e500_subreg8_be): ... this. Restrict to the big
endianness only.
(*mov_sitf_e500_subreg8_le): New instruction pattern.
(*mov_sitf_e500_subreg8_2): Rename to...
(*mov_sitf_e500_subreg8_2_be): ... this. Restrict to the big
endianness only.
(*mov_sitf_e500_subreg8_2_le): New instruction pattern.
(*mov_sitf_e500_subreg12): Rename to...
(*mov_sitf_e500_subreg12_be): ... this. Restrict to the big
endianness only.
(*mov_sitf_e500_subreg12_le): New instruction pattern.
(*mov_sitf_e500_subreg12_2): Rename to...
(*mov_sitf_e500_subreg12_2_be): ... this. Restrict to the big
endianness only.
(*mov_sitf_e500_subreg12_2_le): New instruction pattern.
2014-07-07 Max Ostapenko <m.ostapenko@partner.samsung.com> 2014-07-07 Max Ostapenko <m.ostapenko@partner.samsung.com>
* asan.c (instrument_strlen_call): Do not instrument first byte in strlen * asan.c (instrument_strlen_call): Do not instrument first byte in strlen
......
...@@ -5300,8 +5300,10 @@ output_vec_const_move (rtx *operands) ...@@ -5300,8 +5300,10 @@ output_vec_const_move (rtx *operands)
operands[2] = CONST_VECTOR_ELT (vec, 1); operands[2] = CONST_VECTOR_ELT (vec, 1);
if (cst == cst2) if (cst == cst2)
return "li %0,%1\n\tevmergelo %0,%0,%0"; return "li %0,%1\n\tevmergelo %0,%0,%0";
else else if (WORDS_BIG_ENDIAN)
return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2"; return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
else
return "li %0,%2\n\tevmergelo %0,%0,%0\n\tli %0,%1";
} }
/* Initialize TARGET of vector PAIRED to VALS. */ /* Initialize TARGET of vector PAIRED to VALS. */
......
...@@ -438,7 +438,12 @@ ...@@ -438,7 +438,12 @@
[(set_attr "type" "vecload") [(set_attr "type" "vecload")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_insn "spe_evmergehi" ;; Integer vector permutation instructions. The pairs of digits in the
;; names of these instructions indicate the indices, in the memory vector
;; element ordering, of the vector elements permuted to the output vector
;; from the first and the second input vector respectively.
(define_insn "vec_perm00_v2si"
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(vec_select:V2SI (vec_select:V2SI
(vec_concat:V4SI (vec_concat:V4SI
...@@ -446,11 +451,16 @@ ...@@ -446,11 +451,16 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")) (match_operand:V2SI 2 "gpc_reg_operand" "r"))
(parallel [(const_int 0) (const_int 2)])))] (parallel [(const_int 0) (const_int 2)])))]
"TARGET_SPE" "TARGET_SPE"
"evmergehi %0,%1,%2" {
if (WORDS_BIG_ENDIAN)
return "evmergehi %0,%1,%2";
else
return "evmergelo %0,%2,%1";
}
[(set_attr "type" "vecsimple") [(set_attr "type" "vecsimple")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_insn "spe_evmergehilo" (define_insn "vec_perm01_v2si"
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(vec_select:V2SI (vec_select:V2SI
(vec_concat:V4SI (vec_concat:V4SI
...@@ -458,11 +468,16 @@ ...@@ -458,11 +468,16 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")) (match_operand:V2SI 2 "gpc_reg_operand" "r"))
(parallel [(const_int 0) (const_int 3)])))] (parallel [(const_int 0) (const_int 3)])))]
"TARGET_SPE" "TARGET_SPE"
"evmergehilo %0,%1,%2" {
if (WORDS_BIG_ENDIAN)
return "evmergehilo %0,%1,%2";
else
return "evmergehilo %0,%2,%1";
}
[(set_attr "type" "vecsimple") [(set_attr "type" "vecsimple")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_insn "spe_evmergelo" (define_insn "vec_perm11_v2si"
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(vec_select:V2SI (vec_select:V2SI
(vec_concat:V4SI (vec_concat:V4SI
...@@ -470,11 +485,16 @@ ...@@ -470,11 +485,16 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")) (match_operand:V2SI 2 "gpc_reg_operand" "r"))
(parallel [(const_int 1) (const_int 3)])))] (parallel [(const_int 1) (const_int 3)])))]
"TARGET_SPE" "TARGET_SPE"
"evmergelo %0,%1,%2" {
if (WORDS_BIG_ENDIAN)
return "evmergelo %0,%1,%2";
else
return "evmergehi %0,%2,%1";
}
[(set_attr "type" "vecsimple") [(set_attr "type" "vecsimple")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_insn "spe_evmergelohi" (define_insn "vec_perm10_v2si"
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(vec_select:V2SI (vec_select:V2SI
(vec_concat:V4SI (vec_concat:V4SI
...@@ -482,7 +502,12 @@ ...@@ -482,7 +502,12 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")) (match_operand:V2SI 2 "gpc_reg_operand" "r"))
(parallel [(const_int 1) (const_int 2)])))] (parallel [(const_int 1) (const_int 2)])))]
"TARGET_SPE" "TARGET_SPE"
"evmergelohi %0,%1,%2" {
if (WORDS_BIG_ENDIAN)
return "evmergelohi %0,%1,%2";
else
return "evmergelohi %0,%2,%1";
}
[(set_attr "type" "vecsimple") [(set_attr "type" "vecsimple")
(set_attr "length" "4")]) (set_attr "length" "4")])
...@@ -499,6 +524,60 @@ ...@@ -499,6 +524,60 @@
FAIL; FAIL;
}) })
(define_expand "spe_evmergehi"
[(match_operand:V2SI 0 "register_operand" "")
(match_operand:V2SI 1 "register_operand" "")
(match_operand:V2SI 2 "register_operand" "")]
"TARGET_SPE"
{
if (BYTES_BIG_ENDIAN)
emit_insn (gen_vec_perm00_v2si (operands[0], operands[1], operands[2]));
else
emit_insn (gen_vec_perm11_v2si (operands[0], operands[2], operands[1]));
DONE;
})
(define_expand "spe_evmergehilo"
[(match_operand:V2SI 0 "register_operand" "")
(match_operand:V2SI 1 "register_operand" "")
(match_operand:V2SI 2 "register_operand" "")]
"TARGET_SPE"
{
if (BYTES_BIG_ENDIAN)
emit_insn (gen_vec_perm01_v2si (operands[0], operands[1], operands[2]));
else
emit_insn (gen_vec_perm01_v2si (operands[0], operands[2], operands[1]));
DONE;
})
(define_expand "spe_evmergelo"
[(match_operand:V2SI 0 "register_operand" "")
(match_operand:V2SI 1 "register_operand" "")
(match_operand:V2SI 2 "register_operand" "")]
"TARGET_SPE"
{
if (BYTES_BIG_ENDIAN)
emit_insn (gen_vec_perm11_v2si (operands[0], operands[1], operands[2]));
else
emit_insn (gen_vec_perm00_v2si (operands[0], operands[2], operands[1]));
DONE;
})
(define_expand "spe_evmergelohi"
[(match_operand:V2SI 0 "register_operand" "")
(match_operand:V2SI 1 "register_operand" "")
(match_operand:V2SI 2 "register_operand" "")]
"TARGET_SPE"
{
if (BYTES_BIG_ENDIAN)
emit_insn (gen_vec_perm10_v2si (operands[0], operands[1], operands[2]));
else
emit_insn (gen_vec_perm10_v2si (operands[0], operands[2], operands[1]));
DONE;
})
;; End of integer vector permutation instructions.
(define_insn "spe_evnand" (define_insn "spe_evnand"
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(not:V2SI (and:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r") (not:V2SI (and:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")
...@@ -2220,15 +2299,31 @@ ...@@ -2220,15 +2299,31 @@
(subreg:SPE64 (match_operand:DITI 1 "input_operand" "r,m") 0))] (subreg:SPE64 (match_operand:DITI 1 "input_operand" "r,m") 0))]
"(TARGET_E500_DOUBLE && <SPE64:MODE>mode == DFmode) "(TARGET_E500_DOUBLE && <SPE64:MODE>mode == DFmode)
|| (TARGET_SPE && <SPE64:MODE>mode != DFmode)" || (TARGET_SPE && <SPE64:MODE>mode != DFmode)"
"@ {
evmergelo %0,%1,%L1 switch (which_alternative)
evldd%X1 %0,%y1") {
default:
gcc_unreachable ();
case 0:
if (WORDS_BIG_ENDIAN)
return "evmergelo %0,%1,%L1";
else
return "evmergelo %0,%L1,%1";
case 1:
return "evldd%X1 %0,%y1";
}
})
(define_insn "*frob_tf_ti" (define_insn "*frob_tf_ti"
[(set (match_operand:TF 0 "gpc_reg_operand" "=r") [(set (match_operand:TF 0 "gpc_reg_operand" "=r")
(subreg:TF (match_operand:TI 1 "gpc_reg_operand" "r") 0))] (subreg:TF (match_operand:TI 1 "gpc_reg_operand" "r") 0))]
"TARGET_E500_DOUBLE" "TARGET_E500_DOUBLE"
"evmergelo %0,%1,%L1\;evmergelo %L0,%Y1,%Z1" {
if (WORDS_BIG_ENDIAN)
return "evmergelo %0,%1,%L1\;evmergelo %L0,%Y1,%Z1";
else
return "evmergelo %L0,%Z1,%Y1\;evmergelo %0,%L1,%1";
}
[(set_attr "length" "8")]) [(set_attr "length" "8")])
(define_insn "*frob_<mode>_di_2" (define_insn "*frob_<mode>_di_2"
...@@ -2236,31 +2331,63 @@ ...@@ -2236,31 +2331,63 @@
(match_operand:DI 1 "input_operand" "r,m"))] (match_operand:DI 1 "input_operand" "r,m"))]
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) "(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)" || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
"@ {
evmergelo %0,%1,%L1 switch (which_alternative)
evldd%X1 %0,%y1") {
default:
gcc_unreachable ();
case 0:
if (WORDS_BIG_ENDIAN)
return "evmergelo %0,%1,%L1";
else
return "evmergelo %0,%L1,%1";
case 1:
return "evldd%X1 %0,%y1";
}
})
(define_insn "*frob_tf_di_8_2" (define_insn "*frob_tf_di_8_2"
[(set (subreg:DI (match_operand:TF 0 "nonimmediate_operand" "+&r,r") 8) [(set (subreg:DI (match_operand:TF 0 "nonimmediate_operand" "+&r,r") 8)
(match_operand:DI 1 "input_operand" "r,m"))] (match_operand:DI 1 "input_operand" "r,m"))]
"TARGET_E500_DOUBLE" "TARGET_E500_DOUBLE"
"@ {
evmergelo %L0,%1,%L1 switch (which_alternative)
evldd%X1 %L0,%y1") {
default:
gcc_unreachable ();
case 0:
if (WORDS_BIG_ENDIAN)
return "evmergelo %L0,%1,%L1";
else
return "evmergelo %L0,%L1,%1";
case 1:
return "evldd%X1 %L0,%y1";
}
})
(define_insn "*frob_di_<mode>" (define_insn "*frob_di_<mode>"
[(set (match_operand:DI 0 "nonimmediate_operand" "=&r") [(set (match_operand:DI 0 "nonimmediate_operand" "=&r")
(subreg:DI (match_operand:SPE64TF 1 "input_operand" "r") 0))] (subreg:DI (match_operand:SPE64TF 1 "input_operand" "r") 0))]
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) "(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)" || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
"evmergehi %0,%1,%1\;mr %L0,%1" {
if (WORDS_BIG_ENDIAN)
return "evmergehi %0,%1,%1\;mr %L0,%1";
else
return "evmergehi %L0,%1,%1\;mr %0,%1";
}
[(set_attr "length" "8")]) [(set_attr "length" "8")])
(define_insn "*frob_ti_tf" (define_insn "*frob_ti_tf"
[(set (match_operand:TI 0 "nonimmediate_operand" "=&r") [(set (match_operand:TI 0 "nonimmediate_operand" "=&r")
(subreg:TI (match_operand:TF 1 "input_operand" "r") 0))] (subreg:TI (match_operand:TF 1 "input_operand" "r") 0))]
"TARGET_E500_DOUBLE" "TARGET_E500_DOUBLE"
"evmergehi %0,%1,%1\;mr %L0,%1\;evmergehi %Y0,%L1,%L1\;mr %Z0,%L1" {
if (WORDS_BIG_ENDIAN)
return "evmergehi %0,%1,%1\;mr %L0,%1\;evmergehi %Y0,%L1,%L1\;mr %Z0,%L1";
else
return "evmergehi %Z0,%L1,%L1\;mr %Y0,%L1\;evmergehi %L0,%1,%1\;mr %0,%1";
}
[(set_attr "length" "16")]) [(set_attr "length" "16")])
(define_insn "*frob_<DITI:mode>_<SPE64:mode>_2" (define_insn "*frob_<DITI:mode>_<SPE64:mode>_2"
...@@ -2275,22 +2402,40 @@ ...@@ -2275,22 +2402,40 @@
default: default:
gcc_unreachable (); gcc_unreachable ();
case 0: case 0:
return \"evmergehi %0,%1,%1\;mr %L0,%1\"; if (WORDS_BIG_ENDIAN)
return \"evmergehi %0,%1,%1\;mr %L0,%1\";
else
return \"evmergehi %L0,%1,%1\;mr %0,%1\";
case 1: case 1:
/* If the address is not offsettable we need to load the whole /* If the address is not offsettable we need to load the whole
doubleword into a 64-bit register and then copy the high word doubleword into a 64-bit register and then copy the high word
to form the correct output layout. */ to form the correct output layout. */
if (!offsettable_nonstrict_memref_p (operands[1])) if (!offsettable_nonstrict_memref_p (operands[1]))
return \"evldd%X1 %L0,%y1\;evmergehi %0,%L0,%L0\"; {
if (WORDS_BIG_ENDIAN)
return \"evldd%X1 %L0,%y1\;evmergehi %0,%L0,%L0\";
else
return \"evldd%X1 %0,%y1\;evmergehi %L0,%0,%0\";
}
/* If the low-address word is used in the address, we must load /* If the low-address word is used in the address, we must load
it last. Otherwise, load it first. Note that we cannot have it last. Otherwise, load it first. Note that we cannot have
auto-increment in that case since the address register is auto-increment in that case since the address register is
known to be dead. */ known to be dead. */
if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
operands[1], 0)) operands[1], 0))
return \"lwz %L0,%L1\;lwz %0,%1\"; {
if (WORDS_BIG_ENDIAN)
return \"lwz %L0,%L1\;lwz %0,%1\";
else
return \"lwz %0,%1\;lwz %L0,%L1\";
}
else else
return \"lwz%U1%X1 %0,%1\;lwz %L0,%L1\"; {
if (WORDS_BIG_ENDIAN)
return \"lwz%U1%X1 %0,%1\;lwz %L0,%L1\";
else
return \"lwz%U1%X1 %L0,%L1\;lwz %0,%1\";
}
} }
}" }"
[(set_attr "length" "8,8")]) [(set_attr "length" "8,8")])
...@@ -2308,15 +2453,33 @@ ...@@ -2308,15 +2453,33 @@
default: default:
gcc_unreachable (); gcc_unreachable ();
case 0: case 0:
return \"evmergehi %Y0,%1,%1\;mr %Z0,%1\"; if (WORDS_BIG_ENDIAN)
return \"evmergehi %Y0,%1,%1\;mr %Z0,%1\";
else
return \"evmergehi %Z0,%1,%1\;mr %Y0,%1\";
case 1: case 1:
if (!offsettable_nonstrict_memref_p (operands[1])) if (!offsettable_nonstrict_memref_p (operands[1]))
return \"evldd%X1 %Z0,%y1\;evmergehi %Y0,%Z0,%Z0\"; {
if (WORDS_BIG_ENDIAN)
return \"evldd%X1 %Z0,%y1\;evmergehi %Y0,%Z0,%Z0\";
else
return \"evldd%X1 %Y0,%y1\;evmergehi %Z0,%Y0,%Y0\";
}
if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
operands[1], 0)) operands[1], 0))
return \"lwz %Z0,%L1\;lwz %Y0,%1\"; {
if (WORDS_BIG_ENDIAN)
return \"lwz %Z0,%L1\;lwz %Y0,%1\";
else
return \"lwz %Y0,%1\;lwz %Z0,%L1\";
}
else else
return \"lwz%U1%X1 %Y0,%1\;lwz %Z0,%L1\"; {
if (WORDS_BIG_ENDIAN)
return \"lwz%U1%X1 %Y0,%1\;lwz %Z0,%L1\";
else
return \"lwz%U1%X1 %Z0,%L1\;lwz %Y0,%1\";
}
} }
}" }"
[(set_attr "length" "8,8")]) [(set_attr "length" "8,8")])
...@@ -2325,110 +2488,226 @@ ...@@ -2325,110 +2488,226 @@
[(set (subreg:TF (match_operand:TI 0 "gpc_reg_operand" "=&r") 0) [(set (subreg:TF (match_operand:TI 0 "gpc_reg_operand" "=&r") 0)
(match_operand:TF 1 "input_operand" "r"))] (match_operand:TF 1 "input_operand" "r"))]
"TARGET_E500_DOUBLE" "TARGET_E500_DOUBLE"
"evmergehi %0,%1,%1\;mr %L0,%1\;evmergehi %Y0,%L1,%L1\;mr %Z0,%L1" {
if (WORDS_BIG_ENDIAN)
return "evmergehi %0,%1,%1\;mr %L0,%1\;evmergehi %Y0,%L1,%L1\;mr %Z0,%L1";
else
return "evmergehi %Z0,%L1,%L1\;mr %Y0,%L1\;evmergehi %L0,%1,%1\;mr %0,%1";
}
[(set_attr "length" "16")]) [(set_attr "length" "16")])
(define_insn "mov_si<mode>_e500_subreg0" (define_insn "mov_si<mode>_e500_subreg0_be"
[(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r,&r") 0) [(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r,&r") 0)
(match_operand:SI 1 "input_operand" "r,m"))] (match_operand:SI 1 "input_operand" "r,m"))]
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) "WORDS_BIG_ENDIAN
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)" && ((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))"
"@ "@
evmergelo %0,%1,%0 evmergelo %0,%1,%0
evmergelohi %0,%0,%0\;lwz%U1%X1 %0,%1\;evmergelohi %0,%0,%0" evmergelohi %0,%0,%0\;lwz%U1%X1 %0,%1\;evmergelohi %0,%0,%0"
[(set_attr "length" "4,12")]) [(set_attr "length" "4,12")])
(define_insn_and_split "*mov_si<mode>_e500_subreg0_elf_low" (define_insn "*mov_si<mode>_e500_subreg0_le"
[(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r,r") 0)
(match_operand:SI 1 "input_operand" "r,m"))]
"!WORDS_BIG_ENDIAN
&& ((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))"
"@
mr %0,%1
lwz%U1%X1 %0,%1")
(define_insn_and_split "*mov_si<mode>_e500_subreg0_elf_low_be"
[(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r") 0) [(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r") 0)
(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "r") (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand 2 "" "")))] (match_operand 2 "" "")))]
"((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) "WORDS_BIG_ENDIAN
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)) && (((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
&& TARGET_ELF && !TARGET_64BIT && can_create_pseudo_p ()" || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))
&& TARGET_ELF && !TARGET_64BIT && can_create_pseudo_p ())"
"#" "#"
"&& 1" "&& 1"
[(pc)] [(pc)]
{ {
rtx tmp = gen_reg_rtx (SImode); rtx tmp = gen_reg_rtx (SImode);
emit_insn (gen_elf_low (tmp, operands[1], operands[2])); emit_insn (gen_elf_low (tmp, operands[1], operands[2]));
emit_insn (gen_mov_si<mode>_e500_subreg0 (operands[0], tmp)); emit_insn (gen_mov_si<mode>_e500_subreg0_be (operands[0], tmp));
DONE; DONE;
} }
[(set_attr "length" "8")]) [(set_attr "length" "8")])
(define_insn "*mov_si<mode>_e500_subreg0_elf_low_le"
[(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r") 0)
(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand 2 "" "")))]
"!WORDS_BIG_ENDIAN
&& (((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))
&& TARGET_ELF && !TARGET_64BIT)"
"addic %0,%1,%K2")
;; ??? Could use evstwwe for memory stores in some cases, depending on ;; ??? Could use evstwwe for memory stores in some cases, depending on
;; the offset. ;; the offset.
(define_insn "*mov_si<mode>_e500_subreg0_2" (define_insn "*mov_si<mode>_e500_subreg0_2_be"
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m") [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
(subreg:SI (match_operand:SPE64TF 1 "register_operand" "+r,&r") 0))] (subreg:SI (match_operand:SPE64TF 1 "register_operand" "+r,&r") 0))]
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) "WORDS_BIG_ENDIAN
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)" && ((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))"
"@ "@
evmergehi %0,%0,%1 evmergehi %0,%0,%1
evmergelohi %1,%1,%1\;stw%U0%X0 %1,%0" evmergelohi %1,%1,%1\;stw%U0%X0 %1,%0"
[(set_attr "length" "4,8")]) [(set_attr "length" "4,8")])
(define_insn "*mov_si<mode>_e500_subreg4" (define_insn "*mov_si<mode>_e500_subreg0_2_le"
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
(subreg:SI (match_operand:SPE64TF 1 "register_operand" "+r,r") 0))]
"!WORDS_BIG_ENDIAN
&& ((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))"
"@
mr %0,%1
stw%U0%X0 %1,%0")
(define_insn "*mov_si<mode>_e500_subreg4_be"
[(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r,r") 4) [(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r,r") 4)
(match_operand:SI 1 "input_operand" "r,m"))] (match_operand:SI 1 "input_operand" "r,m"))]
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) "WORDS_BIG_ENDIAN
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)" && ((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))"
"@ "@
mr %0,%1 mr %0,%1
lwz%U1%X1 %0,%1") lwz%U1%X1 %0,%1")
(define_insn "*mov_si<mode>_e500_subreg4_elf_low" (define_insn "mov_si<mode>_e500_subreg4_le"
[(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r,&r") 4)
(match_operand:SI 1 "input_operand" "r,m"))]
"!WORDS_BIG_ENDIAN
&& ((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))"
"@
evmergelo %0,%1,%0
evmergelohi %0,%0,%0\;lwz%U1%X1 %0,%1\;evmergelohi %0,%0,%0"
[(set_attr "length" "4,12")])
(define_insn "*mov_si<mode>_e500_subreg4_elf_low_be"
[(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r") 4) [(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r") 4)
(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "r") (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand 2 "" "")))] (match_operand 2 "" "")))]
"((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) "WORDS_BIG_ENDIAN
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)) && (((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
&& TARGET_ELF && !TARGET_64BIT" || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))
&& TARGET_ELF && !TARGET_64BIT)"
"addic %0,%1,%K2") "addic %0,%1,%K2")
(define_insn "*mov_si<mode>_e500_subreg4_2" (define_insn_and_split "*mov_si<mode>_e500_subreg4_elf_low_le"
[(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r") 4)
(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand 2 "" "")))]
"!WORDS_BIG_ENDIAN
&& (((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))
&& TARGET_ELF && !TARGET_64BIT && can_create_pseudo_p ())"
"#"
"&& 1"
[(pc)]
{
rtx tmp = gen_reg_rtx (SImode);
emit_insn (gen_elf_low (tmp, operands[1], operands[2]));
emit_insn (gen_mov_si<mode>_e500_subreg4_le (operands[0], tmp));
DONE;
}
[(set_attr "length" "8")])
(define_insn "*mov_si<mode>_e500_subreg4_2_be"
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m") [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
(subreg:SI (match_operand:SPE64TF 1 "register_operand" "r,r") 4))] (subreg:SI (match_operand:SPE64TF 1 "register_operand" "r,r") 4))]
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) "WORDS_BIG_ENDIAN
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)" && ((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))"
"@ "@
mr %0,%1 mr %0,%1
stw%U0%X0 %1,%0") stw%U0%X0 %1,%0")
(define_insn "*mov_sitf_e500_subreg8" (define_insn "*mov_si<mode>_e500_subreg4_2_le"
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
(subreg:SI (match_operand:SPE64TF 1 "register_operand" "+r,&r") 4))]
"!WORDS_BIG_ENDIAN
&& ((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))"
"@
evmergehi %0,%0,%1
evmergelohi %1,%1,%1\;stw%U0%X0 %1,%0"
[(set_attr "length" "4,8")])
(define_insn "*mov_sitf_e500_subreg8_be"
[(set (subreg:SI (match_operand:TF 0 "register_operand" "+r,&r") 8) [(set (subreg:SI (match_operand:TF 0 "register_operand" "+r,&r") 8)
(match_operand:SI 1 "input_operand" "r,m"))] (match_operand:SI 1 "input_operand" "r,m"))]
"TARGET_E500_DOUBLE" "WORDS_BIG_ENDIAN && TARGET_E500_DOUBLE"
"@ "@
evmergelo %L0,%1,%L0 evmergelo %L0,%1,%L0
evmergelohi %L0,%L0,%L0\;lwz%U1%X1 %L0,%1\;evmergelohi %L0,%L0,%L0" evmergelohi %L0,%L0,%L0\;lwz%U1%X1 %L0,%1\;evmergelohi %L0,%L0,%L0"
[(set_attr "length" "4,12")]) [(set_attr "length" "4,12")])
(define_insn "*mov_sitf_e500_subreg8_2" (define_insn "*mov_sitf_e500_subreg8_le"
[(set (subreg:SI (match_operand:TF 0 "register_operand" "+r,r") 8)
(match_operand:SI 1 "input_operand" "r,m"))]
"!WORDS_BIG_ENDIAN && TARGET_E500_DOUBLE"
"@
mr %L0,%1
lwz%U1%X1 %L0,%1")
(define_insn "*mov_sitf_e500_subreg8_2_be"
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m") [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
(subreg:SI (match_operand:TF 1 "register_operand" "+r,&r") 8))] (subreg:SI (match_operand:TF 1 "register_operand" "+r,&r") 8))]
"TARGET_E500_DOUBLE" "WORDS_BIG_ENDIAN && TARGET_E500_DOUBLE"
"@ "@
evmergehi %0,%0,%L1 evmergehi %0,%0,%L1
evmergelohi %L1,%L1,%L1\;stw%U0%X0 %L1,%0" evmergelohi %L1,%L1,%L1\;stw%U0%X0 %L1,%0"
[(set_attr "length" "4,8")]) [(set_attr "length" "4,8")])
(define_insn "*mov_sitf_e500_subreg12" (define_insn "*mov_sitf_e500_subreg8_2_le"
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
(subreg:SI (match_operand:TF 1 "register_operand" "r,r") 8))]
"!WORDS_BIG_ENDIAN && TARGET_E500_DOUBLE"
"@
mr %0,%L1
stw%U0%X0 %L1,%0")
(define_insn "*mov_sitf_e500_subreg12_be"
[(set (subreg:SI (match_operand:TF 0 "register_operand" "+r,r") 12) [(set (subreg:SI (match_operand:TF 0 "register_operand" "+r,r") 12)
(match_operand:SI 1 "input_operand" "r,m"))] (match_operand:SI 1 "input_operand" "r,m"))]
"TARGET_E500_DOUBLE" "WORDS_BIG_ENDIAN && TARGET_E500_DOUBLE"
"@ "@
mr %L0,%1 mr %L0,%1
lwz%U1%X1 %L0,%1") lwz%U1%X1 %L0,%1")
(define_insn "*mov_sitf_e500_subreg12_2" (define_insn "*mov_sitf_e500_subreg12_le"
[(set (subreg:SI (match_operand:TF 0 "register_operand" "+r,&r") 12)
(match_operand:SI 1 "input_operand" "r,m"))]
"!WORDS_BIG_ENDIAN && TARGET_E500_DOUBLE"
"@
evmergelo %L0,%1,%L0
evmergelohi %L0,%L0,%L0\;lwz%U1%X1 %L0,%1\;evmergelohi %L0,%L0,%L0"
[(set_attr "length" "4,12")])
(define_insn "*mov_sitf_e500_subreg12_2_be"
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m") [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
(subreg:SI (match_operand:TF 1 "register_operand" "r,r") 12))] (subreg:SI (match_operand:TF 1 "register_operand" "r,r") 12))]
"TARGET_E500_DOUBLE" "WORDS_BIG_ENDIAN && TARGET_E500_DOUBLE"
"@ "@
mr %0,%L1 mr %0,%L1
stw%U0%X0 %L1,%0") stw%U0%X0 %L1,%0")
(define_insn "*mov_sitf_e500_subreg12_2_le"
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
(subreg:SI (match_operand:TF 1 "register_operand" "+r,&r") 12))]
"!WORDS_BIG_ENDIAN && TARGET_E500_DOUBLE"
"@
evmergehi %0,%0,%L1
evmergelohi %L1,%L1,%L1\;stw%U0%X0 %L1,%0"
[(set_attr "length" "4,8")])
;; FIXME: Allow r=CONST0. ;; FIXME: Allow r=CONST0.
(define_insn "*movdf_e500_double" (define_insn "*movdf_e500_double"
[(set (match_operand:DF 0 "rs6000_nonimmediate_operand" "=r,r,m") [(set (match_operand:DF 0 "rs6000_nonimmediate_operand" "=r,r,m")
......
2014-07-07 Maciej W. Rozycki <macro@codesourcery.com>
* gcc.target/powerpc/spe-evmerge.c: New file.
2014-07-07 Paolo Carlini <paolo.carlini@oracle.com> 2014-07-07 Paolo Carlini <paolo.carlini@oracle.com>
* g++.dg/cpp0x/override1.C: Tweak expected error messages. * g++.dg/cpp0x/override1.C: Tweak expected error messages.
......
/* Verify SPE vector permute builtins. */
/* { dg-do run { target { powerpc*-*-* && powerpc_spe } } } */
/* Remove `-ansi' from options so that <spe.h> compiles. */
/* { dg-options "" } */
#include <spe.h>
#include <stdlib.h>
#define vector __attribute__ ((vector_size (8)))
#define WORDS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
int
main (void)
{
vector int a = { 0x11111111, 0x22222222 };
vector int b = { 0x33333333, 0x44444444 };
vector int c;
/* c[hi] = a[hi], c[lo] = b[hi] */
c = __ev_mergehi (a, b);
if (c[0] != (WORDS_BIG_ENDIAN ? 0x11111111 : 0x44444444))
abort ();
if (c[1] != (WORDS_BIG_ENDIAN ? 0x33333333 : 0x22222222))
abort ();
/* c[hi] = a[lo], c[lo] = b[lo] */
c = __ev_mergelo (a, b);
if (c[0] != (WORDS_BIG_ENDIAN ? 0x22222222 : 0x33333333))
abort ();
if (c[1] != (WORDS_BIG_ENDIAN ? 0x44444444 : 0x11111111))
abort ();
/* c[hi] = a[lo], c[lo] = b[hi] */
c = __ev_mergelohi (a, b);
if (c[0] != (WORDS_BIG_ENDIAN ? 0x22222222 : 0x44444444))
abort ();
if (c[1] != (WORDS_BIG_ENDIAN ? 0x33333333 : 0x11111111))
abort ();
/* c[hi] = a[hi], c[lo] = b[lo] */
c = __ev_mergehilo (a, b);
if (c[0] != (WORDS_BIG_ENDIAN ? 0x11111111 : 0x33333333))
abort ();
if (c[1] != (WORDS_BIG_ENDIAN ? 0x44444444 : 0x22222222))
abort ();
/* c[hi] = a[hi], c[lo] = b[hi] */
c = __builtin_spe_evmergehi (a, b);
if (c[0] != (WORDS_BIG_ENDIAN ? 0x11111111 : 0x44444444))
abort ();
if (c[1] != (WORDS_BIG_ENDIAN ? 0x33333333 : 0x22222222))
abort ();
/* c[hi] = a[lo], c[lo] = b[lo] */
c = __builtin_spe_evmergelo (a, b);
if (c[0] != (WORDS_BIG_ENDIAN ? 0x22222222 : 0x33333333))
abort ();
if (c[1] != (WORDS_BIG_ENDIAN ? 0x44444444 : 0x11111111))
abort ();
/* c[hi] = a[lo], c[lo] = b[hi] */
c = __builtin_spe_evmergelohi (a, b);
if (c[0] != (WORDS_BIG_ENDIAN ? 0x22222222 : 0x44444444))
abort ();
if (c[1] != (WORDS_BIG_ENDIAN ? 0x33333333 : 0x11111111))
abort ();
/* c[hi] = a[hi], c[lo] = b[lo] */
c = __builtin_spe_evmergehilo (a, b);
if (c[0] != (WORDS_BIG_ENDIAN ? 0x11111111 : 0x33333333))
abort ();
if (c[1] != (WORDS_BIG_ENDIAN ? 0x44444444 : 0x22222222))
abort ();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment