This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: patch: convert scalar literals to vector constants (PR/7277)
- From: Aldy Hernandez <aldyh at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 4 Jun 2003 13:08:04 -0400
- Subject: Re: patch: convert scalar literals to vector constants (PR/7277)
Hadn't thought of that. What do you suggest gets generated for this?:
I suggest that we actually lay out the bytes as they would
be seen in the target's memory, and then read it back in
piece-wise.
For the FP bits you use real_from_target to generate the
REAL_VALUE_TYPE from the bits.
This is bound to be so confusing as to be unusable. I can't actually
think of anyone *ever* needing:
(v2sf) 3.5;
(as a bit representation of the floating point value).
This is also bound to confuse folks that are accustomed to the AltiVec
compiler, where the above would mean:
(v2sf) {3.5F, 3.5F};
...which makes a lot more sense.
Anywhoo... do you _really_ want something like this?:
2003-06-03 Aldy Hernandez <aldyh@redhat.com>
PR/7277
* expr.c (convert_modes): Handle scalar to vector conversion.
(convert_const_to_vector): New.
* testsuite/gcc.c-torture/compile/simd-7.c: New.
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.545
diff -c -p -r1.545 expr.c
*** expr.c 3 Jun 2003 08:57:52 -0000 1.545
--- expr.c 4 Jun 2003 17:03:35 -0000
*************** static void emit_single_push_insn PARAMS
*** 179,184 ****
--- 179,185 ----
#endif
static void do_tablejump PARAMS ((rtx, enum machine_mode, rtx, rtx,
rtx));
static rtx const_vector_from_tree PARAMS ((tree));
+ static rtx convert_const_to_vector (enum machine_mode, rtx);
/* Record for each mode whether we can move a register directly to or
from an object of that mode in memory. If we can't, we won't try
*************** convert_modes (mode, oldmode, x, unsigne
*** 1433,1443 ****
return gen_lowpart (mode, x);
}
temp = gen_reg_rtx (mode);
convert_move (temp, x, unsignedp);
return temp;
}
!
/* This macro is used to determine what the largest unit size that
move_by_pieces can use is. */
--- 1434,1523 ----
return gen_lowpart (mode, x);
}
+ if (VECTOR_MODE_P (mode) && CONSTANT_P (x)
+ && GET_CODE (x) != CONST_VECTOR)
+ return convert_const_to_vector (mode, x);
+
temp = gen_reg_rtx (mode);
convert_move (temp, x, unsignedp);
return temp;
}
!
! /* Convert a CONST_INT to a CONST_VECTOR. */
! static rtx
! convert_const_to_vector (enum machine_mode mode, rtx x)
! {
! rtvec v;
! int units, i, inner_bits, idx;
! enum machine_mode inner;
! union {
! HOST_WIDE_INT cst[10];
! REAL_VALUE_TYPE real;
! } u;
!
! if (sizeof (u.cst) < sizeof (u.real))
! abort ();
!
! memset (u.cst, 0, sizeof (u));
!
! if (x == const0_rtx)
! return CONST0_RTX (mode);
!
! inner = GET_MODE_INNER (mode);
!
! if (GET_CODE (x) == CONST_INT)
! {
! u.cst[0] = INTVAL (x);
! if (INTVAL (x) < 0)
! u.cst[1] = (unsigned HOST_WIDE_INT) -1;
! else
! u.cst[1] = 0;
! }
! else if (GET_CODE (x) == CONST_DOUBLE)
! {
! long cst[2];
! rtx t;
!
! cst[0] = CONST_DOUBLE_LOW (x);
! cst[1] = CONST_DOUBLE_HIGH (x);
! real_from_target (&u.real, cst, DFmode);
! t = CONST_DOUBLE_FROM_REAL_VALUE (u.real, DFmode);
! u.cst[0] = CONST_DOUBLE_LOW (t);
! u.cst[1] = CONST_DOUBLE_HIGH (t);
! }
! else
! abort ();
!
! units = GET_MODE_NUNITS (mode);
! inner_bits = GET_MODE_BITSIZE (inner);
! v = rtvec_alloc (units);
!
! /* Convert 0x6699 into:
! (const_vector:M (const_int 0x0)
! ...
! (const_int 0x66)
! (const_int 0x99)). */
!
! if (GET_CODE (x) == CONST_DOUBLE)
!
! idx = -1;
! for (i = 0; i < units; ++i)
! {
! int thing;
!
! if (i * inner_bits % HOST_BITS_PER_WIDE_INT == 0)
! ++idx;
!
! thing = u.cst[idx] & ((1 << inner_bits) - 1);
!
! RTVEC_ELT (v, units - i - 1)
! = gen_rtx_CONST_INT (inner, thing);
! u.cst[idx] >>= inner_bits;
! }
!
! return gen_rtx_raw_CONST_VECTOR (mode, v);
! }
!
/* This macro is used to determine what the largest unit size that
move_by_pieces can use is. */
Index: testsuite/gcc.c-torture/compile/simd-7.c
===================================================================
RCS file: testsuite/gcc.c-torture/compile/simd-7.c
diff -N testsuite/gcc.c-torture/compile/simd-7.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.c-torture/compile/simd-7.c 4 Jun 2003 17:03:35 -0000
***************
*** 0 ****
--- 1,6 ----
+ typedef int v8qi __attribute__ ((mode(V8QI)));
+
+ v8qi null(void)
+ {
+ return (v8qi) 0x1122334455667788LL;
+ }