summaryrefslogtreecommitdiff
path: root/src/gpu-compute/hsail_code.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu-compute/hsail_code.hh')
-rw-r--r--src/gpu-compute/hsail_code.hh447
1 files changed, 447 insertions, 0 deletions
diff --git a/src/gpu-compute/hsail_code.hh b/src/gpu-compute/hsail_code.hh
new file mode 100644
index 000000000..d9fbcc577
--- /dev/null
+++ b/src/gpu-compute/hsail_code.hh
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2012-2015 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * For use for simulation and test purposes only
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Steve Reinhardt
+ */
+
+#ifndef __HSAIL_CODE_HH__
+#define __HSAIL_CODE_HH__
+
+#include <cassert>
+#include <list>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "arch/gpu_decoder.hh"
+#include "arch/hsail/Brig.h"
+#include "base/addr_range_map.hh"
+#include "base/intmath.hh"
+#include "config/the_gpu_isa.hh"
+#include "gpu-compute/hsa_code.hh"
+#include "gpu-compute/hsa_kernel_info.hh"
+#include "gpu-compute/misc.hh"
+
+class BrigObject;
+class GPUStaticInst;
+
+inline int
+popcount(uint64_t src, int sz)
+{
+ int cnt = 0;
+
+ for (int i = 0; i < sz; ++i) {
+ if (src & 1)
+ ++cnt;
+ src >>= 1;
+ }
+
+ return cnt;
+}
+
+inline int
+firstbit(uint64_t src, int sz)
+{
+ int i;
+
+ for (i = 0; i < sz; ++i) {
+ if (src & 1)
+ break;
+ src >>= 1;
+ }
+
+ return i;
+}
+
+inline int
+lastbit(uint64_t src, int sz)
+{
+ int i0 = -1;
+
+ for (int i = 0; i < sz; ++i) {
+ if (src & 1)
+ i0 = i;
+ src >>= 1;
+ }
+
+ return i0;
+}
+
+inline int
+signbit(uint64_t src, int sz)
+{
+ int i0 = -1;
+
+ if (src & (1 << (sz - 1))) {
+ for (int i = 0; i < sz - 1; ++i) {
+ if (!(src & 1))
+ i0 = i;
+ src >>= 1;
+ }
+ } else {
+ for (int i = 0; i < sz - 1; ++i) {
+ if (src & 1)
+ i0 = i;
+ src >>= 1;
+ }
+ }
+
+ return i0;
+}
+
+inline uint64_t
+bitrev(uint64_t src, int sz)
+{
+ uint64_t r = 0;
+
+ for (int i = 0; i < sz; ++i) {
+ r <<= 1;
+ if (src & 1)
+ r |= 1;
+ src >>= 1;
+ }
+
+ return r;
+}
+
+inline uint64_t
+mul_hi(uint32_t a, uint32_t b)
+{
+ return ((uint64_t)a * (uint64_t)b) >> 32;
+}
+
+inline uint64_t
+mul_hi(int32_t a, int32_t b)
+{
+ return ((int64_t)a * (int64_t)b) >> 32;
+}
+
+inline uint64_t
+mul_hi(uint64_t a, uint64_t b)
+{
+ return ((uint64_t)a * (uint64_t)b) >> 32;
+}
+
+inline uint64_t
+mul_hi(int64_t a, int64_t b)
+{
+ return ((int64_t)a * (int64_t)b) >> 32;
+}
+
+inline uint64_t
+mul_hi(double a, double b)
+{
+ return 0;
+}
+
+class Label
+{
+ public:
+ std::string name;
+ int value;
+
+ Label() : value(-1)
+ {
+ }
+
+ bool defined() { return value != -1; }
+
+ void
+ checkName(std::string &_name)
+ {
+ if (name.empty()) {
+ name = _name;
+ } else {
+ assert(name == _name);
+ }
+ }
+
+ void
+ define(std::string &_name, int _value)
+ {
+ assert(!defined());
+ assert(_value != -1);
+ value = _value;
+ checkName(_name);
+ }
+
+ int
+ get()
+ {
+ assert(defined());
+ return value;
+ }
+};
+
+class LabelMap
+{
+ std::map<std::string, Label> map;
+
+ public:
+ LabelMap() { }
+
+ void addLabel(const Brig::BrigDirectiveLabel *lbl, int inst_index,
+ const BrigObject *obj);
+
+ Label *refLabel(const Brig::BrigDirectiveLabel *lbl,
+ const BrigObject *obj);
+};
+
+const int NumSegments = Brig::BRIG_SEGMENT_AMD_GCN;
+
+extern const char *segmentNames[];
+
+class StorageElement
+{
+ public:
+ std::string name;
+ uint64_t offset;
+
+ uint64_t size;
+ const Brig::BrigDirectiveVariable *brigSymbol;
+ StorageElement(const char *_name, uint64_t _offset, int _size,
+ const Brig::BrigDirectiveVariable *sym)
+ : name(_name), offset(_offset), size(_size), brigSymbol(sym)
+ {
+ }
+};
+
+class StorageSpace
+{
+ typedef std::map<const Brig::BrigDirectiveVariable*, StorageElement*>
+ DirVarToSE_map;
+
+ std::list<StorageElement*> elements;
+ AddrRangeMap<StorageElement*> elements_by_addr;
+ DirVarToSE_map elements_by_brigptr;
+
+ uint64_t nextOffset;
+ Brig::BrigSegment segment;
+
+ public:
+ StorageSpace(Brig::BrigSegment _class)
+ : nextOffset(0), segment(_class)
+ {
+ }
+
+ StorageElement *addSymbol(const Brig::BrigDirectiveVariable *sym,
+ const BrigObject *obj);
+
+ StorageElement* findSymbol(std::string name);
+ StorageElement* findSymbol(uint64_t addr);
+ StorageElement* findSymbol(const Brig::BrigDirectiveVariable *brigptr);
+
+ int getSize() { return nextOffset; }
+ void resetOffset() { nextOffset = 0; }
+};
+
+class StorageMap
+{
+ StorageMap *outerScopeMap;
+ StorageSpace *space[NumSegments];
+
+ public:
+ StorageMap(StorageMap *outerScope = nullptr);
+
+ StorageElement *addSymbol(const Brig::BrigDirectiveVariable *sym,
+ const BrigObject *obj);
+
+ StorageElement* findSymbol(Brig::BrigSegment segment, std::string name);
+ StorageElement* findSymbol(Brig::BrigSegment segment, uint64_t addr);
+
+ StorageElement* findSymbol(Brig::BrigSegment segment,
+ const Brig::BrigDirectiveVariable *brigptr);
+
+ // overloaded version to avoid casting
+ StorageElement*
+ findSymbol(Brig::BrigSegment8_t segment, std::string name)
+ {
+ return findSymbol((Brig::BrigSegment)segment, name);
+ }
+
+ int getSize(Brig::BrigSegment segment);
+ void resetOffset(Brig::BrigSegment segment);
+};
+
+typedef enum
+{
+ BT_DEFAULT,
+ BT_B8,
+ BT_U8,
+ BT_U16,
+ BT_U32,
+ BT_U64,
+ BT_S8,
+ BT_S16,
+ BT_S32,
+ BT_S64,
+ BT_F16,
+ BT_F32,
+ BT_F64,
+ BT_NULL
+} base_type_e;
+
+/* @class HsailCode
+ * the HsailCode class is used to store information
+ * about HSA kernels stored in the BRIG format. it holds
+ * all information about a kernel, function, or variable
+ * symbol and provides methods for accessing that
+ * information.
+ */
+
+class HsailCode final : public HsaCode
+{
+ public:
+ TheGpuISA::Decoder decoder;
+
+ StorageMap *storageMap;
+ LabelMap labelMap;
+ uint32_t kernarg_start;
+ uint32_t kernarg_end;
+ int32_t private_size;
+
+ int32_t readonly_size;
+
+ // We track the maximum register index used for each register
+ // class when we load the code so we can size the register files
+ // appropriately (i.e., one more than the max index).
+ uint32_t max_creg; // maximum c-register index
+ uint32_t max_sreg; // maximum s-register index
+ uint32_t max_dreg; // maximum d-register index
+
+ HsailCode(const std::string &name_str,
+ const Brig::BrigDirectiveExecutable *code_dir,
+ const BrigObject *obj,
+ StorageMap *objStorageMap);
+
+ // this version is used to create a placeholder when
+ // we encounter a kernel-related directive before the
+ // kernel itself
+ HsailCode(const std::string &name_str);
+
+ void init(const Brig::BrigDirectiveExecutable *code_dir,
+ const BrigObject *obj, StorageMap *objStorageMap);
+
+ void
+ generateHsaKernelInfo(HsaKernelInfo *hsaKernelInfo) const
+ {
+ hsaKernelInfo->sRegCount = max_sreg + 1;
+ hsaKernelInfo->dRegCount = max_dreg + 1;
+ hsaKernelInfo->cRegCount = max_creg + 1;
+
+ hsaKernelInfo->static_lds_size = getSize(Brig::BRIG_SEGMENT_GROUP);
+
+ hsaKernelInfo->private_mem_size =
+ roundUp(getSize(Brig::BRIG_SEGMENT_PRIVATE), 8);
+
+ hsaKernelInfo->spill_mem_size =
+ roundUp(getSize(Brig::BRIG_SEGMENT_SPILL), 8);
+ }
+
+ int
+ getSize(MemorySegment segment) const
+ {
+ Brig::BrigSegment brigSeg;
+
+ switch (segment) {
+ case MemorySegment::NONE:
+ brigSeg = Brig::BRIG_SEGMENT_NONE;
+ break;
+ case MemorySegment::FLAT:
+ brigSeg = Brig::BRIG_SEGMENT_FLAT;
+ break;
+ case MemorySegment::GLOBAL:
+ brigSeg = Brig::BRIG_SEGMENT_GLOBAL;
+ break;
+ case MemorySegment::READONLY:
+ brigSeg = Brig::BRIG_SEGMENT_READONLY;
+ break;
+ case MemorySegment::KERNARG:
+ brigSeg = Brig::BRIG_SEGMENT_KERNARG;
+ break;
+ case MemorySegment::GROUP:
+ brigSeg = Brig::BRIG_SEGMENT_GROUP;
+ break;
+ case MemorySegment::PRIVATE:
+ brigSeg = Brig::BRIG_SEGMENT_PRIVATE;
+ break;
+ case MemorySegment::SPILL:
+ brigSeg = Brig::BRIG_SEGMENT_SPILL;
+ break;
+ case MemorySegment::ARG:
+ brigSeg = Brig::BRIG_SEGMENT_ARG;
+ break;
+ case MemorySegment::EXTSPACE0:
+ brigSeg = Brig::BRIG_SEGMENT_AMD_GCN;
+ break;
+ default:
+ fatal("Unknown BrigSegment type.\n");
+ }
+
+ return getSize(brigSeg);
+ }
+
+ private:
+ int
+ getSize(Brig::BrigSegment segment) const
+ {
+ if (segment == Brig::BRIG_SEGMENT_PRIVATE) {
+ // with the code generated by new HSA compiler the assertion
+ // does not hold anymore..
+ //assert(private_size != -1);
+ return private_size;
+ } else {
+ return storageMap->getSize(segment);
+ }
+ }
+
+ public:
+ StorageElement*
+ findSymbol(Brig::BrigSegment segment, uint64_t addr)
+ {
+ return storageMap->findSymbol(segment, addr);
+ }
+
+ void
+ setPrivateSize(int32_t _private_size)
+ {
+ private_size = _private_size;
+ }
+
+ Label*
+ refLabel(const Brig::BrigDirectiveLabel *lbl, const BrigObject *obj)
+ {
+ return labelMap.refLabel(lbl, obj);
+ }
+};
+
+#endif // __HSAIL_CODE_HH__