From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24802 invoked by alias); 8 Oct 2010 16:37:27 -0000 Received: (qmail 24362 invoked by uid 22791); 8 Oct 2010 16:37:25 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL,BAYES_00,TW_CP,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mtagate1.de.ibm.com (HELO mtagate1.de.ibm.com) (195.212.17.161) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 08 Oct 2010 16:37:18 +0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate1.de.ibm.com (8.13.1/8.13.1) with ESMTP id o98GbFpe002458 for ; Fri, 8 Oct 2010 16:37:15 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id o98GbFob4137002 for ; Fri, 8 Oct 2010 18:37:15 +0200 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id o98GbFVc013154 for ; Fri, 8 Oct 2010 18:37:15 +0200 Received: from leonard.localnet (dyn-9-152-224-33.boeblingen.de.ibm.com [9.152.224.33]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id o98GbB9o012673 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 8 Oct 2010 18:37:15 +0200 From: Ken Werner To: "Ulrich Weigand" Subject: Re: [patch] Scalar to vector widening Date: Fri, 08 Oct 2010 16:37:00 -0000 User-Agent: KMail/1.13.2 (Linux/2.6.32-25-generic; KDE/4.4.2; i686; ; ) Cc: gdb-patches@sourceware.org References: <201010081314.o98DEfAx031234@d12av02.megacenter.de.ibm.com> In-Reply-To: <201010081314.o98DEfAx031234@d12av02.megacenter.de.ibm.com> MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_2i0rMUamrFSRUnO" Message-Id: <201010081837.10645.ken@linux.vnet.ibm.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-10/txt/msg00142.txt.bz2 --Boundary-00=_2i0rMUamrFSRUnO Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-length: 905 On Friday, October 08, 2010 3:14:41 pm Ulrich Weigand wrote: > I don't think these are quite right. If, say, arg2 is a vector of > different type, this may get simply cast away. Likewise, if arg1 > is a very short integer type, the cast may actually remove valid > bits in arg2 ... I think the cast really should only be done if > one side is a vector and the other a scalar. Oh, I overlooked that - thanks. > However, I don't quite like distributing the code between the various > promotion routines. In fact, I'm starting to think this shouldn't > actually be though of as a promotion at all. Instead, why not simply > handle the case directly in vector_binop? If only one side is a vector > and the other is a scalar, cast it there. This should simplify the > patch even further. Sounds good. Attached is a new version of the patch. Tested on i686-*-linux- gnu, no regressions. Regards Ken --Boundary-00=_2i0rMUamrFSRUnO Content-Type: text/x-patch; charset="UTF-8"; name="widen-scalar-to-vector.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="widen-scalar-to-vector.patch" Content-length: 8293 ChangeLog: 2010-10-08 Ken Werner * valops.c (value_cast): Handle vector types. * valarith.c (value_binop): Widen scalar to vector if appropriate. testsuite/ChangeLog: 2010-10-08 Ken Werner * gdb.base/gnu_vector.c (ia, ib, fa, fb): New variables. * gdb.base/gnu_vector.exp: Add tests for scalar to vector widening. Index: gdb/valarith.c =================================================================== RCS file: /cvs/src/src/gdb/valarith.c,v retrieving revision 1.86 diff -p -u -r1.86 valarith.c --- gdb/valarith.c 11 Aug 2010 16:48:26 -0000 1.86 +++ gdb/valarith.c 8 Oct 2010 16:22:00 -0000 @@ -1435,14 +1435,34 @@ vector_binop (struct value *val1, struct struct value * value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) { + struct value *val; struct type *type1 = check_typedef (value_type (arg1)); struct type *type2 = check_typedef (value_type (arg2)); - - if ((TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1)) - || (TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2))) - return vector_binop (arg1, arg2, op); + int t1_is_vec = (TYPE_CODE (type1) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type1)); + int t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type2)); + + if (!t1_is_vec && !t2_is_vec) + val = scalar_binop (arg1, arg2, op); + else if (t1_is_vec && t2_is_vec) + val = vector_binop (arg1, arg2, op); else - return scalar_binop (arg1, arg2, op); + { + /* Widen the scalar operand to a vector. */ + struct value **v = t1_is_vec ? &arg2 : &arg1; + struct type *t = t1_is_vec ? type2 : type1; + + if (TYPE_CODE (t) != TYPE_CODE_FLT + && TYPE_CODE (t) != TYPE_CODE_DECFLOAT + && !is_integral_type (t)) + error (_("Argument to operation not a number or boolean.")); + + *v = value_cast (t1_is_vec ? type1 : type2, *v); + val = vector_binop (arg1, arg2, op); + } + + return val; } /* Simulate the C operator ! -- return 1 if ARG1 contains zero. */ Index: gdb/valops.c =================================================================== RCS file: /cvs/src/src/gdb/valops.c,v retrieving revision 1.251 diff -p -u -r1.251 valops.c --- gdb/valops.c 24 Sep 2010 14:47:53 -0000 1.251 +++ gdb/valops.c 8 Oct 2010 16:22:01 -0000 @@ -421,7 +421,8 @@ value_cast (struct type *type, struct va } if (current_language->c_style_arrays - && TYPE_CODE (type2) == TYPE_CODE_ARRAY) + && TYPE_CODE (type2) == TYPE_CODE_ARRAY + && !TYPE_VECTOR (type2)) arg2 = value_coerce_array (arg2); if (TYPE_CODE (type2) == TYPE_CODE_FUNC) @@ -537,6 +538,26 @@ value_cast (struct type *type, struct va minus one, instead of biasing the normal case. */ return value_from_longest (type, -1); } + else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && scalar) + { + /* Widen the scalar to a vector. */ + struct type *eltype; + struct value *val; + int i, n; + + eltype = check_typedef (TYPE_TARGET_TYPE (type)); + arg2 = value_cast (eltype, arg2); + val = allocate_value (type); + n = TYPE_LENGTH (type) / TYPE_LENGTH (eltype); + + for (i = 0; i < n; i++) + { + /* Duplicate the contents of arg2 into the destination vector. */ + memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)), + value_contents_all (arg2), TYPE_LENGTH (eltype)); + } + return val; + } else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2)) { if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR) Index: gdb/testsuite/gdb.base/gnu_vector.c =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gnu_vector.c,v retrieving revision 1.2 diff -p -u -r1.2 gnu_vector.c --- gdb/testsuite/gdb.base/gnu_vector.c 6 Oct 2010 08:44:15 -0000 1.2 +++ gdb/testsuite/gdb.base/gnu_vector.c 8 Oct 2010 16:22:01 -0000 @@ -17,16 +17,30 @@ Contributed by Ken Werner */ -char __attribute__ ((vector_size (4 * sizeof(char)))) c4 = {1, 2, 3, 4}; -int __attribute__ ((vector_size (4 * sizeof(int)))) i4a = {2, 4, 8, 16}; -int __attribute__ ((vector_size (4 * sizeof(int)))) i4b = {1, 2, 8, 4}; -float __attribute__ ((vector_size (4 * sizeof(float)))) f4a = {2, 4, 8, 16}; -float __attribute__ ((vector_size (4 * sizeof(float)))) f4b = {1, 2, 8, 4}; -unsigned int __attribute__ ((vector_size (4 * sizeof(unsigned int)))) ui4 = {2, 4, 8, 16}; -int __attribute__ ((vector_size (2 * sizeof(int)))) i2 = {1, 2}; -long long __attribute__ ((vector_size (2 * sizeof(long long)))) ll2 = {1, 2}; -float __attribute__ ((vector_size (2 * sizeof(float)))) f2 = {1, 2}; -double __attribute__ ((vector_size (2 * sizeof(double)))) d2 = {1, 2}; +typedef int __attribute__ ((vector_size (4 * sizeof(int)))) int4; +typedef unsigned int __attribute__ ((vector_size (4 * sizeof(unsigned int)))) uint4; +typedef char __attribute__ ((vector_size (4 * sizeof(char)))) char4; +typedef float __attribute__ ((vector_size (4 * sizeof(float)))) float4; + +typedef int __attribute__ ((vector_size (2 * sizeof(int)))) int2; +typedef long long __attribute__ ((vector_size (2 * sizeof(long long)))) longlong2; +typedef float __attribute__ ((vector_size (2 * sizeof(float)))) float2; +typedef double __attribute__ ((vector_size (2 * sizeof(double)))) double2; + +int ia = 2; +int ib = 1; +float fa = 2; +float fb = 1; +char4 c4 = {1, 2, 3, 4}; +int4 i4a = {2, 4, 8, 16}; +int4 i4b = {1, 2, 8, 4}; +float4 f4a = {2, 4, 8, 16}; +float4 f4b = {1, 2, 8, 4}; +uint4 ui4 = {2, 4, 8, 16}; +int2 i2 = {1, 2}; +longlong2 ll2 = {1, 2}; +float2 f2 = {1, 2}; +double2 d2 = {1, 2}; int main () Index: gdb/testsuite/gdb.base/gnu_vector.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gnu_vector.exp,v retrieving revision 1.2 diff -p -u -r1.2 gnu_vector.exp --- gdb/testsuite/gdb.base/gnu_vector.exp 6 Oct 2010 08:44:15 -0000 1.2 +++ gdb/testsuite/gdb.base/gnu_vector.exp 8 Oct 2010 16:22:01 -0000 @@ -76,9 +76,37 @@ gdb_test "print f4a - f4b" "\\\$$decimal gdb_test "print f4a * f4b" "\\\$$decimal = \\{2, 8, 64, 64\\}" gdb_test "print f4a / f4b" "\\\$$decimal = \\{2, 2, 1, 4\\}" -# Test error conditions -gdb_test "print i4a + 1" "Vector operations are only supported among vectors" -gdb_test "print 1 + f4a" "Vector operations are only supported among vectors" +# Test scalar to vector widening +gdb_test "print (int2) 1" "\\\$$decimal = \\{1, 1\\}" +gdb_test "print (longlong2) 2" "\\\$$decimal = \\{2, 2\\}" +gdb_test "print (float2) 3" "\\\$$decimal = \\{3, 3\\}" +gdb_test "print (double2) 4" "\\\$$decimal = \\{4, 4\\}" +gdb_test "print (char4) 12" "\\\$$decimal = \\{12, 12, 12, 12\\}" +gdb_test "print (uint4) ia" "\\\$$decimal = \\{2, 2, 2, 2\\}" +gdb_test "print (int4) -3" "\\\$$decimal = \\{-3, -3, -3, -3\\}" +gdb_test "print (float4) 4" "\\\$$decimal = \\{4, 4, 4, 4\\}" + +gdb_test "print i4a + ib" "\\\$$decimal = \\{3, 5, 9, 17\\}" +gdb_test "print fa - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}" +gdb_test "print f4a * fb" "\\\$$decimal = \\{2, 4, 8, 16\\}" +gdb_test "print ia / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}" +gdb_test "print i4a % ib" "\\\$$decimal = \\{0, 0, 0, 0\\}" + +gdb_test "print ia & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}" +gdb_test "print i4a | ib" "\\\$$decimal = \\{3, 5, 9, 17\\}" +gdb_test "print ia ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}" +gdb_test "print i4a << ib" "\\\$$decimal = \\{4, 8, 16, 32\\}" +gdb_test "print i4a >> ib" "\\\$$decimal = \\{1, 2, 4, 8\\}" + +gdb_test "print i4b = ia" "\\\$$decimal = \\{2, 2, 2, 2\\}" +gdb_test "print i4a = 3" "\\\$$decimal = \\{3, 3, 3, 3\\}" +gdb_test "print f4a = fb" "\\\$$decimal = \\{1, 1, 1, 1\\}" +gdb_test "print f4b = 2" "\\\$$decimal = \\{2, 2, 2, 2\\}" + +gdb_test "print i4a = \{2, 4, 8, 16\}" "\\\$$decimal = \\{2, 4, 8, 16\\}" +gdb_test "print i4a <<= ib" "\\\$$decimal = \\{4, 8, 16, 32\\}" + +# Test some error scenarios gdb_test "print i4a + d2" "Cannot perform operation on vectors with different types" gdb_test "print d2 + i4a" "Cannot perform operation on vectors with different types" gdb_test "print f4a + ll2" "Cannot perform operation on vectors with different types" --Boundary-00=_2i0rMUamrFSRUnO--