722faf45d15ada2a5e17db56bab25df10e1ab51e
2 * Copyright 2017 Advanced Micro Devices, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 #include <llvm/Config/llvm-config.h>
27 #include "si_shader_internal.h"
30 #include "ac_llvm_util.h"
33 * Load a dword from a constant buffer.
35 LLVMValueRef
si_buffer_load_const(struct si_shader_context
*ctx
,
36 LLVMValueRef resource
, LLVMValueRef offset
)
38 return ac_build_buffer_load(&ctx
->ac
, resource
, 1, NULL
, offset
, NULL
,
42 void si_llvm_build_ret(struct si_shader_context
*ctx
, LLVMValueRef ret
)
44 if (LLVMGetTypeKind(LLVMTypeOf(ret
)) == LLVMVoidTypeKind
)
45 LLVMBuildRetVoid(ctx
->ac
.builder
);
47 LLVMBuildRet(ctx
->ac
.builder
, ret
);
50 LLVMValueRef
si_insert_input_ret(struct si_shader_context
*ctx
, LLVMValueRef ret
,
51 struct ac_arg param
, unsigned return_index
)
53 return LLVMBuildInsertValue(ctx
->ac
.builder
, ret
,
54 ac_get_arg(&ctx
->ac
, param
),
58 LLVMValueRef
si_insert_input_ret_float(struct si_shader_context
*ctx
, LLVMValueRef ret
,
59 struct ac_arg param
, unsigned return_index
)
61 LLVMBuilderRef builder
= ctx
->ac
.builder
;
62 LLVMValueRef p
= ac_get_arg(&ctx
->ac
, param
);
64 return LLVMBuildInsertValue(builder
, ret
,
65 ac_to_float(&ctx
->ac
, p
),
69 LLVMValueRef
si_insert_input_ptr(struct si_shader_context
*ctx
, LLVMValueRef ret
,
70 struct ac_arg param
, unsigned return_index
)
72 LLVMBuilderRef builder
= ctx
->ac
.builder
;
73 LLVMValueRef ptr
= ac_get_arg(&ctx
->ac
, param
);
74 ptr
= LLVMBuildPtrToInt(builder
, ptr
, ctx
->i32
, "");
75 return LLVMBuildInsertValue(builder
, ret
, ptr
, return_index
, "");
78 LLVMValueRef
si_prolog_get_rw_buffers(struct si_shader_context
*ctx
)
80 LLVMValueRef ptr
[2], list
;
81 bool merged_shader
= si_is_merged_shader(ctx
);
83 ptr
[0] = LLVMGetParam(ctx
->main_fn
, (merged_shader
? 8 : 0) + SI_SGPR_RW_BUFFERS
);
84 list
= LLVMBuildIntToPtr(ctx
->ac
.builder
, ptr
[0],
85 ac_array_in_const32_addr_space(ctx
->v4i32
), "");
89 LLVMValueRef
si_build_gather_64bit(struct si_shader_context
*ctx
,
90 LLVMTypeRef type
, LLVMValueRef val1
,
93 LLVMValueRef values
[2] = {
94 ac_to_integer(&ctx
->ac
, val1
),
95 ac_to_integer(&ctx
->ac
, val2
),
97 LLVMValueRef result
= ac_build_gather_values(&ctx
->ac
, values
, 2);
98 return LLVMBuildBitCast(ctx
->ac
.builder
, result
, type
, "");
101 void si_llvm_emit_barrier(struct si_shader_context
*ctx
)
103 /* GFX6 only (thanks to a hw bug workaround):
104 * The real barrier instruction isn’t needed, because an entire patch
105 * always fits into a single wave.
107 if (ctx
->screen
->info
.chip_class
== GFX6
&&
108 ctx
->type
== PIPE_SHADER_TESS_CTRL
) {
109 ac_build_waitcnt(&ctx
->ac
, AC_WAIT_LGKM
| AC_WAIT_VLOAD
| AC_WAIT_VSTORE
);
113 ac_build_s_barrier(&ctx
->ac
);
116 /* Ensure that the esgs ring is declared.
118 * We declare it with 64KB alignment as a hint that the
119 * pointer value will always be 0.
121 void si_llvm_declare_esgs_ring(struct si_shader_context
*ctx
)
126 assert(!LLVMGetNamedGlobal(ctx
->ac
.module
, "esgs_ring"));
128 ctx
->esgs_ring
= LLVMAddGlobalInAddressSpace(
129 ctx
->ac
.module
, LLVMArrayType(ctx
->i32
, 0),
132 LLVMSetLinkage(ctx
->esgs_ring
, LLVMExternalLinkage
);
133 LLVMSetAlignment(ctx
->esgs_ring
, 64 * 1024);