xref: /dragonfly/contrib/gdb-7/gdb/opencl-lang.c (revision ef5ccd6c)
1c50c785cSJohn Marino /* OpenCL language support for GDB, the GNU debugger.
2*ef5ccd6cSJohn Marino    Copyright (C) 2010-2013 Free Software Foundation, Inc.
3c50c785cSJohn Marino 
4c50c785cSJohn Marino    Contributed by Ken Werner <ken.werner@de.ibm.com>.
5c50c785cSJohn Marino 
6c50c785cSJohn Marino    This file is part of GDB.
7c50c785cSJohn Marino 
8c50c785cSJohn Marino    This program is free software; you can redistribute it and/or modify
9c50c785cSJohn Marino    it under the terms of the GNU General Public License as published by
10c50c785cSJohn Marino    the Free Software Foundation; either version 3 of the License, or
11c50c785cSJohn Marino    (at your option) any later version.
12c50c785cSJohn Marino 
13c50c785cSJohn Marino    This program is distributed in the hope that it will be useful,
14c50c785cSJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
15c50c785cSJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16c50c785cSJohn Marino    GNU General Public License for more details.
17c50c785cSJohn Marino 
18c50c785cSJohn Marino    You should have received a copy of the GNU General Public License
19c50c785cSJohn Marino    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20c50c785cSJohn Marino 
21c50c785cSJohn Marino #include "defs.h"
22c50c785cSJohn Marino #include "gdb_string.h"
23c50c785cSJohn Marino #include "gdbtypes.h"
24c50c785cSJohn Marino #include "symtab.h"
25c50c785cSJohn Marino #include "expression.h"
26c50c785cSJohn Marino #include "parser-defs.h"
27c50c785cSJohn Marino #include "symtab.h"
28c50c785cSJohn Marino #include "language.h"
29c50c785cSJohn Marino #include "c-lang.h"
30c50c785cSJohn Marino #include "gdb_assert.h"
31c50c785cSJohn Marino 
32c50c785cSJohn Marino extern void _initialize_opencl_language (void);
33c50c785cSJohn Marino 
34c50c785cSJohn Marino /* This macro generates enum values from a given type.  */
35c50c785cSJohn Marino 
36c50c785cSJohn Marino #define OCL_P_TYPE(TYPE)\
37c50c785cSJohn Marino   opencl_primitive_type_##TYPE,\
38c50c785cSJohn Marino   opencl_primitive_type_##TYPE##2,\
39c50c785cSJohn Marino   opencl_primitive_type_##TYPE##3,\
40c50c785cSJohn Marino   opencl_primitive_type_##TYPE##4,\
41c50c785cSJohn Marino   opencl_primitive_type_##TYPE##8,\
42c50c785cSJohn Marino   opencl_primitive_type_##TYPE##16
43c50c785cSJohn Marino 
44c50c785cSJohn Marino enum opencl_primitive_types {
45c50c785cSJohn Marino   OCL_P_TYPE (char),
46c50c785cSJohn Marino   OCL_P_TYPE (uchar),
47c50c785cSJohn Marino   OCL_P_TYPE (short),
48c50c785cSJohn Marino   OCL_P_TYPE (ushort),
49c50c785cSJohn Marino   OCL_P_TYPE (int),
50c50c785cSJohn Marino   OCL_P_TYPE (uint),
51c50c785cSJohn Marino   OCL_P_TYPE (long),
52c50c785cSJohn Marino   OCL_P_TYPE (ulong),
53c50c785cSJohn Marino   OCL_P_TYPE (half),
54c50c785cSJohn Marino   OCL_P_TYPE (float),
55c50c785cSJohn Marino   OCL_P_TYPE (double),
56c50c785cSJohn Marino   opencl_primitive_type_bool,
57c50c785cSJohn Marino   opencl_primitive_type_unsigned_char,
58c50c785cSJohn Marino   opencl_primitive_type_unsigned_short,
59c50c785cSJohn Marino   opencl_primitive_type_unsigned_int,
60c50c785cSJohn Marino   opencl_primitive_type_unsigned_long,
61c50c785cSJohn Marino   opencl_primitive_type_size_t,
62c50c785cSJohn Marino   opencl_primitive_type_ptrdiff_t,
63c50c785cSJohn Marino   opencl_primitive_type_intptr_t,
64c50c785cSJohn Marino   opencl_primitive_type_uintptr_t,
65c50c785cSJohn Marino   opencl_primitive_type_void,
66c50c785cSJohn Marino   nr_opencl_primitive_types
67c50c785cSJohn Marino };
68c50c785cSJohn Marino 
69c50c785cSJohn Marino static struct gdbarch_data *opencl_type_data;
70c50c785cSJohn Marino 
71*ef5ccd6cSJohn Marino static struct type **
builtin_opencl_type(struct gdbarch * gdbarch)72c50c785cSJohn Marino builtin_opencl_type (struct gdbarch *gdbarch)
73c50c785cSJohn Marino {
74c50c785cSJohn Marino   return gdbarch_data (gdbarch, opencl_type_data);
75c50c785cSJohn Marino }
76c50c785cSJohn Marino 
77c50c785cSJohn Marino /* Returns the corresponding OpenCL vector type from the given type code,
78c50c785cSJohn Marino    the length of the element type, the unsigned flag and the amount of
79c50c785cSJohn Marino    elements (N).  */
80c50c785cSJohn Marino 
81c50c785cSJohn Marino static struct type *
lookup_opencl_vector_type(struct gdbarch * gdbarch,enum type_code code,unsigned int el_length,unsigned int flag_unsigned,int n)82c50c785cSJohn Marino lookup_opencl_vector_type (struct gdbarch *gdbarch, enum type_code code,
83c50c785cSJohn Marino 			   unsigned int el_length, unsigned int flag_unsigned,
84c50c785cSJohn Marino 			   int n)
85c50c785cSJohn Marino {
86c50c785cSJohn Marino   int i;
87c50c785cSJohn Marino   unsigned int length;
88c50c785cSJohn Marino   struct type *type = NULL;
89c50c785cSJohn Marino   struct type **types = builtin_opencl_type (gdbarch);
90c50c785cSJohn Marino 
91c50c785cSJohn Marino   /* Check if n describes a valid OpenCL vector size (2, 3, 4, 8, 16).  */
92c50c785cSJohn Marino   if (n != 2 && n != 3 && n != 4 && n != 8 && n != 16)
93c50c785cSJohn Marino     error (_("Invalid OpenCL vector size: %d"), n);
94c50c785cSJohn Marino 
95c50c785cSJohn Marino   /* Triple vectors have the size of a quad vector.  */
96c50c785cSJohn Marino   length = (n == 3) ?  el_length * 4 : el_length * n;
97c50c785cSJohn Marino 
98c50c785cSJohn Marino   for (i = 0; i < nr_opencl_primitive_types; i++)
99c50c785cSJohn Marino     {
100c50c785cSJohn Marino       LONGEST lowb, highb;
101c50c785cSJohn Marino 
102c50c785cSJohn Marino       if (TYPE_CODE (types[i]) == TYPE_CODE_ARRAY && TYPE_VECTOR (types[i])
103c50c785cSJohn Marino 	  && get_array_bounds (types[i], &lowb, &highb)
104c50c785cSJohn Marino 	  && TYPE_CODE (TYPE_TARGET_TYPE (types[i])) == code
105c50c785cSJohn Marino 	  && TYPE_UNSIGNED (TYPE_TARGET_TYPE (types[i])) == flag_unsigned
106c50c785cSJohn Marino 	  && TYPE_LENGTH (TYPE_TARGET_TYPE (types[i])) == el_length
107c50c785cSJohn Marino 	  && TYPE_LENGTH (types[i]) == length
108c50c785cSJohn Marino 	  && highb - lowb + 1 == n)
109c50c785cSJohn Marino 	{
110c50c785cSJohn Marino 	  type = types[i];
111c50c785cSJohn Marino 	  break;
112c50c785cSJohn Marino 	}
113c50c785cSJohn Marino     }
114c50c785cSJohn Marino 
115c50c785cSJohn Marino   return type;
116c50c785cSJohn Marino }
117c50c785cSJohn Marino 
118c50c785cSJohn Marino /* Returns nonzero if the array ARR contains duplicates within
119c50c785cSJohn Marino      the first N elements.  */
120c50c785cSJohn Marino 
121c50c785cSJohn Marino static int
array_has_dups(int * arr,int n)122c50c785cSJohn Marino array_has_dups (int *arr, int n)
123c50c785cSJohn Marino {
124c50c785cSJohn Marino   int i, j;
125c50c785cSJohn Marino 
126c50c785cSJohn Marino   for (i = 0; i < n; i++)
127c50c785cSJohn Marino     {
128c50c785cSJohn Marino       for (j = i + 1; j < n; j++)
129c50c785cSJohn Marino         {
130c50c785cSJohn Marino           if (arr[i] == arr[j])
131c50c785cSJohn Marino             return 1;
132c50c785cSJohn Marino         }
133c50c785cSJohn Marino     }
134c50c785cSJohn Marino 
135c50c785cSJohn Marino   return 0;
136c50c785cSJohn Marino }
137c50c785cSJohn Marino 
138c50c785cSJohn Marino /* The OpenCL component access syntax allows to create lvalues referring to
139c50c785cSJohn Marino    selected elements of an original OpenCL vector in arbitrary order.  This
140c50c785cSJohn Marino    structure holds the information to describe such lvalues.  */
141c50c785cSJohn Marino 
142c50c785cSJohn Marino struct lval_closure
143c50c785cSJohn Marino {
144c50c785cSJohn Marino   /* Reference count.  */
145c50c785cSJohn Marino   int refc;
146c50c785cSJohn Marino   /* The number of indices.  */
147c50c785cSJohn Marino   int n;
148c50c785cSJohn Marino   /* The element indices themselves.  */
149c50c785cSJohn Marino   int *indices;
150c50c785cSJohn Marino   /* A pointer to the original value.  */
151c50c785cSJohn Marino   struct value *val;
152c50c785cSJohn Marino };
153c50c785cSJohn Marino 
154c50c785cSJohn Marino /* Allocates an instance of struct lval_closure.  */
155c50c785cSJohn Marino 
156c50c785cSJohn Marino static struct lval_closure *
allocate_lval_closure(int * indices,int n,struct value * val)157c50c785cSJohn Marino allocate_lval_closure (int *indices, int n, struct value *val)
158c50c785cSJohn Marino {
159c50c785cSJohn Marino   struct lval_closure *c = XZALLOC (struct lval_closure);
160c50c785cSJohn Marino 
161c50c785cSJohn Marino   c->refc = 1;
162c50c785cSJohn Marino   c->n = n;
163c50c785cSJohn Marino   c->indices = XCALLOC (n, int);
164c50c785cSJohn Marino   memcpy (c->indices, indices, n * sizeof (int));
165c50c785cSJohn Marino   value_incref (val); /* Increment the reference counter of the value.  */
166c50c785cSJohn Marino   c->val = val;
167c50c785cSJohn Marino 
168c50c785cSJohn Marino   return c;
169c50c785cSJohn Marino }
170c50c785cSJohn Marino 
171c50c785cSJohn Marino static void
lval_func_read(struct value * v)172c50c785cSJohn Marino lval_func_read (struct value *v)
173c50c785cSJohn Marino {
174c50c785cSJohn Marino   struct lval_closure *c = (struct lval_closure *) value_computed_closure (v);
175c50c785cSJohn Marino   struct type *type = check_typedef (value_type (v));
176c50c785cSJohn Marino   struct type *eltype = TYPE_TARGET_TYPE (check_typedef (value_type (c->val)));
177c50c785cSJohn Marino   int offset = value_offset (v);
178c50c785cSJohn Marino   int elsize = TYPE_LENGTH (eltype);
179c50c785cSJohn Marino   int n, i, j = 0;
180c50c785cSJohn Marino   LONGEST lowb = 0;
181c50c785cSJohn Marino   LONGEST highb = 0;
182c50c785cSJohn Marino 
183c50c785cSJohn Marino   if (TYPE_CODE (type) == TYPE_CODE_ARRAY
184c50c785cSJohn Marino       && !get_array_bounds (type, &lowb, &highb))
185c50c785cSJohn Marino     error (_("Could not determine the vector bounds"));
186c50c785cSJohn Marino 
187c50c785cSJohn Marino   /* Assume elsize aligned offset.  */
188c50c785cSJohn Marino   gdb_assert (offset % elsize == 0);
189c50c785cSJohn Marino   offset /= elsize;
190c50c785cSJohn Marino   n = offset + highb - lowb + 1;
191c50c785cSJohn Marino   gdb_assert (n <= c->n);
192c50c785cSJohn Marino 
193c50c785cSJohn Marino   for (i = offset; i < n; i++)
194c50c785cSJohn Marino     memcpy (value_contents_raw (v) + j++ * elsize,
195c50c785cSJohn Marino 	    value_contents (c->val) + c->indices[i] * elsize,
196c50c785cSJohn Marino 	    elsize);
197c50c785cSJohn Marino }
198c50c785cSJohn Marino 
199c50c785cSJohn Marino static void
lval_func_write(struct value * v,struct value * fromval)200c50c785cSJohn Marino lval_func_write (struct value *v, struct value *fromval)
201c50c785cSJohn Marino {
202c50c785cSJohn Marino   struct value *mark = value_mark ();
203c50c785cSJohn Marino   struct lval_closure *c = (struct lval_closure *) value_computed_closure (v);
204c50c785cSJohn Marino   struct type *type = check_typedef (value_type (v));
205c50c785cSJohn Marino   struct type *eltype = TYPE_TARGET_TYPE (check_typedef (value_type (c->val)));
206c50c785cSJohn Marino   int offset = value_offset (v);
207c50c785cSJohn Marino   int elsize = TYPE_LENGTH (eltype);
208c50c785cSJohn Marino   int n, i, j = 0;
209c50c785cSJohn Marino   LONGEST lowb = 0;
210c50c785cSJohn Marino   LONGEST highb = 0;
211c50c785cSJohn Marino 
212c50c785cSJohn Marino   if (TYPE_CODE (type) == TYPE_CODE_ARRAY
213c50c785cSJohn Marino       && !get_array_bounds (type, &lowb, &highb))
214c50c785cSJohn Marino     error (_("Could not determine the vector bounds"));
215c50c785cSJohn Marino 
216c50c785cSJohn Marino   /* Assume elsize aligned offset.  */
217c50c785cSJohn Marino   gdb_assert (offset % elsize == 0);
218c50c785cSJohn Marino   offset /= elsize;
219c50c785cSJohn Marino   n = offset + highb - lowb + 1;
220c50c785cSJohn Marino 
221c50c785cSJohn Marino   /* Since accesses to the fourth component of a triple vector is undefined we
222c50c785cSJohn Marino      just skip writes to the fourth element.  Imagine something like this:
223c50c785cSJohn Marino        int3 i3 = (int3)(0, 1, 2);
224c50c785cSJohn Marino        i3.hi.hi = 5;
225c50c785cSJohn Marino      In this case n would be 4 (offset=12/4 + 1) while c->n would be 3.  */
226c50c785cSJohn Marino   if (n > c->n)
227c50c785cSJohn Marino     n = c->n;
228c50c785cSJohn Marino 
229c50c785cSJohn Marino   for (i = offset; i < n; i++)
230c50c785cSJohn Marino     {
231c50c785cSJohn Marino       struct value *from_elm_val = allocate_value (eltype);
232c50c785cSJohn Marino       struct value *to_elm_val = value_subscript (c->val, c->indices[i]);
233c50c785cSJohn Marino 
234c50c785cSJohn Marino       memcpy (value_contents_writeable (from_elm_val),
235c50c785cSJohn Marino 	      value_contents (fromval) + j++ * elsize,
236c50c785cSJohn Marino 	      elsize);
237c50c785cSJohn Marino       value_assign (to_elm_val, from_elm_val);
238c50c785cSJohn Marino     }
239c50c785cSJohn Marino 
240c50c785cSJohn Marino   value_free_to_mark (mark);
241c50c785cSJohn Marino }
242c50c785cSJohn Marino 
243c50c785cSJohn Marino /* Return nonzero if all bits in V within OFFSET and LENGTH are valid.  */
244c50c785cSJohn Marino 
245c50c785cSJohn Marino static int
lval_func_check_validity(const struct value * v,int offset,int length)246c50c785cSJohn Marino lval_func_check_validity (const struct value *v, int offset, int length)
247c50c785cSJohn Marino {
248c50c785cSJohn Marino   struct lval_closure *c = (struct lval_closure *) value_computed_closure (v);
249c50c785cSJohn Marino   /* Size of the target type in bits.  */
250c50c785cSJohn Marino   int elsize =
251c50c785cSJohn Marino       TYPE_LENGTH (TYPE_TARGET_TYPE (check_typedef (value_type (c->val)))) * 8;
252c50c785cSJohn Marino   int startrest = offset % elsize;
253c50c785cSJohn Marino   int start = offset / elsize;
254c50c785cSJohn Marino   int endrest = (offset + length) % elsize;
255c50c785cSJohn Marino   int end = (offset + length) / elsize;
256c50c785cSJohn Marino   int i;
257c50c785cSJohn Marino 
258c50c785cSJohn Marino   if (endrest)
259c50c785cSJohn Marino     end++;
260c50c785cSJohn Marino 
261c50c785cSJohn Marino   if (end > c->n)
262c50c785cSJohn Marino     return 0;
263c50c785cSJohn Marino 
264c50c785cSJohn Marino   for (i = start; i < end; i++)
265c50c785cSJohn Marino     {
266c50c785cSJohn Marino       int comp_offset = (i == start) ? startrest : 0;
267c50c785cSJohn Marino       int comp_length = (i == end) ? endrest : elsize;
268c50c785cSJohn Marino 
269c50c785cSJohn Marino       if (!value_bits_valid (c->val, c->indices[i] * elsize + comp_offset,
270c50c785cSJohn Marino 			     comp_length))
271c50c785cSJohn Marino 	return 0;
272c50c785cSJohn Marino     }
273c50c785cSJohn Marino 
274c50c785cSJohn Marino   return 1;
275c50c785cSJohn Marino }
276c50c785cSJohn Marino 
277c50c785cSJohn Marino /* Return nonzero if any bit in V is valid.  */
278c50c785cSJohn Marino 
279c50c785cSJohn Marino static int
lval_func_check_any_valid(const struct value * v)280c50c785cSJohn Marino lval_func_check_any_valid (const struct value *v)
281c50c785cSJohn Marino {
282c50c785cSJohn Marino   struct lval_closure *c = (struct lval_closure *) value_computed_closure (v);
283c50c785cSJohn Marino   /* Size of the target type in bits.  */
284c50c785cSJohn Marino   int elsize =
285c50c785cSJohn Marino       TYPE_LENGTH (TYPE_TARGET_TYPE (check_typedef (value_type (c->val)))) * 8;
286c50c785cSJohn Marino   int i;
287c50c785cSJohn Marino 
288c50c785cSJohn Marino   for (i = 0; i < c->n; i++)
289c50c785cSJohn Marino     if (value_bits_valid (c->val, c->indices[i] * elsize, elsize))
290c50c785cSJohn Marino       return 1;
291c50c785cSJohn Marino 
292c50c785cSJohn Marino   return 0;
293c50c785cSJohn Marino }
294c50c785cSJohn Marino 
295c50c785cSJohn Marino /* Return nonzero if bits in V from OFFSET and LENGTH represent a
296c50c785cSJohn Marino    synthetic pointer.  */
297c50c785cSJohn Marino 
298c50c785cSJohn Marino static int
lval_func_check_synthetic_pointer(const struct value * v,int offset,int length)299c50c785cSJohn Marino lval_func_check_synthetic_pointer (const struct value *v,
300c50c785cSJohn Marino 				   int offset, int length)
301c50c785cSJohn Marino {
302c50c785cSJohn Marino   struct lval_closure *c = (struct lval_closure *) value_computed_closure (v);
303c50c785cSJohn Marino   /* Size of the target type in bits.  */
304c50c785cSJohn Marino   int elsize =
305c50c785cSJohn Marino       TYPE_LENGTH (TYPE_TARGET_TYPE (check_typedef (value_type (c->val)))) * 8;
306c50c785cSJohn Marino   int startrest = offset % elsize;
307c50c785cSJohn Marino   int start = offset / elsize;
308c50c785cSJohn Marino   int endrest = (offset + length) % elsize;
309c50c785cSJohn Marino   int end = (offset + length) / elsize;
310c50c785cSJohn Marino   int i;
311c50c785cSJohn Marino 
312c50c785cSJohn Marino   if (endrest)
313c50c785cSJohn Marino     end++;
314c50c785cSJohn Marino 
315c50c785cSJohn Marino   if (end > c->n)
316c50c785cSJohn Marino     return 0;
317c50c785cSJohn Marino 
318c50c785cSJohn Marino   for (i = start; i < end; i++)
319c50c785cSJohn Marino     {
320c50c785cSJohn Marino       int comp_offset = (i == start) ? startrest : 0;
321c50c785cSJohn Marino       int comp_length = (i == end) ? endrest : elsize;
322c50c785cSJohn Marino 
323c50c785cSJohn Marino       if (!value_bits_synthetic_pointer (c->val,
324c50c785cSJohn Marino 					 c->indices[i] * elsize + comp_offset,
325c50c785cSJohn Marino 					 comp_length))
326c50c785cSJohn Marino 	return 0;
327c50c785cSJohn Marino     }
328c50c785cSJohn Marino 
329c50c785cSJohn Marino   return 1;
330c50c785cSJohn Marino }
331c50c785cSJohn Marino 
332c50c785cSJohn Marino static void *
lval_func_copy_closure(const struct value * v)333c50c785cSJohn Marino lval_func_copy_closure (const struct value *v)
334c50c785cSJohn Marino {
335c50c785cSJohn Marino   struct lval_closure *c = (struct lval_closure *) value_computed_closure (v);
336c50c785cSJohn Marino 
337c50c785cSJohn Marino   ++c->refc;
338c50c785cSJohn Marino 
339c50c785cSJohn Marino   return c;
340c50c785cSJohn Marino }
341c50c785cSJohn Marino 
342c50c785cSJohn Marino static void
lval_func_free_closure(struct value * v)343c50c785cSJohn Marino lval_func_free_closure (struct value *v)
344c50c785cSJohn Marino {
345c50c785cSJohn Marino   struct lval_closure *c = (struct lval_closure *) value_computed_closure (v);
346c50c785cSJohn Marino 
347c50c785cSJohn Marino   --c->refc;
348c50c785cSJohn Marino 
349c50c785cSJohn Marino   if (c->refc == 0)
350c50c785cSJohn Marino     {
351c50c785cSJohn Marino       value_free (c->val); /* Decrement the reference counter of the value.  */
352c50c785cSJohn Marino       xfree (c->indices);
353c50c785cSJohn Marino       xfree (c);
354c50c785cSJohn Marino     }
355c50c785cSJohn Marino }
356c50c785cSJohn Marino 
357a45ae5f8SJohn Marino static const struct lval_funcs opencl_value_funcs =
358c50c785cSJohn Marino   {
359c50c785cSJohn Marino     lval_func_read,
360c50c785cSJohn Marino     lval_func_write,
361c50c785cSJohn Marino     lval_func_check_validity,
362c50c785cSJohn Marino     lval_func_check_any_valid,
363a45ae5f8SJohn Marino     NULL,	/* indirect */
364a45ae5f8SJohn Marino     NULL,	/* coerce_ref */
365c50c785cSJohn Marino     lval_func_check_synthetic_pointer,
366c50c785cSJohn Marino     lval_func_copy_closure,
367c50c785cSJohn Marino     lval_func_free_closure
368c50c785cSJohn Marino   };
369c50c785cSJohn Marino 
370c50c785cSJohn Marino /* Creates a sub-vector from VAL.  The elements are selected by the indices of
371c50c785cSJohn Marino    an array with the length of N.  Supported values for NOSIDE are
372c50c785cSJohn Marino    EVAL_NORMAL and EVAL_AVOID_SIDE_EFFECTS.  */
373c50c785cSJohn Marino 
374c50c785cSJohn Marino static struct value *
create_value(struct gdbarch * gdbarch,struct value * val,enum noside noside,int * indices,int n)375c50c785cSJohn Marino create_value (struct gdbarch *gdbarch, struct value *val, enum noside noside,
376c50c785cSJohn Marino 	      int *indices, int n)
377c50c785cSJohn Marino {
378c50c785cSJohn Marino   struct type *type = check_typedef (value_type (val));
379c50c785cSJohn Marino   struct type *elm_type = TYPE_TARGET_TYPE (type);
380c50c785cSJohn Marino   struct value *ret;
381c50c785cSJohn Marino 
382c50c785cSJohn Marino   /* Check if a single component of a vector is requested which means
383c50c785cSJohn Marino      the resulting type is a (primitive) scalar type.  */
384c50c785cSJohn Marino   if (n == 1)
385c50c785cSJohn Marino     {
386c50c785cSJohn Marino       if (noside == EVAL_AVOID_SIDE_EFFECTS)
387c50c785cSJohn Marino         ret = value_zero (elm_type, not_lval);
388c50c785cSJohn Marino       else
389c50c785cSJohn Marino         ret = value_subscript (val, indices[0]);
390c50c785cSJohn Marino     }
391c50c785cSJohn Marino   else
392c50c785cSJohn Marino     {
393c50c785cSJohn Marino       /* Multiple components of the vector are requested which means the
394c50c785cSJohn Marino 	 resulting type is a vector as well.  */
395c50c785cSJohn Marino       struct type *dst_type =
396c50c785cSJohn Marino 	lookup_opencl_vector_type (gdbarch, TYPE_CODE (elm_type),
397c50c785cSJohn Marino 				   TYPE_LENGTH (elm_type),
398c50c785cSJohn Marino 				   TYPE_UNSIGNED (elm_type), n);
399c50c785cSJohn Marino 
400c50c785cSJohn Marino       if (dst_type == NULL)
401c50c785cSJohn Marino 	dst_type = init_vector_type (elm_type, n);
402c50c785cSJohn Marino 
403c50c785cSJohn Marino       make_cv_type (TYPE_CONST (type), TYPE_VOLATILE (type), dst_type, NULL);
404c50c785cSJohn Marino 
405c50c785cSJohn Marino       if (noside == EVAL_AVOID_SIDE_EFFECTS)
406c50c785cSJohn Marino 	ret = allocate_value (dst_type);
407c50c785cSJohn Marino       else
408c50c785cSJohn Marino 	{
409c50c785cSJohn Marino 	  /* Check whether to create a lvalue or not.  */
410c50c785cSJohn Marino 	  if (VALUE_LVAL (val) != not_lval && !array_has_dups (indices, n))
411c50c785cSJohn Marino 	    {
412c50c785cSJohn Marino 	      struct lval_closure *c = allocate_lval_closure (indices, n, val);
413c50c785cSJohn Marino 	      ret = allocate_computed_value (dst_type, &opencl_value_funcs, c);
414c50c785cSJohn Marino 	    }
415c50c785cSJohn Marino 	  else
416c50c785cSJohn Marino 	    {
417c50c785cSJohn Marino 	      int i;
418c50c785cSJohn Marino 
419c50c785cSJohn Marino 	      ret = allocate_value (dst_type);
420c50c785cSJohn Marino 
421c50c785cSJohn Marino 	      /* Copy src val contents into the destination value.  */
422c50c785cSJohn Marino 	      for (i = 0; i < n; i++)
423c50c785cSJohn Marino 		memcpy (value_contents_writeable (ret)
424c50c785cSJohn Marino 			+ (i * TYPE_LENGTH (elm_type)),
425c50c785cSJohn Marino 			value_contents (val)
426c50c785cSJohn Marino 			+ (indices[i] * TYPE_LENGTH (elm_type)),
427c50c785cSJohn Marino 			TYPE_LENGTH (elm_type));
428c50c785cSJohn Marino 	    }
429c50c785cSJohn Marino 	}
430c50c785cSJohn Marino     }
431c50c785cSJohn Marino   return ret;
432c50c785cSJohn Marino }
433c50c785cSJohn Marino 
434c50c785cSJohn Marino /* OpenCL vector component access.  */
435c50c785cSJohn Marino 
436c50c785cSJohn Marino static struct value *
opencl_component_ref(struct expression * exp,struct value * val,char * comps,enum noside noside)437c50c785cSJohn Marino opencl_component_ref (struct expression *exp, struct value *val, char *comps,
438c50c785cSJohn Marino 		      enum noside noside)
439c50c785cSJohn Marino {
440c50c785cSJohn Marino   LONGEST lowb, highb;
441c50c785cSJohn Marino   int src_len;
442c50c785cSJohn Marino   struct value *v;
443c50c785cSJohn Marino   int indices[16], i;
444c50c785cSJohn Marino   int dst_len;
445c50c785cSJohn Marino 
446c50c785cSJohn Marino   if (!get_array_bounds (check_typedef (value_type (val)), &lowb, &highb))
447c50c785cSJohn Marino     error (_("Could not determine the vector bounds"));
448c50c785cSJohn Marino 
449c50c785cSJohn Marino   src_len = highb - lowb + 1;
450c50c785cSJohn Marino 
451c50c785cSJohn Marino   /* Throw an error if the amount of array elements does not fit a
452c50c785cSJohn Marino      valid OpenCL vector size (2, 3, 4, 8, 16).  */
453c50c785cSJohn Marino   if (src_len != 2 && src_len != 3 && src_len != 4 && src_len != 8
454c50c785cSJohn Marino       && src_len != 16)
455c50c785cSJohn Marino     error (_("Invalid OpenCL vector size"));
456c50c785cSJohn Marino 
457c50c785cSJohn Marino   if (strcmp (comps, "lo") == 0 )
458c50c785cSJohn Marino     {
459c50c785cSJohn Marino       dst_len = (src_len == 3) ? 2 : src_len / 2;
460c50c785cSJohn Marino 
461c50c785cSJohn Marino       for (i = 0; i < dst_len; i++)
462c50c785cSJohn Marino 	indices[i] = i;
463c50c785cSJohn Marino     }
464c50c785cSJohn Marino   else if (strcmp (comps, "hi") == 0)
465c50c785cSJohn Marino     {
466c50c785cSJohn Marino       dst_len = (src_len == 3) ? 2 : src_len / 2;
467c50c785cSJohn Marino 
468c50c785cSJohn Marino       for (i = 0; i < dst_len; i++)
469c50c785cSJohn Marino 	indices[i] = dst_len + i;
470c50c785cSJohn Marino     }
471c50c785cSJohn Marino   else if (strcmp (comps, "even") == 0)
472c50c785cSJohn Marino     {
473c50c785cSJohn Marino       dst_len = (src_len == 3) ? 2 : src_len / 2;
474c50c785cSJohn Marino 
475c50c785cSJohn Marino       for (i = 0; i < dst_len; i++)
476c50c785cSJohn Marino 	indices[i] = i*2;
477c50c785cSJohn Marino     }
478c50c785cSJohn Marino   else if (strcmp (comps, "odd") == 0)
479c50c785cSJohn Marino     {
480c50c785cSJohn Marino       dst_len = (src_len == 3) ? 2 : src_len / 2;
481c50c785cSJohn Marino 
482c50c785cSJohn Marino       for (i = 0; i < dst_len; i++)
483c50c785cSJohn Marino         indices[i] = i*2+1;
484c50c785cSJohn Marino     }
485c50c785cSJohn Marino   else if (strncasecmp (comps, "s", 1) == 0)
486c50c785cSJohn Marino     {
487c50c785cSJohn Marino #define HEXCHAR_TO_INT(C) ((C >= '0' && C <= '9') ? \
488c50c785cSJohn Marino                            C-'0' : ((C >= 'A' && C <= 'F') ? \
489c50c785cSJohn Marino                            C-'A'+10 : ((C >= 'a' && C <= 'f') ? \
490c50c785cSJohn Marino                            C-'a'+10 : -1)))
491c50c785cSJohn Marino 
492c50c785cSJohn Marino       dst_len = strlen (comps);
493c50c785cSJohn Marino       /* Skip the s/S-prefix.  */
494c50c785cSJohn Marino       dst_len--;
495c50c785cSJohn Marino 
496c50c785cSJohn Marino       for (i = 0; i < dst_len; i++)
497c50c785cSJohn Marino 	{
498c50c785cSJohn Marino 	  indices[i] = HEXCHAR_TO_INT(comps[i+1]);
499c50c785cSJohn Marino 	  /* Check if the requested component is invalid or exceeds
500c50c785cSJohn Marino 	     the vector.  */
501c50c785cSJohn Marino 	  if (indices[i] < 0 || indices[i] >= src_len)
502c50c785cSJohn Marino 	    error (_("Invalid OpenCL vector component accessor %s"), comps);
503c50c785cSJohn Marino 	}
504c50c785cSJohn Marino     }
505c50c785cSJohn Marino   else
506c50c785cSJohn Marino     {
507c50c785cSJohn Marino       dst_len = strlen (comps);
508c50c785cSJohn Marino 
509c50c785cSJohn Marino       for (i = 0; i < dst_len; i++)
510c50c785cSJohn Marino 	{
511c50c785cSJohn Marino 	  /* x, y, z, w */
512c50c785cSJohn Marino 	  switch (comps[i])
513c50c785cSJohn Marino 	  {
514c50c785cSJohn Marino 	  case 'x':
515c50c785cSJohn Marino 	    indices[i] = 0;
516c50c785cSJohn Marino 	    break;
517c50c785cSJohn Marino 	  case 'y':
518c50c785cSJohn Marino 	    indices[i] = 1;
519c50c785cSJohn Marino 	    break;
520c50c785cSJohn Marino 	  case 'z':
521c50c785cSJohn Marino 	    if (src_len < 3)
522c50c785cSJohn Marino 	      error (_("Invalid OpenCL vector component accessor %s"), comps);
523c50c785cSJohn Marino 	    indices[i] = 2;
524c50c785cSJohn Marino 	    break;
525c50c785cSJohn Marino 	  case 'w':
526c50c785cSJohn Marino 	    if (src_len < 4)
527c50c785cSJohn Marino 	      error (_("Invalid OpenCL vector component accessor %s"), comps);
528c50c785cSJohn Marino 	    indices[i] = 3;
529c50c785cSJohn Marino 	    break;
530c50c785cSJohn Marino 	  default:
531c50c785cSJohn Marino 	    error (_("Invalid OpenCL vector component accessor %s"), comps);
532c50c785cSJohn Marino 	    break;
533c50c785cSJohn Marino 	  }
534c50c785cSJohn Marino 	}
535c50c785cSJohn Marino     }
536c50c785cSJohn Marino 
537c50c785cSJohn Marino   /* Throw an error if the amount of requested components does not
538c50c785cSJohn Marino      result in a valid length (1, 2, 3, 4, 8, 16).  */
539c50c785cSJohn Marino   if (dst_len != 1 && dst_len != 2 && dst_len != 3 && dst_len != 4
540c50c785cSJohn Marino       && dst_len != 8 && dst_len != 16)
541c50c785cSJohn Marino     error (_("Invalid OpenCL vector component accessor %s"), comps);
542c50c785cSJohn Marino 
543c50c785cSJohn Marino   v = create_value (exp->gdbarch, val, noside, indices, dst_len);
544c50c785cSJohn Marino 
545c50c785cSJohn Marino   return v;
546c50c785cSJohn Marino }
547c50c785cSJohn Marino 
548c50c785cSJohn Marino /* Perform the unary logical not (!) operation.  */
549c50c785cSJohn Marino 
550c50c785cSJohn Marino static struct value *
opencl_logical_not(struct expression * exp,struct value * arg)551c50c785cSJohn Marino opencl_logical_not (struct expression *exp, struct value *arg)
552c50c785cSJohn Marino {
553c50c785cSJohn Marino   struct type *type = check_typedef (value_type (arg));
554c50c785cSJohn Marino   struct type *rettype;
555c50c785cSJohn Marino   struct value *ret;
556c50c785cSJohn Marino 
557c50c785cSJohn Marino   if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
558c50c785cSJohn Marino     {
559c50c785cSJohn Marino       struct type *eltype = check_typedef (TYPE_TARGET_TYPE (type));
560c50c785cSJohn Marino       LONGEST lowb, highb;
561c50c785cSJohn Marino       int i;
562c50c785cSJohn Marino 
563c50c785cSJohn Marino       if (!get_array_bounds (type, &lowb, &highb))
564c50c785cSJohn Marino 	error (_("Could not determine the vector bounds"));
565c50c785cSJohn Marino 
566c50c785cSJohn Marino       /* Determine the resulting type of the operation and allocate the
567c50c785cSJohn Marino 	 value.  */
568c50c785cSJohn Marino       rettype = lookup_opencl_vector_type (exp->gdbarch, TYPE_CODE_INT,
569c50c785cSJohn Marino 					   TYPE_LENGTH (eltype), 0,
570c50c785cSJohn Marino 					   highb - lowb + 1);
571c50c785cSJohn Marino       ret = allocate_value (rettype);
572c50c785cSJohn Marino 
573c50c785cSJohn Marino       for (i = 0; i < highb - lowb + 1; i++)
574c50c785cSJohn Marino 	{
575c50c785cSJohn Marino 	  /* For vector types, the unary operator shall return a 0 if the
576c50c785cSJohn Marino 	  value of its operand compares unequal to 0, and -1 (i.e. all bits
577c50c785cSJohn Marino 	  set) if the value of its operand compares equal to 0.  */
578c50c785cSJohn Marino 	  int tmp = value_logical_not (value_subscript (arg, i)) ? -1 : 0;
579c50c785cSJohn Marino 	  memset (value_contents_writeable (ret) + i * TYPE_LENGTH (eltype),
580c50c785cSJohn Marino 		  tmp, TYPE_LENGTH (eltype));
581c50c785cSJohn Marino 	}
582c50c785cSJohn Marino     }
583c50c785cSJohn Marino   else
584c50c785cSJohn Marino     {
585c50c785cSJohn Marino       rettype = language_bool_type (exp->language_defn, exp->gdbarch);
586c50c785cSJohn Marino       ret = value_from_longest (rettype, value_logical_not (arg));
587c50c785cSJohn Marino     }
588c50c785cSJohn Marino 
589c50c785cSJohn Marino   return ret;
590c50c785cSJohn Marino }
591c50c785cSJohn Marino 
592c50c785cSJohn Marino /* Perform a relational operation on two scalar operands.  */
593c50c785cSJohn Marino 
594c50c785cSJohn Marino static int
scalar_relop(struct value * val1,struct value * val2,enum exp_opcode op)595c50c785cSJohn Marino scalar_relop (struct value *val1, struct value *val2, enum exp_opcode op)
596c50c785cSJohn Marino {
597c50c785cSJohn Marino   int ret;
598c50c785cSJohn Marino 
599c50c785cSJohn Marino   switch (op)
600c50c785cSJohn Marino     {
601c50c785cSJohn Marino     case BINOP_EQUAL:
602c50c785cSJohn Marino       ret = value_equal (val1, val2);
603c50c785cSJohn Marino       break;
604c50c785cSJohn Marino     case BINOP_NOTEQUAL:
605c50c785cSJohn Marino       ret = !value_equal (val1, val2);
606c50c785cSJohn Marino       break;
607c50c785cSJohn Marino     case BINOP_LESS:
608c50c785cSJohn Marino       ret = value_less (val1, val2);
609c50c785cSJohn Marino       break;
610c50c785cSJohn Marino     case BINOP_GTR:
611c50c785cSJohn Marino       ret = value_less (val2, val1);
612c50c785cSJohn Marino       break;
613c50c785cSJohn Marino     case BINOP_GEQ:
614c50c785cSJohn Marino       ret = value_less (val2, val1) || value_equal (val1, val2);
615c50c785cSJohn Marino       break;
616c50c785cSJohn Marino     case BINOP_LEQ:
617c50c785cSJohn Marino       ret = value_less (val1, val2) || value_equal (val1, val2);
618c50c785cSJohn Marino       break;
619c50c785cSJohn Marino     case BINOP_LOGICAL_AND:
620c50c785cSJohn Marino       ret = !value_logical_not (val1) && !value_logical_not (val2);
621c50c785cSJohn Marino       break;
622c50c785cSJohn Marino     case BINOP_LOGICAL_OR:
623c50c785cSJohn Marino       ret = !value_logical_not (val1) || !value_logical_not (val2);
624c50c785cSJohn Marino       break;
625c50c785cSJohn Marino     default:
626c50c785cSJohn Marino       error (_("Attempt to perform an unsupported operation"));
627c50c785cSJohn Marino       break;
628c50c785cSJohn Marino     }
629c50c785cSJohn Marino   return ret;
630c50c785cSJohn Marino }
631c50c785cSJohn Marino 
632c50c785cSJohn Marino /* Perform a relational operation on two vector operands.  */
633c50c785cSJohn Marino 
634c50c785cSJohn Marino static struct value *
vector_relop(struct expression * exp,struct value * val1,struct value * val2,enum exp_opcode op)635c50c785cSJohn Marino vector_relop (struct expression *exp, struct value *val1, struct value *val2,
636c50c785cSJohn Marino 	      enum exp_opcode op)
637c50c785cSJohn Marino {
638c50c785cSJohn Marino   struct value *ret;
639c50c785cSJohn Marino   struct type *type1, *type2, *eltype1, *eltype2, *rettype;
640c50c785cSJohn Marino   int t1_is_vec, t2_is_vec, i;
641c50c785cSJohn Marino   LONGEST lowb1, lowb2, highb1, highb2;
642c50c785cSJohn Marino 
643c50c785cSJohn Marino   type1 = check_typedef (value_type (val1));
644c50c785cSJohn Marino   type2 = check_typedef (value_type (val2));
645c50c785cSJohn Marino 
646c50c785cSJohn Marino   t1_is_vec = (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1));
647c50c785cSJohn Marino   t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2));
648c50c785cSJohn Marino 
649c50c785cSJohn Marino   if (!t1_is_vec || !t2_is_vec)
650c50c785cSJohn Marino     error (_("Vector operations are not supported on scalar types"));
651c50c785cSJohn Marino 
652c50c785cSJohn Marino   eltype1 = check_typedef (TYPE_TARGET_TYPE (type1));
653c50c785cSJohn Marino   eltype2 = check_typedef (TYPE_TARGET_TYPE (type2));
654c50c785cSJohn Marino 
655c50c785cSJohn Marino   if (!get_array_bounds (type1,&lowb1, &highb1)
656c50c785cSJohn Marino       || !get_array_bounds (type2, &lowb2, &highb2))
657c50c785cSJohn Marino     error (_("Could not determine the vector bounds"));
658c50c785cSJohn Marino 
659c50c785cSJohn Marino   /* Check whether the vector types are compatible.  */
660c50c785cSJohn Marino   if (TYPE_CODE (eltype1) != TYPE_CODE (eltype2)
661c50c785cSJohn Marino       || TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2)
662c50c785cSJohn Marino       || TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2)
663c50c785cSJohn Marino       || lowb1 != lowb2 || highb1 != highb2)
664c50c785cSJohn Marino     error (_("Cannot perform operation on vectors with different types"));
665c50c785cSJohn Marino 
666c50c785cSJohn Marino   /* Determine the resulting type of the operation and allocate the value.  */
667c50c785cSJohn Marino   rettype = lookup_opencl_vector_type (exp->gdbarch, TYPE_CODE_INT,
668c50c785cSJohn Marino 				       TYPE_LENGTH (eltype1), 0,
669c50c785cSJohn Marino 				       highb1 - lowb1 + 1);
670c50c785cSJohn Marino   ret = allocate_value (rettype);
671c50c785cSJohn Marino 
672c50c785cSJohn Marino   for (i = 0; i < highb1 - lowb1 + 1; i++)
673c50c785cSJohn Marino     {
674c50c785cSJohn Marino       /* For vector types, the relational, equality and logical operators shall
675c50c785cSJohn Marino 	 return 0 if the specified relation is false and -1 (i.e. all bits set)
676c50c785cSJohn Marino 	 if the specified relation is true.  */
677c50c785cSJohn Marino       int tmp = scalar_relop (value_subscript (val1, i),
678c50c785cSJohn Marino 			      value_subscript (val2, i), op) ? -1 : 0;
679c50c785cSJohn Marino       memset (value_contents_writeable (ret) + i * TYPE_LENGTH (eltype1),
680c50c785cSJohn Marino 	      tmp, TYPE_LENGTH (eltype1));
681c50c785cSJohn Marino      }
682c50c785cSJohn Marino 
683c50c785cSJohn Marino   return ret;
684c50c785cSJohn Marino }
685c50c785cSJohn Marino 
686*ef5ccd6cSJohn Marino /* Perform a cast of ARG into TYPE.  There's sadly a lot of duplication in
687*ef5ccd6cSJohn Marino    here from valops.c:value_cast, opencl is different only in the
688*ef5ccd6cSJohn Marino    behaviour of scalar to vector casting.  As far as possibly we're going
689*ef5ccd6cSJohn Marino    to try and delegate back to the standard value_cast function. */
690*ef5ccd6cSJohn Marino 
691*ef5ccd6cSJohn Marino static struct value *
opencl_value_cast(struct type * type,struct value * arg)692*ef5ccd6cSJohn Marino opencl_value_cast (struct type *type, struct value *arg)
693*ef5ccd6cSJohn Marino {
694*ef5ccd6cSJohn Marino   if (type != value_type (arg))
695*ef5ccd6cSJohn Marino     {
696*ef5ccd6cSJohn Marino       /* Casting scalar to vector is a special case for OpenCL, scalar
697*ef5ccd6cSJohn Marino 	 is cast to element type of vector then replicated into each
698*ef5ccd6cSJohn Marino 	 element of the vector.  First though, we need to work out if
699*ef5ccd6cSJohn Marino 	 this is a scalar to vector cast; code lifted from
700*ef5ccd6cSJohn Marino 	 valops.c:value_cast.  */
701*ef5ccd6cSJohn Marino       enum type_code code1, code2;
702*ef5ccd6cSJohn Marino       struct type *to_type;
703*ef5ccd6cSJohn Marino       int scalar;
704*ef5ccd6cSJohn Marino 
705*ef5ccd6cSJohn Marino       to_type = check_typedef (type);
706*ef5ccd6cSJohn Marino 
707*ef5ccd6cSJohn Marino       code1 = TYPE_CODE (to_type);
708*ef5ccd6cSJohn Marino       code2 = TYPE_CODE (check_typedef (value_type (arg)));
709*ef5ccd6cSJohn Marino 
710*ef5ccd6cSJohn Marino       if (code2 == TYPE_CODE_REF)
711*ef5ccd6cSJohn Marino 	code2 = TYPE_CODE (check_typedef (value_type (coerce_ref (arg))));
712*ef5ccd6cSJohn Marino 
713*ef5ccd6cSJohn Marino       scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL
714*ef5ccd6cSJohn Marino 		|| code2 == TYPE_CODE_CHAR || code2 == TYPE_CODE_FLT
715*ef5ccd6cSJohn Marino 		|| code2 == TYPE_CODE_DECFLOAT || code2 == TYPE_CODE_ENUM
716*ef5ccd6cSJohn Marino 		|| code2 == TYPE_CODE_RANGE);
717*ef5ccd6cSJohn Marino 
718*ef5ccd6cSJohn Marino       if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (to_type) && scalar)
719*ef5ccd6cSJohn Marino 	{
720*ef5ccd6cSJohn Marino 	  struct type *eltype;
721*ef5ccd6cSJohn Marino 
722*ef5ccd6cSJohn Marino 	  /* Cast to the element type of the vector here as
723*ef5ccd6cSJohn Marino 	     value_vector_widen will error if the scalar value is
724*ef5ccd6cSJohn Marino 	     truncated by the cast.  To avoid the error, cast (and
725*ef5ccd6cSJohn Marino 	     possibly truncate) here.  */
726*ef5ccd6cSJohn Marino 	  eltype = check_typedef (TYPE_TARGET_TYPE (to_type));
727*ef5ccd6cSJohn Marino 	  arg = value_cast (eltype, arg);
728*ef5ccd6cSJohn Marino 
729*ef5ccd6cSJohn Marino 	  return value_vector_widen (arg, type);
730*ef5ccd6cSJohn Marino 	}
731*ef5ccd6cSJohn Marino       else
732*ef5ccd6cSJohn Marino 	/* Standard cast handler.  */
733*ef5ccd6cSJohn Marino 	arg = value_cast (type, arg);
734*ef5ccd6cSJohn Marino     }
735*ef5ccd6cSJohn Marino   return arg;
736*ef5ccd6cSJohn Marino }
737*ef5ccd6cSJohn Marino 
738c50c785cSJohn Marino /* Perform a relational operation on two operands.  */
739c50c785cSJohn Marino 
740c50c785cSJohn Marino static struct value *
opencl_relop(struct expression * exp,struct value * arg1,struct value * arg2,enum exp_opcode op)741c50c785cSJohn Marino opencl_relop (struct expression *exp, struct value *arg1, struct value *arg2,
742c50c785cSJohn Marino 	      enum exp_opcode op)
743c50c785cSJohn Marino {
744c50c785cSJohn Marino   struct value *val;
745c50c785cSJohn Marino   struct type *type1 = check_typedef (value_type (arg1));
746c50c785cSJohn Marino   struct type *type2 = check_typedef (value_type (arg2));
747c50c785cSJohn Marino   int t1_is_vec = (TYPE_CODE (type1) == TYPE_CODE_ARRAY
748c50c785cSJohn Marino 		   && TYPE_VECTOR (type1));
749c50c785cSJohn Marino   int t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY
750c50c785cSJohn Marino 		   && TYPE_VECTOR (type2));
751c50c785cSJohn Marino 
752c50c785cSJohn Marino   if (!t1_is_vec && !t2_is_vec)
753c50c785cSJohn Marino     {
754c50c785cSJohn Marino       int tmp = scalar_relop (arg1, arg2, op);
755c50c785cSJohn Marino       struct type *type =
756c50c785cSJohn Marino 	language_bool_type (exp->language_defn, exp->gdbarch);
757c50c785cSJohn Marino 
758c50c785cSJohn Marino       val = value_from_longest (type, tmp);
759c50c785cSJohn Marino     }
760c50c785cSJohn Marino   else if (t1_is_vec && t2_is_vec)
761c50c785cSJohn Marino     {
762c50c785cSJohn Marino       val = vector_relop (exp, arg1, arg2, op);
763c50c785cSJohn Marino     }
764c50c785cSJohn Marino   else
765c50c785cSJohn Marino     {
766c50c785cSJohn Marino       /* Widen the scalar operand to a vector.  */
767c50c785cSJohn Marino       struct value **v = t1_is_vec ? &arg2 : &arg1;
768c50c785cSJohn Marino       struct type *t = t1_is_vec ? type2 : type1;
769c50c785cSJohn Marino 
770c50c785cSJohn Marino       if (TYPE_CODE (t) != TYPE_CODE_FLT && !is_integral_type (t))
771c50c785cSJohn Marino 	error (_("Argument to operation not a number or boolean."));
772c50c785cSJohn Marino 
773*ef5ccd6cSJohn Marino       *v = opencl_value_cast (t1_is_vec ? type1 : type2, *v);
774c50c785cSJohn Marino       val = vector_relop (exp, arg1, arg2, op);
775c50c785cSJohn Marino     }
776c50c785cSJohn Marino 
777c50c785cSJohn Marino   return val;
778c50c785cSJohn Marino }
779c50c785cSJohn Marino 
780c50c785cSJohn Marino /* Expression evaluator for the OpenCL.  Most operations are delegated to
781c50c785cSJohn Marino    evaluate_subexp_standard; see that function for a description of the
782c50c785cSJohn Marino    arguments.  */
783c50c785cSJohn Marino 
784c50c785cSJohn Marino static struct value *
evaluate_subexp_opencl(struct type * expect_type,struct expression * exp,int * pos,enum noside noside)785c50c785cSJohn Marino evaluate_subexp_opencl (struct type *expect_type, struct expression *exp,
786c50c785cSJohn Marino 		   int *pos, enum noside noside)
787c50c785cSJohn Marino {
788c50c785cSJohn Marino   enum exp_opcode op = exp->elts[*pos].opcode;
789c50c785cSJohn Marino   struct value *arg1 = NULL;
790c50c785cSJohn Marino   struct value *arg2 = NULL;
791c50c785cSJohn Marino   struct type *type1, *type2;
792c50c785cSJohn Marino 
793c50c785cSJohn Marino   switch (op)
794c50c785cSJohn Marino     {
795*ef5ccd6cSJohn Marino     /* Handle assignment and cast operators to support OpenCL-style
796*ef5ccd6cSJohn Marino        scalar-to-vector widening.  */
797*ef5ccd6cSJohn Marino     case BINOP_ASSIGN:
798*ef5ccd6cSJohn Marino       (*pos)++;
799*ef5ccd6cSJohn Marino       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
800*ef5ccd6cSJohn Marino       type1 = value_type (arg1);
801*ef5ccd6cSJohn Marino       arg2 = evaluate_subexp (type1, exp, pos, noside);
802*ef5ccd6cSJohn Marino 
803*ef5ccd6cSJohn Marino       if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
804*ef5ccd6cSJohn Marino 	return arg1;
805*ef5ccd6cSJohn Marino 
806*ef5ccd6cSJohn Marino       if (deprecated_value_modifiable (arg1)
807*ef5ccd6cSJohn Marino 	  && VALUE_LVAL (arg1) != lval_internalvar)
808*ef5ccd6cSJohn Marino 	arg2 = opencl_value_cast (type1, arg2);
809*ef5ccd6cSJohn Marino 
810*ef5ccd6cSJohn Marino       return value_assign (arg1, arg2);
811*ef5ccd6cSJohn Marino 
812*ef5ccd6cSJohn Marino     case UNOP_CAST:
813*ef5ccd6cSJohn Marino       type1 = exp->elts[*pos + 1].type;
814*ef5ccd6cSJohn Marino       (*pos) += 2;
815*ef5ccd6cSJohn Marino       arg1 = evaluate_subexp (type1, exp, pos, noside);
816*ef5ccd6cSJohn Marino 
817*ef5ccd6cSJohn Marino       if (noside == EVAL_SKIP)
818*ef5ccd6cSJohn Marino 	return value_from_longest (builtin_type (exp->gdbarch)->
819*ef5ccd6cSJohn Marino 				   builtin_int, 1);
820*ef5ccd6cSJohn Marino 
821*ef5ccd6cSJohn Marino       return opencl_value_cast (type1, arg1);
822*ef5ccd6cSJohn Marino 
823*ef5ccd6cSJohn Marino     case UNOP_CAST_TYPE:
824*ef5ccd6cSJohn Marino       (*pos)++;
825*ef5ccd6cSJohn Marino       arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
826*ef5ccd6cSJohn Marino       type1 = value_type (arg1);
827*ef5ccd6cSJohn Marino       arg1 = evaluate_subexp (type1, exp, pos, noside);
828*ef5ccd6cSJohn Marino 
829*ef5ccd6cSJohn Marino       if (noside == EVAL_SKIP)
830*ef5ccd6cSJohn Marino 	return value_from_longest (builtin_type (exp->gdbarch)->
831*ef5ccd6cSJohn Marino 				   builtin_int, 1);
832*ef5ccd6cSJohn Marino 
833*ef5ccd6cSJohn Marino       return opencl_value_cast (type1, arg1);
834*ef5ccd6cSJohn Marino 
835c50c785cSJohn Marino     /* Handle binary relational and equality operators that are either not
836c50c785cSJohn Marino        or differently defined for GNU vectors.  */
837c50c785cSJohn Marino     case BINOP_EQUAL:
838c50c785cSJohn Marino     case BINOP_NOTEQUAL:
839c50c785cSJohn Marino     case BINOP_LESS:
840c50c785cSJohn Marino     case BINOP_GTR:
841c50c785cSJohn Marino     case BINOP_GEQ:
842c50c785cSJohn Marino     case BINOP_LEQ:
843c50c785cSJohn Marino       (*pos)++;
844c50c785cSJohn Marino       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
845c50c785cSJohn Marino       arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
846c50c785cSJohn Marino 
847c50c785cSJohn Marino       if (noside == EVAL_SKIP)
848c50c785cSJohn Marino 	return value_from_longest (builtin_type (exp->gdbarch)->
849c50c785cSJohn Marino 				   builtin_int, 1);
850c50c785cSJohn Marino 
851c50c785cSJohn Marino       return opencl_relop (exp, arg1, arg2, op);
852c50c785cSJohn Marino 
853c50c785cSJohn Marino     /* Handle the logical unary operator not(!).  */
854c50c785cSJohn Marino     case UNOP_LOGICAL_NOT:
855c50c785cSJohn Marino       (*pos)++;
856c50c785cSJohn Marino       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
857c50c785cSJohn Marino 
858c50c785cSJohn Marino       if (noside == EVAL_SKIP)
859c50c785cSJohn Marino 	return value_from_longest (builtin_type (exp->gdbarch)->
860c50c785cSJohn Marino 				   builtin_int, 1);
861c50c785cSJohn Marino 
862c50c785cSJohn Marino       return opencl_logical_not (exp, arg1);
863c50c785cSJohn Marino 
864c50c785cSJohn Marino     /* Handle the logical operator and(&&) and or(||).  */
865c50c785cSJohn Marino     case BINOP_LOGICAL_AND:
866c50c785cSJohn Marino     case BINOP_LOGICAL_OR:
867c50c785cSJohn Marino       (*pos)++;
868c50c785cSJohn Marino       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
869c50c785cSJohn Marino 
870c50c785cSJohn Marino       if (noside == EVAL_SKIP)
871c50c785cSJohn Marino 	{
872c50c785cSJohn Marino 	  evaluate_subexp (NULL_TYPE, exp, pos, noside);
873c50c785cSJohn Marino 
874c50c785cSJohn Marino 	  return value_from_longest (builtin_type (exp->gdbarch)->
875c50c785cSJohn Marino 				     builtin_int, 1);
876c50c785cSJohn Marino 	}
877c50c785cSJohn Marino       else
878c50c785cSJohn Marino 	{
879c50c785cSJohn Marino 	  /* For scalar operations we need to avoid evaluating operands
880c50c785cSJohn Marino 	     unecessarily.  However, for vector operations we always need to
881c50c785cSJohn Marino 	     evaluate both operands.  Unfortunately we only know which of the
882c50c785cSJohn Marino 	     two cases apply after we know the type of the second operand.
883c50c785cSJohn Marino 	     Therefore we evaluate it once using EVAL_AVOID_SIDE_EFFECTS.  */
884c50c785cSJohn Marino 	  int oldpos = *pos;
885c50c785cSJohn Marino 
886c50c785cSJohn Marino 	  arg2 = evaluate_subexp (NULL_TYPE, exp, pos,
887c50c785cSJohn Marino 				  EVAL_AVOID_SIDE_EFFECTS);
888c50c785cSJohn Marino 	  *pos = oldpos;
889c50c785cSJohn Marino 	  type1 = check_typedef (value_type (arg1));
890c50c785cSJohn Marino 	  type2 = check_typedef (value_type (arg2));
891c50c785cSJohn Marino 
892c50c785cSJohn Marino 	  if ((TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1))
893c50c785cSJohn Marino 	      || (TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)))
894c50c785cSJohn Marino 	    {
895c50c785cSJohn Marino 	      arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
896c50c785cSJohn Marino 
897c50c785cSJohn Marino 	      return opencl_relop (exp, arg1, arg2, op);
898c50c785cSJohn Marino 	    }
899c50c785cSJohn Marino 	  else
900c50c785cSJohn Marino 	    {
901c50c785cSJohn Marino 	      /* For scalar built-in types, only evaluate the right
902c50c785cSJohn Marino 		 hand operand if the left hand operand compares
903c50c785cSJohn Marino 		 unequal(&&)/equal(||) to 0.  */
904c50c785cSJohn Marino 	      int res;
905c50c785cSJohn Marino 	      int tmp = value_logical_not (arg1);
906c50c785cSJohn Marino 
907c50c785cSJohn Marino 	      if (op == BINOP_LOGICAL_OR)
908c50c785cSJohn Marino 		tmp = !tmp;
909c50c785cSJohn Marino 
910c50c785cSJohn Marino 	      arg2 = evaluate_subexp (NULL_TYPE, exp, pos,
911c50c785cSJohn Marino 				      tmp ? EVAL_SKIP : noside);
912c50c785cSJohn Marino 	      type1 = language_bool_type (exp->language_defn, exp->gdbarch);
913c50c785cSJohn Marino 
914c50c785cSJohn Marino 	      if (op == BINOP_LOGICAL_AND)
915c50c785cSJohn Marino 		res = !tmp && !value_logical_not (arg2);
916c50c785cSJohn Marino 	      else /* BINOP_LOGICAL_OR */
917c50c785cSJohn Marino 		res = tmp || !value_logical_not (arg2);
918c50c785cSJohn Marino 
919c50c785cSJohn Marino 	      return value_from_longest (type1, res);
920c50c785cSJohn Marino 	    }
921c50c785cSJohn Marino 	}
922c50c785cSJohn Marino 
923c50c785cSJohn Marino     /* Handle the ternary selection operator.  */
924c50c785cSJohn Marino     case TERNOP_COND:
925c50c785cSJohn Marino       (*pos)++;
926c50c785cSJohn Marino       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
927c50c785cSJohn Marino       type1 = check_typedef (value_type (arg1));
928c50c785cSJohn Marino       if (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1))
929c50c785cSJohn Marino 	{
930c50c785cSJohn Marino 	  struct value *arg3, *tmp, *ret;
931c50c785cSJohn Marino 	  struct type *eltype2, *type3, *eltype3;
932c50c785cSJohn Marino 	  int t2_is_vec, t3_is_vec, i;
933c50c785cSJohn Marino 	  LONGEST lowb1, lowb2, lowb3, highb1, highb2, highb3;
934c50c785cSJohn Marino 
935c50c785cSJohn Marino 	  arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
936c50c785cSJohn Marino 	  arg3 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
937c50c785cSJohn Marino 	  type2 = check_typedef (value_type (arg2));
938c50c785cSJohn Marino 	  type3 = check_typedef (value_type (arg3));
939c50c785cSJohn Marino 	  t2_is_vec
940c50c785cSJohn Marino 	    = TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2);
941c50c785cSJohn Marino 	  t3_is_vec
942c50c785cSJohn Marino 	    = TYPE_CODE (type3) == TYPE_CODE_ARRAY && TYPE_VECTOR (type3);
943c50c785cSJohn Marino 
944c50c785cSJohn Marino 	  /* Widen the scalar operand to a vector if necessary.  */
945c50c785cSJohn Marino 	  if (t2_is_vec || !t3_is_vec)
946c50c785cSJohn Marino 	    {
947*ef5ccd6cSJohn Marino 	      arg3 = opencl_value_cast (type2, arg3);
948c50c785cSJohn Marino 	      type3 = value_type (arg3);
949c50c785cSJohn Marino 	    }
950c50c785cSJohn Marino 	  else if (!t2_is_vec || t3_is_vec)
951c50c785cSJohn Marino 	    {
952*ef5ccd6cSJohn Marino 	      arg2 = opencl_value_cast (type3, arg2);
953c50c785cSJohn Marino 	      type2 = value_type (arg2);
954c50c785cSJohn Marino 	    }
955c50c785cSJohn Marino 	  else if (!t2_is_vec || !t3_is_vec)
956c50c785cSJohn Marino 	    {
957c50c785cSJohn Marino 	      /* Throw an error if arg2 or arg3 aren't vectors.  */
958c50c785cSJohn Marino 	      error (_("\
959c50c785cSJohn Marino Cannot perform conditional operation on incompatible types"));
960c50c785cSJohn Marino 	    }
961c50c785cSJohn Marino 
962c50c785cSJohn Marino 	  eltype2 = check_typedef (TYPE_TARGET_TYPE (type2));
963c50c785cSJohn Marino 	  eltype3 = check_typedef (TYPE_TARGET_TYPE (type3));
964c50c785cSJohn Marino 
965c50c785cSJohn Marino 	  if (!get_array_bounds (type1, &lowb1, &highb1)
966c50c785cSJohn Marino 	      || !get_array_bounds (type2, &lowb2, &highb2)
967c50c785cSJohn Marino 	      || !get_array_bounds (type3, &lowb3, &highb3))
968c50c785cSJohn Marino 	    error (_("Could not determine the vector bounds"));
969c50c785cSJohn Marino 
970c50c785cSJohn Marino 	  /* Throw an error if the types of arg2 or arg3 are incompatible.  */
971c50c785cSJohn Marino 	  if (TYPE_CODE (eltype2) != TYPE_CODE (eltype3)
972c50c785cSJohn Marino 	      || TYPE_LENGTH (eltype2) != TYPE_LENGTH (eltype3)
973c50c785cSJohn Marino 	      || TYPE_UNSIGNED (eltype2) != TYPE_UNSIGNED (eltype3)
974c50c785cSJohn Marino 	      || lowb2 != lowb3 || highb2 != highb3)
975c50c785cSJohn Marino 	    error (_("\
976c50c785cSJohn Marino Cannot perform operation on vectors with different types"));
977c50c785cSJohn Marino 
978c50c785cSJohn Marino 	  /* Throw an error if the sizes of arg1 and arg2/arg3 differ.  */
979c50c785cSJohn Marino 	  if (lowb1 != lowb2 || lowb1 != lowb3
980c50c785cSJohn Marino 	      || highb1 != highb2 || highb1 != highb3)
981c50c785cSJohn Marino 	    error (_("\
982c50c785cSJohn Marino Cannot perform conditional operation on vectors with different sizes"));
983c50c785cSJohn Marino 
984c50c785cSJohn Marino 	  ret = allocate_value (type2);
985c50c785cSJohn Marino 
986c50c785cSJohn Marino 	  for (i = 0; i < highb1 - lowb1 + 1; i++)
987c50c785cSJohn Marino 	    {
988c50c785cSJohn Marino 	      tmp = value_logical_not (value_subscript (arg1, i)) ?
989c50c785cSJohn Marino 		    value_subscript (arg3, i) : value_subscript (arg2, i);
990c50c785cSJohn Marino 	      memcpy (value_contents_writeable (ret) +
991c50c785cSJohn Marino 		      i * TYPE_LENGTH (eltype2), value_contents_all (tmp),
992c50c785cSJohn Marino 		      TYPE_LENGTH (eltype2));
993c50c785cSJohn Marino 	    }
994c50c785cSJohn Marino 
995c50c785cSJohn Marino 	  return ret;
996c50c785cSJohn Marino 	}
997c50c785cSJohn Marino       else
998c50c785cSJohn Marino 	{
999c50c785cSJohn Marino 	  if (value_logical_not (arg1))
1000c50c785cSJohn Marino 	    {
1001c50c785cSJohn Marino 	      /* Skip the second operand.  */
1002c50c785cSJohn Marino 	      evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
1003c50c785cSJohn Marino 
1004c50c785cSJohn Marino 	      return evaluate_subexp (NULL_TYPE, exp, pos, noside);
1005c50c785cSJohn Marino 	    }
1006c50c785cSJohn Marino 	  else
1007c50c785cSJohn Marino 	    {
1008c50c785cSJohn Marino 	      /* Skip the third operand.  */
1009c50c785cSJohn Marino 	      arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
1010c50c785cSJohn Marino 	      evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
1011c50c785cSJohn Marino 
1012c50c785cSJohn Marino 	      return arg2;
1013c50c785cSJohn Marino 	    }
1014c50c785cSJohn Marino 	}
1015c50c785cSJohn Marino 
1016c50c785cSJohn Marino     /* Handle STRUCTOP_STRUCT to allow component access on OpenCL vectors.  */
1017c50c785cSJohn Marino     case STRUCTOP_STRUCT:
1018c50c785cSJohn Marino       {
1019c50c785cSJohn Marino 	int pc = (*pos)++;
1020c50c785cSJohn Marino 	int tem = longest_to_int (exp->elts[pc + 1].longconst);
1021c50c785cSJohn Marino 
1022c50c785cSJohn Marino 	(*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
1023c50c785cSJohn Marino 	arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
1024c50c785cSJohn Marino 	type1 = check_typedef (value_type (arg1));
1025c50c785cSJohn Marino 
1026c50c785cSJohn Marino 	if (noside == EVAL_SKIP)
1027c50c785cSJohn Marino 	  {
1028c50c785cSJohn Marino 	    return value_from_longest (builtin_type (exp->gdbarch)->
1029c50c785cSJohn Marino 				       builtin_int, 1);
1030c50c785cSJohn Marino 	  }
1031c50c785cSJohn Marino 	else if (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1))
1032c50c785cSJohn Marino 	  {
1033c50c785cSJohn Marino 	    return opencl_component_ref (exp, arg1, &exp->elts[pc + 2].string,
1034c50c785cSJohn Marino 					 noside);
1035c50c785cSJohn Marino 	  }
1036c50c785cSJohn Marino 	else
1037c50c785cSJohn Marino 	  {
1038c50c785cSJohn Marino 	    if (noside == EVAL_AVOID_SIDE_EFFECTS)
1039c50c785cSJohn Marino 	      return
1040c50c785cSJohn Marino 		  value_zero (lookup_struct_elt_type
1041c50c785cSJohn Marino 			      (value_type (arg1),&exp->elts[pc + 2].string, 0),
1042c50c785cSJohn Marino 			      lval_memory);
1043c50c785cSJohn Marino 	    else
1044c50c785cSJohn Marino 	      return value_struct_elt (&arg1, NULL,
1045c50c785cSJohn Marino 				       &exp->elts[pc + 2].string, NULL,
1046c50c785cSJohn Marino 				       "structure");
1047c50c785cSJohn Marino 	  }
1048c50c785cSJohn Marino       }
1049c50c785cSJohn Marino     default:
1050c50c785cSJohn Marino       break;
1051c50c785cSJohn Marino     }
1052c50c785cSJohn Marino 
1053c50c785cSJohn Marino   return evaluate_subexp_c (expect_type, exp, pos, noside);
1054c50c785cSJohn Marino }
1055c50c785cSJohn Marino 
1056*ef5ccd6cSJohn Marino /* Print OpenCL types.  */
1057*ef5ccd6cSJohn Marino 
1058*ef5ccd6cSJohn Marino static void
opencl_print_type(struct type * type,const char * varstring,struct ui_file * stream,int show,int level,const struct type_print_options * flags)1059*ef5ccd6cSJohn Marino opencl_print_type (struct type *type, const char *varstring,
1060*ef5ccd6cSJohn Marino 		   struct ui_file *stream, int show, int level,
1061*ef5ccd6cSJohn Marino 		   const struct type_print_options *flags)
1062*ef5ccd6cSJohn Marino {
1063*ef5ccd6cSJohn Marino   /* We nearly always defer to C type printing, except that vector
1064*ef5ccd6cSJohn Marino      types are considered primitive in OpenCL, and should always
1065*ef5ccd6cSJohn Marino      be printed using their TYPE_NAME.  */
1066*ef5ccd6cSJohn Marino   if (show > 0)
1067*ef5ccd6cSJohn Marino     {
1068*ef5ccd6cSJohn Marino       CHECK_TYPEDEF (type);
1069*ef5ccd6cSJohn Marino       if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
1070*ef5ccd6cSJohn Marino 	  && TYPE_NAME (type) != NULL)
1071*ef5ccd6cSJohn Marino 	show = 0;
1072*ef5ccd6cSJohn Marino     }
1073*ef5ccd6cSJohn Marino 
1074*ef5ccd6cSJohn Marino   c_print_type (type, varstring, stream, show, level, flags);
1075*ef5ccd6cSJohn Marino }
1076*ef5ccd6cSJohn Marino 
1077*ef5ccd6cSJohn Marino static void
opencl_language_arch_info(struct gdbarch * gdbarch,struct language_arch_info * lai)1078c50c785cSJohn Marino opencl_language_arch_info (struct gdbarch *gdbarch,
1079c50c785cSJohn Marino 			   struct language_arch_info *lai)
1080c50c785cSJohn Marino {
1081c50c785cSJohn Marino   struct type **types = builtin_opencl_type (gdbarch);
1082c50c785cSJohn Marino 
1083c50c785cSJohn Marino   /* Copy primitive types vector from gdbarch.  */
1084c50c785cSJohn Marino   lai->primitive_type_vector = types;
1085c50c785cSJohn Marino 
1086c50c785cSJohn Marino   /* Type of elements of strings.  */
1087c50c785cSJohn Marino   lai->string_char_type = types [opencl_primitive_type_char];
1088c50c785cSJohn Marino 
1089c50c785cSJohn Marino   /* Specifies the return type of logical and relational operations.  */
1090c50c785cSJohn Marino   lai->bool_type_symbol = "int";
1091c50c785cSJohn Marino   lai->bool_type_default = types [opencl_primitive_type_int];
1092c50c785cSJohn Marino }
1093c50c785cSJohn Marino 
1094c50c785cSJohn Marino const struct exp_descriptor exp_descriptor_opencl =
1095c50c785cSJohn Marino {
1096c50c785cSJohn Marino   print_subexp_standard,
1097c50c785cSJohn Marino   operator_length_standard,
1098c50c785cSJohn Marino   operator_check_standard,
1099c50c785cSJohn Marino   op_name_standard,
1100c50c785cSJohn Marino   dump_subexp_body_standard,
1101c50c785cSJohn Marino   evaluate_subexp_opencl
1102c50c785cSJohn Marino };
1103c50c785cSJohn Marino 
1104c50c785cSJohn Marino const struct language_defn opencl_language_defn =
1105c50c785cSJohn Marino {
1106c50c785cSJohn Marino   "opencl",			/* Language name */
1107c50c785cSJohn Marino   language_opencl,
1108c50c785cSJohn Marino   range_check_off,
1109c50c785cSJohn Marino   case_sensitive_on,
1110c50c785cSJohn Marino   array_row_major,
1111c50c785cSJohn Marino   macro_expansion_c,
1112c50c785cSJohn Marino   &exp_descriptor_opencl,
1113c50c785cSJohn Marino   c_parse,
1114c50c785cSJohn Marino   c_error,
1115c50c785cSJohn Marino   null_post_parser,
1116c50c785cSJohn Marino   c_printchar,			/* Print a character constant */
1117c50c785cSJohn Marino   c_printstr,			/* Function to print string constant */
1118c50c785cSJohn Marino   c_emit_char,			/* Print a single char */
1119*ef5ccd6cSJohn Marino   opencl_print_type,		/* Print a type using appropriate syntax */
1120c50c785cSJohn Marino   c_print_typedef,		/* Print a typedef using appropriate syntax */
1121c50c785cSJohn Marino   c_val_print,			/* Print a value using appropriate syntax */
1122c50c785cSJohn Marino   c_value_print,		/* Print a top-level value */
1123*ef5ccd6cSJohn Marino   default_read_var_value,	/* la_read_var_value */
1124c50c785cSJohn Marino   NULL,				/* Language specific skip_trampoline */
1125c50c785cSJohn Marino   NULL,                         /* name_of_this */
1126c50c785cSJohn Marino   basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
1127c50c785cSJohn Marino   basic_lookup_transparent_type,/* lookup_transparent_type */
1128c50c785cSJohn Marino   NULL,				/* Language specific symbol demangler */
1129c50c785cSJohn Marino   NULL,				/* Language specific
1130c50c785cSJohn Marino 				   class_name_from_physname */
1131c50c785cSJohn Marino   c_op_print_tab,		/* expression operators for printing */
1132c50c785cSJohn Marino   1,				/* c-style arrays */
1133c50c785cSJohn Marino   0,				/* String lower bound */
1134c50c785cSJohn Marino   default_word_break_characters,
1135c50c785cSJohn Marino   default_make_symbol_completion_list,
1136c50c785cSJohn Marino   opencl_language_arch_info,
1137c50c785cSJohn Marino   default_print_array_index,
1138c50c785cSJohn Marino   default_pass_by_reference,
1139c50c785cSJohn Marino   c_get_string,
1140*ef5ccd6cSJohn Marino   NULL,				/* la_get_symbol_name_cmp */
1141a45ae5f8SJohn Marino   iterate_over_symbols,
1142c50c785cSJohn Marino   LANG_MAGIC
1143c50c785cSJohn Marino };
1144c50c785cSJohn Marino 
1145c50c785cSJohn Marino static void *
build_opencl_types(struct gdbarch * gdbarch)1146c50c785cSJohn Marino build_opencl_types (struct gdbarch *gdbarch)
1147c50c785cSJohn Marino {
1148c50c785cSJohn Marino   struct type **types
1149c50c785cSJohn Marino     = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_opencl_primitive_types + 1,
1150c50c785cSJohn Marino 			      struct type *);
1151c50c785cSJohn Marino 
1152c50c785cSJohn Marino /* Helper macro to create strings.  */
1153c50c785cSJohn Marino #define OCL_STRING(S) #S
1154c50c785cSJohn Marino /* This macro allocates and assigns the type struct pointers
1155c50c785cSJohn Marino    for the vector types.  */
1156c50c785cSJohn Marino #define BUILD_OCL_VTYPES(TYPE)\
1157c50c785cSJohn Marino   types[opencl_primitive_type_##TYPE##2] \
1158c50c785cSJohn Marino     = init_vector_type (types[opencl_primitive_type_##TYPE], 2); \
1159c50c785cSJohn Marino   TYPE_NAME (types[opencl_primitive_type_##TYPE##2]) = OCL_STRING(TYPE ## 2); \
1160c50c785cSJohn Marino   types[opencl_primitive_type_##TYPE##3] \
1161c50c785cSJohn Marino     = init_vector_type (types[opencl_primitive_type_##TYPE], 3); \
1162c50c785cSJohn Marino   TYPE_NAME (types[opencl_primitive_type_##TYPE##3]) = OCL_STRING(TYPE ## 3); \
1163c50c785cSJohn Marino   TYPE_LENGTH (types[opencl_primitive_type_##TYPE##3]) \
1164c50c785cSJohn Marino     = 4 * TYPE_LENGTH (types[opencl_primitive_type_##TYPE]); \
1165c50c785cSJohn Marino   types[opencl_primitive_type_##TYPE##4] \
1166c50c785cSJohn Marino     = init_vector_type (types[opencl_primitive_type_##TYPE], 4); \
1167c50c785cSJohn Marino   TYPE_NAME (types[opencl_primitive_type_##TYPE##4]) = OCL_STRING(TYPE ## 4); \
1168c50c785cSJohn Marino   types[opencl_primitive_type_##TYPE##8] \
1169c50c785cSJohn Marino     = init_vector_type (types[opencl_primitive_type_##TYPE], 8); \
1170c50c785cSJohn Marino   TYPE_NAME (types[opencl_primitive_type_##TYPE##8]) = OCL_STRING(TYPE ## 8); \
1171c50c785cSJohn Marino   types[opencl_primitive_type_##TYPE##16] \
1172c50c785cSJohn Marino     = init_vector_type (types[opencl_primitive_type_##TYPE], 16); \
1173c50c785cSJohn Marino   TYPE_NAME (types[opencl_primitive_type_##TYPE##16]) = OCL_STRING(TYPE ## 16)
1174c50c785cSJohn Marino 
1175c50c785cSJohn Marino   types[opencl_primitive_type_char]
1176c50c785cSJohn Marino     = arch_integer_type (gdbarch, 8, 0, "char");
1177c50c785cSJohn Marino   BUILD_OCL_VTYPES (char);
1178c50c785cSJohn Marino   types[opencl_primitive_type_uchar]
1179c50c785cSJohn Marino     = arch_integer_type (gdbarch, 8, 1, "uchar");
1180c50c785cSJohn Marino   BUILD_OCL_VTYPES (uchar);
1181c50c785cSJohn Marino   types[opencl_primitive_type_short]
1182c50c785cSJohn Marino     = arch_integer_type (gdbarch, 16, 0, "short");
1183c50c785cSJohn Marino   BUILD_OCL_VTYPES (short);
1184c50c785cSJohn Marino   types[opencl_primitive_type_ushort]
1185c50c785cSJohn Marino     = arch_integer_type (gdbarch, 16, 1, "ushort");
1186c50c785cSJohn Marino   BUILD_OCL_VTYPES (ushort);
1187c50c785cSJohn Marino   types[opencl_primitive_type_int]
1188c50c785cSJohn Marino     = arch_integer_type (gdbarch, 32, 0, "int");
1189c50c785cSJohn Marino   BUILD_OCL_VTYPES (int);
1190c50c785cSJohn Marino   types[opencl_primitive_type_uint]
1191c50c785cSJohn Marino     = arch_integer_type (gdbarch, 32, 1, "uint");
1192c50c785cSJohn Marino   BUILD_OCL_VTYPES (uint);
1193c50c785cSJohn Marino   types[opencl_primitive_type_long]
1194c50c785cSJohn Marino     = arch_integer_type (gdbarch, 64, 0, "long");
1195c50c785cSJohn Marino   BUILD_OCL_VTYPES (long);
1196c50c785cSJohn Marino   types[opencl_primitive_type_ulong]
1197c50c785cSJohn Marino     = arch_integer_type (gdbarch, 64, 1, "ulong");
1198c50c785cSJohn Marino   BUILD_OCL_VTYPES (ulong);
1199c50c785cSJohn Marino   types[opencl_primitive_type_half]
1200c50c785cSJohn Marino     = arch_float_type (gdbarch, 16, "half", floatformats_ieee_half);
1201c50c785cSJohn Marino   BUILD_OCL_VTYPES (half);
1202c50c785cSJohn Marino   types[opencl_primitive_type_float]
1203c50c785cSJohn Marino     = arch_float_type (gdbarch, 32, "float", floatformats_ieee_single);
1204c50c785cSJohn Marino   BUILD_OCL_VTYPES (float);
1205c50c785cSJohn Marino   types[opencl_primitive_type_double]
1206c50c785cSJohn Marino     = arch_float_type (gdbarch, 64, "double", floatformats_ieee_double);
1207c50c785cSJohn Marino   BUILD_OCL_VTYPES (double);
1208c50c785cSJohn Marino   types[opencl_primitive_type_bool]
1209c50c785cSJohn Marino     = arch_boolean_type (gdbarch, 8, 1, "bool");
1210c50c785cSJohn Marino   types[opencl_primitive_type_unsigned_char]
1211c50c785cSJohn Marino     = arch_integer_type (gdbarch, 8, 1, "unsigned char");
1212c50c785cSJohn Marino   types[opencl_primitive_type_unsigned_short]
1213c50c785cSJohn Marino     = arch_integer_type (gdbarch, 16, 1, "unsigned short");
1214c50c785cSJohn Marino   types[opencl_primitive_type_unsigned_int]
1215c50c785cSJohn Marino     = arch_integer_type (gdbarch, 32, 1, "unsigned int");
1216c50c785cSJohn Marino   types[opencl_primitive_type_unsigned_long]
1217c50c785cSJohn Marino     = arch_integer_type (gdbarch, 64, 1, "unsigned long");
1218c50c785cSJohn Marino   types[opencl_primitive_type_size_t]
1219c50c785cSJohn Marino     = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 1, "size_t");
1220c50c785cSJohn Marino   types[opencl_primitive_type_ptrdiff_t]
1221c50c785cSJohn Marino     = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 0, "ptrdiff_t");
1222c50c785cSJohn Marino   types[opencl_primitive_type_intptr_t]
1223c50c785cSJohn Marino     = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 0, "intptr_t");
1224c50c785cSJohn Marino   types[opencl_primitive_type_uintptr_t]
1225c50c785cSJohn Marino     = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 1, "uintptr_t");
1226c50c785cSJohn Marino   types[opencl_primitive_type_void]
1227c50c785cSJohn Marino     = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void");
1228c50c785cSJohn Marino 
1229c50c785cSJohn Marino   return types;
1230c50c785cSJohn Marino }
1231c50c785cSJohn Marino 
1232*ef5ccd6cSJohn Marino /* Provide a prototype to silence -Wmissing-prototypes.  */
1233*ef5ccd6cSJohn Marino extern initialize_file_ftype _initialize_opencl_language;
1234*ef5ccd6cSJohn Marino 
1235c50c785cSJohn Marino void
_initialize_opencl_language(void)1236c50c785cSJohn Marino _initialize_opencl_language (void)
1237c50c785cSJohn Marino {
1238c50c785cSJohn Marino   opencl_type_data = gdbarch_data_register_post_init (build_opencl_types);
1239c50c785cSJohn Marino   add_language (&opencl_language_defn);
1240c50c785cSJohn Marino }
1241