annotate gcc/brig/brigfrontend/brig-cmp-inst-handler.cc @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* brig-cmp-inst-handler.cc -- brig cmp instruction handling
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2016-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
kono
parents:
diff changeset
4 for General Processor Tech.
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 This file is part of GCC.
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
9 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
10 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
11 version.
kono
parents:
diff changeset
12
kono
parents:
diff changeset
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
16 for more details.
kono
parents:
diff changeset
17
kono
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
19 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
20 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 #include "brig-code-entry-handler.h"
kono
parents:
diff changeset
23 #include "diagnostic.h"
kono
parents:
diff changeset
24 #include "tree-pretty-print.h"
kono
parents:
diff changeset
25 #include "print-tree.h"
kono
parents:
diff changeset
26 #include "brig-util.h"
kono
parents:
diff changeset
27 #include "convert.h"
kono
parents:
diff changeset
28
kono
parents:
diff changeset
29 size_t
kono
parents:
diff changeset
30 brig_cmp_inst_handler::operator () (const BrigBase *base)
kono
parents:
diff changeset
31 {
kono
parents:
diff changeset
32 const BrigInstBase *inst_base = (const BrigInstBase *) base;
kono
parents:
diff changeset
33 const BrigInstCmp *inst = (const BrigInstCmp *) base;
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 tree cmp_type = get_tree_expr_type_for_hsa_type (inst->sourceType);
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 /* The destination type to convert the comparison result to. */
kono
parents:
diff changeset
38 tree dest_type = gccbrig_tree_type_for_hsa_type (inst_base->type);
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 const bool is_fp16_dest
kono
parents:
diff changeset
41 = (inst_base->type & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_F16;
kono
parents:
diff changeset
42 const bool is_boolean_dest
kono
parents:
diff changeset
43 = (inst_base->type & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_B1;
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45 bool is_int_cmp = VECTOR_TYPE_P (cmp_type)
kono
parents:
diff changeset
46 ? INTEGRAL_TYPE_P (TREE_TYPE (cmp_type))
kono
parents:
diff changeset
47 : INTEGRAL_TYPE_P (cmp_type);
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 /* The type for the GENERIC comparison. It should match the
kono
parents:
diff changeset
50 input operand width for vector comparisons, a boolean
kono
parents:
diff changeset
51 otherwise. */
kono
parents:
diff changeset
52 tree result_type = get_comparison_result_type (cmp_type);
kono
parents:
diff changeset
53
kono
parents:
diff changeset
54 /* Save the result as a boolean and extend/convert it to the
kono
parents:
diff changeset
55 wanted destination type. */
kono
parents:
diff changeset
56 tree expr = NULL_TREE;
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 std::vector<tree> operands = build_operands (*inst_base);
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 switch (inst->compare)
kono
parents:
diff changeset
61 {
kono
parents:
diff changeset
62 case BRIG_COMPARE_SEQ:
kono
parents:
diff changeset
63 case BRIG_COMPARE_EQ:
kono
parents:
diff changeset
64 expr = build2 (EQ_EXPR, result_type, operands[1], operands[2]);
kono
parents:
diff changeset
65 break;
kono
parents:
diff changeset
66 case BRIG_COMPARE_SNE:
kono
parents:
diff changeset
67 case BRIG_COMPARE_NE:
kono
parents:
diff changeset
68 expr = build2 (NE_EXPR, result_type, operands[1], operands[2]);
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 if (!is_int_cmp)
kono
parents:
diff changeset
71 expr = build2 (BIT_AND_EXPR, TREE_TYPE (expr),
kono
parents:
diff changeset
72 expr,
kono
parents:
diff changeset
73 build2 (ORDERED_EXPR, result_type, operands[1],
kono
parents:
diff changeset
74 operands[2]));
kono
parents:
diff changeset
75 break;
kono
parents:
diff changeset
76 case BRIG_COMPARE_SLT:
kono
parents:
diff changeset
77 case BRIG_COMPARE_LT:
kono
parents:
diff changeset
78 expr = build2 (LT_EXPR, result_type, operands[1], operands[2]);
kono
parents:
diff changeset
79 break;
kono
parents:
diff changeset
80 case BRIG_COMPARE_SLE:
kono
parents:
diff changeset
81 case BRIG_COMPARE_LE:
kono
parents:
diff changeset
82 expr = build2 (LE_EXPR, result_type, operands[1], operands[2]);
kono
parents:
diff changeset
83 break;
kono
parents:
diff changeset
84 case BRIG_COMPARE_SGT:
kono
parents:
diff changeset
85 case BRIG_COMPARE_GT:
kono
parents:
diff changeset
86 expr = build2 (GT_EXPR, result_type, operands[1], operands[2]);
kono
parents:
diff changeset
87 break;
kono
parents:
diff changeset
88 case BRIG_COMPARE_SGE:
kono
parents:
diff changeset
89 case BRIG_COMPARE_GE:
kono
parents:
diff changeset
90 expr = build2 (GE_EXPR, result_type, operands[1], operands[2]);
kono
parents:
diff changeset
91 break;
kono
parents:
diff changeset
92 case BRIG_COMPARE_SEQU:
kono
parents:
diff changeset
93 case BRIG_COMPARE_EQU:
kono
parents:
diff changeset
94 expr = build2 (UNEQ_EXPR, result_type, operands[1], operands[2]);
kono
parents:
diff changeset
95 break;
kono
parents:
diff changeset
96 case BRIG_COMPARE_SNEU:
kono
parents:
diff changeset
97 case BRIG_COMPARE_NEU:
kono
parents:
diff changeset
98 expr = build2 (NE_EXPR, result_type, operands[1], operands[2]);
kono
parents:
diff changeset
99 break;
kono
parents:
diff changeset
100 case BRIG_COMPARE_SLTU:
kono
parents:
diff changeset
101 case BRIG_COMPARE_LTU:
kono
parents:
diff changeset
102 expr = build2 (UNLT_EXPR, result_type, operands[1], operands[2]);
kono
parents:
diff changeset
103 break;
kono
parents:
diff changeset
104 case BRIG_COMPARE_SLEU:
kono
parents:
diff changeset
105 case BRIG_COMPARE_LEU:
kono
parents:
diff changeset
106 expr = build2 (UNLE_EXPR, result_type, operands[1], operands[2]);
kono
parents:
diff changeset
107 break;
kono
parents:
diff changeset
108 case BRIG_COMPARE_SGTU:
kono
parents:
diff changeset
109 case BRIG_COMPARE_GTU:
kono
parents:
diff changeset
110 expr = build2 (UNGT_EXPR, result_type, operands[1], operands[2]);
kono
parents:
diff changeset
111 break;
kono
parents:
diff changeset
112 case BRIG_COMPARE_SGEU:
kono
parents:
diff changeset
113 case BRIG_COMPARE_GEU:
kono
parents:
diff changeset
114 expr = build2 (UNGE_EXPR, result_type, operands[1], operands[2]);
kono
parents:
diff changeset
115 break;
kono
parents:
diff changeset
116 case BRIG_COMPARE_SNUM:
kono
parents:
diff changeset
117 case BRIG_COMPARE_NUM:
kono
parents:
diff changeset
118 expr = build2 (ORDERED_EXPR, result_type, operands[1], operands[2]);
kono
parents:
diff changeset
119 break;
kono
parents:
diff changeset
120 case BRIG_COMPARE_SNAN:
kono
parents:
diff changeset
121 case BRIG_COMPARE_NAN:
kono
parents:
diff changeset
122 expr = build2 (UNORDERED_EXPR, result_type, operands[1], operands[2]);
kono
parents:
diff changeset
123 break;
kono
parents:
diff changeset
124 default:
kono
parents:
diff changeset
125 break;
kono
parents:
diff changeset
126 }
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 if (expr == NULL_TREE)
kono
parents:
diff changeset
129 gcc_unreachable ();
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 if (is_fp16_dest)
kono
parents:
diff changeset
132 {
kono
parents:
diff changeset
133 expr = convert_to_real (brig_to_generic::s_fp32_type, expr);
kono
parents:
diff changeset
134 }
kono
parents:
diff changeset
135 else if (VECTOR_TYPE_P (dest_type) && ANY_INTEGRAL_TYPE_P (dest_type)
kono
parents:
diff changeset
136 && !is_boolean_dest
kono
parents:
diff changeset
137 && (inst->sourceType & BRIG_TYPE_BASE_MASK) != BRIG_TYPE_F16)
kono
parents:
diff changeset
138 {
kono
parents:
diff changeset
139 /* In later gcc versions, the output of comparison is not
kono
parents:
diff changeset
140 all ones for vectors like still in 4.9.1. We need to use
kono
parents:
diff changeset
141 an additional VEC_COND_EXPR to produce the all ones 'true' value
kono
parents:
diff changeset
142 required by HSA.
kono
parents:
diff changeset
143 VEC_COND_EXPR <a == b, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; */
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 tree all_ones
kono
parents:
diff changeset
146 = build_vector_from_val (dest_type,
kono
parents:
diff changeset
147 build_minus_one_cst (TREE_TYPE (dest_type)));
kono
parents:
diff changeset
148 tree all_zeroes
kono
parents:
diff changeset
149 = build_vector_from_val (dest_type,
kono
parents:
diff changeset
150 build_zero_cst (TREE_TYPE (dest_type)));
kono
parents:
diff changeset
151 expr = build3 (VEC_COND_EXPR, dest_type, expr, all_ones, all_zeroes);
kono
parents:
diff changeset
152 }
kono
parents:
diff changeset
153 else if (INTEGRAL_TYPE_P (dest_type) && !is_boolean_dest)
kono
parents:
diff changeset
154 {
kono
parents:
diff changeset
155 /* We need to produce the all-ones pattern for the width of the whole
kono
parents:
diff changeset
156 resulting integer type. Use back and forth shifts for propagating
kono
parents:
diff changeset
157 the lower 1. */
kono
parents:
diff changeset
158 tree signed_type = signed_type_for (dest_type);
kono
parents:
diff changeset
159 tree signed_result = convert_to_integer (signed_type, expr);
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 size_t result_width = int_size_in_bytes (dest_type) * BITS_PER_UNIT;
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 tree shift_amount_cst
kono
parents:
diff changeset
164 = build_int_cstu (signed_type, result_width - 1);
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 tree shift_left_result
kono
parents:
diff changeset
167 = build2 (LSHIFT_EXPR, signed_type, signed_result, shift_amount_cst);
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 expr = build2 (RSHIFT_EXPR, signed_type, shift_left_result,
kono
parents:
diff changeset
170 shift_amount_cst);
kono
parents:
diff changeset
171 }
kono
parents:
diff changeset
172 else if (SCALAR_FLOAT_TYPE_P (dest_type))
kono
parents:
diff changeset
173 {
kono
parents:
diff changeset
174 expr = convert_to_real (dest_type, expr);
kono
parents:
diff changeset
175 }
kono
parents:
diff changeset
176 else if (VECTOR_TYPE_P (dest_type)
kono
parents:
diff changeset
177 && (inst->sourceType & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_F16)
kono
parents:
diff changeset
178 {
kono
parents:
diff changeset
179 /* Because F16 comparison is emulated as an F32 comparison with S32
kono
parents:
diff changeset
180 results, we must now truncate the result vector to S16s so it
kono
parents:
diff changeset
181 fits to the destination register. We can build the target vector
kono
parents:
diff changeset
182 type from the f16 storage type (unsigned ints). */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
183 expr = m_parent.m_cf->add_temp_var ("wide_cmp_result", expr);
111
kono
parents:
diff changeset
184 tree_stl_vec wide_elements;
kono
parents:
diff changeset
185 tree_stl_vec shrunk_elements;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
186 m_parent.m_cf->unpack (expr, wide_elements);
111
kono
parents:
diff changeset
187 for (size_t i = 0; i < wide_elements.size (); ++i)
kono
parents:
diff changeset
188 {
kono
parents:
diff changeset
189 tree wide = wide_elements.at (i);
kono
parents:
diff changeset
190 shrunk_elements.push_back
kono
parents:
diff changeset
191 (convert_to_integer (short_integer_type_node, wide));
kono
parents:
diff changeset
192 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
193 expr = m_parent.m_cf->pack (shrunk_elements);
111
kono
parents:
diff changeset
194 }
kono
parents:
diff changeset
195 build_output_assignment (*inst_base, operands[0], expr);
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 return base->byteCount;
kono
parents:
diff changeset
198 }