1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // The University of Illinois/NCSA
4 // Open Source License (NCSA)
5 //
6 // Copyright (c) 2014-2016, Advanced Micro Devices, Inc. All rights reserved.
7 //
8 // Developed by:
9 //
10 // AMD Research and AMD HSA Software Development
11 //
12 // Advanced Micro Devices, Inc.
13 //
14 // www.amd.com
15 //
16 // Permission is hereby granted, free of charge, to any person obtaining a copy
17 // of this software and associated documentation files (the "Software"), to
18 // deal with the Software without restriction, including without limitation
19 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 // and/or sell copies of the Software, and to permit persons to whom the
21 // Software is furnished to do so, subject to the following conditions:
22 //
23 // - Redistributions of source code must retain the above copyright notice,
24 // this list of conditions and the following disclaimers.
25 // - Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimers in
27 // the documentation and/or other materials provided with the distribution.
28 // - Neither the names of Advanced Micro Devices, Inc,
29 // nor the names of its contributors may be used to endorse or promote
30 // products derived from this Software without specific prior written
31 // permission.
32 //
33 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
36 // THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
37 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
38 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
39 // DEALINGS WITH THE SOFTWARE.
40 //
41 ////////////////////////////////////////////////////////////////////////////////
42
43 #ifndef AMD_HSA_CODE_UTIL_HPP_
44 #define AMD_HSA_CODE_UTIL_HPP_
45
46 #include <cassert>
47 #include <string>
48 #include <vector>
49 #include <iostream>
50 #ifdef _WIN32
51 #include <malloc.h>
52 #else // _WIN32
53 #include <cstdlib>
54 #endif // _WIN32
55 #include "amd_hsa_kernel_code.h"
56 #include "amd_hsa_elf.h"
57 #include "hsa.h"
58 #include "hsa_ext_finalize.h"
59
60 #define hsa_error(e) static_cast<hsa_status_t>(e)
61
62 #define release_assert(e) \
63 if (!(e)) { \
64 std::cerr << __FILE__ << ":"; \
65 std::cerr << __LINE__ << ":"; \
66 std::cerr << " Assertion `" << #e << "' failed." << std::endl; \
67 std::abort(); \
68 } \
69
70 namespace amd {
71 namespace hsa {
72
73 std::string HsaSymbolKindToString(hsa_symbol_kind_t kind);
74 std::string HsaSymbolLinkageToString(hsa_symbol_linkage_t linkage);
75 std::string HsaVariableAllocationToString(hsa_variable_allocation_t allocation);
76 std::string HsaVariableSegmentToString(hsa_variable_segment_t segment);
77 std::string HsaProfileToString(hsa_profile_t profile);
78 std::string HsaMachineModelToString(hsa_machine_model_t model);
79 std::string HsaFloatRoundingModeToString(hsa_default_float_rounding_mode_t mode);
80 std::string AmdMachineKindToString(amd_machine_kind16_t machine);
81 std::string AmdFloatRoundModeToString(amd_float_round_mode_t round_mode);
82 std::string AmdFloatDenormModeToString(amd_float_denorm_mode_t denorm_mode);
83 std::string AmdSystemVgprWorkitemIdToString(amd_system_vgpr_workitem_id_t system_vgpr_workitem_id);
84 std::string AmdElementByteSizeToString(amd_element_byte_size_t element_byte_size);
85 std::string AmdExceptionKindToString(amd_exception_kind16_t exceptions);
86 std::string AmdPowerTwoToString(amd_powertwo8_t p);
87 amdgpu_hsa_elf_segment_t AmdHsaElfSectionSegment(amdgpu_hsa_elf_section_t sec);
88 bool IsAmdHsaElfSectionROData(amdgpu_hsa_elf_section_t sec);
89 std::string AmdHsaElfSegmentToString(amdgpu_hsa_elf_segment_t seg);
90 std::string AmdPTLoadToString(uint64_t type);
91
92 void PrintAmdKernelCode(std::ostream& out, const amd_kernel_code_t *akc);
93 void PrintAmdComputePgmRsrcOne(std::ostream& out, amd_compute_pgm_rsrc_one32_t compute_pgm_rsrc1);
94 void PrintAmdComputePgmRsrcTwo(std::ostream& out, amd_compute_pgm_rsrc_two32_t compute_pgm_rsrc2);
95 void PrintAmdKernelCodeProperties(std::ostream& out, amd_kernel_code_properties32_t kernel_code_properties);
96 void PrintAmdControlDirectives(std::ostream& out, const amd_control_directives_t &control_directives);
97
98 namespace code_options {
99 // Space between options (not at the beginning).
100 std::ostream& space(std::ostream& out);
101
102 // Control directive option without value.
103 struct control_directive {
104 const char *name;
control_directiveamd::hsa::code_options::control_directive105 control_directive(const char* name_) : name(name_) { }
106 };
107 std::ostream& operator<<(std::ostream& out, const control_directive& d);
108
109 // Exceptions mask string.
110 struct exceptions_mask {
111 uint16_t mask;
exceptions_maskamd::hsa::code_options::exceptions_mask112 exceptions_mask(uint16_t mask_) : mask(mask_) { }
113 };
114 std::ostream& operator<<(std::ostream& out, const exceptions_mask& e);
115
116 // Control directives options.
117 struct control_directives {
118 const hsa_ext_control_directives_t& d;
control_directivesamd::hsa::code_options::control_directives119 control_directives(const hsa_ext_control_directives_t& d_) : d(d_) { }
120 };
121 std::ostream& operator<<(std::ostream& out, const control_directives& cd);
122 }
123
124 const char* hsaerr2str(hsa_status_t status);
125 bool ReadFileIntoBuffer(const std::string& filename, std::vector<char>& buffer);
126
127 // Create new empty temporary file that will be deleted when closed.
128 int OpenTempFile(const char* prefix);
129 void CloseTempFile(int fd);
130
131 // Helper comment types for isa disassembler
132 enum DumpIsaCommentType {
133 COMMENT_AMD_KERNEL_CODE_T_BEGIN = 1,
134 COMMENT_AMD_KERNEL_CODE_T_END,
135 COMMENT_KERNEL_ISA_BEGIN,
136 };
137
138 // Callbacks to create helper comments for isa disassembler
139 const char * CommentTopCallBack(void *ctx, int type);
140 const char * CommentRightCallBack(void *ctx, int type);
141
142 // Parse disassembler instruction line to find offset
143 uint32_t ParseInstructionOffset(const std::string& instruction);
144
145 // Trim whitespaces from start of string
146 void ltrim(std::string &str);
147
148
149 // Helper function that allocates an aligned memory.
150 inline void*
alignedMalloc(size_t size,size_t alignment)151 alignedMalloc(size_t size, size_t alignment)
152 {
153 #if defined(_WIN32)
154 return ::_aligned_malloc(size, alignment);
155 #else
156 void * ptr = NULL;
157 alignment = (std::max)(alignment, sizeof(void*));
158 if (0 == ::posix_memalign(&ptr, alignment, size)) {
159 return ptr;
160 }
161 return NULL;
162 #endif
163 }
164
165 // Helper function that frees an aligned memory.
166 inline void
alignedFree(void * ptr)167 alignedFree(void *ptr)
168 {
169 #if defined(_WIN32)
170 ::_aligned_free(ptr);
171 #else
172 free(ptr);
173 #endif
174 }
175
alignUp(uint64_t num,uint64_t align)176 inline uint64_t alignUp(uint64_t num, uint64_t align)
177 {
178 assert(align);
179 assert((align & (align - 1)) == 0);
180 return (num + align - 1) & ~(align - 1);
181 }
182
alignUp(uint32_t num,uint32_t align)183 inline uint32_t alignUp(uint32_t num, uint32_t align)
184 {
185 assert(align);
186 assert((align & (align - 1)) == 0);
187 return (num + align - 1) & ~(align - 1);
188 }
189
190 std::string DumpFileName(const std::string& dir, const char* prefix, const char* ext, unsigned n, unsigned i = 0);
191
192 }
193 }
194
195 #endif // AMD_HSA_CODE_UTIL_HPP_
196