xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/brig/brigfrontend/brig-code-entry-handler.h (revision d90047b5d07facf36e6c01dcc0bded8997ce9cc2)
1 /* brig-code-entry-handler.h -- a gccbrig base class
2    Copyright (C) 2016-2017 Free Software Foundation, Inc.
3    Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
4    for General Processor Tech.
5 
6    This file is part of GCC.
7 
8    GCC is free software; you can redistribute it and/or modify it under
9    the terms of the GNU General Public License as published by the Free
10    Software Foundation; either version 3, or (at your option) any later
11    version.
12 
13    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14    WARRANTY; without even the implied warranty of MERCHANTABILITY or
15    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16    for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with GCC; see the file COPYING3.  If not see
20    <http://www.gnu.org/licenses/>.  */
21 
22 #ifndef GCC_BRIG_CODE_ENTRY_HANDLER_H
23 #define GCC_BRIG_CODE_ENTRY_HANDLER_H
24 
25 #include "brig-to-generic.h"
26 
27 #include <map>
28 #include <vector>
29 
30 class tree_element_unary_visitor;
31 
32 /* An interface to organize the different types of element handlers
33    for the code section.  */
34 
35 class brig_code_entry_handler : public brig_entry_handler
36 {
37 public:
38   typedef std::map<std::pair<BrigOpcode16_t, BrigType16_t>, tree> builtin_map;
39 
40   brig_code_entry_handler (brig_to_generic &parent);
41 
42   /* Handles the brig_code data at the given pointer and adds it to the
43      currently built tree.  Returns the number of consumed bytes.  */
44 
45   virtual size_t operator () (const BrigBase *base) = 0;
46 
47   void append_statement (tree stmt);
48 
49 protected:
50 
51   tree get_tree_expr_type_for_hsa_type (BrigType16_t brig_type) const;
52   tree get_tree_cst_for_hsa_operand (const BrigOperandConstantBytes *brigConst,
53 				     tree type) const;
54   tree get_builtin_for_hsa_opcode (tree type, BrigOpcode16_t brig_opcode,
55 				   BrigType16_t brig_type) const;
56   tree get_comparison_result_type (tree source_type);
57 
58   tree build_code_ref (const BrigBase &ref);
59 
60   tree build_tree_operand (const BrigInstBase &brig_inst,
61 			   const BrigBase &operand,
62 			   tree operand_type = NULL_TREE,
63 			   bool is_input = false);
64 
65   tree build_address_operand (const BrigInstBase &brig_inst,
66 			      const BrigOperandAddress &addr_operand);
67 
68   tree build_tree_operand_from_brig (const BrigInstBase *brig_inst,
69 				     tree operand_type, size_t operand_index);
70 
71   tree build_tree_cst_element (BrigType16_t element_type,
72 			       const unsigned char *next_data) const;
73 
74   bool needs_workitem_context_data (BrigOpcode16_t brig_opcode) const;
75 
76   void unpack (tree value, tree_stl_vec &elements);
77   tree pack (tree_stl_vec &elements);
78 
79   bool can_expand_builtin (BrigOpcode16_t brig_opcode) const;
80   tree expand_builtin (BrigOpcode16_t brig_opcode, tree_stl_vec &operands);
81 
82   tree expand_or_call_builtin (BrigOpcode16_t brig_opcode,
83 			       BrigType16_t brig_type, tree arith_type,
84 			       tree_stl_vec &operands);
85 
86   tree add_temp_var (std::string name, tree expr);
87 
88   tree build_f2h_conversion (tree source);
89   tree build_h2f_conversion (tree source);
90 
91   tree_stl_vec build_operands (const BrigInstBase &brig_inst);
92   tree build_output_assignment (const BrigInstBase &brig_inst, tree output,
93 				tree inst_expr);
94 
95   tree apply_to_all_elements (tree_element_unary_visitor &visitor,
96 			      tree operand);
97 
98   HOST_WIDE_INT int_constant_value (tree node);
99 
100   tree extend_int (tree input, tree dest_type, tree src_type);
101 
102   /* HSAIL-specific builtin functions not yet integrated to gcc.  */
103 
104   static builtin_map s_custom_builtins;
105 };
106 
107 /* Implement the Visitor software pattern for performing various actions on
108    elements of vector operands.  This enables separating the vector element
109    traversal/extraction/packing code from whatever different actions are
110    performed to each element.  */
111 
112 class tree_element_unary_visitor
113 {
114 public:
115   tree operator () (brig_code_entry_handler &handler, tree operand);
116 
117   /* Performs an action to a single element, which can have originally
118      been a vector element or a scalar.  */
119 
120   virtual tree visit_element (brig_code_entry_handler &handler, tree operand)
121     = 0;
122 };
123 
124 class tree_element_binary_visitor
125 {
126 public:
127   tree operator () (brig_code_entry_handler &handler, tree operand0,
128 		   tree operand1);
129 
130   /* Performs an action to a pair of elements, which can have originally
131      been a vector element or a scalar.  */
132 
133   virtual tree visit_element (brig_code_entry_handler &handler, tree operand0,
134 			      tree operand1)
135     = 0;
136 };
137 
138 /* Visitor for flushing float elements to zero.  */
139 
140 class flush_to_zero : public tree_element_unary_visitor
141 {
142 public:
143   flush_to_zero (bool fp16) : m_fp16 (fp16)
144   {
145   }
146 
147   virtual tree visit_element (brig_code_entry_handler &caller, tree operand);
148 
149 private:
150 
151   /* True if the value should be flushed according to fp16 limits.  */
152 
153   bool m_fp16;
154 };
155 
156 /* Visitor for converting F16 elements to F32.  */
157 
158 class half_to_float : public tree_element_unary_visitor
159 {
160 public:
161   virtual tree visit_element (brig_code_entry_handler &caller, tree operand);
162 };
163 
164 /* Visitor for converting F32 elements to F16.  */
165 
166 class float_to_half : public tree_element_unary_visitor
167 {
168 public:
169   virtual tree visit_element (brig_code_entry_handler &caller, tree operand);
170 };
171 
172 /* A base class for instruction types that support floating point
173    modifiers.
174 
175    operator () delegates to subclasses (template method pattern) in
176    type specific parts.  */
177 
178 class brig_inst_mod_handler : public brig_code_entry_handler
179 {
180 public:
181   brig_inst_mod_handler (brig_to_generic &parent)
182     : brig_code_entry_handler (parent)
183   {
184   }
185 
186   virtual size_t generate (const BrigBase *base);
187   virtual const BrigAluModifier8_t *modifier (const BrigBase *base) const;
188   virtual const BrigRound8_t *round (const BrigBase *base) const;
189 
190   size_t operator () (const BrigBase *base);
191 };
192 
193 class brig_directive_function_handler : public brig_code_entry_handler
194 {
195 public:
196   brig_directive_function_handler (brig_to_generic &parent)
197     : brig_code_entry_handler (parent)
198   {
199   }
200   size_t operator () (const BrigBase *base);
201 };
202 
203 class brig_directive_control_handler : public brig_code_entry_handler
204 {
205 public:
206   brig_directive_control_handler (brig_to_generic &parent)
207     : brig_code_entry_handler (parent)
208   {
209   }
210 
211   size_t operator () (const BrigBase *base);
212 };
213 
214 class brig_directive_variable_handler : public brig_code_entry_handler
215 {
216 public:
217   brig_directive_variable_handler (brig_to_generic &parent)
218     : brig_code_entry_handler (parent)
219   {
220   }
221 
222   size_t operator () (const BrigBase *base);
223 
224   tree build_variable (const BrigDirectiveVariable *brigVar,
225 		       tree_code var_decltype = VAR_DECL);
226 
227   size_t get_brig_var_alignment (const BrigDirectiveVariable *brigVar);
228 };
229 
230 class brig_directive_fbarrier_handler : public brig_code_entry_handler
231 {
232 public:
233   brig_directive_fbarrier_handler (brig_to_generic &parent)
234     : brig_code_entry_handler (parent)
235   {
236   }
237 
238   size_t operator () (const BrigBase *base);
239 };
240 
241 class brig_directive_label_handler : public brig_code_entry_handler
242 {
243 public:
244   brig_directive_label_handler (brig_to_generic &parent)
245     : brig_code_entry_handler (parent)
246   {
247   }
248 
249   size_t operator () (const BrigBase *base);
250 };
251 
252 class brig_directive_comment_handler : public brig_code_entry_handler
253 {
254 public:
255   brig_directive_comment_handler (brig_to_generic &parent)
256     : brig_code_entry_handler (parent)
257   {
258   }
259 
260   size_t operator () (const BrigBase *base);
261 };
262 
263 class brig_directive_arg_block_handler : public brig_code_entry_handler
264 {
265 public:
266   brig_directive_arg_block_handler (brig_to_generic &parent)
267     : brig_code_entry_handler (parent)
268   {
269   }
270 
271   size_t operator () (const BrigBase *base);
272 };
273 
274 class brig_basic_inst_handler : public brig_code_entry_handler
275 {
276 public:
277   brig_basic_inst_handler (brig_to_generic &parent);
278 
279   size_t operator () (const BrigBase *base);
280 
281 private:
282   tree build_lower_element_broadcast (tree vec_operand);
283 
284   bool must_be_scalarized (const BrigInstBase *brig_inst,
285 			   tree instr_type) const;
286 
287   tree build_inst_expr (BrigOpcode16_t brig_opcode, BrigType16_t brig_type,
288 			 tree arith_type, tree_stl_vec &operands);
289 
290   tree build_shuffle (tree arith_type, tree_stl_vec &operands);
291   tree build_unpack (tree_stl_vec &operands);
292   tree build_pack (tree_stl_vec &operands);
293 
294   tree build_unpack_lo_or_hi (BrigOpcode16_t brig_opcode, tree arith_type,
295 			      tree_stl_vec &operands);
296 
297   tree_code get_tree_code_for_hsa_opcode (BrigOpcode16_t brig_opcode,
298 					  BrigType16_t brig_type) const;
299 };
300 
301 class brig_cvt_inst_handler : public brig_inst_mod_handler
302 {
303 public:
304   brig_cvt_inst_handler (brig_to_generic &parent)
305     : brig_inst_mod_handler (parent)
306   {
307   }
308 
309   virtual size_t generate (const BrigBase *base);
310   virtual const BrigAluModifier8_t *modifier (const BrigBase *base) const;
311   virtual const BrigRound8_t *round (const BrigBase *base) const;
312 };
313 
314 class brig_branch_inst_handler : public brig_code_entry_handler
315 {
316 public:
317   brig_branch_inst_handler (brig_to_generic &parent)
318     : brig_code_entry_handler (parent)
319   {
320   }
321 
322   size_t operator () (const BrigBase *base);
323 };
324 
325 class brig_mem_inst_handler : public brig_code_entry_handler
326 {
327 public:
328   brig_mem_inst_handler (brig_to_generic &parent)
329     : brig_code_entry_handler (parent)
330   {
331   }
332 
333   size_t operator () (const BrigBase *base);
334 
335 private:
336   tree build_mem_access (const BrigInstBase *brig_inst, tree addr, tree data);
337 };
338 
339 class brig_copy_move_inst_handler : public brig_code_entry_handler
340 {
341 public:
342   brig_copy_move_inst_handler (brig_to_generic &parent)
343     : brig_code_entry_handler (parent)
344   {
345   }
346 
347   size_t operator () (const BrigBase *base);
348 
349 private:
350   size_t handle_lda (const BrigInstBase *base);
351 };
352 
353 class brig_atomic_inst_handler : public brig_code_entry_handler
354 {
355 private:
356   typedef std::map<std::string, tree> atomic_builtins_map;
357 
358 public:
359   brig_atomic_inst_handler (brig_to_generic &parent);
360 
361   size_t operator () (const BrigBase *base);
362 
363 protected:
364   size_t generate_tree (const BrigInstBase &inst,
365 			BrigAtomicOperation8_t atomic_opcode);
366 };
367 
368 class brig_signal_inst_handler : public brig_atomic_inst_handler
369 {
370 public:
371   brig_signal_inst_handler (brig_to_generic &parent)
372     : brig_atomic_inst_handler (parent)
373   {
374   }
375   size_t operator () (const BrigBase *base);
376 };
377 
378 class brig_cmp_inst_handler : public brig_code_entry_handler
379 {
380 public:
381   brig_cmp_inst_handler (brig_to_generic &parent)
382     : brig_code_entry_handler (parent)
383   {
384   }
385 
386   size_t operator () (const BrigBase *base);
387 };
388 
389 class brig_seg_inst_handler : public brig_code_entry_handler
390 {
391 public:
392   brig_seg_inst_handler (brig_to_generic &parent);
393 
394   size_t operator () (const BrigBase *base);
395 };
396 
397 class brig_lane_inst_handler : public brig_code_entry_handler
398 {
399 public:
400   brig_lane_inst_handler (brig_to_generic &parent);
401 
402   size_t operator () (const BrigBase *base);
403 };
404 
405 class brig_queue_inst_handler : public brig_code_entry_handler
406 {
407 public:
408   brig_queue_inst_handler (brig_to_generic &parent);
409 
410   size_t operator () (const BrigBase *base);
411 };
412 
413 class brig_directive_module_handler : public brig_code_entry_handler
414 {
415 public:
416   brig_directive_module_handler (brig_to_generic &parent)
417     : brig_code_entry_handler (parent)
418   {
419   }
420 
421   size_t operator () (const BrigBase *base);
422 };
423 
424 
425 #endif
426