111308Santhony.gutierrez@amd.com/*
211308Santhony.gutierrez@amd.com * Copyright (c) 2012-2015 Advanced Micro Devices, Inc.
311308Santhony.gutierrez@amd.com * All rights reserved.
411308Santhony.gutierrez@amd.com *
511308Santhony.gutierrez@amd.com * For use for simulation and test purposes only
611308Santhony.gutierrez@amd.com *
711308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without
811308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are met:
911308Santhony.gutierrez@amd.com *
1011308Santhony.gutierrez@amd.com * 1. Redistributions of source code must retain the above copyright notice,
1111308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer.
1211308Santhony.gutierrez@amd.com *
1311308Santhony.gutierrez@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice,
1411308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer in the documentation
1511308Santhony.gutierrez@amd.com * and/or other materials provided with the distribution.
1611308Santhony.gutierrez@amd.com *
1711308Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its contributors
1811308Santhony.gutierrez@amd.com * may be used to endorse or promote products derived from this software
1911308Santhony.gutierrez@amd.com * without specific prior written permission.
2011308Santhony.gutierrez@amd.com *
2111308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2211308Santhony.gutierrez@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2311308Santhony.gutierrez@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2411308Santhony.gutierrez@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2511308Santhony.gutierrez@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2611308Santhony.gutierrez@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2711308Santhony.gutierrez@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2811308Santhony.gutierrez@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2911308Santhony.gutierrez@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3011308Santhony.gutierrez@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3111308Santhony.gutierrez@amd.com * POSSIBILITY OF SUCH DAMAGE.
3211308Santhony.gutierrez@amd.com *
3311308Santhony.gutierrez@amd.com * Author: Steve Reinhardt, Anthony Gutierrez
3411308Santhony.gutierrez@amd.com */
3511308Santhony.gutierrez@amd.com
3611308Santhony.gutierrez@amd.com#include "gpu-compute/brig_object.hh"
3711308Santhony.gutierrez@amd.com
3811308Santhony.gutierrez@amd.com#include <fcntl.h>
3911308Santhony.gutierrez@amd.com#include <sys/mman.h>
4011308Santhony.gutierrez@amd.com#include <sys/types.h>
4111308Santhony.gutierrez@amd.com#include <unistd.h>
4211308Santhony.gutierrez@amd.com
4311308Santhony.gutierrez@amd.com#include <cassert>
4411308Santhony.gutierrez@amd.com#include <cstddef>
4511308Santhony.gutierrez@amd.com#include <cstdlib>
4611308Santhony.gutierrez@amd.com
4711308Santhony.gutierrez@amd.com#include "arch/hsail/Brig.h"
4812334Sgabeblack@google.com#include "base/logging.hh"
4911308Santhony.gutierrez@amd.com#include "base/trace.hh"
5011308Santhony.gutierrez@amd.com#include "debug/BRIG.hh"
5111308Santhony.gutierrez@amd.com#include "debug/HSAILObject.hh"
5211308Santhony.gutierrez@amd.com#include "debug/HSALoader.hh"
5311308Santhony.gutierrez@amd.com
5411308Santhony.gutierrez@amd.comusing namespace Brig;
5511308Santhony.gutierrez@amd.com
5611308Santhony.gutierrez@amd.comstd::vector<std::function<HsaObject*(const std::string&, int, uint8_t*)>>
5711308Santhony.gutierrez@amd.com    HsaObject::tryFileFuncs = { BrigObject::tryFile };
5811308Santhony.gutierrez@amd.com
5911308Santhony.gutierrez@amd.comextern int getBrigDataTypeBytes(BrigType16_t t);
6011308Santhony.gutierrez@amd.com
6111308Santhony.gutierrez@amd.comconst char *BrigObject::sectionNames[] =
6211308Santhony.gutierrez@amd.com{
6311308Santhony.gutierrez@amd.com    "hsa_data",
6411308Santhony.gutierrez@amd.com    "hsa_code",
6511308Santhony.gutierrez@amd.com    "hsa_operand",
6611308Santhony.gutierrez@amd.com    ".shstrtab"
6711308Santhony.gutierrez@amd.com};
6811308Santhony.gutierrez@amd.com
6911308Santhony.gutierrez@amd.comconst char *segmentNames[] =
7011308Santhony.gutierrez@amd.com{
7111308Santhony.gutierrez@amd.com    "none",
7211308Santhony.gutierrez@amd.com    "flat",
7311308Santhony.gutierrez@amd.com    "global",
7411308Santhony.gutierrez@amd.com    "readonly",
7511308Santhony.gutierrez@amd.com    "kernarg",
7611308Santhony.gutierrez@amd.com    "group",
7711308Santhony.gutierrez@amd.com    "private",
7811308Santhony.gutierrez@amd.com    "spill",
7911308Santhony.gutierrez@amd.com    "args"
8011308Santhony.gutierrez@amd.com};
8111308Santhony.gutierrez@amd.com
8211308Santhony.gutierrez@amd.comconst uint8_t*
8311308Santhony.gutierrez@amd.comBrigObject::getSectionOffset(enum SectionIndex sec, int offs) const
8411308Santhony.gutierrez@amd.com{
8511308Santhony.gutierrez@amd.com    // allow offs == size for dummy end pointers
8611308Santhony.gutierrez@amd.com    assert(offs <= sectionInfo[sec].size);
8711308Santhony.gutierrez@amd.com
8811308Santhony.gutierrez@amd.com    return sectionInfo[sec].ptr + offs;
8911308Santhony.gutierrez@amd.com}
9011308Santhony.gutierrez@amd.com
9111308Santhony.gutierrez@amd.comconst char*
9211308Santhony.gutierrez@amd.comBrigObject::getString(int offs) const
9311308Santhony.gutierrez@amd.com{
9411308Santhony.gutierrez@amd.com    return (const char*)(getSectionOffset(DataSectionIndex, offs) + 4);
9511308Santhony.gutierrez@amd.com}
9611308Santhony.gutierrez@amd.com
9711308Santhony.gutierrez@amd.comconst BrigBase*
9811308Santhony.gutierrez@amd.comBrigObject::getCodeSectionEntry(int offs) const
9911308Santhony.gutierrez@amd.com{
10011308Santhony.gutierrez@amd.com    return (const BrigBase*)getSectionOffset(CodeSectionIndex, offs);
10111308Santhony.gutierrez@amd.com}
10211308Santhony.gutierrez@amd.com
10311308Santhony.gutierrez@amd.comconst BrigData*
10411308Santhony.gutierrez@amd.comBrigObject::getBrigBaseData(int offs) const
10511308Santhony.gutierrez@amd.com{
10611308Santhony.gutierrez@amd.com    return (Brig::BrigData*)(getSectionOffset(DataSectionIndex, offs));
10711308Santhony.gutierrez@amd.com}
10811308Santhony.gutierrez@amd.com
10911308Santhony.gutierrez@amd.comconst uint8_t*
11011308Santhony.gutierrez@amd.comBrigObject::getData(int offs) const
11111308Santhony.gutierrez@amd.com{
11211308Santhony.gutierrez@amd.com    return getSectionOffset(DataSectionIndex, offs);
11311308Santhony.gutierrez@amd.com}
11411308Santhony.gutierrez@amd.com
11511308Santhony.gutierrez@amd.comconst BrigOperand*
11611308Santhony.gutierrez@amd.comBrigObject::getOperand(int offs) const
11711308Santhony.gutierrez@amd.com{
11811308Santhony.gutierrez@amd.com    return (const BrigOperand*)getSectionOffset(OperandsSectionIndex, offs);
11911308Santhony.gutierrez@amd.com}
12011308Santhony.gutierrez@amd.com
12111308Santhony.gutierrez@amd.comunsigned
12211308Santhony.gutierrez@amd.comBrigObject::getOperandPtr(int offs, int index) const
12311308Santhony.gutierrez@amd.com{
12411308Santhony.gutierrez@amd.com    unsigned *op_offs = (unsigned*)(getData(offs + 4 * (index + 1)));
12511308Santhony.gutierrez@amd.com
12611308Santhony.gutierrez@amd.com    return *op_offs;
12711308Santhony.gutierrez@amd.com}
12811308Santhony.gutierrez@amd.com
12911308Santhony.gutierrez@amd.comconst BrigInstBase*
13011308Santhony.gutierrez@amd.comBrigObject::getInst(int offs) const
13111308Santhony.gutierrez@amd.com{
13211308Santhony.gutierrez@amd.com    return (const BrigInstBase*)getSectionOffset(CodeSectionIndex, offs);
13311308Santhony.gutierrez@amd.com}
13411308Santhony.gutierrez@amd.com
13511308Santhony.gutierrez@amd.comHsaCode*
13611308Santhony.gutierrez@amd.comBrigObject::getKernel(const std::string &name) const
13711308Santhony.gutierrez@amd.com{
13811308Santhony.gutierrez@amd.com    return nullptr;
13911308Santhony.gutierrez@amd.com}
14011308Santhony.gutierrez@amd.com
14111308Santhony.gutierrez@amd.comHsaCode*
14211308Santhony.gutierrez@amd.comBrigObject::getFunction(const std::string &name) const
14311308Santhony.gutierrez@amd.com{
14411308Santhony.gutierrez@amd.com    for (int i = 0; i < functions.size(); ++i) {
14511308Santhony.gutierrez@amd.com        if (functions[i]->name() == name) {
14611308Santhony.gutierrez@amd.com            return functions[i];
14711308Santhony.gutierrez@amd.com        }
14811308Santhony.gutierrez@amd.com    }
14911308Santhony.gutierrez@amd.com
15011308Santhony.gutierrez@amd.com    return nullptr;
15111308Santhony.gutierrez@amd.com}
15211308Santhony.gutierrez@amd.com
15311308Santhony.gutierrez@amd.comvoid
15411308Santhony.gutierrez@amd.comBrigObject::processDirectives(const BrigBase *dirPtr, const BrigBase *endPtr,
15511308Santhony.gutierrez@amd.com                              StorageMap *storageMap)
15611308Santhony.gutierrez@amd.com{
15711308Santhony.gutierrez@amd.com    while (dirPtr < endPtr) {
15811308Santhony.gutierrez@amd.com        if (!dirPtr->byteCount) {
15911308Santhony.gutierrez@amd.com            fatal("Bad directive size 0\n");
16011308Santhony.gutierrez@amd.com        }
16111308Santhony.gutierrez@amd.com
16211308Santhony.gutierrez@amd.com        // calculate next pointer now so we can override it if needed
16311308Santhony.gutierrez@amd.com        const BrigBase *nextDirPtr = brigNext(dirPtr);
16411308Santhony.gutierrez@amd.com
16511308Santhony.gutierrez@amd.com        DPRINTF(HSAILObject, "Code section entry kind: #%x, byte count: %d\n",
16611308Santhony.gutierrez@amd.com                dirPtr->kind, dirPtr->byteCount);
16711308Santhony.gutierrez@amd.com
16811308Santhony.gutierrez@amd.com        switch (dirPtr->kind) {
16911308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_FUNCTION:
17011308Santhony.gutierrez@amd.com            {
17111308Santhony.gutierrez@amd.com                const BrigDirectiveExecutable *p M5_VAR_USED =
17211308Santhony.gutierrez@amd.com                    reinterpret_cast<const BrigDirectiveExecutable*>(dirPtr);
17311308Santhony.gutierrez@amd.com
17411308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject,"DIRECTIVE_FUNCTION: %s offset: "
17511308Santhony.gutierrez@amd.com                        "%d next: %d\n", getString(p->name),
17611308Santhony.gutierrez@amd.com                        p->firstCodeBlockEntry, p->nextModuleEntry);
17711308Santhony.gutierrez@amd.com
17811308Santhony.gutierrez@amd.com                if (p->firstCodeBlockEntry != p->nextModuleEntry) {
17911734Sbrandon.potter@amd.com                    // Function calls are not supported. We allow the BRIG
18011734Sbrandon.potter@amd.com                    // object file to create stubs, but the function calls will
18111734Sbrandon.potter@amd.com                    // not work properly if the application makes use of them.
18211734Sbrandon.potter@amd.com                    warn("HSA function invocations are unsupported.\n");
18311308Santhony.gutierrez@amd.com
18411308Santhony.gutierrez@amd.com                    const char *name = getString(p->name);
18511308Santhony.gutierrez@amd.com
18611308Santhony.gutierrez@amd.com                    HsailCode *code_obj = nullptr;
18711308Santhony.gutierrez@amd.com
18811308Santhony.gutierrez@amd.com                    for (int i = 0; i < functions.size(); ++i) {
18911308Santhony.gutierrez@amd.com                        if (functions[i]->name() == name) {
19011308Santhony.gutierrez@amd.com                            code_obj = functions[i];
19111308Santhony.gutierrez@amd.com                            break;
19211308Santhony.gutierrez@amd.com                        }
19311308Santhony.gutierrez@amd.com                    }
19411308Santhony.gutierrez@amd.com
19511308Santhony.gutierrez@amd.com                    if (!code_obj) {
19611308Santhony.gutierrez@amd.com                        // create new local storage map for kernel-local symbols
19711308Santhony.gutierrez@amd.com                        code_obj = new HsailCode(name, p, this,
19811308Santhony.gutierrez@amd.com                                                 new StorageMap(storageMap));
19911308Santhony.gutierrez@amd.com                        functions.push_back(code_obj);
20011308Santhony.gutierrez@amd.com                    } else {
20111308Santhony.gutierrez@amd.com                        panic("Multiple definition of Function!!: %s\n",
20211308Santhony.gutierrez@amd.com                              getString(p->name));
20311308Santhony.gutierrez@amd.com                    }
20411734Sbrandon.potter@amd.com                }
20511308Santhony.gutierrez@amd.com
20611308Santhony.gutierrez@amd.com                nextDirPtr = getCodeSectionEntry(p->nextModuleEntry);
20711308Santhony.gutierrez@amd.com            }
20811308Santhony.gutierrez@amd.com            break;
20911308Santhony.gutierrez@amd.com
21011308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_KERNEL:
21111308Santhony.gutierrez@amd.com            {
21211308Santhony.gutierrez@amd.com                const BrigDirectiveExecutable *p =
21311308Santhony.gutierrez@amd.com                    reinterpret_cast<const BrigDirectiveExecutable*>(dirPtr);
21411308Santhony.gutierrez@amd.com
21511308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject,"DIRECTIVE_KERNEL: %s offset: %d count: "
21611308Santhony.gutierrez@amd.com                        "next: %d\n", getString(p->name),
21711308Santhony.gutierrez@amd.com                        p->firstCodeBlockEntry, p->nextModuleEntry);
21811308Santhony.gutierrez@amd.com
21911308Santhony.gutierrez@amd.com                const char *name = getString(p->name);
22011308Santhony.gutierrez@amd.com
22111308Santhony.gutierrez@amd.com                if (name[0] == '&')
22211308Santhony.gutierrez@amd.com                    name++;
22311308Santhony.gutierrez@amd.com
22411308Santhony.gutierrez@amd.com                std::string str = name;
22511308Santhony.gutierrez@amd.com                char *temp;
22611308Santhony.gutierrez@amd.com                int len = str.length();
22711308Santhony.gutierrez@amd.com
22811308Santhony.gutierrez@amd.com                if (str[len - 1] >= 'a' && str[len - 1] <= 'z') {
22911308Santhony.gutierrez@amd.com                    temp = new char[str.size() + 1];
23011308Santhony.gutierrez@amd.com                    std::copy(str.begin(), str.end() , temp);
23111308Santhony.gutierrez@amd.com                    temp[str.size()] = '\0';
23211308Santhony.gutierrez@amd.com                } else {
23311308Santhony.gutierrez@amd.com                    temp = new char[str.size()];
23411308Santhony.gutierrez@amd.com                    std::copy(str.begin(), str.end() - 1 , temp);
23511308Santhony.gutierrez@amd.com                    temp[str.size() - 1 ] = '\0';
23611308Santhony.gutierrez@amd.com                }
23711308Santhony.gutierrez@amd.com
23811308Santhony.gutierrez@amd.com                std::string kernel_name = temp;
23911308Santhony.gutierrez@amd.com                delete[] temp;
24011308Santhony.gutierrez@amd.com
24111308Santhony.gutierrez@amd.com                HsailCode *code_obj = nullptr;
24211308Santhony.gutierrez@amd.com
24311308Santhony.gutierrez@amd.com                for (const auto &kernel : kernels) {
24411308Santhony.gutierrez@amd.com                    if (kernel->name() == kernel_name) {
24511308Santhony.gutierrez@amd.com                        code_obj = kernel;
24611308Santhony.gutierrez@amd.com                        break;
24711308Santhony.gutierrez@amd.com                    }
24811308Santhony.gutierrez@amd.com                }
24911308Santhony.gutierrez@amd.com
25011308Santhony.gutierrez@amd.com                if (!code_obj) {
25111308Santhony.gutierrez@amd.com                    // create new local storage map for kernel-local symbols
25211308Santhony.gutierrez@amd.com                    code_obj = new HsailCode(kernel_name, p, this,
25311308Santhony.gutierrez@amd.com                                             new StorageMap(storageMap));
25411308Santhony.gutierrez@amd.com
25511308Santhony.gutierrez@amd.com                    kernels.push_back(code_obj);
25611308Santhony.gutierrez@amd.com                }
25711308Santhony.gutierrez@amd.com
25811308Santhony.gutierrez@amd.com                nextDirPtr = getCodeSectionEntry(p->nextModuleEntry);
25911308Santhony.gutierrez@amd.com            }
26011308Santhony.gutierrez@amd.com            break;
26111308Santhony.gutierrez@amd.com
26211308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_VARIABLE:
26311308Santhony.gutierrez@amd.com            {
26411308Santhony.gutierrez@amd.com                const BrigDirectiveVariable *p =
26511308Santhony.gutierrez@amd.com                    reinterpret_cast<const BrigDirectiveVariable*>(dirPtr);
26611308Santhony.gutierrez@amd.com
26711308Santhony.gutierrez@amd.com                uint64_t readonlySize_old =
26811308Santhony.gutierrez@amd.com                    storageMap->getSize(BRIG_SEGMENT_READONLY);
26911308Santhony.gutierrez@amd.com
27011308Santhony.gutierrez@amd.com                StorageElement* se = storageMap->addSymbol(p, this);
27111308Santhony.gutierrez@amd.com
27211308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject, "DIRECTIVE_VARIABLE, symbol %s\n",
27311308Santhony.gutierrez@amd.com                        getString(p->name));
27411308Santhony.gutierrez@amd.com
27511308Santhony.gutierrez@amd.com                if (p->segment == BRIG_SEGMENT_READONLY) {
27611308Santhony.gutierrez@amd.com                    // readonly memory has initialization data
27711308Santhony.gutierrez@amd.com                    uint8_t* readonlyData_old = readonlyData;
27811308Santhony.gutierrez@amd.com
27911308Santhony.gutierrez@amd.com                    readonlyData =
28011308Santhony.gutierrez@amd.com                        new uint8_t[storageMap->getSize(BRIG_SEGMENT_READONLY)];
28111308Santhony.gutierrez@amd.com
28211308Santhony.gutierrez@amd.com                    if (p->init) {
28311308Santhony.gutierrez@amd.com                        if ((p->type == BRIG_TYPE_ROIMG) ||
28411308Santhony.gutierrez@amd.com                            (p->type == BRIG_TYPE_WOIMG) ||
28511308Santhony.gutierrez@amd.com                            (p->type == BRIG_TYPE_SAMP) ||
28611308Santhony.gutierrez@amd.com                            (p->type == BRIG_TYPE_SIG32) ||
28711308Santhony.gutierrez@amd.com                            (p->type == BRIG_TYPE_SIG64)) {
28811308Santhony.gutierrez@amd.com                            panic("Read only data type not supported: %s\n",
28911308Santhony.gutierrez@amd.com                                  getString(p->name));
29011308Santhony.gutierrez@amd.com                        }
29111308Santhony.gutierrez@amd.com
29211308Santhony.gutierrez@amd.com                        const BrigOperand *brigOp = getOperand(p->init);
29311308Santhony.gutierrez@amd.com                        assert(brigOp->kind ==
29411308Santhony.gutierrez@amd.com                               BRIG_KIND_OPERAND_CONSTANT_BYTES);
29511308Santhony.gutierrez@amd.com
29611308Santhony.gutierrez@amd.com                        const Brig::BrigData *operand_data M5_VAR_USED =
29711308Santhony.gutierrez@amd.com                            getBrigBaseData(((BrigOperandConstantBytes*)
29811308Santhony.gutierrez@amd.com                                            brigOp)->bytes);
29911308Santhony.gutierrez@amd.com
30011308Santhony.gutierrez@amd.com                        assert((operand_data->byteCount / 4) > 0);
30111308Santhony.gutierrez@amd.com
30211308Santhony.gutierrez@amd.com                        uint8_t *symbol_data =
30311308Santhony.gutierrez@amd.com                            (uint8_t*)getData(((BrigOperandConstantBytes*)
30411308Santhony.gutierrez@amd.com                                              brigOp)->bytes + 4);
30511308Santhony.gutierrez@amd.com
30611308Santhony.gutierrez@amd.com                        // copy the old data and add the new data
30711308Santhony.gutierrez@amd.com                        if (readonlySize_old > 0) {
30811308Santhony.gutierrez@amd.com                            memcpy(readonlyData, readonlyData_old,
30911308Santhony.gutierrez@amd.com                                   readonlySize_old);
31011308Santhony.gutierrez@amd.com                        }
31111308Santhony.gutierrez@amd.com
31211308Santhony.gutierrez@amd.com                        memcpy(readonlyData + se->offset, symbol_data,
31311308Santhony.gutierrez@amd.com                               se->size);
31411308Santhony.gutierrez@amd.com
31511308Santhony.gutierrez@amd.com                        delete[] readonlyData_old;
31611308Santhony.gutierrez@amd.com                   }
31711308Santhony.gutierrez@amd.com                }
31811308Santhony.gutierrez@amd.com            }
31911308Santhony.gutierrez@amd.com            break;
32011308Santhony.gutierrez@amd.com
32111308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_LABEL:
32211308Santhony.gutierrez@amd.com            {
32311308Santhony.gutierrez@amd.com              const BrigDirectiveLabel M5_VAR_USED *p =
32411308Santhony.gutierrez@amd.com                    reinterpret_cast<const BrigDirectiveLabel*>(dirPtr);
32511308Santhony.gutierrez@amd.com
32611308Santhony.gutierrez@amd.com              panic("Label directives cannot be at the module level: %s\n",
32711308Santhony.gutierrez@amd.com                    getString(p->name));
32811308Santhony.gutierrez@amd.com
32911308Santhony.gutierrez@amd.com            }
33011308Santhony.gutierrez@amd.com            break;
33111308Santhony.gutierrez@amd.com
33211308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_COMMENT:
33311308Santhony.gutierrez@amd.com            {
33411308Santhony.gutierrez@amd.com              const BrigDirectiveComment M5_VAR_USED *p =
33511308Santhony.gutierrez@amd.com                  reinterpret_cast<const BrigDirectiveComment*>(dirPtr);
33611308Santhony.gutierrez@amd.com
33711308Santhony.gutierrez@amd.com              DPRINTF(HSAILObject, "DIRECTIVE_COMMENT: %s\n",
33811308Santhony.gutierrez@amd.com                      getString(p->name));
33911308Santhony.gutierrez@amd.com            }
34011308Santhony.gutierrez@amd.com            break;
34111308Santhony.gutierrez@amd.com
34211308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_LOC:
34311308Santhony.gutierrez@amd.com            {
34411308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject, "BRIG_DIRECTIVE_LOC\n");
34511308Santhony.gutierrez@amd.com            }
34611308Santhony.gutierrez@amd.com            break;
34711308Santhony.gutierrez@amd.com
34811308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_MODULE:
34911308Santhony.gutierrez@amd.com            {
35011308Santhony.gutierrez@amd.com                const BrigDirectiveModule M5_VAR_USED *p =
35111308Santhony.gutierrez@amd.com                    reinterpret_cast<const BrigDirectiveModule*>(dirPtr);
35211308Santhony.gutierrez@amd.com
35311308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject, "BRIG_DIRECTIVE_MODULE: %s\n",
35411308Santhony.gutierrez@amd.com                        getString(p->name));
35511308Santhony.gutierrez@amd.com            }
35611308Santhony.gutierrez@amd.com            break;
35711308Santhony.gutierrez@amd.com
35811308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_CONTROL:
35911308Santhony.gutierrez@amd.com            {
36011308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject, "DIRECTIVE_CONTROL\n");
36111308Santhony.gutierrez@amd.com            }
36211308Santhony.gutierrez@amd.com            break;
36311308Santhony.gutierrez@amd.com
36411308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_PRAGMA:
36511308Santhony.gutierrez@amd.com            {
36611308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject, "DIRECTIVE_PRAGMA\n");
36711308Santhony.gutierrez@amd.com            }
36811308Santhony.gutierrez@amd.com            break;
36911308Santhony.gutierrez@amd.com
37011308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_EXTENSION:
37111308Santhony.gutierrez@amd.com            {
37211308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject, "DIRECTIVE_EXTENSION\n");
37311308Santhony.gutierrez@amd.com            }
37411308Santhony.gutierrez@amd.com            break;
37511308Santhony.gutierrez@amd.com
37611308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_ARG_BLOCK_START:
37711308Santhony.gutierrez@amd.com            {
37811308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject, "DIRECTIVE_ARG_BLOCK_START\n");
37911308Santhony.gutierrez@amd.com            }
38011308Santhony.gutierrez@amd.com            break;
38111308Santhony.gutierrez@amd.com
38211308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_ARG_BLOCK_END:
38311308Santhony.gutierrez@amd.com            {
38411308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject, "DIRECTIVE_ARG_BLOCK_END\n");
38511308Santhony.gutierrez@amd.com            }
38611308Santhony.gutierrez@amd.com            break;
38711308Santhony.gutierrez@amd.com          default:
38811308Santhony.gutierrez@amd.com            if (dirPtr->kind >= BRIG_KIND_INST_BEGIN &&
38911308Santhony.gutierrez@amd.com                dirPtr->kind <= BRIG_KIND_INST_END)
39011308Santhony.gutierrez@amd.com                break;
39111308Santhony.gutierrez@amd.com
39211308Santhony.gutierrez@amd.com            if (dirPtr->kind >= BRIG_KIND_OPERAND_BEGIN &&
39311308Santhony.gutierrez@amd.com                dirPtr->kind <= BRIG_KIND_OPERAND_END)
39411308Santhony.gutierrez@amd.com                break;
39511308Santhony.gutierrez@amd.com
39611308Santhony.gutierrez@amd.com            warn("Unknown Brig directive kind: %d\n", dirPtr->kind);
39711308Santhony.gutierrez@amd.com            break;
39811308Santhony.gutierrez@amd.com        }
39911308Santhony.gutierrez@amd.com
40011308Santhony.gutierrez@amd.com        dirPtr = nextDirPtr;
40111308Santhony.gutierrez@amd.com    }
40211308Santhony.gutierrez@amd.com}
40311308Santhony.gutierrez@amd.com
40411308Santhony.gutierrez@amd.comHsaObject*
40511308Santhony.gutierrez@amd.comBrigObject::tryFile(const std::string &fname, int len, uint8_t *fileData)
40611308Santhony.gutierrez@amd.com{
40711308Santhony.gutierrez@amd.com    const char *brig_ident = "HSA BRIG";
40811308Santhony.gutierrez@amd.com
40911308Santhony.gutierrez@amd.com    if (memcmp(brig_ident, fileData, MODULE_IDENTIFICATION_LENGTH))
41011308Santhony.gutierrez@amd.com        return nullptr;
41111308Santhony.gutierrez@amd.com
41211308Santhony.gutierrez@amd.com    return new BrigObject(fname, len, fileData);
41311308Santhony.gutierrez@amd.com}
41411308Santhony.gutierrez@amd.com
41511308Santhony.gutierrez@amd.comBrigObject::BrigObject(const std::string &fname, int len, uint8_t *fileData)
41611308Santhony.gutierrez@amd.com    : HsaObject(fname), storageMap(new StorageMap())
41711308Santhony.gutierrez@amd.com{
41811308Santhony.gutierrez@amd.com    const char *brig_ident = "HSA BRIG";
41911308Santhony.gutierrez@amd.com    BrigModuleHeader *mod_hdr = (BrigModuleHeader*)fileData;
42011308Santhony.gutierrez@amd.com
42111308Santhony.gutierrez@amd.com    fatal_if(memcmp(brig_ident, mod_hdr, MODULE_IDENTIFICATION_LENGTH),
42211308Santhony.gutierrez@amd.com             "%s is not a BRIG file\n", fname);
42311308Santhony.gutierrez@amd.com
42411308Santhony.gutierrez@amd.com    if (mod_hdr->brigMajor != BRIG_VERSION_BRIG_MAJOR ||
42511308Santhony.gutierrez@amd.com        mod_hdr->brigMinor != BRIG_VERSION_BRIG_MINOR) {
42611308Santhony.gutierrez@amd.com        fatal("%s: BRIG version mismatch, %d.%d != %d.%d\n",
42711308Santhony.gutierrez@amd.com              fname, mod_hdr->brigMajor, mod_hdr->brigMinor,
42811308Santhony.gutierrez@amd.com              BRIG_VERSION_BRIG_MAJOR, BRIG_VERSION_BRIG_MINOR);
42911308Santhony.gutierrez@amd.com    }
43011308Santhony.gutierrez@amd.com
43111308Santhony.gutierrez@amd.com    fatal_if(mod_hdr->sectionCount != NumSectionIndices, "%s: BRIG section "
43211308Santhony.gutierrez@amd.com             "count (%d) != expected value (%d)\n", fname,
43311308Santhony.gutierrez@amd.com             mod_hdr->sectionCount, NumSectionIndices);
43411308Santhony.gutierrez@amd.com
43511308Santhony.gutierrez@amd.com    for (int i = 0; i < NumSectionIndices; ++i) {
43611308Santhony.gutierrez@amd.com        sectionInfo[i].ptr = nullptr;
43711308Santhony.gutierrez@amd.com    }
43811308Santhony.gutierrez@amd.com
43911308Santhony.gutierrez@amd.com    uint64_t *sec_idx_table = (uint64_t*)(fileData + mod_hdr->sectionIndex);
44011308Santhony.gutierrez@amd.com    for (int sec_idx = 0; sec_idx < mod_hdr->sectionCount; ++sec_idx) {
44111308Santhony.gutierrez@amd.com        uint8_t *sec_hdr_byte_ptr = fileData + sec_idx_table[sec_idx];
44211308Santhony.gutierrez@amd.com        BrigSectionHeader *sec_hdr = (BrigSectionHeader*)sec_hdr_byte_ptr;
44311308Santhony.gutierrez@amd.com
44411308Santhony.gutierrez@amd.com        // It doesn't look like cprintf supports string precision values,
44511308Santhony.gutierrez@amd.com        // but if this breaks, the right answer is to fix that
44611308Santhony.gutierrez@amd.com        DPRINTF(HSAILObject, "found section %.*s\n", sec_hdr->nameLength,
44711308Santhony.gutierrez@amd.com                sec_hdr->name);
44811308Santhony.gutierrez@amd.com
44911308Santhony.gutierrez@amd.com        sectionInfo[sec_idx].ptr = new uint8_t[sec_hdr->byteCount];
45011308Santhony.gutierrez@amd.com        memcpy(sectionInfo[sec_idx].ptr, sec_hdr_byte_ptr, sec_hdr->byteCount);
45111308Santhony.gutierrez@amd.com        sectionInfo[sec_idx].size = sec_hdr->byteCount;
45211308Santhony.gutierrez@amd.com    }
45311308Santhony.gutierrez@amd.com
45411308Santhony.gutierrez@amd.com    BrigSectionHeader *code_hdr =
45511308Santhony.gutierrez@amd.com        (BrigSectionHeader*)sectionInfo[CodeSectionIndex].ptr;
45611308Santhony.gutierrez@amd.com
45711308Santhony.gutierrez@amd.com    DPRINTF(HSAILObject, "Code section hdr, count: %d, hdr count: %d, "
45811308Santhony.gutierrez@amd.com            "name len: %d\n", code_hdr->byteCount, code_hdr->headerByteCount,
45911308Santhony.gutierrez@amd.com            code_hdr->nameLength);
46011308Santhony.gutierrez@amd.com
46111308Santhony.gutierrez@amd.com    // start at offset 4 to skip initial null entry (see Brig spec)
46211308Santhony.gutierrez@amd.com    processDirectives(getCodeSectionEntry(code_hdr->headerByteCount),
46311308Santhony.gutierrez@amd.com                      getCodeSectionEntry(sectionInfo[CodeSectionIndex].size),
46411308Santhony.gutierrez@amd.com                      storageMap);
46511308Santhony.gutierrez@amd.com
46611308Santhony.gutierrez@amd.com    delete[] fileData;
46711308Santhony.gutierrez@amd.com
46811308Santhony.gutierrez@amd.com    DPRINTF(HSALoader, "BRIG object %s loaded.\n", fname);
46911308Santhony.gutierrez@amd.com}
47011308Santhony.gutierrez@amd.com
47111308Santhony.gutierrez@amd.comBrigObject::~BrigObject()
47211308Santhony.gutierrez@amd.com{
47311308Santhony.gutierrez@amd.com    for (int i = 0; i < NumSectionIndices; ++i)
47411308Santhony.gutierrez@amd.com        if (sectionInfo[i].ptr)
47511308Santhony.gutierrez@amd.com            delete[] sectionInfo[i].ptr;
47611308Santhony.gutierrez@amd.com}
477