1 /* upc-pts-packed.c: implement UPC packed pointer-to-shared representation
2 Copyright (C) 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4 Contributed by Gary Funck <gary@intrepid.com>
5 and Nenad Vukicevic <nenad@intrepid.com>.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
30 #include "langhooks.h"
42 #include "upc-rts-names.h"
44 #include "c-family/c-common.h"
45 #include "c-family/c-pragma.h"
46 #include "c-family/c-upc.h"
47 /* define decl_default_tls_model() prototype */
50 static tree
upc_pts_packed_build_addrfield (location_t
, tree
);
51 static tree
upc_pts_packed_build_cond_expr (location_t
, tree
);
52 static tree
upc_pts_packed_build_constant (location_t
, tree
);
53 static tree
upc_pts_packed_build_cvt (location_t
, tree
);
54 static tree
upc_pts_packed_build_diff (location_t
, tree
);
55 static tree
upc_pts_packed_build_phaseof (location_t
, tree
);
56 static tree
upc_pts_packed_build_sum (location_t
, tree
);
57 static tree
upc_pts_packed_build_threadof (location_t
, tree
);
58 static tree
upc_pts_packed_build_value (location_t
, tree
, tree
, tree
, tree
);
59 static void upc_pts_packed_init_type (void);
60 static int upc_pts_packed_is_null_p (tree
);
62 const upc_pts_ops_t upc_pts_packed_ops
=
64 upc_pts_packed_build_value
,
65 upc_pts_packed_build_cond_expr
,
66 upc_pts_packed_build_constant
,
67 upc_pts_packed_build_cvt
,
68 upc_pts_packed_build_diff
,
69 upc_pts_packed_init_type
,
70 upc_pts_packed_is_null_p
,
71 upc_pts_packed_build_sum
,
72 upc_pts_packed_build_threadof
75 /* Build the internal representation of UPC's packed
76 pointer-to-shared type. */
79 upc_pts_packed_init_type (void)
81 tree shared_void_type
, shared_char_type
;
82 upc_pts_rep_type_node
= c_common_type_for_size (UPC_PTS_SIZE
, 1);
83 gcc_assert (TYPE_MODE (upc_pts_rep_type_node
) != BLKmode
);
84 record_builtin_type (RID_SHARED
, "upc_shared_ptr_t",
85 upc_pts_rep_type_node
);
86 shared_void_type
= c_build_qualified_type_1 (void_type_node
,
87 TYPE_QUAL_SHARED
, NULL_TREE
);
88 upc_pts_type_node
= build_pointer_type (shared_void_type
);
89 shared_char_type
= c_build_qualified_type_1 (char_type_node
,
92 upc_char_pts_type_node
= build_pointer_type (shared_char_type
);
94 build_int_cst (upc_pts_rep_type_node
, UPC_PTS_VADDR_MASK
);
95 upc_thread_mask_node
=
96 build_int_cst (upc_pts_rep_type_node
, UPC_PTS_THREAD_MASK
);
98 build_int_cst (upc_pts_rep_type_node
, UPC_PTS_PHASE_MASK
);
99 upc_vaddr_shift_node
=
100 build_int_cst (unsigned_type_node
, UPC_PTS_VADDR_SHIFT
);
101 upc_thread_shift_node
=
102 build_int_cst (unsigned_type_node
, UPC_PTS_THREAD_SHIFT
);
103 upc_phase_shift_node
=
104 build_int_cst (unsigned_type_node
, UPC_PTS_PHASE_SHIFT
);
106 upc_pts_packed_build_value (UNKNOWN_LOCATION
, upc_pts_type_node
,
107 integer_zero_node
, integer_zero_node
,
111 /* Called to expand a UPC specific constant into something the
112 backend can handle. Upon return a UPC pointer-to-shared will be
113 seen as the representation type of a UPC pointer-to-shared, with
114 individual (thread, phase, and virtual address) fields. */
117 upc_pts_packed_build_constant (location_t loc
, tree c
)
120 if (upc_pts_is_valid_p (c
))
122 const enum tree_code code
= TREE_CODE (c
);
123 if (!((code
== VIEW_CONVERT_EXPR
|| code
== NOP_EXPR
)
124 && (TREE_TYPE (TREE_OPERAND (c
, 0)) == upc_pts_rep_type_node
)))
127 build1 (VIEW_CONVERT_EXPR
, upc_pts_rep_type_node
,
129 const tree phase
= upc_pts_packed_build_phaseof (loc
, val
);
130 const tree thread
= upc_pts_packed_build_threadof (loc
, val
);
131 const tree vaddr
= upc_pts_packed_build_addrfield (loc
, val
);
133 upc_pts_packed_build_value (loc
, TREE_TYPE (c
), vaddr
, thread
,
140 /* Build a constructor of the form {phase, thread, vaddr}. */
143 upc_pts_packed_build_value (location_t loc
, tree type
, tree vaddr
,
144 tree thread
, tree phase
)
147 const tree upc_pts_rep_t
= upc_pts_rep_type_node
;
148 const int is_null
= integer_zerop (phase
)
149 && integer_zerop (thread
) && integer_zerop (vaddr
);
150 const int is_const
= TREE_CONSTANT (phase
)
151 && TREE_CONSTANT (thread
) && TREE_CONSTANT (vaddr
);
154 result
= fold_convert (upc_pts_rep_t
, integer_zero_node
);
158 vaddr
= fold_convert (upc_pts_rep_t
, vaddr
);
160 build_binary_op (loc
, LSHIFT_EXPR
, vaddr
, upc_vaddr_shift_node
, 0);
161 if (!integer_zerop (thread
))
163 thread
= fold_convert (upc_pts_rep_t
, thread
);
164 result
= build_binary_op (loc
, BIT_IOR_EXPR
, result
,
165 build_binary_op (loc
, LSHIFT_EXPR
,
167 upc_thread_shift_node
,
170 if (!integer_zerop (phase
))
172 phase
= fold_convert (upc_pts_rep_t
, phase
);
173 result
= build_binary_op (loc
, BIT_IOR_EXPR
, result
,
174 build_binary_op (loc
, LSHIFT_EXPR
,
176 upc_phase_shift_node
,
180 TREE_CONSTANT (result
) = is_const
;
181 /* Wrap the representation value into the specified
182 UPC pointer-to-shared type */
183 result
= fold (build1 (VIEW_CONVERT_EXPR
, type
, result
));
184 TREE_CONSTANT (result
) = is_const
;
188 /* Return TRUE if EXP is a null UPC pointer-to-shared. */
191 upc_pts_packed_is_null_p (tree exp
)
193 if (exp
&& upc_pts_is_valid_p (exp
))
197 TREE_CODE (value
) == NOP_EXPR
198 || TREE_CODE (value
) == CONVERT_EXPR
199 || TREE_CODE (value
) == VIEW_CONVERT_EXPR
200 || TREE_CODE (value
) == NON_LVALUE_EXPR
;
201 value
= TREE_OPERAND (value
, 0)) /* loop */ ;
202 if ((TREE_TYPE (value
) == upc_pts_rep_type_node
)
203 && TREE_CONSTANT (value
))
204 return integer_zerop (value
);
209 /* Given EXP, whose type must be the UPC pointer-to-shared
210 representation type, isolate the virtual address field,
211 and return it. Caller must insure that EXP is a
212 stable reference, if required. */
215 upc_pts_packed_build_addrfield (location_t loc
, tree exp
)
218 gcc_assert (TREE_TYPE (exp
) == upc_pts_rep_type_node
);
219 vaddr
= build_binary_op (loc
, BIT_AND_EXPR
,
220 build_binary_op (loc
, RSHIFT_EXPR
, exp
,
221 upc_vaddr_shift_node
, 0),
222 upc_vaddr_mask_node
, 0);
223 vaddr
= fold_convert (sizetype
, vaddr
);
227 /* Given, EXP, whose type must be the UPC pointer-to-shared
228 representation type, isolate the thread field,
229 and return it. Caller must insure that EXP is a
230 stable reference, if required. */
233 upc_pts_packed_build_threadof (location_t loc
, tree exp
)
236 gcc_assert (TREE_TYPE (exp
) == upc_pts_rep_type_node
);
237 affinity
= build_binary_op (loc
, BIT_AND_EXPR
,
238 build_binary_op (loc
, RSHIFT_EXPR
, exp
,
239 upc_thread_shift_node
, 0),
240 upc_thread_mask_node
, 0);
241 affinity
= fold_convert (sizetype
, affinity
);
245 /* Given, EXP, whose type must be the UPC pointer-to-shared
246 representation type, isolate the phase field,
247 and return it. Caller must insure that EXP is a
248 stable reference, if required. */
251 upc_pts_packed_build_phaseof (location_t loc
, tree exp
)
254 gcc_assert (TREE_TYPE (exp
) == upc_pts_rep_type_node
);
255 phase
= build_binary_op (loc
, BIT_AND_EXPR
,
256 build_binary_op (loc
, RSHIFT_EXPR
, exp
,
257 upc_phase_shift_node
, 0),
258 upc_phase_mask_node
, 0);
259 phase
= fold_convert (sizetype
, phase
);
263 /* Rewrite EXP, an expression involving addition of an
264 integer to a UPC pointer-to-shared, into representation-specific
265 lower level operations. */
268 upc_pts_packed_build_sum (location_t loc
, tree exp
)
270 const tree op0
= TREE_OPERAND (exp
, 0);
271 const tree op1
= TREE_OPERAND (exp
, 1);
272 const enum tree_code op0_code
= TREE_CODE (TREE_TYPE (op0
));
273 const tree targ_type
= TREE_TYPE (TREE_TYPE (exp
));
274 const tree ptrop
= (op0_code
== POINTER_TYPE
) ? op0
: op1
;
275 const tree intop
= (op0_code
== POINTER_TYPE
) ? op1
: op0
;
278 if (integer_zerop (intop
))
284 const tree ptrop_as_pts_rep
= fold (build1 (VIEW_CONVERT_EXPR
,
285 upc_pts_rep_type_node
,
287 const tree sptrop
= save_expr (ptrop_as_pts_rep
);
288 const tree elem_type
= strip_array_types (targ_type
);
289 const tree elem_size
= !VOID_TYPE_P (elem_type
)
290 ? size_in_bytes (elem_type
) : integer_one_node
;
291 const tree block_factor
= upc_get_block_factor (elem_type
);
292 const int has_phase
= !(integer_zerop (block_factor
)
293 || integer_onep (block_factor
));
294 const tree old_vaddr
= upc_pts_packed_build_addrfield (loc
, sptrop
);
295 const tree index
= save_expr (intop
);
296 tree phase
, thread
, vaddr
;
297 if (VOID_TYPE_P (targ_type
) || integer_zerop (block_factor
))
299 /* vaddr = old_vaddr + index * elem_size */
300 vaddr
= build_binary_op (loc
, PLUS_EXPR
, old_vaddr
,
301 build_binary_op (loc
, MULT_EXPR
,
302 index
, elem_size
, 0),
304 thread
= upc_pts_packed_build_threadof (loc
, sptrop
);
305 phase
= integer_zero_node
;
309 const tree old_thread
=
310 upc_pts_packed_build_threadof (loc
, sptrop
);
311 const tree thread_cnt
= save_expr (upc_num_threads ());
312 /* n_threads must be a signed type, for various calculations
313 to work properly, below. */
314 const tree n_threads
= !TYPE_UNSIGNED (TREE_TYPE (thread_cnt
))
315 ? thread_cnt
: convert (integer_type_node
, thread_cnt
);
319 const tree elem_per_block
= block_factor
;
320 const tree old_phase
=
321 upc_pts_packed_build_phaseof (loc
, sptrop
);
322 tree nt_elems
, phase_diff
;
323 /* tincr = old_thread * elem_per_block + old_phase + index; */
324 tincr
= build_binary_op (loc
, PLUS_EXPR
,
325 build_binary_op (loc
, PLUS_EXPR
,
332 tincr
= save_expr (tincr
);
333 /* nt_elems = n_threads * elem_per_block; */
334 nt_elems
= build_binary_op (loc
, MULT_EXPR
, n_threads
,
336 nt_elems
= save_expr (nt_elems
);
337 /* Calculate floor_divmod (tincr, nt_elems, &t1, &t2);
338 n_elems and tincr must be a signed type, to ensure
339 that FLOOR_DIV and FLOOR_MOD work as expected. */
340 if (TYPE_UNSIGNED (TREE_TYPE (tincr
)))
341 tincr
= convert (integer_type_node
, tincr
);
342 if (TYPE_UNSIGNED (TREE_TYPE (nt_elems
)))
343 nt_elems
= convert (integer_type_node
, nt_elems
);
345 build_binary_op (loc
, FLOOR_DIV_EXPR
, tincr
, nt_elems
, 0);
347 build_binary_op (loc
, FLOOR_MOD_EXPR
, tincr
, nt_elems
, 0);
349 /* thread = t2 / elem_per_block; */
350 thread
= build_binary_op (loc
, TRUNC_DIV_EXPR
,
351 t2
, elem_per_block
, 0);
352 /* phase = t2 % elem_per_block; */
353 phase
= build_binary_op (loc
, TRUNC_MOD_EXPR
,
354 t2
, elem_per_block
, 0);
355 phase_diff
= build_binary_op (loc
, MINUS_EXPR
,
356 phase
, old_phase
, 0);
357 /* vaddr = old_vaddr + (t1 * elem_per_block + phase_diff)
359 vaddr
= build_binary_op (loc
, PLUS_EXPR
,
361 build_binary_op (loc
, MULT_EXPR
,
362 build_binary_op (loc
, PLUS_EXPR
,
363 build_binary_op (loc
, MULT_EXPR
,
364 t1
, elem_per_block
, 0),
370 /* tincr = old_thread + index; */
372 build_binary_op (loc
, PLUS_EXPR
, old_thread
, index
, 0);
373 tincr
= save_expr (tincr
);
374 /* floor_divmod (tincr, n_threads, &t1, &t2); */
375 if (TYPE_UNSIGNED (TREE_TYPE (tincr
)))
376 tincr
= convert (integer_type_node
, tincr
);
378 build_binary_op (loc
, FLOOR_DIV_EXPR
, tincr
, n_threads
, 0);
380 build_binary_op (loc
, FLOOR_MOD_EXPR
, tincr
, n_threads
, 0);
381 /* vaddr = old_vaddr + t1 * elem_size; */
382 vaddr
= build_binary_op (loc
, PLUS_EXPR
, old_vaddr
,
383 build_binary_op (loc
, MULT_EXPR
,
388 phase
= integer_zero_node
;
391 result
= upc_pts_packed_build_value (loc
, TREE_TYPE (exp
),
392 vaddr
, thread
, phase
);
397 /* Expand the expression EXP, which calculates the difference
398 between two UPC pointers-to-shared. */
401 upc_pts_packed_build_diff (location_t loc
, tree exp
)
403 tree op0
= TREE_OPERAND (exp
, 0);
404 tree op1
= TREE_OPERAND (exp
, 1);
405 const tree result_type
= ptrdiff_type_node
;
406 const tree target_type
= TREE_TYPE (TREE_TYPE (op0
));
407 const tree n_threads
= upc_num_threads ();
408 const tree elem_size
= convert (ssizetype
, size_in_bytes (target_type
));
409 const tree block_factor
= upc_get_block_factor (target_type
);
410 tree thread0
, thread1
, thread_diff
;
412 tree off0
, off1
, offset_diff
, elem_diff
;
415 /* The two pointers must both point to UPC shared objects, and we
416 have to perform the reverse of addition on UPC pointers-to-shared */
418 if ((upc_shared_type_p (target_type
)
419 && !upc_shared_type_p (TREE_TYPE (TREE_TYPE (op1
))))
420 || (upc_shared_type_p (TREE_TYPE (TREE_TYPE (op1
)))
421 && !upc_shared_type_p (target_type
)))
423 error ("attempt to take the difference of a UPC pointer-to-shared "
424 "and a local pointer");
425 return error_mark_node
;
427 op0
= save_expr (op0
);
428 op1
= save_expr (op1
);
429 op0
= build1 (VIEW_CONVERT_EXPR
, upc_pts_rep_type_node
, op0
);
430 op1
= build1 (VIEW_CONVERT_EXPR
, upc_pts_rep_type_node
, op1
);
431 off0
= upc_pts_packed_build_addrfield (loc
, op0
);
432 off1
= upc_pts_packed_build_addrfield (loc
, op1
);
433 /* Convert offset fields into ptrdiff_t types so that the
434 result of the difference comes out as a signed type. */
435 off0
= convert (result_type
, off0
);
436 off1
= convert (result_type
, off1
);
437 offset_diff
= build_binary_op (loc
, MINUS_EXPR
, off0
, off1
, 0);
438 elem_diff
= build_binary_op (loc
, EXACT_DIV_EXPR
,
439 offset_diff
, elem_size
, 0);
440 if (integer_zerop (block_factor
))
444 thread0
= convert (ssizetype
, upc_pts_packed_build_threadof (loc
, op0
));
445 thread1
= convert (ssizetype
, upc_pts_packed_build_threadof (loc
, op1
));
446 thread_diff
= build_binary_op (loc
, MINUS_EXPR
, thread0
, thread1
, 0);
447 phase_diff
= integer_zero_node
;
448 if (!tree_int_cst_equal (block_factor
, integer_one_node
))
451 convert (ssizetype
, upc_pts_packed_build_phaseof (loc
, op0
));
453 convert (ssizetype
, upc_pts_packed_build_phaseof (loc
, op1
));
455 save_expr (build_binary_op (loc
, MINUS_EXPR
, phase0
, phase1
, 0));
457 /* The expression below calculates the following:
458 (elem_diff - phase_diff) * THREADS
459 + (thread_diff * block_factor) + phase_diff; */
460 result
= build_binary_op (loc
, PLUS_EXPR
,
461 build_binary_op (loc
, PLUS_EXPR
,
462 build_binary_op (loc
, MULT_EXPR
,
463 build_binary_op (loc
, MINUS_EXPR
,
467 build_binary_op (loc
, MULT_EXPR
,
469 block_factor
, 0), 0),
471 result
= fold_convert (result_type
, result
);
475 /* Handle conversions between UPC pointers-to-shared and
476 local pointers, or between UPC pointers-to-shared which
477 have differing block factors. */
480 upc_pts_packed_build_cvt (location_t loc
, tree exp
)
482 const tree type
= TREE_TYPE (exp
);
483 const tree ptr
= TREE_OPERAND (exp
, 0);
484 tree tt1
, tt2
, b1
, b2
;
486 tt1
= TREE_TYPE (TREE_TYPE (exp
));
487 tt2
= TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp
, 0)));
488 b1
= upc_get_block_factor (tt1
);
489 b2
= upc_get_block_factor (tt2
);
490 if (upc_shared_type_p (tt1
) != upc_shared_type_p (tt2
))
492 if (upc_shared_type_p (tt1
))
494 /* Error: local -> shared */
495 result
= error_mark_node
;
499 /* shared -> local */
500 int doprofcall
= flag_upc_debug
501 || (flag_upc_instrument
&& get_upc_pupc_mode ());
502 const char *libfunc_name
=
503 doprofcall
? UPC_GETADDRG_LIBCALL
: UPC_GETADDR_LIBCALL
;
504 tree src
= build1 (NOP_EXPR
, upc_pts_rep_type_node
,
505 TREE_OPERAND (exp
, 0));
506 tree libfunc
, lib_args
, lib_call
;
507 libfunc
= identifier_global_value (get_identifier (libfunc_name
));
509 internal_error ("library function %s not found", libfunc_name
);
510 lib_args
= tree_cons (NULL_TREE
, src
, NULL_TREE
);
513 upc_gasp_add_src_args (lib_args
, input_filename
, input_line
);
514 lib_call
= build_function_call (loc
, libfunc
, lib_args
);
515 result
= build1 (VIEW_CONVERT_EXPR
, type
, lib_call
);
518 else if ((upc_shared_type_p (tt1
) && !VOID_TYPE_P (tt1
))
519 && !(integer_zerop (b1
) && integer_zerop (b2
)))
521 /* Below, we handle the case of conversions to non-generic
523 tree s1
= TYPE_SIZE (tt1
);
524 tree s2
= TYPE_SIZE (tt2
);
525 /* normalize block sizes, so that [0] => NULL */
526 if (integer_zerop (b1
))
528 if (integer_zerop (b2
))
530 /* normalize type size so that 0 => NULL */
531 if (s1
&& integer_zerop (s1
))
533 if (s2
&& integer_zerop (s2
))
535 /* If the source type is a not a generic pointer to shared, and
536 either its block size or type size differs from the target,
537 then the result must have zero phase. If the source type is
538 a generic pointer to shared and the target type is a pointer
539 to a shared type with either an indefinite block size, or
540 a block size of one, then the resulting value must have a
542 if ((!VOID_TYPE_P (tt2
)
543 && !(tree_int_cst_equal (b1
, b2
)
544 && tree_int_cst_equal (s1
, s2
)))
545 || (VOID_TYPE_P (tt2
)
547 || tree_int_cst_equal (b1
, integer_one_node
))))
549 const tree ptr_as_pts_rep
= fold (build1 (VIEW_CONVERT_EXPR
,
550 upc_pts_rep_type_node
,
552 const tree sptr
= save_expr (ptr_as_pts_rep
);
553 const tree ptr_with_zero_phase
=
554 upc_pts_packed_build_value (loc
, type
,
555 upc_pts_packed_build_addrfield (loc
, sptr
),
556 upc_pts_packed_build_threadof (loc
, sptr
),
558 result
= ptr_with_zero_phase
;
561 else if (upc_shared_type_p (tt1
) && VOID_TYPE_P (tt1
))
563 /* If the target is a generic pointer-to-shared type, we can
564 safely use the source value directly. */
567 gcc_assert (TREE_CODE (type
) != CONVERT_EXPR
);
571 /* Expand the expression EXP, which is a comparison between two
572 UPC pointers-to-shared.
575 Two compatible pointers-to-shared which point to the same object
576 (i.e. having the same address and thread components) shall compare
577 as equal according to == and !=, regardless of whether the phase
580 When a UPC pointer-to-shared is represented as (vaddr, thread, phase)
581 and the underlying pointer component types have a block size <=1,
582 we can use a straight unsigned integer comparison of the
583 representation types. Otherwise, if vaddr comes
584 last, then the straight bit-wise comparison works only for equality.
586 For the equality operation when the block size is greater than 1,
587 the phase field is first masked off. */
589 upc_pts_packed_build_cond_expr (location_t loc
, tree exp
)
592 const enum tree_code code
= TREE_CODE (exp
);
593 tree op0
= TREE_OPERAND (exp
, 0);
594 tree op1
= TREE_OPERAND (exp
, 1);
595 const tree type0
= TREE_TYPE (op0
);
596 const tree type1
= TREE_TYPE (op1
);
597 gcc_assert (POINTER_TYPE_P (type0
));
598 gcc_assert (POINTER_TYPE_P (type1
));
600 const tree ttype0
= TREE_TYPE (type0
);
601 const tree ttype1
= TREE_TYPE (type1
);
602 const enum tree_code ttcode0
= TREE_CODE (ttype0
);
603 const enum tree_code ttcode1
= TREE_CODE (ttype1
);
604 const tree elem_type0
= strip_array_types (ttype0
);
605 const tree elem_type1
= strip_array_types (ttype1
);
606 gcc_assert (TREE_SHARED (elem_type0
));
607 gcc_assert (TREE_SHARED (elem_type1
));
609 const tree bs0
= upc_get_block_factor (elem_type0
);
610 const tree bs1
= upc_get_block_factor (elem_type1
);
611 const int has_phase0
= !(integer_zerop (bs0
) || integer_onep (bs0
));
612 const int has_phase1
= !(integer_zerop (bs1
) || integer_onep (bs1
));
613 const int has_phase
= has_phase0
|| has_phase1
;
614 const int is_eq_op
= (code
== EQ_EXPR
|| code
== NE_EXPR
);
615 const int is_bitwise_cmp
= is_eq_op
616 || (!has_phase
&& UPC_PTS_VADDR_FIRST
);
619 if (ttcode0
== VIEW_CONVERT_EXPR
620 && TREE_TYPE (TREE_OPERAND (op0
, 0)) == upc_pts_rep_type_node
)
621 op0
= TREE_OPERAND (op0
, 0);
623 op0
= build1 (VIEW_CONVERT_EXPR
, upc_pts_rep_type_node
, op0
);
624 if (ttcode1
== VIEW_CONVERT_EXPR
625 && TREE_TYPE (TREE_OPERAND (op1
, 0)) == upc_pts_rep_type_node
)
626 op1
= TREE_OPERAND (op1
, 0);
628 op1
= build1 (VIEW_CONVERT_EXPR
, upc_pts_rep_type_node
, op1
);
631 /* Mask off the phase value. */
633 fold_build1_loc (loc
, BIT_NOT_EXPR
, upc_pts_rep_type_node
,
634 build_binary_op (loc
, LSHIFT_EXPR
,
636 upc_phase_shift_node
, 0));
637 op0
= build_binary_op (loc
, BIT_AND_EXPR
, op0
, phase_mask
, 0);
638 op1
= build_binary_op (loc
, BIT_AND_EXPR
, op1
, phase_mask
, 0);
643 const tree ptr_diff
= build_binary_op (loc
, MINUS_EXPR
,
646 op1
= build_int_cst (TREE_TYPE (op0
), 0);
648 TREE_OPERAND (exp
, 0) = op0
;
649 TREE_OPERAND (exp
, 1) = op1
;