mirror of git://gcc.gnu.org/git/gcc.git
vector.md (xor<mode>3): Move 128-bit boolean expanders to rs6000.md.
[gcc] 2013-07-23 Michael Meissner <meissner@linux.vnet.ibm.com> * config/rs6000/vector.md (xor<mode>3): Move 128-bit boolean expanders to rs6000.md. (ior<mode>3): Likewise. (and<mode>3): Likewise. (one_cmpl<mode>2): Likewise. (nor<mode>3): Likewise. (andc<mode>3): Likewise. (eqv<mode>3): Likewise. (nand<mode>3): Likewise. (orc<mode>3): Likewise. * config/rs6000/rs6000-protos.h (rs6000_split_logical): New declaration. * config/rs6000/rs6000.c (rs6000_split_logical_inner): Add support to split multi-word logical operations. (rs6000_split_logical_di): Likewise. (rs6000_split_logical): Likewise. * config/rs6000/vsx.md (VSX_L2): Delete, no longer used. (vsx_and<mode>3_32bit): Move 128-bit logical insns to rs6000.md, and allow TImode operations in 32-bit. (vsx_and<mode>3_64bit): Likewise. (vsx_ior<mode>3_32bit): Likewise. (vsx_ior<mode>3_64bit): Likewise. (vsx_xor<mode>3_32bit): Likewise. (vsx_xor<mode>3_64bit): Likewise. (vsx_one_cmpl<mode>2_32bit): Likewise. (vsx_one_cmpl<mode>2_64bit): Likewise. (vsx_nor<mode>3_32bit): Likewise. (vsx_nor<mode>3_64bit): Likewise. (vsx_andc<mode>3_32bit): Likewise. (vsx_andc<mode>3_64bit): Likewise. (vsx_eqv<mode>3_32bit): Likewise. (vsx_eqv<mode>3_64bit): Likewise. (vsx_nand<mode>3_32bit): Likewise. (vsx_nand<mode>3_64bit): Likewise. (vsx_orc<mode>3_32bit): Likewise. (vsx_orc<mode>3_64bit): Likewise. * config/rs6000/rs6000.h (VLOGICAL_REGNO_P): Always allow vector logical types in GPRs. * config/rs6000/altivec.md (altivec_and<mode>3): Move 128-bit logical insns to rs6000.md, and allow TImode operations in 32-bit. (altivec_ior<mode>3): Likewise. (altivec_xor<mode>3): Likewise. (altivec_one_cmpl<mode>2): Likewise. (altivec_nor<mode>3): Likewise. (altivec_andc<mode>3): Likewise. * config/rs6000/rs6000.md (BOOL_128): New mode iterators and mode attributes for moving the 128-bit logical operations into rs6000.md. (BOOL_REGS_OUTPUT): Likewise. (BOOL_REGS_OP1): Likewise. (BOOL_REGS_OP2): Likewise. (BOOL_REGS_UNARY): Likewise. (BOOL_REGS_AND_CR0): Likewise. (one_cmpl<mode>2): Add support for DI logical operations on 32-bit, splitting the operations to 32-bit. (anddi3): Likewise. (iordi3): Likewise. (xordi3): Likewise. (and<mode>3, 128-bit types): Rewrite 2013-06-06 logical operator changes to combine the 32/64-bit code, allow logical operations on TI mode in 32-bit, and to use similar match_operator patterns like scalar mode uses. Combine the Altivec and VSX code for logical operations, and move it here. (ior<mode>3, 128-bit types): Likewise. (xor<mode>3, 128-bit types): Likewise. (one_cmpl<mode>3, 128-bit types): Likewise. (nor<mode>3, 128-bit types): Likewise. (andc<mode>3, 128-bit types): Likewise. (eqv<mode>3, 128-bit types): Likewise. (nand<mode>3, 128-bit types): Likewise. (orc<mode>3, 128-bit types): Likewise. (and<mode>3_internal): Likewise. (bool<mode>3_internal): Likewise. (boolc<mode>3_internal1): Likewise. (boolc<mode>3_internal2): Likewise. (boolcc<mode>3_internal1): Likewise. (boolcc<mode>3_internal2): Likewise. (eqv<mode>3_internal1): Likewise. (eqv<mode>3_internal2): Likewise. (one_cmpl1<mode>3_internal): Likewise. [gcc/testsuite] 2013-07-23 Michael Meissner <meissner@linux.vnet.ibm.com> * gcc.target/powerpc/bool2.h: New file, test the code generation of logical operations for power5, altivec, power7, and power8 systems. * gcc.target/powerpc/bool2-p5.c: Likewise. * gcc.target/powerpc/bool2-av.c: Likewise. * gcc.target/powerpc/bool2-p7.c: Likewise. * gcc.target/powerpc/bool2-p8.c: Likewise. * gcc.target/powerpc/bool3.h: Likewise. * gcc.target/powerpc/bool3-av.c: Likewise. * gcc.target/powerpc/bool2-p7.c: Likewise. * gcc.target/powerpc/bool2-p8.c: Likewise. From-SVN: r201187
This commit is contained in:
parent
9b69d4b4b1
commit
dd7a40e14c
|
|
@ -1,3 +1,93 @@
|
|||
2013-07-23 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
* config/rs6000/vector.md (xor<mode>3): Move 128-bit boolean
|
||||
expanders to rs6000.md.
|
||||
(ior<mode>3): Likewise.
|
||||
(and<mode>3): Likewise.
|
||||
(one_cmpl<mode>2): Likewise.
|
||||
(nor<mode>3): Likewise.
|
||||
(andc<mode>3): Likewise.
|
||||
(eqv<mode>3): Likewise.
|
||||
(nand<mode>3): Likewise.
|
||||
(orc<mode>3): Likewise.
|
||||
|
||||
* config/rs6000/rs6000-protos.h (rs6000_split_logical): New
|
||||
declaration.
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_split_logical_inner): Add support
|
||||
to split multi-word logical operations.
|
||||
(rs6000_split_logical_di): Likewise.
|
||||
(rs6000_split_logical): Likewise.
|
||||
|
||||
* config/rs6000/vsx.md (VSX_L2): Delete, no longer used.
|
||||
(vsx_and<mode>3_32bit): Move 128-bit logical insns to rs6000.md,
|
||||
and allow TImode operations in 32-bit.
|
||||
(vsx_and<mode>3_64bit): Likewise.
|
||||
(vsx_ior<mode>3_32bit): Likewise.
|
||||
(vsx_ior<mode>3_64bit): Likewise.
|
||||
(vsx_xor<mode>3_32bit): Likewise.
|
||||
(vsx_xor<mode>3_64bit): Likewise.
|
||||
(vsx_one_cmpl<mode>2_32bit): Likewise.
|
||||
(vsx_one_cmpl<mode>2_64bit): Likewise.
|
||||
(vsx_nor<mode>3_32bit): Likewise.
|
||||
(vsx_nor<mode>3_64bit): Likewise.
|
||||
(vsx_andc<mode>3_32bit): Likewise.
|
||||
(vsx_andc<mode>3_64bit): Likewise.
|
||||
(vsx_eqv<mode>3_32bit): Likewise.
|
||||
(vsx_eqv<mode>3_64bit): Likewise.
|
||||
(vsx_nand<mode>3_32bit): Likewise.
|
||||
(vsx_nand<mode>3_64bit): Likewise.
|
||||
(vsx_orc<mode>3_32bit): Likewise.
|
||||
(vsx_orc<mode>3_64bit): Likewise.
|
||||
|
||||
* config/rs6000/rs6000.h (VLOGICAL_REGNO_P): Always allow vector
|
||||
logical types in GPRs.
|
||||
|
||||
* config/rs6000/altivec.md (altivec_and<mode>3): Move 128-bit
|
||||
logical insns to rs6000.md, and allow TImode operations in
|
||||
32-bit.
|
||||
(altivec_ior<mode>3): Likewise.
|
||||
(altivec_xor<mode>3): Likewise.
|
||||
(altivec_one_cmpl<mode>2): Likewise.
|
||||
(altivec_nor<mode>3): Likewise.
|
||||
(altivec_andc<mode>3): Likewise.
|
||||
|
||||
* config/rs6000/rs6000.md (BOOL_128): New mode iterators and mode
|
||||
attributes for moving the 128-bit logical operations into
|
||||
rs6000.md.
|
||||
(BOOL_REGS_OUTPUT): Likewise.
|
||||
(BOOL_REGS_OP1): Likewise.
|
||||
(BOOL_REGS_OP2): Likewise.
|
||||
(BOOL_REGS_UNARY): Likewise.
|
||||
(BOOL_REGS_AND_CR0): Likewise.
|
||||
(one_cmpl<mode>2): Add support for DI logical operations on
|
||||
32-bit, splitting the operations to 32-bit.
|
||||
(anddi3): Likewise.
|
||||
(iordi3): Likewise.
|
||||
(xordi3): Likewise.
|
||||
(and<mode>3, 128-bit types): Rewrite 2013-06-06 logical operator
|
||||
changes to combine the 32/64-bit code, allow logical operations on
|
||||
TI mode in 32-bit, and to use similar match_operator patterns like
|
||||
scalar mode uses. Combine the Altivec and VSX code for logical
|
||||
operations, and move it here.
|
||||
(ior<mode>3, 128-bit types): Likewise.
|
||||
(xor<mode>3, 128-bit types): Likewise.
|
||||
(one_cmpl<mode>3, 128-bit types): Likewise.
|
||||
(nor<mode>3, 128-bit types): Likewise.
|
||||
(andc<mode>3, 128-bit types): Likewise.
|
||||
(eqv<mode>3, 128-bit types): Likewise.
|
||||
(nand<mode>3, 128-bit types): Likewise.
|
||||
(orc<mode>3, 128-bit types): Likewise.
|
||||
(and<mode>3_internal): Likewise.
|
||||
(bool<mode>3_internal): Likewise.
|
||||
(boolc<mode>3_internal1): Likewise.
|
||||
(boolc<mode>3_internal2): Likewise.
|
||||
(boolcc<mode>3_internal1): Likewise.
|
||||
(boolcc<mode>3_internal2): Likewise.
|
||||
(eqv<mode>3_internal1): Likewise.
|
||||
(eqv<mode>3_internal2): Likewise.
|
||||
(one_cmpl1<mode>3_internal): Likewise.
|
||||
|
||||
2013-07-23 David Holsgrove <david.holsgrove@xilinx.com>
|
||||
|
||||
* config/microblaze/microblaze.c (microblaze_expand_prologue):
|
||||
|
|
|
|||
|
|
@ -1040,59 +1040,7 @@
|
|||
[(set_attr "type" "veccomplex")])
|
||||
|
||||
|
||||
;; logical ops. Have the logical ops follow the memory ops in
|
||||
;; terms of whether to prefer VSX or Altivec
|
||||
|
||||
;; AND has a clobber to be consistant with VSX, which adds splitters for using
|
||||
;; the GPR registers.
|
||||
(define_insn "*altivec_and<mode>3"
|
||||
[(set (match_operand:VM 0 "register_operand" "=v")
|
||||
(and:VM (match_operand:VM 1 "register_operand" "v")
|
||||
(match_operand:VM 2 "register_operand" "v")))
|
||||
(clobber (match_scratch:CC 3 "=X"))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
"vand %0,%1,%2"
|
||||
[(set_attr "type" "vecsimple")])
|
||||
|
||||
(define_insn "*altivec_ior<mode>3"
|
||||
[(set (match_operand:VM 0 "register_operand" "=v")
|
||||
(ior:VM (match_operand:VM 1 "register_operand" "v")
|
||||
(match_operand:VM 2 "register_operand" "v")))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
"vor %0,%1,%2"
|
||||
[(set_attr "type" "vecsimple")])
|
||||
|
||||
(define_insn "*altivec_xor<mode>3"
|
||||
[(set (match_operand:VM 0 "register_operand" "=v")
|
||||
(xor:VM (match_operand:VM 1 "register_operand" "v")
|
||||
(match_operand:VM 2 "register_operand" "v")))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
"vxor %0,%1,%2"
|
||||
[(set_attr "type" "vecsimple")])
|
||||
|
||||
(define_insn "*altivec_one_cmpl<mode>2"
|
||||
[(set (match_operand:VM 0 "register_operand" "=v")
|
||||
(not:VM (match_operand:VM 1 "register_operand" "v")))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
"vnor %0,%1,%1"
|
||||
[(set_attr "type" "vecsimple")])
|
||||
|
||||
(define_insn "*altivec_nor<mode>3"
|
||||
[(set (match_operand:VM 0 "register_operand" "=v")
|
||||
(and:VM (not:VM (match_operand:VM 1 "register_operand" "v"))
|
||||
(not:VM (match_operand:VM 2 "register_operand" "v"))))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
"vnor %0,%1,%2"
|
||||
[(set_attr "type" "vecsimple")])
|
||||
|
||||
(define_insn "*altivec_andc<mode>3"
|
||||
[(set (match_operand:VM 0 "register_operand" "=v")
|
||||
(and:VM (not:VM (match_operand:VM 2 "register_operand" "v"))
|
||||
(match_operand:VM 1 "register_operand" "v")))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
"vandc %0,%1,%2"
|
||||
[(set_attr "type" "vecsimple")])
|
||||
|
||||
;; Vector pack/unpack
|
||||
(define_insn "altivec_vpkpx"
|
||||
[(set (match_operand:V8HI 0 "register_operand" "=v")
|
||||
(unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ extern rtx rs6000_address_for_fpconvert (rtx);
|
|||
extern rtx rs6000_address_for_altivec (rtx);
|
||||
extern rtx rs6000_allocate_stack_temp (enum machine_mode, bool, bool);
|
||||
extern int rs6000_loop_align (rtx);
|
||||
extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool, rtx);
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
#ifdef TREE_CODE
|
||||
|
|
|
|||
|
|
@ -30139,6 +30139,280 @@ rs6000_set_up_by_prologue (struct hard_reg_set_container *set)
|
|||
add_to_hard_reg_set (&set->set, Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
|
||||
}
|
||||
|
||||
|
||||
/* Helper function for rs6000_split_logical to emit a logical instruction after
|
||||
spliting the operation to single GPR registers.
|
||||
|
||||
DEST is the destination register.
|
||||
OP1 and OP2 are the input source registers.
|
||||
CODE is the base operation (AND, IOR, XOR, NOT).
|
||||
MODE is the machine mode.
|
||||
If COMPLEMENT_FINAL_P is true, wrap the whole operation with NOT.
|
||||
If COMPLEMENT_OP1_P is true, wrap operand1 with NOT.
|
||||
If COMPLEMENT_OP2_P is true, wrap operand2 with NOT.
|
||||
CLOBBER_REG is either NULL or a scratch register of type CC to allow
|
||||
formation of the AND instructions. */
|
||||
|
||||
static void
|
||||
rs6000_split_logical_inner (rtx dest,
|
||||
rtx op1,
|
||||
rtx op2,
|
||||
enum rtx_code code,
|
||||
enum machine_mode mode,
|
||||
bool complement_final_p,
|
||||
bool complement_op1_p,
|
||||
bool complement_op2_p,
|
||||
rtx clobber_reg)
|
||||
{
|
||||
rtx bool_rtx;
|
||||
rtx set_rtx;
|
||||
|
||||
/* Optimize AND of 0/0xffffffff and IOR/XOR of 0. */
|
||||
if (op2 && GET_CODE (op2) == CONST_INT
|
||||
&& (mode == SImode || (mode == DImode && TARGET_POWERPC64))
|
||||
&& !complement_final_p && !complement_op1_p && !complement_op2_p)
|
||||
{
|
||||
HOST_WIDE_INT mask = GET_MODE_MASK (mode);
|
||||
HOST_WIDE_INT value = INTVAL (op2) & mask;
|
||||
|
||||
/* Optimize AND of 0 to just set 0. Optimize AND of -1 to be a move. */
|
||||
if (code == AND)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
emit_insn (gen_rtx_SET (VOIDmode, dest, const0_rtx));
|
||||
return;
|
||||
}
|
||||
|
||||
else if (value == mask)
|
||||
{
|
||||
if (!rtx_equal_p (dest, op1))
|
||||
emit_insn (gen_rtx_SET (VOIDmode, dest, op1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Optimize IOR/XOR of 0 to be a simple move. Split large operations
|
||||
into separate ORI/ORIS or XORI/XORIS instrucitons. */
|
||||
else if (code == IOR || code == XOR)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
if (!rtx_equal_p (dest, op1))
|
||||
emit_insn (gen_rtx_SET (VOIDmode, dest, op1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (complement_op1_p)
|
||||
op1 = gen_rtx_NOT (mode, op1);
|
||||
|
||||
if (complement_op2_p)
|
||||
op2 = gen_rtx_NOT (mode, op2);
|
||||
|
||||
bool_rtx = ((code == NOT)
|
||||
? gen_rtx_NOT (mode, op1)
|
||||
: gen_rtx_fmt_ee (code, mode, op1, op2));
|
||||
|
||||
if (complement_final_p)
|
||||
bool_rtx = gen_rtx_NOT (mode, bool_rtx);
|
||||
|
||||
set_rtx = gen_rtx_SET (VOIDmode, dest, bool_rtx);
|
||||
|
||||
/* Is this AND with an explicit clobber? */
|
||||
if (clobber_reg)
|
||||
{
|
||||
rtx clobber = gen_rtx_CLOBBER (VOIDmode, clobber_reg);
|
||||
set_rtx = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set_rtx, clobber));
|
||||
}
|
||||
|
||||
emit_insn (set_rtx);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Split a DImode AND/IOR/XOR with a constant on a 32-bit system. These
|
||||
operations are split immediately during RTL generation to allow for more
|
||||
optimizations of the AND/IOR/XOR.
|
||||
|
||||
OPERANDS is an array containing the destination and two input operands.
|
||||
CODE is the base operation (AND, IOR, XOR, NOT).
|
||||
MODE is the machine mode.
|
||||
If COMPLEMENT_FINAL_P is true, wrap the whole operation with NOT.
|
||||
If COMPLEMENT_OP1_P is true, wrap operand1 with NOT.
|
||||
If COMPLEMENT_OP2_P is true, wrap operand2 with NOT.
|
||||
CLOBBER_REG is either NULL or a scratch register of type CC to allow
|
||||
formation of the AND instructions. */
|
||||
|
||||
static void
|
||||
rs6000_split_logical_di (rtx operands[3],
|
||||
enum rtx_code code,
|
||||
bool complement_final_p,
|
||||
bool complement_op1_p,
|
||||
bool complement_op2_p,
|
||||
rtx clobber_reg)
|
||||
{
|
||||
const HOST_WIDE_INT lower_32bits = HOST_WIDE_INT_C(0xffffffff);
|
||||
const HOST_WIDE_INT upper_32bits = ~ lower_32bits;
|
||||
const HOST_WIDE_INT sign_bit = HOST_WIDE_INT_C(0x80000000);
|
||||
enum hi_lo { hi = 0, lo = 1 };
|
||||
rtx op0_hi_lo[2], op1_hi_lo[2], op2_hi_lo[2];
|
||||
size_t i;
|
||||
|
||||
op0_hi_lo[hi] = gen_highpart (SImode, operands[0]);
|
||||
op1_hi_lo[hi] = gen_highpart (SImode, operands[1]);
|
||||
op0_hi_lo[lo] = gen_lowpart (SImode, operands[0]);
|
||||
op1_hi_lo[lo] = gen_lowpart (SImode, operands[1]);
|
||||
|
||||
if (code == NOT)
|
||||
op2_hi_lo[hi] = op2_hi_lo[lo] = NULL_RTX;
|
||||
else
|
||||
{
|
||||
if (GET_CODE (operands[2]) != CONST_INT)
|
||||
{
|
||||
op2_hi_lo[hi] = gen_highpart_mode (SImode, DImode, operands[2]);
|
||||
op2_hi_lo[lo] = gen_lowpart (SImode, operands[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
HOST_WIDE_INT value = INTVAL (operands[2]);
|
||||
HOST_WIDE_INT value_hi_lo[2];
|
||||
|
||||
gcc_assert (!complement_final_p);
|
||||
gcc_assert (!complement_op1_p);
|
||||
gcc_assert (!complement_op2_p);
|
||||
|
||||
value_hi_lo[hi] = value >> 32;
|
||||
value_hi_lo[lo] = value & lower_32bits;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
HOST_WIDE_INT sub_value = value_hi_lo[i];
|
||||
|
||||
if (sub_value & sign_bit)
|
||||
sub_value |= upper_32bits;
|
||||
|
||||
op2_hi_lo[i] = GEN_INT (sub_value);
|
||||
|
||||
/* If this is an AND instruction, check to see if we need to load
|
||||
the value in a register. */
|
||||
if (code == AND && sub_value != -1 && sub_value != 0
|
||||
&& !and_operand (op2_hi_lo[i], SImode))
|
||||
op2_hi_lo[i] = force_reg (SImode, op2_hi_lo[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
/* Split large IOR/XOR operations. */
|
||||
if ((code == IOR || code == XOR)
|
||||
&& GET_CODE (op2_hi_lo[i]) == CONST_INT
|
||||
&& !complement_final_p
|
||||
&& !complement_op1_p
|
||||
&& !complement_op2_p
|
||||
&& clobber_reg == NULL_RTX
|
||||
&& !logical_const_operand (op2_hi_lo[i], SImode))
|
||||
{
|
||||
HOST_WIDE_INT value = INTVAL (op2_hi_lo[i]);
|
||||
HOST_WIDE_INT hi_16bits = value & HOST_WIDE_INT_C(0xffff0000);
|
||||
HOST_WIDE_INT lo_16bits = value & HOST_WIDE_INT_C(0x0000ffff);
|
||||
rtx tmp = gen_reg_rtx (SImode);
|
||||
|
||||
/* Make sure the constant is sign extended. */
|
||||
if ((hi_16bits & sign_bit) != 0)
|
||||
hi_16bits |= upper_32bits;
|
||||
|
||||
rs6000_split_logical_inner (tmp, op1_hi_lo[i], GEN_INT (hi_16bits),
|
||||
code, SImode, false, false, false,
|
||||
NULL_RTX);
|
||||
|
||||
rs6000_split_logical_inner (op0_hi_lo[i], tmp, GEN_INT (lo_16bits),
|
||||
code, SImode, false, false, false,
|
||||
NULL_RTX);
|
||||
}
|
||||
else
|
||||
rs6000_split_logical_inner (op0_hi_lo[i], op1_hi_lo[i], op2_hi_lo[i],
|
||||
code, SImode, complement_final_p,
|
||||
complement_op1_p, complement_op2_p,
|
||||
clobber_reg);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Split the insns that make up boolean operations operating on multiple GPR
|
||||
registers. The boolean MD patterns ensure that the inputs either are
|
||||
exactly the same as the output registers, or there is no overlap.
|
||||
|
||||
OPERANDS is an array containing the destination and two input operands.
|
||||
CODE is the base operation (AND, IOR, XOR, NOT).
|
||||
MODE is the machine mode.
|
||||
If COMPLEMENT_FINAL_P is true, wrap the whole operation with NOT.
|
||||
If COMPLEMENT_OP1_P is true, wrap operand1 with NOT.
|
||||
If COMPLEMENT_OP2_P is true, wrap operand2 with NOT.
|
||||
CLOBBER_REG is either NULL or a scratch register of type CC to allow
|
||||
formation of the AND instructions. */
|
||||
|
||||
void
|
||||
rs6000_split_logical (rtx operands[3],
|
||||
enum rtx_code code,
|
||||
bool complement_final_p,
|
||||
bool complement_op1_p,
|
||||
bool complement_op2_p,
|
||||
rtx clobber_reg)
|
||||
{
|
||||
enum machine_mode mode = GET_MODE (operands[0]);
|
||||
enum machine_mode sub_mode;
|
||||
rtx op0, op1, op2;
|
||||
int sub_size, regno0, regno1, nregs, i;
|
||||
|
||||
/* If this is DImode, use the specialized version that can run before
|
||||
register allocation. */
|
||||
if (mode == DImode && !TARGET_POWERPC64)
|
||||
{
|
||||
rs6000_split_logical_di (operands, code, complement_final_p,
|
||||
complement_op1_p, complement_op2_p,
|
||||
clobber_reg);
|
||||
return;
|
||||
}
|
||||
|
||||
op0 = operands[0];
|
||||
op1 = operands[1];
|
||||
op2 = (code == NOT) ? NULL_RTX : operands[2];
|
||||
sub_mode = (TARGET_POWERPC64) ? DImode : SImode;
|
||||
sub_size = GET_MODE_SIZE (sub_mode);
|
||||
regno0 = REGNO (op0);
|
||||
regno1 = REGNO (op1);
|
||||
|
||||
gcc_assert (reload_completed);
|
||||
gcc_assert (IN_RANGE (regno0, FIRST_GPR_REGNO, LAST_GPR_REGNO));
|
||||
gcc_assert (IN_RANGE (regno1, FIRST_GPR_REGNO, LAST_GPR_REGNO));
|
||||
|
||||
nregs = rs6000_hard_regno_nregs[(int)mode][regno0];
|
||||
gcc_assert (nregs > 1);
|
||||
|
||||
if (op2 && REG_P (op2))
|
||||
gcc_assert (IN_RANGE (REGNO (op2), FIRST_GPR_REGNO, LAST_GPR_REGNO));
|
||||
|
||||
for (i = 0; i < nregs; i++)
|
||||
{
|
||||
int offset = i * sub_size;
|
||||
rtx sub_op0 = simplify_subreg (sub_mode, op0, mode, offset);
|
||||
rtx sub_op1 = simplify_subreg (sub_mode, op1, mode, offset);
|
||||
rtx sub_op2 = ((code == NOT)
|
||||
? NULL_RTX
|
||||
: simplify_subreg (sub_mode, op2, mode, offset));
|
||||
|
||||
rs6000_split_logical_inner (sub_op0, sub_op1, sub_op2, code, sub_mode,
|
||||
complement_final_p, complement_op1_p,
|
||||
complement_op2_p, clobber_reg);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
#include "gt-rs6000.h"
|
||||
|
|
|
|||
|
|
@ -1121,14 +1121,11 @@ enum data_align { align_abi, align_opt, align_both };
|
|||
#define VINT_REGNO_P(N) ALTIVEC_REGNO_P (N)
|
||||
|
||||
/* Alternate name for any vector register supporting logical operations, no
|
||||
matter which instruction set(s) are available. For 64-bit mode, we also
|
||||
allow logical operations in the GPRS. This is to allow atomic quad word
|
||||
builtins not to need the VSX registers for lqarx/stqcx. It also helps with
|
||||
__int128_t arguments that are passed in GPRs. */
|
||||
matter which instruction set(s) are available. Allow GPRs as well as the
|
||||
vector registers. */
|
||||
#define VLOGICAL_REGNO_P(N) \
|
||||
(ALTIVEC_REGNO_P (N) \
|
||||
|| (TARGET_VSX && FP_REGNO_P (N)) \
|
||||
|| (TARGET_VSX && TARGET_POWERPC64 && INT_REGNO_P (N)))
|
||||
(INT_REGNO_P (N) || ALTIVEC_REGNO_P (N) \
|
||||
|| (TARGET_VSX && FP_REGNO_P (N))) \
|
||||
|
||||
/* Return number of consecutive hard regs needed starting at reg REGNO
|
||||
to hold something of mode MODE. */
|
||||
|
|
|
|||
|
|
@ -391,6 +391,77 @@
|
|||
|
||||
(define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
|
||||
(DF "TARGET_DOUBLE_FLOAT")])
|
||||
|
||||
;; Mode iterator for logical operations on 128-bit types
|
||||
(define_mode_iterator BOOL_128 [TI
|
||||
PTI
|
||||
(V16QI "TARGET_ALTIVEC")
|
||||
(V8HI "TARGET_ALTIVEC")
|
||||
(V4SI "TARGET_ALTIVEC")
|
||||
(V4SF "TARGET_ALTIVEC")
|
||||
(V2DI "TARGET_ALTIVEC")
|
||||
(V2DF "TARGET_ALTIVEC")])
|
||||
|
||||
;; For the GPRs we use 3 constraints for register outputs, two that are the
|
||||
;; same as the output register, and a third where the output register is an
|
||||
;; early clobber, so we don't have to deal with register overlaps. For the
|
||||
;; vector types, we prefer to use the vector registers. For TI mode, allow
|
||||
;; either.
|
||||
|
||||
;; Mode attribute for boolean operation register constraints for output
|
||||
(define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
|
||||
(PTI "&r,r,r")
|
||||
(V16QI "wa,v,&?r,?r,?r")
|
||||
(V8HI "wa,v,&?r,?r,?r")
|
||||
(V4SI "wa,v,&?r,?r,?r")
|
||||
(V4SF "wa,v,&?r,?r,?r")
|
||||
(V2DI "wa,v,&?r,?r,?r")
|
||||
(V2DF "wa,v,&?r,?r,?r")])
|
||||
|
||||
;; Mode attribute for boolean operation register constraints for operand1
|
||||
(define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
|
||||
(PTI "r,0,r")
|
||||
(V16QI "wa,v,r,0,r")
|
||||
(V8HI "wa,v,r,0,r")
|
||||
(V4SI "wa,v,r,0,r")
|
||||
(V4SF "wa,v,r,0,r")
|
||||
(V2DI "wa,v,r,0,r")
|
||||
(V2DF "wa,v,r,0,r")])
|
||||
|
||||
;; Mode attribute for boolean operation register constraints for operand2
|
||||
(define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
|
||||
(PTI "r,r,0")
|
||||
(V16QI "wa,v,r,r,0")
|
||||
(V8HI "wa,v,r,r,0")
|
||||
(V4SI "wa,v,r,r,0")
|
||||
(V4SF "wa,v,r,r,0")
|
||||
(V2DI "wa,v,r,r,0")
|
||||
(V2DF "wa,v,r,r,0")])
|
||||
|
||||
;; Mode attribute for boolean operation register constraints for operand1
|
||||
;; for one_cmpl. To simplify things, we repeat the constraint where 0
|
||||
;; is used for operand1 or operand2
|
||||
(define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
|
||||
(PTI "r,0,0")
|
||||
(V16QI "wa,v,r,0,0")
|
||||
(V8HI "wa,v,r,0,0")
|
||||
(V4SI "wa,v,r,0,0")
|
||||
(V4SF "wa,v,r,0,0")
|
||||
(V2DI "wa,v,r,0,0")
|
||||
(V2DF "wa,v,r,0,0")])
|
||||
|
||||
;; Mode attribute for the clobber of CC0 for AND expansion.
|
||||
;; For the 128-bit types, we never do AND immediate, but we need to
|
||||
;; get the correct number of X's for the number of operands.
|
||||
(define_mode_attr BOOL_REGS_AND_CR0 [(TI "X,X,X,X,X")
|
||||
(PTI "X,X,X")
|
||||
(V16QI "X,X,X,X,X")
|
||||
(V8HI "X,X,X,X,X")
|
||||
(V4SI "X,X,X,X,X")
|
||||
(V4SF "X,X,X,X,X")
|
||||
(V2DI "X,X,X,X,X")
|
||||
(V2DF "X,X,X,X,X")])
|
||||
|
||||
|
||||
;; Start with fixed-point load and store insns. Here we put only the more
|
||||
;; complex forms. Basic data transfer is done later.
|
||||
|
|
@ -1840,7 +1911,19 @@
|
|||
FAIL;
|
||||
})
|
||||
|
||||
(define_insn "one_cmpl<mode>2"
|
||||
(define_expand "one_cmpl<mode>2"
|
||||
[(set (match_operand:SDI 0 "gpc_reg_operand" "")
|
||||
(not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
|
||||
""
|
||||
{
|
||||
if (<MODE>mode == DImode && !TARGET_POWERPC64)
|
||||
{
|
||||
rs6000_split_logical (operands, NOT, false, false, false, NULL_RTX);
|
||||
DONE;
|
||||
}
|
||||
})
|
||||
|
||||
(define_insn "*one_cmpl<mode>2"
|
||||
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
||||
(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
|
||||
""
|
||||
|
|
@ -7962,10 +8045,19 @@
|
|||
[(parallel
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "")
|
||||
(and:DI (match_operand:DI 1 "gpc_reg_operand" "")
|
||||
(match_operand:DI 2 "and64_2_operand" "")))
|
||||
(match_operand:DI 2 "reg_or_cint_operand" "")))
|
||||
(clobber (match_scratch:CC 3 ""))])]
|
||||
"TARGET_POWERPC64"
|
||||
"")
|
||||
""
|
||||
{
|
||||
if (!TARGET_POWERPC64)
|
||||
{
|
||||
rtx cc = gen_rtx_SCRATCH (CCmode);
|
||||
rs6000_split_logical (operands, AND, false, false, false, cc);
|
||||
DONE;
|
||||
}
|
||||
else if (!and64_2_operand (operands[2], DImode))
|
||||
operands[2] = force_reg (DImode, operands[2]);
|
||||
})
|
||||
|
||||
(define_insn "anddi3_mc"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
|
||||
|
|
@ -8146,11 +8238,17 @@
|
|||
(define_expand "iordi3"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "")
|
||||
(ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
|
||||
(match_operand:DI 2 "reg_or_logical_cint_operand" "")))]
|
||||
"TARGET_POWERPC64"
|
||||
"
|
||||
(match_operand:DI 2 "reg_or_cint_operand" "")))]
|
||||
""
|
||||
{
|
||||
if (non_logical_cint_operand (operands[2], DImode))
|
||||
if (!TARGET_POWERPC64)
|
||||
{
|
||||
rs6000_split_logical (operands, IOR, false, false, false, NULL_RTX);
|
||||
DONE;
|
||||
}
|
||||
else if (!reg_or_logical_cint_operand (operands[2], DImode))
|
||||
operands[2] = force_reg (DImode, operands[2]);
|
||||
else if (non_logical_cint_operand (operands[2], DImode))
|
||||
{
|
||||
HOST_WIDE_INT value;
|
||||
rtx tmp = ((!can_create_pseudo_p ()
|
||||
|
|
@ -8164,15 +8262,21 @@
|
|||
emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
|
||||
DONE;
|
||||
}
|
||||
}")
|
||||
})
|
||||
|
||||
(define_expand "xordi3"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "")
|
||||
(xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
|
||||
(match_operand:DI 2 "reg_or_logical_cint_operand" "")))]
|
||||
"TARGET_POWERPC64"
|
||||
"
|
||||
(match_operand:DI 2 "reg_or_cint_operand" "")))]
|
||||
""
|
||||
{
|
||||
if (!TARGET_POWERPC64)
|
||||
{
|
||||
rs6000_split_logical (operands, XOR, false, false, false, NULL_RTX);
|
||||
DONE;
|
||||
}
|
||||
else if (!reg_or_logical_cint_operand (operands[2], DImode))
|
||||
operands[2] = force_reg (DImode, operands[2]);
|
||||
if (non_logical_cint_operand (operands[2], DImode))
|
||||
{
|
||||
HOST_WIDE_INT value;
|
||||
|
|
@ -8187,7 +8291,7 @@
|
|||
emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
|
||||
DONE;
|
||||
}
|
||||
}")
|
||||
})
|
||||
|
||||
(define_insn "*booldi3_internal1"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
|
||||
|
|
@ -8424,6 +8528,372 @@
|
|||
[(set_attr "type" "integer")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
|
||||
;; 128-bit logical operations expanders
|
||||
|
||||
(define_expand "and<mode>3"
|
||||
[(parallel [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
|
||||
(and:BOOL_128
|
||||
(match_operand:BOOL_128 1 "vlogical_operand" "")
|
||||
(match_operand:BOOL_128 2 "vlogical_operand" "")))
|
||||
(clobber (match_scratch:CC 3 ""))])]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_expand "ior<mode>3"
|
||||
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
|
||||
(ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
|
||||
(match_operand:BOOL_128 2 "vlogical_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_expand "xor<mode>3"
|
||||
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
|
||||
(xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
|
||||
(match_operand:BOOL_128 2 "vlogical_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_expand "one_cmpl<mode>2"
|
||||
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
|
||||
(not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_expand "nor<mode>3"
|
||||
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
|
||||
(and:BOOL_128
|
||||
(not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
|
||||
(not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_expand "andc<mode>3"
|
||||
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
|
||||
(and:BOOL_128
|
||||
(not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
|
||||
(match_operand:BOOL_128 1 "vlogical_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
;; Power8 vector logical instructions.
|
||||
(define_expand "eqv<mode>3"
|
||||
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
|
||||
(not:BOOL_128
|
||||
(xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
|
||||
(match_operand:BOOL_128 2 "vlogical_operand" ""))))]
|
||||
"<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
|
||||
"")
|
||||
|
||||
;; Rewrite nand into canonical form
|
||||
(define_expand "nand<mode>3"
|
||||
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
|
||||
(ior:BOOL_128
|
||||
(not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
|
||||
(not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
|
||||
"<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
|
||||
"")
|
||||
|
||||
;; The canonical form is to have the negated element first, so we need to
|
||||
;; reverse arguments.
|
||||
(define_expand "orc<mode>3"
|
||||
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
|
||||
(ior:BOOL_128
|
||||
(not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
|
||||
(match_operand:BOOL_128 1 "vlogical_operand" "")))]
|
||||
"<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
|
||||
"")
|
||||
|
||||
;; 128-bit logical operations insns and split operations
|
||||
(define_insn_and_split "*and<mode>3_internal"
|
||||
[(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
|
||||
(and:BOOL_128
|
||||
(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
|
||||
(match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))
|
||||
(clobber (match_scratch:CC 3 "<BOOL_REGS_AND_CR0>"))]
|
||||
""
|
||||
{
|
||||
if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
|
||||
return "xxland %x0,%x1,%x2";
|
||||
|
||||
if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
|
||||
return "vand %0,%1,%2";
|
||||
|
||||
return "#";
|
||||
}
|
||||
"reload_completed && int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(const_int 0)]
|
||||
{
|
||||
rs6000_split_logical (operands, AND, false, false, false, operands[3]);
|
||||
DONE;
|
||||
}
|
||||
[(set (attr "type")
|
||||
(if_then_else
|
||||
(match_test "vsx_register_operand (operands[0], <MODE>mode)")
|
||||
(const_string "vecsimple")
|
||||
(const_string "integer")))
|
||||
(set (attr "length")
|
||||
(if_then_else
|
||||
(match_test "vsx_register_operand (operands[0], <MODE>mode)")
|
||||
(const_string "4")
|
||||
(if_then_else
|
||||
(match_test "TARGET_POWERPC64")
|
||||
(const_string "8")
|
||||
(const_string "16"))))])
|
||||
|
||||
;; 128-bit IOR/XOR
|
||||
(define_insn_and_split "*bool<mode>3_internal"
|
||||
[(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
|
||||
(match_operator:BOOL_128 3 "boolean_or_operator"
|
||||
[(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
|
||||
(match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
|
||||
""
|
||||
{
|
||||
if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
|
||||
return "xxl%q3 %x0,%x1,%x2";
|
||||
|
||||
if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
|
||||
return "v%q3 %0,%1,%2";
|
||||
|
||||
return "#";
|
||||
}
|
||||
"reload_completed && int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(const_int 0)]
|
||||
{
|
||||
rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false,
|
||||
NULL_RTX);
|
||||
DONE;
|
||||
}
|
||||
[(set (attr "type")
|
||||
(if_then_else
|
||||
(match_test "vsx_register_operand (operands[0], <MODE>mode)")
|
||||
(const_string "vecsimple")
|
||||
(const_string "integer")))
|
||||
(set (attr "length")
|
||||
(if_then_else
|
||||
(match_test "vsx_register_operand (operands[0], <MODE>mode)")
|
||||
(const_string "4")
|
||||
(if_then_else
|
||||
(match_test "TARGET_POWERPC64")
|
||||
(const_string "8")
|
||||
(const_string "16"))))])
|
||||
|
||||
;; 128-bit ANDC/ORC
|
||||
(define_insn_and_split "*boolc<mode>3_internal1"
|
||||
[(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
|
||||
(match_operator:BOOL_128 3 "boolean_operator"
|
||||
[(not:BOOL_128
|
||||
(match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP1>"))
|
||||
(match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
|
||||
"TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
|
||||
{
|
||||
if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
|
||||
return "xxl%q3 %x0,%x1,%x2";
|
||||
|
||||
if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
|
||||
return "v%q3 %0,%1,%2";
|
||||
|
||||
return "#";
|
||||
}
|
||||
"(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
|
||||
&& reload_completed && int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(const_int 0)]
|
||||
{
|
||||
rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, false,
|
||||
NULL_RTX);
|
||||
DONE;
|
||||
}
|
||||
[(set (attr "type")
|
||||
(if_then_else
|
||||
(match_test "vsx_register_operand (operands[0], <MODE>mode)")
|
||||
(const_string "vecsimple")
|
||||
(const_string "integer")))
|
||||
(set (attr "length")
|
||||
(if_then_else
|
||||
(match_test "vsx_register_operand (operands[0], <MODE>mode)")
|
||||
(const_string "4")
|
||||
(if_then_else
|
||||
(match_test "TARGET_POWERPC64")
|
||||
(const_string "8")
|
||||
(const_string "16"))))])
|
||||
|
||||
(define_insn_and_split "*boolc<mode>3_internal2"
|
||||
[(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
|
||||
(match_operator:TI2 3 "boolean_operator"
|
||||
[(not:TI2
|
||||
(match_operand:TI2 1 "int_reg_operand" "r,0,r"))
|
||||
(match_operand:TI2 2 "int_reg_operand" "r,r,0")]))]
|
||||
"!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
|
||||
"#"
|
||||
"reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
|
||||
[(const_int 0)]
|
||||
{
|
||||
rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, false,
|
||||
NULL_RTX);
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "type" "integer")
|
||||
(set (attr "length")
|
||||
(if_then_else
|
||||
(match_test "TARGET_POWERPC64")
|
||||
(const_string "8")
|
||||
(const_string "16")))])
|
||||
|
||||
;; 128-bit NAND/NOR
|
||||
(define_insn_and_split "*boolcc<mode>3_internal1"
|
||||
[(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
|
||||
(match_operator:BOOL_128 3 "boolean_operator"
|
||||
[(not:BOOL_128
|
||||
(match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
|
||||
(not:BOOL_128
|
||||
(match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
|
||||
"TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
|
||||
{
|
||||
if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
|
||||
return "xxl%q3 %x0,%x1,%x2";
|
||||
|
||||
if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
|
||||
return "v%q3 %0,%1,%2";
|
||||
|
||||
return "#";
|
||||
}
|
||||
"(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
|
||||
&& reload_completed && int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(const_int 0)]
|
||||
{
|
||||
rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true,
|
||||
NULL_RTX);
|
||||
DONE;
|
||||
}
|
||||
[(set (attr "type")
|
||||
(if_then_else
|
||||
(match_test "vsx_register_operand (operands[0], <MODE>mode)")
|
||||
(const_string "vecsimple")
|
||||
(const_string "integer")))
|
||||
(set (attr "length")
|
||||
(if_then_else
|
||||
(match_test "vsx_register_operand (operands[0], <MODE>mode)")
|
||||
(const_string "4")
|
||||
(if_then_else
|
||||
(match_test "TARGET_POWERPC64")
|
||||
(const_string "8")
|
||||
(const_string "16"))))])
|
||||
|
||||
(define_insn_and_split "*boolcc<mode>3_internal2"
|
||||
[(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
|
||||
(match_operator:TI2 3 "boolean_operator"
|
||||
[(not:TI2
|
||||
(match_operand:TI2 1 "int_reg_operand" "r,0,r"))
|
||||
(not:TI2
|
||||
(match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
|
||||
"!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
|
||||
"#"
|
||||
"reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
|
||||
[(const_int 0)]
|
||||
{
|
||||
rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true,
|
||||
NULL_RTX);
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "type" "integer")
|
||||
(set (attr "length")
|
||||
(if_then_else
|
||||
(match_test "TARGET_POWERPC64")
|
||||
(const_string "8")
|
||||
(const_string "16")))])
|
||||
|
||||
|
||||
;; 128-bit EQV
|
||||
(define_insn_and_split "*eqv<mode>3_internal1"
|
||||
[(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
|
||||
(not:BOOL_128
|
||||
(xor:BOOL_128
|
||||
(match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
|
||||
(match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
|
||||
"TARGET_P8_VECTOR"
|
||||
{
|
||||
if (vsx_register_operand (operands[0], <MODE>mode))
|
||||
return "xxleqv %x0,%x1,%x2";
|
||||
|
||||
return "#";
|
||||
}
|
||||
"TARGET_P8_VECTOR && reload_completed
|
||||
&& int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(const_int 0)]
|
||||
{
|
||||
rs6000_split_logical (operands, XOR, true, false, false, NULL_RTX);
|
||||
DONE;
|
||||
}
|
||||
[(set (attr "type")
|
||||
(if_then_else
|
||||
(match_test "vsx_register_operand (operands[0], <MODE>mode)")
|
||||
(const_string "vecsimple")
|
||||
(const_string "integer")))
|
||||
(set (attr "length")
|
||||
(if_then_else
|
||||
(match_test "vsx_register_operand (operands[0], <MODE>mode)")
|
||||
(const_string "4")
|
||||
(if_then_else
|
||||
(match_test "TARGET_POWERPC64")
|
||||
(const_string "8")
|
||||
(const_string "16"))))])
|
||||
|
||||
(define_insn_and_split "*eqv<mode>3_internal2"
|
||||
[(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
|
||||
(not:TI2
|
||||
(xor:TI2
|
||||
(match_operand:TI2 1 "int_reg_operand" "r,0,r")
|
||||
(match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
|
||||
"!TARGET_P8_VECTOR"
|
||||
"#"
|
||||
"reload_completed && !TARGET_P8_VECTOR"
|
||||
[(const_int 0)]
|
||||
{
|
||||
rs6000_split_logical (operands, XOR, true, false, false, NULL_RTX);
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "type" "integer")
|
||||
(set (attr "length")
|
||||
(if_then_else
|
||||
(match_test "TARGET_POWERPC64")
|
||||
(const_string "8")
|
||||
(const_string "16")))])
|
||||
|
||||
;; 128-bit one's complement
|
||||
(define_insn_and_split "*one_cmpl<mode>3_internal"
|
||||
[(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
|
||||
(not:BOOL_128
|
||||
(match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
|
||||
""
|
||||
{
|
||||
if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
|
||||
return "xxlnor %x0,%x1,%x1";
|
||||
|
||||
if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
|
||||
return "vnor %0,%1,%1";
|
||||
|
||||
return "#";
|
||||
}
|
||||
"reload_completed && int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(const_int 0)]
|
||||
{
|
||||
rs6000_split_logical (operands, NOT, false, false, false, NULL_RTX);
|
||||
DONE;
|
||||
}
|
||||
[(set (attr "type")
|
||||
(if_then_else
|
||||
(match_test "vsx_register_operand (operands[0], <MODE>mode)")
|
||||
(const_string "vecsimple")
|
||||
(const_string "integer")))
|
||||
(set (attr "length")
|
||||
(if_then_else
|
||||
(match_test "vsx_register_operand (operands[0], <MODE>mode)")
|
||||
(const_string "4")
|
||||
(if_then_else
|
||||
(match_test "TARGET_POWERPC64")
|
||||
(const_string "8")
|
||||
(const_string "16"))))])
|
||||
|
||||
|
||||
;; Now define ways of moving data around.
|
||||
|
||||
|
|
|
|||
|
|
@ -710,87 +710,6 @@
|
|||
"")
|
||||
|
||||
|
||||
;; Vector logical instructions
|
||||
;; Do not support TImode logical instructions on 32-bit at present, because the
|
||||
;; compiler will see that we have a TImode and when it wanted DImode, and
|
||||
;; convert the DImode to TImode, store it on the stack, and load it in a VSX
|
||||
;; register.
|
||||
(define_expand "xor<mode>3"
|
||||
[(set (match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(xor:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
|
||||
(match_operand:VEC_L 2 "vlogical_operand" "")))]
|
||||
"VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)
|
||||
&& (<MODE>mode != TImode || TARGET_POWERPC64)"
|
||||
"")
|
||||
|
||||
(define_expand "ior<mode>3"
|
||||
[(set (match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
|
||||
(match_operand:VEC_L 2 "vlogical_operand" "")))]
|
||||
"VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)
|
||||
&& (<MODE>mode != TImode || TARGET_POWERPC64)"
|
||||
"")
|
||||
|
||||
(define_expand "and<mode>3"
|
||||
[(parallel [(set (match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(and:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
|
||||
(match_operand:VEC_L 2 "vlogical_operand" "")))
|
||||
(clobber (match_scratch:CC 3 ""))])]
|
||||
"VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)
|
||||
&& (<MODE>mode != TImode || TARGET_POWERPC64)"
|
||||
"")
|
||||
|
||||
(define_expand "one_cmpl<mode>2"
|
||||
[(set (match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(not:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")))]
|
||||
"VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)
|
||||
&& (<MODE>mode != TImode || TARGET_POWERPC64)"
|
||||
"")
|
||||
|
||||
(define_expand "nor<mode>3"
|
||||
[(set (match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(and:VEC_L (not:VEC_L (match_operand:VEC_L 1 "vlogical_operand" ""))
|
||||
(not:VEC_L (match_operand:VEC_L 2 "vlogical_operand" ""))))]
|
||||
"VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)
|
||||
&& (<MODE>mode != TImode || TARGET_POWERPC64)"
|
||||
"")
|
||||
|
||||
(define_expand "andc<mode>3"
|
||||
[(set (match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(and:VEC_L (not:VEC_L (match_operand:VEC_L 2 "vlogical_operand" ""))
|
||||
(match_operand:VEC_L 1 "vlogical_operand" "")))]
|
||||
"VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)
|
||||
&& (<MODE>mode != TImode || TARGET_POWERPC64)"
|
||||
"")
|
||||
|
||||
;; Power8 vector logical instructions.
|
||||
(define_expand "eqv<mode>3"
|
||||
[(set (match_operand:VEC_L 0 "register_operand" "")
|
||||
(not:VEC_L
|
||||
(xor:VEC_L (match_operand:VEC_L 1 "register_operand" "")
|
||||
(match_operand:VEC_L 2 "register_operand" ""))))]
|
||||
"TARGET_P8_VECTOR && VECTOR_MEM_VSX_P (<MODE>mode)
|
||||
&& (<MODE>mode != TImode || TARGET_POWERPC64)")
|
||||
|
||||
;; Rewrite nand into canonical form
|
||||
(define_expand "nand<mode>3"
|
||||
[(set (match_operand:VEC_L 0 "register_operand" "")
|
||||
(ior:VEC_L
|
||||
(not:VEC_L (match_operand:VEC_L 1 "register_operand" ""))
|
||||
(not:VEC_L (match_operand:VEC_L 2 "register_operand" ""))))]
|
||||
"TARGET_P8_VECTOR && VECTOR_MEM_VSX_P (<MODE>mode)
|
||||
&& (<MODE>mode != TImode || TARGET_POWERPC64)")
|
||||
|
||||
;; The canonical form is to have the negated elment first, so we need to
|
||||
;; reverse arguments.
|
||||
(define_expand "orc<mode>3"
|
||||
[(set (match_operand:VEC_L 0 "register_operand" "")
|
||||
(ior:VEC_L
|
||||
(not:VEC_L (match_operand:VEC_L 1 "register_operand" ""))
|
||||
(match_operand:VEC_L 2 "register_operand" "")))]
|
||||
"TARGET_P8_VECTOR && VECTOR_MEM_VSX_P (<MODE>mode)
|
||||
&& (<MODE>mode != TImode || TARGET_POWERPC64)")
|
||||
|
||||
;; Vector count leading zeros
|
||||
(define_expand "clz<mode>2"
|
||||
[(set (match_operand:VEC_I 0 "register_operand" "")
|
||||
|
|
|
|||
|
|
@ -36,10 +36,6 @@
|
|||
;; Iterator for logical types supported by VSX
|
||||
(define_mode_iterator VSX_L [V16QI V8HI V4SI V2DI V4SF V2DF TI])
|
||||
|
||||
;; Like VSX_L, but don't support TImode for doing logical instructions in
|
||||
;; 32-bit
|
||||
(define_mode_iterator VSX_L2 [V16QI V8HI V4SI V2DI V4SF V2DF])
|
||||
|
||||
;; Iterator for memory move. Handle TImode specially to allow
|
||||
;; it to use gprs as well as vsx registers.
|
||||
(define_mode_iterator VSX_M [V16QI V8HI V4SI V2DI V4SF V2DF])
|
||||
|
|
@ -1046,370 +1042,6 @@
|
|||
[(set_attr "type" "<VStype_simple>")
|
||||
(set_attr "fp_type" "<VSfptype_simple>")])
|
||||
|
||||
|
||||
;; Logical operations. Do not support TImode logical instructions on 32-bit at
|
||||
;; present, because the compiler will see that we have a TImode and when it
|
||||
;; wanted DImode, and convert the DImode to TImode, store it on the stack, and
|
||||
;; load it in a VSX register or generate extra logical instructions in GPR
|
||||
;; registers.
|
||||
|
||||
;; When we are splitting the operations to GPRs, we use three alternatives, two
|
||||
;; where the first/second inputs and output are in the same register, and the
|
||||
;; third where the output specifies an early clobber so that we don't have to
|
||||
;; worry about overlapping registers.
|
||||
|
||||
(define_insn "*vsx_and<mode>3_32bit"
|
||||
[(set (match_operand:VSX_L2 0 "vlogical_operand" "=wa")
|
||||
(and:VSX_L2 (match_operand:VSX_L2 1 "vlogical_operand" "%wa")
|
||||
(match_operand:VSX_L2 2 "vlogical_operand" "wa")))
|
||||
(clobber (match_scratch:CC 3 "X"))]
|
||||
"!TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"xxland %x0,%x1,%x2"
|
||||
[(set_attr "type" "vecsimple")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn_and_split "*vsx_and<mode>3_64bit"
|
||||
[(set (match_operand:VSX_L 0 "vlogical_operand" "=wa,?r,?r,&?r")
|
||||
(and:VSX_L
|
||||
(match_operand:VSX_L 1 "vlogical_operand" "%wa,0,r,r")
|
||||
(match_operand:VSX_L 2 "vlogical_operand" "wa,r,0,r")))
|
||||
(clobber (match_scratch:CC 3 "X,X,X,X"))]
|
||||
"TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"@
|
||||
xxland %x0,%x1,%x2
|
||||
#
|
||||
#
|
||||
#"
|
||||
"reload_completed && TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)
|
||||
&& int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(parallel [(set (match_dup 4) (and:DI (match_dup 5) (match_dup 6)))
|
||||
(clobber (match_dup 3))])
|
||||
(parallel [(set (match_dup 7) (and:DI (match_dup 8) (match_dup 9)))
|
||||
(clobber (match_dup 3))])]
|
||||
{
|
||||
operands[4] = simplify_subreg (DImode, operands[0], <MODE>mode, 0);
|
||||
operands[5] = simplify_subreg (DImode, operands[1], <MODE>mode, 0);
|
||||
operands[6] = simplify_subreg (DImode, operands[2], <MODE>mode, 0);
|
||||
operands[7] = simplify_subreg (DImode, operands[0], <MODE>mode, 8);
|
||||
operands[8] = simplify_subreg (DImode, operands[1], <MODE>mode, 8);
|
||||
operands[9] = simplify_subreg (DImode, operands[2], <MODE>mode, 8);
|
||||
}
|
||||
[(set_attr "type" "vecsimple,two,two,two")
|
||||
(set_attr "length" "4,8,8,8")])
|
||||
|
||||
(define_insn "*vsx_ior<mode>3_32bit"
|
||||
[(set (match_operand:VSX_L2 0 "vlogical_operand" "=wa")
|
||||
(ior:VSX_L2 (match_operand:VSX_L2 1 "vlogical_operand" "%wa")
|
||||
(match_operand:VSX_L2 2 "vlogical_operand" "wa")))]
|
||||
"!TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"xxlor %x0,%x1,%x2"
|
||||
[(set_attr "type" "vecsimple")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn_and_split "*vsx_ior<mode>3_64bit"
|
||||
[(set (match_operand:VSX_L 0 "vlogical_operand" "=wa,?r,?r,&?r,?r,&?r")
|
||||
(ior:VSX_L
|
||||
(match_operand:VSX_L 1 "vlogical_operand" "%wa,0,r,r,0,r")
|
||||
(match_operand:VSX_L 2 "vsx_reg_or_cint_operand" "wa,r,0,r,n,n")))]
|
||||
"TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"@
|
||||
xxlor %x0,%x1,%x2
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#"
|
||||
"reload_completed && TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)
|
||||
&& int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(const_int 0)]
|
||||
{
|
||||
operands[3] = simplify_subreg (DImode, operands[0], <MODE>mode, 0);
|
||||
operands[4] = simplify_subreg (DImode, operands[1], <MODE>mode, 0);
|
||||
operands[5] = simplify_subreg (DImode, operands[2], <MODE>mode, 0);
|
||||
operands[6] = simplify_subreg (DImode, operands[0], <MODE>mode, 8);
|
||||
operands[7] = simplify_subreg (DImode, operands[1], <MODE>mode, 8);
|
||||
operands[8] = simplify_subreg (DImode, operands[2], <MODE>mode, 8);
|
||||
|
||||
if (operands[5] == constm1_rtx)
|
||||
emit_move_insn (operands[3], constm1_rtx);
|
||||
|
||||
else if (operands[5] == const0_rtx)
|
||||
{
|
||||
if (!rtx_equal_p (operands[3], operands[4]))
|
||||
emit_move_insn (operands[3], operands[4]);
|
||||
}
|
||||
else
|
||||
emit_insn (gen_iordi3 (operands[3], operands[4], operands[5]));
|
||||
|
||||
if (operands[8] == constm1_rtx)
|
||||
emit_move_insn (operands[8], constm1_rtx);
|
||||
|
||||
else if (operands[8] == const0_rtx)
|
||||
{
|
||||
if (!rtx_equal_p (operands[6], operands[7]))
|
||||
emit_move_insn (operands[6], operands[7]);
|
||||
}
|
||||
else
|
||||
emit_insn (gen_iordi3 (operands[6], operands[7], operands[8]));
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "type" "vecsimple,two,two,two,three,three")
|
||||
(set_attr "length" "4,8,8,8,16,16")])
|
||||
|
||||
(define_insn "*vsx_xor<mode>3_32bit"
|
||||
[(set (match_operand:VSX_L2 0 "vlogical_operand" "=wa")
|
||||
(xor:VSX_L2 (match_operand:VSX_L2 1 "vlogical_operand" "%wa")
|
||||
(match_operand:VSX_L2 2 "vlogical_operand" "wa")))]
|
||||
"VECTOR_MEM_VSX_P (<MODE>mode) && !TARGET_POWERPC64"
|
||||
"xxlxor %x0,%x1,%x2"
|
||||
[(set_attr "type" "vecsimple")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn_and_split "*vsx_xor<mode>3_64bit"
|
||||
[(set (match_operand:VSX_L 0 "vlogical_operand" "=wa,?r,?r,&?r,?r,&?r")
|
||||
(xor:VSX_L
|
||||
(match_operand:VSX_L 1 "vlogical_operand" "%wa,0,r,r,0,r")
|
||||
(match_operand:VSX_L 2 "vsx_reg_or_cint_operand" "wa,r,0,r,n,n")))]
|
||||
"TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"@
|
||||
xxlxor %x0,%x1,%x2
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#"
|
||||
"reload_completed && TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)
|
||||
&& int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(set (match_dup 3) (xor:DI (match_dup 4) (match_dup 5)))
|
||||
(set (match_dup 6) (xor:DI (match_dup 7) (match_dup 8)))]
|
||||
{
|
||||
operands[3] = simplify_subreg (DImode, operands[0], <MODE>mode, 0);
|
||||
operands[4] = simplify_subreg (DImode, operands[1], <MODE>mode, 0);
|
||||
operands[5] = simplify_subreg (DImode, operands[2], <MODE>mode, 0);
|
||||
operands[6] = simplify_subreg (DImode, operands[0], <MODE>mode, 8);
|
||||
operands[7] = simplify_subreg (DImode, operands[1], <MODE>mode, 8);
|
||||
operands[8] = simplify_subreg (DImode, operands[2], <MODE>mode, 8);
|
||||
}
|
||||
[(set_attr "type" "vecsimple,two,two,two,three,three")
|
||||
(set_attr "length" "4,8,8,8,16,16")])
|
||||
|
||||
(define_insn "*vsx_one_cmpl<mode>2_32bit"
|
||||
[(set (match_operand:VSX_L2 0 "vlogical_operand" "=wa")
|
||||
(not:VSX_L2 (match_operand:VSX_L2 1 "vlogical_operand" "wa")))]
|
||||
"!TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"xxlnor %x0,%x1,%x1"
|
||||
[(set_attr "type" "vecsimple")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn_and_split "*vsx_one_cmpl<mode>2_64bit"
|
||||
[(set (match_operand:VSX_L 0 "vlogical_operand" "=wa,?r,&?r")
|
||||
(not:VSX_L (match_operand:VSX_L 1 "vlogical_operand" "wa,0,r")))]
|
||||
"TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"@
|
||||
xxlnor %x0,%x1,%x1
|
||||
#
|
||||
#"
|
||||
"reload_completed && TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)
|
||||
&& int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(set (match_dup 2) (not:DI (match_dup 3)))
|
||||
(set (match_dup 4) (not:DI (match_dup 5)))]
|
||||
{
|
||||
operands[2] = simplify_subreg (DImode, operands[0], <MODE>mode, 0);
|
||||
operands[3] = simplify_subreg (DImode, operands[1], <MODE>mode, 0);
|
||||
operands[4] = simplify_subreg (DImode, operands[0], <MODE>mode, 8);
|
||||
operands[5] = simplify_subreg (DImode, operands[1], <MODE>mode, 8);
|
||||
}
|
||||
[(set_attr "type" "vecsimple,two,two")
|
||||
(set_attr "length" "4,8,8")])
|
||||
|
||||
(define_insn "*vsx_nor<mode>3_32bit"
|
||||
[(set (match_operand:VSX_L2 0 "vlogical_operand" "=wa")
|
||||
(and:VSX_L2
|
||||
(not:VSX_L2 (match_operand:VSX_L 1 "vlogical_operand" "%wa"))
|
||||
(not:VSX_L2 (match_operand:VSX_L 2 "vlogical_operand" "wa"))))]
|
||||
"!TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"xxlnor %x0,%x1,%x2"
|
||||
[(set_attr "type" "vecsimple")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn_and_split "*vsx_nor<mode>3_64bit"
|
||||
[(set (match_operand:VSX_L 0 "vlogical_operand" "=wa,?r,?r,&?r")
|
||||
(and:VSX_L
|
||||
(not:VSX_L (match_operand:VSX_L 1 "vlogical_operand" "%wa,0,r,r"))
|
||||
(not:VSX_L (match_operand:VSX_L 2 "vlogical_operand" "wa,r,0,r"))))]
|
||||
"TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"@
|
||||
xxlnor %x0,%x1,%x2
|
||||
#
|
||||
#
|
||||
#"
|
||||
"reload_completed && TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)
|
||||
&& int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(set (match_dup 3) (and:DI (not:DI (match_dup 4)) (not:DI (match_dup 5))))
|
||||
(set (match_dup 6) (and:DI (not:DI (match_dup 7)) (not:DI (match_dup 8))))]
|
||||
{
|
||||
operands[3] = simplify_subreg (DImode, operands[0], <MODE>mode, 0);
|
||||
operands[4] = simplify_subreg (DImode, operands[1], <MODE>mode, 0);
|
||||
operands[5] = simplify_subreg (DImode, operands[2], <MODE>mode, 0);
|
||||
operands[6] = simplify_subreg (DImode, operands[0], <MODE>mode, 8);
|
||||
operands[7] = simplify_subreg (DImode, operands[1], <MODE>mode, 8);
|
||||
operands[8] = simplify_subreg (DImode, operands[2], <MODE>mode, 8);
|
||||
}
|
||||
[(set_attr "type" "vecsimple,two,two,two")
|
||||
(set_attr "length" "4,8,8,8")])
|
||||
|
||||
(define_insn "*vsx_andc<mode>3_32bit"
|
||||
[(set (match_operand:VSX_L2 0 "vlogical_operand" "=wa")
|
||||
(and:VSX_L2
|
||||
(not:VSX_L2
|
||||
(match_operand:VSX_L2 2 "vlogical_operand" "wa"))
|
||||
(match_operand:VSX_L2 1 "vlogical_operand" "wa")))]
|
||||
"!TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"xxlandc %x0,%x1,%x2"
|
||||
[(set_attr "type" "vecsimple")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn_and_split "*vsx_andc<mode>3_64bit"
|
||||
[(set (match_operand:VSX_L 0 "vlogical_operand" "=wa,?r,?r,?r")
|
||||
(and:VSX_L
|
||||
(not:VSX_L
|
||||
(match_operand:VSX_L 2 "vlogical_operand" "wa,0,r,r"))
|
||||
(match_operand:VSX_L 1 "vlogical_operand" "wa,r,0,r")))]
|
||||
"TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"@
|
||||
xxlandc %x0,%x1,%x2
|
||||
#
|
||||
#
|
||||
#"
|
||||
"reload_completed && TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)
|
||||
&& int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(set (match_dup 3) (and:DI (not:DI (match_dup 4)) (match_dup 5)))
|
||||
(set (match_dup 6) (and:DI (not:DI (match_dup 7)) (match_dup 8)))]
|
||||
{
|
||||
operands[3] = simplify_subreg (DImode, operands[0], <MODE>mode, 0);
|
||||
operands[4] = simplify_subreg (DImode, operands[1], <MODE>mode, 0);
|
||||
operands[5] = simplify_subreg (DImode, operands[2], <MODE>mode, 0);
|
||||
operands[6] = simplify_subreg (DImode, operands[0], <MODE>mode, 8);
|
||||
operands[7] = simplify_subreg (DImode, operands[1], <MODE>mode, 8);
|
||||
operands[8] = simplify_subreg (DImode, operands[2], <MODE>mode, 8);
|
||||
}
|
||||
[(set_attr "type" "vecsimple,two,two,two")
|
||||
(set_attr "length" "4,8,8,8")])
|
||||
|
||||
;; Power8 vector logical instructions.
|
||||
(define_insn "*vsx_eqv<mode>3_32bit"
|
||||
[(set (match_operand:VSX_L2 0 "vlogical_operand" "=wa")
|
||||
(not:VSX_L2
|
||||
(xor:VSX_L2 (match_operand:VSX_L2 1 "vlogical_operand" "wa")
|
||||
(match_operand:VSX_L2 2 "vlogical_operand" "wa"))))]
|
||||
"!TARGET_POWERPC64 && TARGET_P8_VECTOR && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"xxleqv %x0,%x1,%x2"
|
||||
[(set_attr "type" "vecsimple")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn_and_split "*vsx_eqv<mode>3_64bit"
|
||||
[(set (match_operand:VSX_L 0 "vlogical_operand" "=wa,?r,?r,?r")
|
||||
(not:VSX_L
|
||||
(xor:VSX_L (match_operand:VSX_L 1 "vlogical_operand" "wa,0,r,r")
|
||||
(match_operand:VSX_L 2 "vlogical_operand" "wa,r,0,r"))))]
|
||||
"TARGET_POWERPC64 && TARGET_P8_VECTOR && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"@
|
||||
xxleqv %x0,%x1,%x2
|
||||
#
|
||||
#
|
||||
#"
|
||||
"reload_completed && TARGET_POWERPC64 && TARGET_P8_VECTOR
|
||||
&& VECTOR_MEM_VSX_P (<MODE>mode)
|
||||
&& int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(set (match_dup 3) (not:DI (xor:DI (match_dup 4) (match_dup 5))))
|
||||
(set (match_dup 6) (not:DI (xor:DI (match_dup 7) (match_dup 8))))]
|
||||
{
|
||||
operands[3] = simplify_subreg (DImode, operands[0], <MODE>mode, 0);
|
||||
operands[4] = simplify_subreg (DImode, operands[1], <MODE>mode, 0);
|
||||
operands[5] = simplify_subreg (DImode, operands[2], <MODE>mode, 0);
|
||||
operands[6] = simplify_subreg (DImode, operands[0], <MODE>mode, 8);
|
||||
operands[7] = simplify_subreg (DImode, operands[1], <MODE>mode, 8);
|
||||
operands[8] = simplify_subreg (DImode, operands[2], <MODE>mode, 8);
|
||||
}
|
||||
[(set_attr "type" "vecsimple,two,two,two")
|
||||
(set_attr "length" "4,8,8,8")])
|
||||
|
||||
;; Rewrite nand into canonical form
|
||||
(define_insn "*vsx_nand<mode>3_32bit"
|
||||
[(set (match_operand:VSX_L2 0 "vlogical_operand" "=wa")
|
||||
(ior:VSX_L2
|
||||
(not:VSX_L2 (match_operand:VSX_L2 1 "vlogical_operand" "wa"))
|
||||
(not:VSX_L2 (match_operand:VSX_L2 2 "vlogical_operand" "wa"))))]
|
||||
"!TARGET_POWERPC64 && TARGET_P8_VECTOR && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"xxlnand %x0,%x1,%x2"
|
||||
[(set_attr "type" "vecsimple")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn_and_split "*vsx_nand<mode>3_64bit"
|
||||
[(set (match_operand:VSX_L 0 "register_operand" "=wa,?r,?r,?r")
|
||||
(ior:VSX_L
|
||||
(not:VSX_L (match_operand:VSX_L 1 "register_operand" "wa,0,r,r"))
|
||||
(not:VSX_L (match_operand:VSX_L 2 "register_operand" "wa,r,0,r"))))]
|
||||
"TARGET_POWERPC64 && TARGET_P8_VECTOR && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"@
|
||||
xxlnand %x0,%x1,%x2
|
||||
#
|
||||
#
|
||||
#"
|
||||
"reload_completed && TARGET_POWERPC64 && TARGET_P8_VECTOR
|
||||
&& VECTOR_MEM_VSX_P (<MODE>mode)
|
||||
&& int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(set (match_dup 3) (ior:DI (not:DI (match_dup 4)) (not:DI (match_dup 5))))
|
||||
(set (match_dup 6) (ior:DI (not:DI (match_dup 7)) (not:DI (match_dup 8))))]
|
||||
{
|
||||
operands[3] = simplify_subreg (DImode, operands[0], <MODE>mode, 0);
|
||||
operands[4] = simplify_subreg (DImode, operands[1], <MODE>mode, 0);
|
||||
operands[5] = simplify_subreg (DImode, operands[2], <MODE>mode, 0);
|
||||
operands[6] = simplify_subreg (DImode, operands[0], <MODE>mode, 8);
|
||||
operands[7] = simplify_subreg (DImode, operands[1], <MODE>mode, 8);
|
||||
operands[8] = simplify_subreg (DImode, operands[2], <MODE>mode, 8);
|
||||
}
|
||||
[(set_attr "type" "vecsimple,two,two,two")
|
||||
(set_attr "length" "4,8,8,8")])
|
||||
|
||||
;; Rewrite or complement into canonical form, by reversing the arguments
|
||||
(define_insn "*vsx_orc<mode>3_32bit"
|
||||
[(set (match_operand:VSX_L2 0 "vlogical_operand" "=wa")
|
||||
(ior:VSX_L2
|
||||
(not:VSX_L2 (match_operand:VSX_L2 1 "vlogical_operand" "wa"))
|
||||
(match_operand:VSX_L2 2 "vlogical_operand" "wa")))]
|
||||
"!TARGET_POWERPC64 && TARGET_P8_VECTOR && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"xxlorc %x0,%x2,%x1"
|
||||
[(set_attr "type" "vecsimple")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn_and_split "*vsx_orc<mode>3_64bit"
|
||||
[(set (match_operand:VSX_L 0 "vlogical_operand" "=wa,?r,?r,?r")
|
||||
(ior:VSX_L
|
||||
(not:VSX_L (match_operand:VSX_L 1 "vlogical_operand" "wa,0,r,r"))
|
||||
(match_operand:VSX_L 2 "vlogical_operand" "wa,r,0,r")))]
|
||||
"TARGET_POWERPC64 && TARGET_P8_VECTOR && VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||
"@
|
||||
xxlorc %x0,%x2,%x1
|
||||
#
|
||||
#
|
||||
#"
|
||||
"reload_completed && TARGET_POWERPC64 && TARGET_P8_VECTOR
|
||||
&& VECTOR_MEM_VSX_P (<MODE>mode)
|
||||
&& int_reg_operand (operands[0], <MODE>mode)"
|
||||
[(set (match_dup 3) (ior:DI (not:DI (match_dup 4)) (match_dup 5)))
|
||||
(set (match_dup 6) (ior:DI (not:DI (match_dup 7)) (match_dup 8)))]
|
||||
{
|
||||
operands[3] = simplify_subreg (DImode, operands[0], <MODE>mode, 0);
|
||||
operands[4] = simplify_subreg (DImode, operands[1], <MODE>mode, 0);
|
||||
operands[5] = simplify_subreg (DImode, operands[2], <MODE>mode, 0);
|
||||
operands[6] = simplify_subreg (DImode, operands[0], <MODE>mode, 8);
|
||||
operands[7] = simplify_subreg (DImode, operands[1], <MODE>mode, 8);
|
||||
operands[8] = simplify_subreg (DImode, operands[2], <MODE>mode, 8);
|
||||
}
|
||||
[(set_attr "type" "vecsimple,two,two,two")
|
||||
(set_attr "length" "4,8,8,8")])
|
||||
|
||||
|
||||
;; Permute operations
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,17 @@
|
|||
2013-07-23 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
* gcc.target/powerpc/bool2.h: New file, test the code generation
|
||||
of logical operations for power5, altivec, power7, and power8
|
||||
systems.
|
||||
* gcc.target/powerpc/bool2-p5.c: Likewise.
|
||||
* gcc.target/powerpc/bool2-av.c: Likewise.
|
||||
* gcc.target/powerpc/bool2-p7.c: Likewise.
|
||||
* gcc.target/powerpc/bool2-p8.c: Likewise.
|
||||
* gcc.target/powerpc/bool3.h: Likewise.
|
||||
* gcc.target/powerpc/bool3-av.c: Likewise.
|
||||
* gcc.target/powerpc/bool2-p7.c: Likewise.
|
||||
* gcc.target/powerpc/bool2-p8.c: Likewise.
|
||||
|
||||
2013-07-23 Yufeng Zhang <yufeng.zhang@arm.com>
|
||||
|
||||
* gcc.target/aarch64/vect_smlal_1.c: Replace 'long' with 'long long'.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target powerpc_altivec_ok } */
|
||||
/* { dg-options "-O2 -mcpu=power6 -maltivec" } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]and " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]or " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]nor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]andc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]eqv " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]orc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]nand " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]vand " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]vandc " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]vor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]vxor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]vnor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxland " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlxor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlnor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlandc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxleqv " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlorc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlnand " } } */
|
||||
|
||||
#ifndef TYPE
|
||||
typedef int v4si __attribute__ ((vector_size (16)));
|
||||
#define TYPE v4si
|
||||
#endif
|
||||
|
||||
#include "bool2.h"
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target powerpc_altivec_ok } */
|
||||
/* { dg-options "-O2 -mcpu=power5 -mabi=altivec -mno-altivec -mno-vsx" } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]and " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]or " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]nor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]andc " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]eqv " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]orc " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]nand " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vand " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vandc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vxor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vnor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxland " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlxor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlnor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlandc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxleqv " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlorc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlnand " } } */
|
||||
|
||||
#ifndef TYPE
|
||||
typedef int v4si __attribute__ ((vector_size (16)));
|
||||
#define TYPE v4si
|
||||
#endif
|
||||
|
||||
#include "bool2.h"
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target powerpc_vsx_ok } */
|
||||
/* { dg-options "-O2 -mcpu=power7" } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]and " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]or " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]nor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]eqv " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]andc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]orc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]nand " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vand " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vxor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vnor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xxland " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xxlor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xxlxor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xxlnor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xxlandc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxleqv " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlorc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlnand " } } */
|
||||
|
||||
#ifndef TYPE
|
||||
typedef int v4si __attribute__ ((vector_size (16)));
|
||||
#define TYPE v4si
|
||||
#endif
|
||||
|
||||
#include "bool2.h"
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target powerpc_p8vector_ok } */
|
||||
/* { dg-options "-O2 -mcpu=power8" } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]and " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]or " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]nor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]eqv " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]andc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]orc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]nand " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vand " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vandc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vxor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vnor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xxland " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xxlor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xxlxor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xxlnor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xxlandc " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xxleqv " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xxlorc " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xxlnand " } } */
|
||||
|
||||
#ifndef TYPE
|
||||
typedef int v4si __attribute__ ((vector_size (16)));
|
||||
#define TYPE v4si
|
||||
#endif
|
||||
|
||||
#include "bool2.h"
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/* Test various logical operations. */
|
||||
|
||||
TYPE arg1 (TYPE p, TYPE q) { return p & q; } /* AND */
|
||||
TYPE arg2 (TYPE p, TYPE q) { return p | q; } /* OR */
|
||||
TYPE arg3 (TYPE p, TYPE q) { return p ^ q; } /* XOR */
|
||||
TYPE arg4 (TYPE p) { return ~ p; } /* NOR */
|
||||
TYPE arg5 (TYPE p, TYPE q) { return ~(p & q); } /* NAND */
|
||||
TYPE arg6 (TYPE p, TYPE q) { return ~(p | q); } /* NOR */
|
||||
TYPE arg7 (TYPE p, TYPE q) { return ~(p ^ q); } /* EQV */
|
||||
TYPE arg8 (TYPE p, TYPE q) { return (~p) & q; } /* ANDC */
|
||||
TYPE arg9 (TYPE p, TYPE q) { return (~p) | q; } /* ORC */
|
||||
TYPE arg10(TYPE p, TYPE q) { return (~p) ^ q; } /* EQV */
|
||||
TYPE arg11(TYPE p, TYPE q) { return p & (~q); } /* ANDC */
|
||||
TYPE arg12(TYPE p, TYPE q) { return p | (~q); } /* ORC */
|
||||
TYPE arg13(TYPE p, TYPE q) { return p ^ (~q); } /* EQV */
|
||||
|
||||
void ptr1 (TYPE *p) { p[0] = p[1] & p[2]; } /* AND */
|
||||
void ptr2 (TYPE *p) { p[0] = p[1] | p[2]; } /* OR */
|
||||
void ptr3 (TYPE *p) { p[0] = p[1] ^ p[2]; } /* XOR */
|
||||
void ptr4 (TYPE *p) { p[0] = ~p[1]; } /* NOR */
|
||||
void ptr5 (TYPE *p) { p[0] = ~(p[1] & p[2]); } /* NAND */
|
||||
void ptr6 (TYPE *p) { p[0] = ~(p[1] | p[2]); } /* NOR */
|
||||
void ptr7 (TYPE *p) { p[0] = ~(p[1] ^ p[2]); } /* EQV */
|
||||
void ptr8 (TYPE *p) { p[0] = ~(p[1]) & p[2]; } /* ANDC */
|
||||
void ptr9 (TYPE *p) { p[0] = (~p[1]) | p[2]; } /* ORC */
|
||||
void ptr10(TYPE *p) { p[0] = (~p[1]) ^ p[2]; } /* EQV */
|
||||
void ptr11(TYPE *p) { p[0] = p[1] & (~p[2]); } /* ANDC */
|
||||
void ptr12(TYPE *p) { p[0] = p[1] | (~p[2]); } /* ORC */
|
||||
void ptr13(TYPE *p) { p[0] = p[1] ^ (~p[2]); } /* EQV */
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target powerpc_altivec_ok } */
|
||||
/* { dg-options "-O2 -mcpu=power6 -mabi=altivec -maltivec -mno-vsx" } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]and " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]or " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]nor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]andc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vand " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vandc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vxor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vnor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxland " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlxor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlnor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlandc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxleqv " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlorc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlnand " } } */
|
||||
|
||||
/* On altivec, for 128-bit types, ORC/ANDC/EQV might not show up, since the
|
||||
vector unit doesn't support these, so the appropriate combine patterns may
|
||||
not be generated. */
|
||||
|
||||
#ifndef TYPE
|
||||
#ifdef _ARCH_PPC64
|
||||
#define TYPE __int128_t
|
||||
#else
|
||||
typedef int v4si __attribute__ ((vector_size (16)));
|
||||
#define TYPE v4si
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "bool3.h"
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target powerpc_vsx_ok } */
|
||||
/* { dg-options "-O2 -mcpu=power7" } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]and " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]or " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]nor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]andc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vand " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vandc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vxor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vnor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxland " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlxor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlnor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlandc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxleqv " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlorc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlnand " } } */
|
||||
|
||||
/* On power7, for 128-bit types, ORC/ANDC/EQV might not show up, since the
|
||||
vector unit doesn't support these, so the appropriate combine patterns may
|
||||
not be generated. */
|
||||
|
||||
#ifndef TYPE
|
||||
#ifdef _ARCH_PPC64
|
||||
#define TYPE __int128_t
|
||||
#else
|
||||
typedef int v4si __attribute__ ((vector_size (16)));
|
||||
#define TYPE v4si
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "bool3.h"
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target powerpc_p8vector_ok } */
|
||||
/* { dg-options "-O2 -mcpu=power8" } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]and " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]or " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]xor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]nor " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]andc " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]eqv " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]orc " } } */
|
||||
/* { dg-final { scan-assembler "\[ \t\]nand " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vand " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vandc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vxor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]vnor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxland " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlxor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlnor " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlandc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxleqv " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlorc " } } */
|
||||
/* { dg-final { scan-assembler-not "\[ \t\]xxlnand " } } */
|
||||
|
||||
#ifndef TYPE
|
||||
#ifdef _ARCH_PPC64
|
||||
#define TYPE __int128_t
|
||||
#else
|
||||
typedef int v4si __attribute__ ((vector_size (16)));
|
||||
#define TYPE v4si
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "bool3.h"
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
/* Test forcing 128-bit logical types into GPR registers. */
|
||||
|
||||
#if defined(NO_ASM)
|
||||
#define FORCE_REG1(X)
|
||||
#define FORCE_REG2(X,Y)
|
||||
|
||||
#else
|
||||
#if defined(USE_ALTIVEC)
|
||||
#define REG_CLASS "+v"
|
||||
#define PRINT_REG1 "# altivec reg %0"
|
||||
#define PRINT_REG2 "# altivec reg %0, %1"
|
||||
|
||||
#elif defined(USE_FPR)
|
||||
#define REG_CLASS "+d"
|
||||
#define PRINT_REG1 "# fpr reg %0"
|
||||
#define PRINT_REG2 "# fpr reg %0, %1"
|
||||
|
||||
#elif defined(USE_VSX)
|
||||
#define REG_CLASS "+wa"
|
||||
#define PRINT_REG1 "# vsx reg %x0"
|
||||
#define PRINT_REG2 "# vsx reg %x0, %x1"
|
||||
|
||||
#else
|
||||
#define REG_CLASS "+r"
|
||||
#define PRINT_REG1 "# gpr reg %0"
|
||||
#define PRINT_REG2 "# gpr reg %0, %1"
|
||||
#endif
|
||||
|
||||
#define FORCE_REG1(X) __asm__ (PRINT_REG1 : REG_CLASS (X))
|
||||
#define FORCE_REG2(X,Y) __asm__ (PRINT_REG2 : REG_CLASS (X), REG_CLASS (Y))
|
||||
#endif
|
||||
|
||||
void ptr1 (TYPE *p)
|
||||
{
|
||||
TYPE a = p[1];
|
||||
TYPE b = p[2];
|
||||
TYPE c;
|
||||
|
||||
FORCE_REG2 (a, b);
|
||||
c = a & b; /* AND */
|
||||
FORCE_REG1 (c);
|
||||
p[0] = c;
|
||||
}
|
||||
|
||||
void ptr2 (TYPE *p)
|
||||
{
|
||||
TYPE a = p[1];
|
||||
TYPE b = p[2];
|
||||
TYPE c;
|
||||
|
||||
FORCE_REG2 (a, b);
|
||||
c = a | b; /* OR */
|
||||
FORCE_REG1 (c);
|
||||
p[0] = c;
|
||||
}
|
||||
|
||||
void ptr3 (TYPE *p)
|
||||
{
|
||||
TYPE a = p[1];
|
||||
TYPE b = p[2];
|
||||
TYPE c;
|
||||
|
||||
FORCE_REG2 (a, b);
|
||||
c = a ^ b; /* XOR */
|
||||
FORCE_REG1 (c);
|
||||
p[0] = c;
|
||||
}
|
||||
|
||||
void ptr4 (TYPE *p)
|
||||
{
|
||||
TYPE a = p[1];
|
||||
TYPE b;
|
||||
|
||||
FORCE_REG1 (a);
|
||||
b = ~a; /* NOR */
|
||||
FORCE_REG1 (b);
|
||||
p[0] = b;
|
||||
}
|
||||
|
||||
void ptr5 (TYPE *p)
|
||||
{
|
||||
TYPE a = p[1];
|
||||
TYPE b = p[2];
|
||||
TYPE c;
|
||||
|
||||
FORCE_REG2 (a, b);
|
||||
c = ~(a & b); /* NAND */
|
||||
FORCE_REG1 (c);
|
||||
p[0] = c;
|
||||
}
|
||||
|
||||
void ptr6 (TYPE *p)
|
||||
{
|
||||
TYPE a = p[1];
|
||||
TYPE b = p[2];
|
||||
TYPE c;
|
||||
|
||||
FORCE_REG2 (a, b);
|
||||
c = ~(a | b); /* AND */
|
||||
FORCE_REG1 (c);
|
||||
p[0] = c;
|
||||
}
|
||||
|
||||
void ptr7 (TYPE *p)
|
||||
{
|
||||
TYPE a = p[1];
|
||||
TYPE b = p[2];
|
||||
TYPE c;
|
||||
|
||||
FORCE_REG2 (a, b);
|
||||
c = ~(a ^ b); /* EQV */
|
||||
FORCE_REG1 (c);
|
||||
p[0] = c;
|
||||
}
|
||||
|
||||
void ptr8 (TYPE *p)
|
||||
{
|
||||
TYPE a = p[1];
|
||||
TYPE b = p[2];
|
||||
TYPE c;
|
||||
|
||||
FORCE_REG2 (a, b);
|
||||
c = (~a) & b; /* ANDC */
|
||||
FORCE_REG1 (c);
|
||||
p[0] = c;
|
||||
}
|
||||
|
||||
void ptr9 (TYPE *p)
|
||||
{
|
||||
TYPE a = p[1];
|
||||
TYPE b = p[2];
|
||||
TYPE c;
|
||||
|
||||
FORCE_REG2 (a, b);
|
||||
c = (~a) | b; /* ORC */
|
||||
FORCE_REG1 (c);
|
||||
p[0] = c;
|
||||
}
|
||||
|
||||
void ptr10 (TYPE *p)
|
||||
{
|
||||
TYPE a = p[1];
|
||||
TYPE b = p[2];
|
||||
TYPE c;
|
||||
|
||||
FORCE_REG2 (a, b);
|
||||
c = (~a) ^ b; /* EQV */
|
||||
FORCE_REG1 (c);
|
||||
p[0] = c;
|
||||
}
|
||||
|
||||
void ptr11 (TYPE *p)
|
||||
{
|
||||
TYPE a = p[1];
|
||||
TYPE b = p[2];
|
||||
TYPE c;
|
||||
|
||||
FORCE_REG2 (a, b);
|
||||
c = a & (~b); /* ANDC */
|
||||
FORCE_REG1 (c);
|
||||
p[0] = c;
|
||||
}
|
||||
|
||||
void ptr12 (TYPE *p)
|
||||
{
|
||||
TYPE a = p[1];
|
||||
TYPE b = p[2];
|
||||
TYPE c;
|
||||
|
||||
FORCE_REG2 (a, b);
|
||||
c = a | (~b); /* ORC */
|
||||
FORCE_REG1 (c);
|
||||
p[0] = c;
|
||||
}
|
||||
|
||||
void ptr13 (TYPE *p)
|
||||
{
|
||||
TYPE a = p[1];
|
||||
TYPE b = p[2];
|
||||
TYPE c;
|
||||
|
||||
FORCE_REG2 (a, b);
|
||||
c = a ^ (~b); /* AND */
|
||||
FORCE_REG1 (c);
|
||||
p[0] = c;
|
||||
}
|
||||
Loading…
Reference in New Issue