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