1 /* brig-lane-inst-handler.cc -- brig lane instruction handling 2 Copyright (C) 2016-2018 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 #include "brig-code-entry-handler.h" 23 #include "errors.h" 24 #include "diagnostic-core.h" 25 #include "brig-util.h" 26 27 brig_lane_inst_handler::brig_lane_inst_handler (brig_to_generic &parent) 28 : brig_code_entry_handler (parent) 29 { 30 } 31 32 size_t 33 brig_lane_inst_handler::operator () (const BrigBase *base) 34 { 35 const BrigInstLane &inst = *(const BrigInstLane *) base; 36 tree_stl_vec operands = build_operands (inst.base); 37 38 tree expr = NULL_TREE; 39 if (inst.base.opcode == BRIG_OPCODE_ACTIVELANECOUNT) 40 { 41 /* Because we are fixed to single WI per wave, it's enough to 42 just check the src value of the single work item itself. */ 43 expr = build2 (NE_EXPR, uint32_type_node, 44 build_zero_cst (uint32_type_node), operands[1]); 45 } 46 else if (inst.base.opcode == BRIG_OPCODE_ACTIVELANEID) 47 { 48 expr = build_zero_cst (uint32_type_node); 49 } 50 else if (inst.base.opcode == BRIG_OPCODE_ACTIVELANEMASK) 51 { 52 tree u64_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U64); 53 tree zero_cst = build_zero_cst (u64_type); 54 expr = build2 (NE_EXPR, u64_type, zero_cst, operands[1]); 55 56 tree_stl_vec elements; 57 elements.push_back (expr); 58 elements.push_back (zero_cst); 59 elements.push_back (zero_cst); 60 elements.push_back (zero_cst); 61 62 expr = pack (elements); 63 } 64 else if (inst.base.opcode == BRIG_OPCODE_ACTIVELANEPERMUTE) 65 { 66 tree src = operands[1]; 67 tree identity = operands[3]; 68 tree use_identity = operands[4]; 69 70 /* When WAVESIZE is 1, we either select the src of the work-item 71 itself or 'identity' in case use_identity is 1. */ 72 73 tree cmp = build2 (EQ_EXPR, uint32_type_node, 74 build_int_cstu (TREE_TYPE (use_identity), 1), 75 use_identity); 76 77 expr = build3 (COND_EXPR, TREE_TYPE (src), cmp, identity, src); 78 } 79 else 80 gcc_unreachable (); 81 82 build_output_assignment (inst.base, operands[0], expr); 83 84 return base->byteCount; 85 } 86