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
This commit is contained in:
parent
e762392918
commit
3ca588d3e2
|
@ -1,3 +1,73 @@
|
|||
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>
|
||||
|
||||
* asan.c (instrument_strlen_call): Do not instrument first byte in strlen
|
||||
|
|
|
@ -5300,8 +5300,10 @@ output_vec_const_move (rtx *operands)
|
|||
operands[2] = CONST_VECTOR_ELT (vec, 1);
|
||||
if (cst == cst2)
|
||||
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";
|
||||
else
|
||||
return "li %0,%2\n\tevmergelo %0,%0,%0\n\tli %0,%1";
|
||||
}
|
||||
|
||||
/* Initialize TARGET of vector PAIRED to VALS. */
|
||||
|
|
|
@ -438,7 +438,12 @@
|
|||
[(set_attr "type" "vecload")
|
||||
(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")
|
||||
(vec_select:V2SI
|
||||
(vec_concat:V4SI
|
||||
|
@ -446,11 +451,16 @@
|
|||
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
|
||||
(parallel [(const_int 0) (const_int 2)])))]
|
||||
"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 "length" "4")])
|
||||
|
||||
(define_insn "spe_evmergehilo"
|
||||
(define_insn "vec_perm01_v2si"
|
||||
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
|
||||
(vec_select:V2SI
|
||||
(vec_concat:V4SI
|
||||
|
@ -458,11 +468,16 @@
|
|||
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
|
||||
(parallel [(const_int 0) (const_int 3)])))]
|
||||
"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 "length" "4")])
|
||||
|
||||
(define_insn "spe_evmergelo"
|
||||
(define_insn "vec_perm11_v2si"
|
||||
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
|
||||
(vec_select:V2SI
|
||||
(vec_concat:V4SI
|
||||
|
@ -470,11 +485,16 @@
|
|||
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
|
||||
(parallel [(const_int 1) (const_int 3)])))]
|
||||
"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 "length" "4")])
|
||||
|
||||
(define_insn "spe_evmergelohi"
|
||||
(define_insn "vec_perm10_v2si"
|
||||
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
|
||||
(vec_select:V2SI
|
||||
(vec_concat:V4SI
|
||||
|
@ -482,7 +502,12 @@
|
|||
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
|
||||
(parallel [(const_int 1) (const_int 2)])))]
|
||||
"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 "length" "4")])
|
||||
|
||||
|
@ -499,6 +524,60 @@
|
|||
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"
|
||||
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
|
||||
(not:V2SI (and:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")
|
||||
|
@ -2220,15 +2299,31 @@
|
|||
(subreg:SPE64 (match_operand:DITI 1 "input_operand" "r,m") 0))]
|
||||
"(TARGET_E500_DOUBLE && <SPE64:MODE>mode == DFmode)
|
||||
|| (TARGET_SPE && <SPE64:MODE>mode != DFmode)"
|
||||
"@
|
||||
evmergelo %0,%1,%L1
|
||||
evldd%X1 %0,%y1")
|
||||
{
|
||||
switch (which_alternative)
|
||||
{
|
||||
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"
|
||||
[(set (match_operand:TF 0 "gpc_reg_operand" "=r")
|
||||
(subreg:TF (match_operand:TI 1 "gpc_reg_operand" "r") 0))]
|
||||
"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")])
|
||||
|
||||
(define_insn "*frob_<mode>_di_2"
|
||||
|
@ -2236,31 +2331,63 @@
|
|||
(match_operand:DI 1 "input_operand" "r,m"))]
|
||||
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|
||||
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
|
||||
"@
|
||||
evmergelo %0,%1,%L1
|
||||
evldd%X1 %0,%y1")
|
||||
{
|
||||
switch (which_alternative)
|
||||
{
|
||||
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"
|
||||
[(set (subreg:DI (match_operand:TF 0 "nonimmediate_operand" "+&r,r") 8)
|
||||
(match_operand:DI 1 "input_operand" "r,m"))]
|
||||
"TARGET_E500_DOUBLE"
|
||||
"@
|
||||
evmergelo %L0,%1,%L1
|
||||
evldd%X1 %L0,%y1")
|
||||
{
|
||||
switch (which_alternative)
|
||||
{
|
||||
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>"
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand" "=&r")
|
||||
(subreg:DI (match_operand:SPE64TF 1 "input_operand" "r") 0))]
|
||||
"(TARGET_E500_DOUBLE && (<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")])
|
||||
|
||||
(define_insn "*frob_ti_tf"
|
||||
[(set (match_operand:TI 0 "nonimmediate_operand" "=&r")
|
||||
(subreg:TI (match_operand:TF 1 "input_operand" "r") 0))]
|
||||
"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")])
|
||||
|
||||
(define_insn "*frob_<DITI:mode>_<SPE64:mode>_2"
|
||||
|
@ -2275,22 +2402,40 @@
|
|||
default:
|
||||
gcc_unreachable ();
|
||||
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:
|
||||
/* If the address is not offsettable we need to load the whole
|
||||
doubleword into a 64-bit register and then copy the high word
|
||||
to form the correct output layout. */
|
||||
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
|
||||
it last. Otherwise, load it first. Note that we cannot have
|
||||
auto-increment in that case since the address register is
|
||||
known to be dead. */
|
||||
if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
|
||||
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
|
||||
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")])
|
||||
|
@ -2308,15 +2453,33 @@
|
|||
default:
|
||||
gcc_unreachable ();
|
||||
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:
|
||||
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,
|
||||
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
|
||||
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")])
|
||||
|
@ -2325,110 +2488,226 @@
|
|||
[(set (subreg:TF (match_operand:TI 0 "gpc_reg_operand" "=&r") 0)
|
||||
(match_operand:TF 1 "input_operand" "r"))]
|
||||
"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")])
|
||||
|
||||
(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)
|
||||
(match_operand:SI 1 "input_operand" "r,m"))]
|
||||
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|
||||
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
|
||||
"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_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)
|
||||
(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "r")
|
||||
(match_operand 2 "" "")))]
|
||||
"((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 ()"
|
||||
"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_subreg0 (operands[0], tmp));
|
||||
emit_insn (gen_mov_si<mode>_e500_subreg0_be (operands[0], tmp));
|
||||
DONE;
|
||||
}
|
||||
[(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
|
||||
;; 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")
|
||||
(subreg:SI (match_operand:SPE64TF 1 "register_operand" "+r,&r") 0))]
|
||||
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|
||||
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
|
||||
"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_si<mode>_e500_subreg4"
|
||||
[(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r,r") 4)
|
||||
(match_operand:SI 1 "input_operand" "r,m"))]
|
||||
"(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 "*mov_si<mode>_e500_subreg4_elf_low"
|
||||
[(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 "" "")))]
|
||||
"((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")
|
||||
|
||||
(define_insn "*mov_si<mode>_e500_subreg4_2"
|
||||
(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") 4))]
|
||||
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|
||||
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
|
||||
(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_sitf_e500_subreg8"
|
||||
(define_insn "*mov_si<mode>_e500_subreg4_be"
|
||||
[(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))"
|
||||
"@
|
||||
mr %0,%1
|
||||
lwz%U1%X1 %0,%1")
|
||||
|
||||
(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)
|
||||
(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")
|
||||
|
||||
(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")
|
||||
(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))"
|
||||
"@
|
||||
mr %0,%1
|
||||
stw%U0%X0 %1,%0")
|
||||
|
||||
(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)
|
||||
(match_operand:SI 1 "input_operand" "r,m"))]
|
||||
"TARGET_E500_DOUBLE"
|
||||
"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_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")
|
||||
(subreg:SI (match_operand:TF 1 "register_operand" "+r,&r") 8))]
|
||||
"TARGET_E500_DOUBLE"
|
||||
"WORDS_BIG_ENDIAN && TARGET_E500_DOUBLE"
|
||||
"@
|
||||
evmergehi %0,%0,%L1
|
||||
evmergelohi %L1,%L1,%L1\;stw%U0%X0 %L1,%0"
|
||||
[(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)
|
||||
(match_operand:SI 1 "input_operand" "r,m"))]
|
||||
"TARGET_E500_DOUBLE"
|
||||
"WORDS_BIG_ENDIAN && TARGET_E500_DOUBLE"
|
||||
"@
|
||||
mr %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")
|
||||
(subreg:SI (match_operand:TF 1 "register_operand" "r,r") 12))]
|
||||
"TARGET_E500_DOUBLE"
|
||||
"WORDS_BIG_ENDIAN && TARGET_E500_DOUBLE"
|
||||
"@
|
||||
mr %0,%L1
|
||||
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.
|
||||
(define_insn "*movdf_e500_double"
|
||||
[(set (match_operand:DF 0 "rs6000_nonimmediate_operand" "=r,r,m")
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
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>
|
||||
|
||||
* g++.dg/cpp0x/override1.C: Tweak expected error messages.
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* 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;
|
||||
}
|
Loading…
Reference in New Issue