]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/brig/brigfrontend/brig-seg-inst-handler.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / brig / brigfrontend / brig-seg-inst-handler.cc
1 /* brig-seg-inst-handler.cc -- brig segment related 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 <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 }