1 /* brig-seg-inst-handler.cc -- brig segment related instruction handling 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 #include <sstream> 23 24 #include "brig-code-entry-handler.h" 25 #include "brig-util.h" 26 #include "convert.h" 27 #include "tree-pretty-print.h" 28 #include "errors.h" 29 #include "diagnostic-core.h" 30 31 brig_seg_inst_handler::brig_seg_inst_handler (brig_to_generic &parent) 32 : brig_code_entry_handler (parent) 33 { 34 } 35 36 size_t 37 brig_seg_inst_handler::operator () (const BrigBase *base) 38 { 39 const BrigInstBase &inst_base = *(const BrigInstBase *) base; 40 41 std::vector<tree> operands = build_operands (inst_base); 42 43 tree expr = NULL_TREE; 44 45 if (inst_base.opcode == BRIG_OPCODE_STOF) 46 { 47 const BrigInstSegCvt &inst = *(const BrigInstSegCvt *) base; 48 49 if (inst.segment == BRIG_SEGMENT_GROUP) 50 expr = build2 (PLUS_EXPR, size_type_node, 51 convert_to_integer (size_type_node, 52 m_parent.m_cf->m_group_base_arg), 53 convert_to_integer (size_type_node, operands[1])); 54 else if (inst.segment == BRIG_SEGMENT_PRIVATE 55 || inst.segment == BRIG_SEGMENT_SPILL) 56 expr = build2 (PLUS_EXPR, size_type_node, 57 convert_to_integer (size_type_node, 58 m_parent.m_cf->m_private_base_arg), 59 convert_to_integer (size_type_node, operands[1])); 60 else 61 gcc_unreachable (); 62 63 if (!(inst.modifier & BRIG_SEG_CVT_NONULL)) 64 { 65 /* Need to convert the null value. -1 is used for 32b segments, 66 and 0 for flat/global. */ 67 tree cmp 68 = build2 (EQ_EXPR, uint32_type_node, 69 build_int_cstu (uint32_type_node, -1), operands[1]); 70 71 tree null_check = build3 (COND_EXPR, size_type_node, cmp, 72 build_int_cstu (size_type_node, 0), expr); 73 74 expr = null_check; 75 } 76 } 77 else if (inst_base.opcode == BRIG_OPCODE_FTOS) 78 { 79 const BrigInstSegCvt &inst = *(const BrigInstSegCvt *) base; 80 81 if (inst.segment == BRIG_SEGMENT_GROUP) 82 expr = build2 (MINUS_EXPR, size_type_node, 83 convert_to_integer (size_type_node, 84 m_parent.m_cf->m_group_base_arg), 85 convert_to_integer (size_type_node, operands[1])); 86 else if (inst.segment == BRIG_SEGMENT_PRIVATE) 87 expr = build2 (MINUS_EXPR, size_type_node, 88 convert_to_integer (size_type_node, 89 m_parent.m_cf->m_private_base_arg), 90 convert_to_integer (size_type_node, operands[1])); 91 else 92 gcc_unreachable (); 93 94 if (!(inst.modifier & BRIG_SEG_CVT_NONULL)) 95 { 96 /* Need to convert the null value. -1 is used for 32b segments, 97 and 0 for flat/global. */ 98 tree cmp = build2 (EQ_EXPR, size_type_node, 99 build_int_cstu (size_type_node, 0), operands[1]); 100 101 tree null_check 102 = build3 (COND_EXPR, size_type_node, cmp, 103 build_int_cstu (uint32_type_node, -1), expr); 104 expr = null_check; 105 } 106 } 107 else if (inst_base.opcode == BRIG_OPCODE_NULLPTR) 108 { 109 const BrigInstSeg &inst = *(const BrigInstSeg *) base; 110 if (inst.segment == BRIG_SEGMENT_GLOBAL 111 || inst.segment == BRIG_SEGMENT_FLAT 112 || inst.segment == BRIG_SEGMENT_READONLY) 113 expr = build_int_cstu (uint64_type_node, 0); 114 else 115 expr = build_int_cstu (uint32_type_node, -1); 116 } 117 else if (inst_base.opcode == BRIG_OPCODE_SEGMENTP) 118 { 119 const BrigInstSegCvt &inst = *(const BrigInstSegCvt *) base; 120 121 tree builtin = NULL_TREE; 122 switch (inst.segment) 123 { 124 case BRIG_SEGMENT_GLOBAL: 125 builtin = builtin_decl_explicit (BUILT_IN_HSAIL_SEGMENTP_GLOBAL); 126 break; 127 case BRIG_SEGMENT_GROUP: 128 builtin = builtin_decl_explicit (BUILT_IN_HSAIL_SEGMENTP_GROUP); 129 break; 130 case BRIG_SEGMENT_PRIVATE: 131 builtin = builtin_decl_explicit (BUILT_IN_HSAIL_SEGMENTP_PRIVATE); 132 break; 133 default: 134 gcc_unreachable (); 135 } 136 137 expr = call_builtin (builtin, 2, 138 uint32_type_node, uint64_type_node, operands[1], 139 ptr_type_node, m_parent.m_cf->m_context_arg); 140 } 141 else 142 gcc_unreachable (); 143 144 build_output_assignment (inst_base, operands[0], expr); 145 return base->byteCount; 146 } 147