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.
6 This file is part of GCC.
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
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
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/>. */
24 #include "brig-code-entry-handler.h"
25 #include "brig-util.h"
27 #include "tree-pretty-print.h"
29 #include "diagnostic-core.h"
31 brig_seg_inst_handler::brig_seg_inst_handler (brig_to_generic
&parent
)
32 : brig_code_entry_handler (parent
)
37 brig_seg_inst_handler::operator () (const BrigBase
*base
)
39 const BrigInstBase
&inst_base
= *(const BrigInstBase
*) base
;
41 std::vector
<tree
> operands
= build_operands (inst_base
);
43 tree expr
= NULL_TREE
;
45 if (inst_base
.opcode
== BRIG_OPCODE_STOF
)
47 const BrigInstSegCvt
&inst
= *(const BrigInstSegCvt
*) base
;
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]));
63 if (!(inst
.modifier
& BRIG_SEG_CVT_NONULL
))
65 /* Need to convert the null value. -1 is used for 32b segments,
66 and 0 for flat/global. */
68 = build2 (EQ_EXPR
, uint32_type_node
,
69 build_int_cstu (uint32_type_node
, -1), operands
[1]);
71 tree null_check
= build3 (COND_EXPR
, size_type_node
, cmp
,
72 build_int_cstu (size_type_node
, 0), expr
);
77 else if (inst_base
.opcode
== BRIG_OPCODE_FTOS
)
79 const BrigInstSegCvt
&inst
= *(const BrigInstSegCvt
*) base
;
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]));
94 if (!(inst
.modifier
& BRIG_SEG_CVT_NONULL
))
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]);
102 = build3 (COND_EXPR
, size_type_node
, cmp
,
103 build_int_cstu (uint32_type_node
, -1), expr
);
107 else if (inst_base
.opcode
== BRIG_OPCODE_NULLPTR
)
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);
115 expr
= build_int_cstu (uint32_type_node
, -1);
117 else if (inst_base
.opcode
== BRIG_OPCODE_SEGMENTP
)
119 const BrigInstSegCvt
&inst
= *(const BrigInstSegCvt
*) base
;
121 tree builtin
= NULL_TREE
;
122 switch (inst
.segment
)
124 case BRIG_SEGMENT_GLOBAL
:
125 builtin
= builtin_decl_explicit (BUILT_IN_HSAIL_SEGMENTP_GLOBAL
);
127 case BRIG_SEGMENT_GROUP
:
128 builtin
= builtin_decl_explicit (BUILT_IN_HSAIL_SEGMENTP_GROUP
);
130 case BRIG_SEGMENT_PRIVATE
:
131 builtin
= builtin_decl_explicit (BUILT_IN_HSAIL_SEGMENTP_PRIVATE
);
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
);
144 build_output_assignment (inst_base
, operands
[0], expr
);
145 return base
->byteCount
;