1 /* brig-code-entry-handler.h -- a gccbrig base class 2 Copyright (C) 2016-2019 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 brig_code_entry_handler (brig_to_generic &parent); 39 40 /* Handles the brig_code data at the given pointer and adds it to the 41 currently built tree. Returns the number of consumed bytes. */ 42 43 virtual size_t operator () (const BrigBase *base) = 0; 44 45 void append_statement (tree stmt); 46 47 protected: 48 49 tree get_tree_expr_type_for_hsa_type (BrigType16_t brig_type) const; 50 tree get_tree_cst_for_hsa_operand (const BrigOperandConstantBytes *brigConst, 51 tree type) const; 52 tree get_comparison_result_type (tree source_type); 53 54 tree build_code_ref (const BrigBase &ref); 55 56 tree build_tree_operand (const BrigInstBase &brig_inst, 57 const BrigBase &operand, 58 tree operand_type = NULL_TREE, 59 bool is_input = false); 60 61 tree build_address_operand (const BrigInstBase &brig_inst, 62 const BrigOperandAddress &addr_operand); 63 64 tree build_tree_operand_from_brig (const BrigInstBase *brig_inst, 65 tree operand_type, size_t operand_index); 66 67 tree build_tree_cst_element (BrigType16_t element_type, 68 const unsigned char *next_data) const; 69 70 bool needs_workitem_context_data (BrigOpcode16_t brig_opcode) const; 71 72 tree add_temp_var (std::string name, tree expr); 73 74 tree build_f2h_conversion (tree source); 75 tree build_h2f_conversion (tree source); 76 77 tree_stl_vec build_operands (const BrigInstBase &brig_inst); 78 void analyze_operands (const BrigInstBase &brig_inst); 79 tree build_output_assignment (const BrigInstBase &brig_inst, tree output, 80 tree inst_expr); 81 82 tree apply_to_all_elements (tree_element_unary_visitor &visitor, 83 tree operand); 84 85 HOST_WIDE_INT int_constant_value (tree node); 86 87 tree extend_int (tree input, tree dest_type, tree src_type); 88 89 private: 90 91 tree_stl_vec build_or_analyze_operands (const BrigInstBase &brig_inst, 92 bool analyze); 93 }; 94 95 /* Implement the Visitor software pattern for performing various actions on 96 elements of vector operands. This enables separating the vector element 97 traversal/extraction/packing code from whatever different actions are 98 performed to each element. */ 99 100 class tree_element_unary_visitor 101 { 102 public: 103 tree operator () (brig_code_entry_handler &handler, tree operand); 104 105 /* Performs an action to a single element, which can have originally 106 been a vector element or a scalar. */ 107 108 virtual tree visit_element (brig_code_entry_handler &handler, tree operand) 109 = 0; 110 }; 111 112 class tree_element_binary_visitor 113 { 114 public: 115 tree operator () (brig_code_entry_handler &handler, tree operand0, 116 tree operand1); 117 118 /* Performs an action to a pair of elements, which can have originally 119 been a vector element or a scalar. */ 120 121 virtual tree visit_element (brig_code_entry_handler &handler, tree operand0, 122 tree operand1) 123 = 0; 124 }; 125 126 /* Visitor for flushing float elements to zero. */ 127 128 class flush_to_zero : public tree_element_unary_visitor 129 { 130 public: flush_to_zero(bool fp16)131 flush_to_zero (bool fp16) : m_fp16 (fp16) 132 { 133 } 134 135 virtual tree visit_element (brig_code_entry_handler &caller, tree operand); 136 137 private: 138 139 /* True if the value should be flushed according to fp16 limits. */ 140 141 bool m_fp16; 142 }; 143 144 /* Visitor for converting F16 elements to F32. */ 145 146 class half_to_float : public tree_element_unary_visitor 147 { 148 public: 149 virtual tree visit_element (brig_code_entry_handler &caller, tree operand); 150 }; 151 152 /* Visitor for converting F32 elements to F16. */ 153 154 class float_to_half : public tree_element_unary_visitor 155 { 156 public: 157 virtual tree visit_element (brig_code_entry_handler &caller, tree operand); 158 }; 159 160 /* A base class for instruction types that support floating point 161 modifiers. 162 163 operator () delegates to subclasses (template method pattern) in 164 type specific parts. */ 165 166 class brig_inst_mod_handler : public brig_code_entry_handler 167 { 168 public: brig_inst_mod_handler(brig_to_generic & parent)169 brig_inst_mod_handler (brig_to_generic &parent) 170 : brig_code_entry_handler (parent) 171 { 172 } 173 174 virtual size_t generate (const BrigBase *base); 175 virtual const BrigAluModifier8_t *modifier (const BrigBase *base) const; 176 virtual const BrigRound8_t *round (const BrigBase *base) const; 177 178 size_t operator () (const BrigBase *base); 179 }; 180 181 class brig_directive_function_handler : public brig_code_entry_handler 182 { 183 public: brig_directive_function_handler(brig_to_generic & parent)184 brig_directive_function_handler (brig_to_generic &parent) 185 : brig_code_entry_handler (parent) 186 { 187 } 188 size_t operator () (const BrigBase *base); 189 }; 190 191 class brig_directive_control_handler : public brig_code_entry_handler 192 { 193 public: brig_directive_control_handler(brig_to_generic & parent)194 brig_directive_control_handler (brig_to_generic &parent) 195 : brig_code_entry_handler (parent) 196 { 197 } 198 199 size_t operator () (const BrigBase *base); 200 }; 201 202 class brig_directive_variable_handler : public brig_code_entry_handler 203 { 204 public: brig_directive_variable_handler(brig_to_generic & parent)205 brig_directive_variable_handler (brig_to_generic &parent) 206 : brig_code_entry_handler (parent) 207 { 208 } 209 210 size_t operator () (const BrigBase *base); 211 212 tree build_variable (const BrigDirectiveVariable *brigVar, 213 tree_code var_decltype = VAR_DECL); 214 215 size_t get_brig_var_alignment (const BrigDirectiveVariable *brigVar); 216 }; 217 218 class brig_directive_fbarrier_handler : public brig_code_entry_handler 219 { 220 public: brig_directive_fbarrier_handler(brig_to_generic & parent)221 brig_directive_fbarrier_handler (brig_to_generic &parent) 222 : brig_code_entry_handler (parent) 223 { 224 } 225 226 size_t operator () (const BrigBase *base); 227 }; 228 229 class brig_directive_label_handler : public brig_code_entry_handler 230 { 231 public: brig_directive_label_handler(brig_to_generic & parent)232 brig_directive_label_handler (brig_to_generic &parent) 233 : brig_code_entry_handler (parent) 234 { 235 } 236 237 size_t operator () (const BrigBase *base); 238 }; 239 240 class brig_directive_comment_handler : public brig_code_entry_handler 241 { 242 public: brig_directive_comment_handler(brig_to_generic & parent)243 brig_directive_comment_handler (brig_to_generic &parent) 244 : brig_code_entry_handler (parent) 245 { 246 } 247 248 size_t operator () (const BrigBase *base); 249 }; 250 251 class brig_directive_arg_block_handler : public brig_code_entry_handler 252 { 253 public: brig_directive_arg_block_handler(brig_to_generic & parent)254 brig_directive_arg_block_handler (brig_to_generic &parent) 255 : brig_code_entry_handler (parent) 256 { 257 } 258 259 size_t operator () (const BrigBase *base); 260 }; 261 262 class brig_basic_inst_handler : public brig_code_entry_handler 263 { 264 public: 265 brig_basic_inst_handler (brig_to_generic &parent); 266 267 size_t operator () (const BrigBase *base); 268 269 private: 270 tree build_lower_element_broadcast (tree vec_operand); 271 272 bool must_be_scalarized (const BrigInstBase *brig_inst, 273 tree instr_type) const; 274 275 tree build_inst_expr (BrigOpcode16_t brig_opcode, BrigType16_t brig_type, 276 tree arith_type, tree_stl_vec &operands); 277 278 tree build_shuffle (tree arith_type, tree_stl_vec &operands); 279 tree build_unpack (tree_stl_vec &operands); 280 tree build_pack (tree_stl_vec &operands); 281 282 tree build_unpack_lo_or_hi (BrigOpcode16_t brig_opcode, tree arith_type, 283 tree_stl_vec &operands); 284 }; 285 286 class brig_cvt_inst_handler : public brig_inst_mod_handler 287 { 288 public: brig_cvt_inst_handler(brig_to_generic & parent)289 brig_cvt_inst_handler (brig_to_generic &parent) 290 : brig_inst_mod_handler (parent) 291 { 292 } 293 294 virtual size_t generate (const BrigBase *base); 295 virtual const BrigAluModifier8_t *modifier (const BrigBase *base) const; 296 virtual const BrigRound8_t *round (const BrigBase *base) const; 297 }; 298 299 class brig_branch_inst_handler : public brig_code_entry_handler 300 { 301 public: brig_branch_inst_handler(brig_to_generic & parent)302 brig_branch_inst_handler (brig_to_generic &parent) 303 : brig_code_entry_handler (parent) 304 { 305 } 306 307 size_t operator () (const BrigBase *base); 308 }; 309 310 class brig_mem_inst_handler : public brig_code_entry_handler 311 { 312 public: brig_mem_inst_handler(brig_to_generic & parent)313 brig_mem_inst_handler (brig_to_generic &parent) 314 : brig_code_entry_handler (parent) 315 { 316 } 317 318 size_t operator () (const BrigBase *base); 319 320 private: 321 tree build_mem_access (const BrigInstBase *brig_inst, tree addr, tree data); 322 }; 323 324 class brig_copy_move_inst_handler : public brig_code_entry_handler 325 { 326 public: brig_copy_move_inst_handler(brig_to_generic & parent)327 brig_copy_move_inst_handler (brig_to_generic &parent) 328 : brig_code_entry_handler (parent) 329 { 330 } 331 332 size_t operator () (const BrigBase *base); 333 334 private: 335 size_t handle_lda (const BrigInstBase *base); 336 }; 337 338 class brig_atomic_inst_handler : public brig_code_entry_handler 339 { 340 private: 341 typedef std::map<std::string, tree> atomic_builtins_map; 342 343 public: 344 brig_atomic_inst_handler (brig_to_generic &parent); 345 346 size_t operator () (const BrigBase *base); 347 348 protected: 349 size_t generate_tree (const BrigInstBase &inst, 350 BrigAtomicOperation8_t atomic_opcode); 351 }; 352 353 class brig_signal_inst_handler : public brig_atomic_inst_handler 354 { 355 public: brig_signal_inst_handler(brig_to_generic & parent)356 brig_signal_inst_handler (brig_to_generic &parent) 357 : brig_atomic_inst_handler (parent) 358 { 359 } 360 size_t operator () (const BrigBase *base); 361 }; 362 363 class brig_cmp_inst_handler : public brig_code_entry_handler 364 { 365 public: brig_cmp_inst_handler(brig_to_generic & parent)366 brig_cmp_inst_handler (brig_to_generic &parent) 367 : brig_code_entry_handler (parent) 368 { 369 } 370 371 size_t operator () (const BrigBase *base); 372 }; 373 374 class brig_seg_inst_handler : public brig_code_entry_handler 375 { 376 public: 377 brig_seg_inst_handler (brig_to_generic &parent); 378 379 size_t operator () (const BrigBase *base); 380 }; 381 382 class brig_lane_inst_handler : public brig_code_entry_handler 383 { 384 public: 385 brig_lane_inst_handler (brig_to_generic &parent); 386 387 size_t operator () (const BrigBase *base); 388 }; 389 390 class brig_queue_inst_handler : public brig_code_entry_handler 391 { 392 public: 393 brig_queue_inst_handler (brig_to_generic &parent); 394 395 size_t operator () (const BrigBase *base); 396 }; 397 398 class brig_directive_module_handler : public brig_code_entry_handler 399 { 400 public: brig_directive_module_handler(brig_to_generic & parent)401 brig_directive_module_handler (brig_to_generic &parent) 402 : brig_code_entry_handler (parent) 403 { 404 } 405 406 size_t operator () (const BrigBase *base); 407 }; 408 409 410 #endif 411