hsail_code.cc revision 11308
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
3411308Santhony.gutierrez@amd.com */
3511308Santhony.gutierrez@amd.com
3611308Santhony.gutierrez@amd.com#include "gpu-compute/hsail_code.hh"
3711308Santhony.gutierrez@amd.com
3811308Santhony.gutierrez@amd.com#include "arch/gpu_types.hh"
3911308Santhony.gutierrez@amd.com#include "arch/hsail/Brig.h"
4011308Santhony.gutierrez@amd.com#include "arch/hsail/operand.hh"
4111308Santhony.gutierrez@amd.com#include "config/the_gpu_isa.hh"
4211308Santhony.gutierrez@amd.com#include "debug/BRIG.hh"
4311308Santhony.gutierrez@amd.com#include "debug/HSAILObject.hh"
4411308Santhony.gutierrez@amd.com#include "gpu-compute/brig_object.hh"
4511308Santhony.gutierrez@amd.com#include "gpu-compute/gpu_static_inst.hh"
4611308Santhony.gutierrez@amd.com#include "gpu-compute/kernel_cfg.hh"
4711308Santhony.gutierrez@amd.com
4811308Santhony.gutierrez@amd.comusing namespace Brig;
4911308Santhony.gutierrez@amd.com
5011308Santhony.gutierrez@amd.comint getBrigDataTypeBytes(BrigType16_t t);
5111308Santhony.gutierrez@amd.com
5211308Santhony.gutierrez@amd.comHsailCode::HsailCode(const std::string &name_str)
5311308Santhony.gutierrez@amd.com    : HsaCode(name_str), private_size(-1), readonly_size(-1)
5411308Santhony.gutierrez@amd.com{
5511308Santhony.gutierrez@amd.com}
5611308Santhony.gutierrez@amd.com
5711308Santhony.gutierrez@amd.comvoid
5811308Santhony.gutierrez@amd.comHsailCode::init(const BrigDirectiveExecutable *code_dir, const BrigObject *obj,
5911308Santhony.gutierrez@amd.com                StorageMap *objStorageMap)
6011308Santhony.gutierrez@amd.com{
6111308Santhony.gutierrez@amd.com    storageMap = objStorageMap;
6211308Santhony.gutierrez@amd.com
6311308Santhony.gutierrez@amd.com    // set pointer so that decoding process can find this kernel context when
6411308Santhony.gutierrez@amd.com    // needed
6511308Santhony.gutierrez@amd.com    obj->currentCode = this;
6611308Santhony.gutierrez@amd.com
6711308Santhony.gutierrez@amd.com    if (code_dir->base.kind != BRIG_KIND_DIRECTIVE_FUNCTION &&
6811308Santhony.gutierrez@amd.com        code_dir->base.kind != BRIG_KIND_DIRECTIVE_KERNEL) {
6911308Santhony.gutierrez@amd.com        fatal("unexpected directive kind %d inside kernel/function init\n",
7011308Santhony.gutierrez@amd.com              code_dir->base.kind);
7111308Santhony.gutierrez@amd.com    }
7211308Santhony.gutierrez@amd.com
7311308Santhony.gutierrez@amd.com    DPRINTF(HSAILObject, "Initializing code, first code block entry is: %d\n",
7411308Santhony.gutierrez@amd.com            code_dir->firstCodeBlockEntry);
7511308Santhony.gutierrez@amd.com
7611308Santhony.gutierrez@amd.com    // clear these static vars so we can properly track the max index
7711308Santhony.gutierrez@amd.com    // for this kernel
7811308Santhony.gutierrez@amd.com    SRegOperand::maxRegIdx = 0;
7911308Santhony.gutierrez@amd.com    DRegOperand::maxRegIdx = 0;
8011308Santhony.gutierrez@amd.com    CRegOperand::maxRegIdx = 0;
8111308Santhony.gutierrez@amd.com    setPrivateSize(0);
8211308Santhony.gutierrez@amd.com
8311308Santhony.gutierrez@amd.com    const BrigBase *entryPtr = brigNext((BrigBase*)code_dir);
8411308Santhony.gutierrez@amd.com    const BrigBase *endPtr =
8511308Santhony.gutierrez@amd.com        obj->getCodeSectionEntry(code_dir->nextModuleEntry);
8611308Santhony.gutierrez@amd.com
8711308Santhony.gutierrez@amd.com    int inst_idx = 0;
8811308Santhony.gutierrez@amd.com    std::vector<GPUStaticInst*> instructions;
8911308Santhony.gutierrez@amd.com    int funcarg_size_scope = 0;
9011308Santhony.gutierrez@amd.com
9111308Santhony.gutierrez@amd.com    // walk through instructions in code section and directives in
9211308Santhony.gutierrez@amd.com    // directive section in parallel, processing directives that apply
9311308Santhony.gutierrez@amd.com    // when we reach the relevant code point.
9411308Santhony.gutierrez@amd.com    while (entryPtr < endPtr) {
9511308Santhony.gutierrez@amd.com        switch (entryPtr->kind) {
9611308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_VARIABLE:
9711308Santhony.gutierrez@amd.com           {
9811308Santhony.gutierrez@amd.com                const BrigDirectiveVariable *sym =
9911308Santhony.gutierrez@amd.com                    (const BrigDirectiveVariable*)entryPtr;
10011308Santhony.gutierrez@amd.com
10111308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject,"Initializing code, directive is "
10211308Santhony.gutierrez@amd.com                        "kind_variable, symbol is: %s\n",
10311308Santhony.gutierrez@amd.com                        obj->getString(sym->name));
10411308Santhony.gutierrez@amd.com
10511308Santhony.gutierrez@amd.com                StorageElement *se = storageMap->addSymbol(sym, obj);
10611308Santhony.gutierrez@amd.com
10711308Santhony.gutierrez@amd.com                if (sym->segment == BRIG_SEGMENT_PRIVATE) {
10811308Santhony.gutierrez@amd.com                    setPrivateSize(se->size);
10911308Santhony.gutierrez@amd.com                } else { // spill
11011308Santhony.gutierrez@amd.com                    funcarg_size_scope += se->size;
11111308Santhony.gutierrez@amd.com                }
11211308Santhony.gutierrez@amd.com            }
11311308Santhony.gutierrez@amd.com            break;
11411308Santhony.gutierrez@amd.com
11511308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_LABEL:
11611308Santhony.gutierrez@amd.com            {
11711308Santhony.gutierrez@amd.com                const BrigDirectiveLabel *lbl =
11811308Santhony.gutierrez@amd.com                    (const BrigDirectiveLabel*)entryPtr;
11911308Santhony.gutierrez@amd.com
12011308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject,"Initializing code, directive is "
12111308Santhony.gutierrez@amd.com                        "kind_label, label is: %s \n",
12211308Santhony.gutierrez@amd.com                        obj->getString(lbl->name));
12311308Santhony.gutierrez@amd.com
12411308Santhony.gutierrez@amd.com                labelMap.addLabel(lbl, inst_idx, obj);
12511308Santhony.gutierrez@amd.com            }
12611308Santhony.gutierrez@amd.com            break;
12711308Santhony.gutierrez@amd.com
12811308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_PRAGMA:
12911308Santhony.gutierrez@amd.com            {
13011308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject, "Initializing code, directive "
13111308Santhony.gutierrez@amd.com                        "is kind_pragma\n");
13211308Santhony.gutierrez@amd.com            }
13311308Santhony.gutierrez@amd.com            break;
13411308Santhony.gutierrez@amd.com
13511308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_COMMENT:
13611308Santhony.gutierrez@amd.com            {
13711308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject, "Initializing code, directive is "
13811308Santhony.gutierrez@amd.com                        "kind_comment\n");
13911308Santhony.gutierrez@amd.com            }
14011308Santhony.gutierrez@amd.com            break;
14111308Santhony.gutierrez@amd.com
14211308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_ARG_BLOCK_START:
14311308Santhony.gutierrez@amd.com            {
14411308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject, "Initializing code, directive is "
14511308Santhony.gutierrez@amd.com                        "kind_arg_block_start\n");
14611308Santhony.gutierrez@amd.com
14711308Santhony.gutierrez@amd.com                storageMap->resetOffset(BRIG_SEGMENT_ARG);
14811308Santhony.gutierrez@amd.com                funcarg_size_scope = 0;
14911308Santhony.gutierrez@amd.com            }
15011308Santhony.gutierrez@amd.com            break;
15111308Santhony.gutierrez@amd.com
15211308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_ARG_BLOCK_END:
15311308Santhony.gutierrez@amd.com            {
15411308Santhony.gutierrez@amd.com                DPRINTF(HSAILObject, "Initializing code, directive is "
15511308Santhony.gutierrez@amd.com                        "kind_arg_block_end\n");
15611308Santhony.gutierrez@amd.com
15711308Santhony.gutierrez@amd.com                funcarg_size = funcarg_size < funcarg_size_scope ?
15811308Santhony.gutierrez@amd.com                                              funcarg_size_scope : funcarg_size;
15911308Santhony.gutierrez@amd.com            }
16011308Santhony.gutierrez@amd.com            break;
16111308Santhony.gutierrez@amd.com
16211308Santhony.gutierrez@amd.com          case BRIG_KIND_DIRECTIVE_END:
16311308Santhony.gutierrez@amd.com            DPRINTF(HSAILObject, "Initializing code, dircetive is "
16411308Santhony.gutierrez@amd.com                    "kind_end\n");
16511308Santhony.gutierrez@amd.com
16611308Santhony.gutierrez@amd.com            break;
16711308Santhony.gutierrez@amd.com
16811308Santhony.gutierrez@amd.com          default:
16911308Santhony.gutierrez@amd.com            if (entryPtr->kind >= BRIG_KIND_INST_BEGIN &&
17011308Santhony.gutierrez@amd.com                entryPtr->kind <= BRIG_KIND_INST_END) {
17111308Santhony.gutierrez@amd.com
17211308Santhony.gutierrez@amd.com                BrigInstBase *instPtr = (BrigInstBase*)entryPtr;
17311308Santhony.gutierrez@amd.com                TheGpuISA::MachInst machInst = { instPtr, obj };
17411308Santhony.gutierrez@amd.com                GPUStaticInst *iptr = decoder.decode(machInst);
17511308Santhony.gutierrez@amd.com
17611308Santhony.gutierrez@amd.com                if (iptr) {
17711308Santhony.gutierrez@amd.com                    DPRINTF(HSAILObject, "Initializing code, processing inst "
17811308Santhony.gutierrez@amd.com                            "#%d idx %d: OPCODE=%d\n",
17911308Santhony.gutierrez@amd.com                            inst_idx,  _insts.size(), instPtr->opcode);
18011308Santhony.gutierrez@amd.com
18111308Santhony.gutierrez@amd.com                    TheGpuISA::RawMachInst inst_num = decoder.saveInst(iptr);
18211308Santhony.gutierrez@amd.com                    iptr->instNum(inst_idx);
18311308Santhony.gutierrez@amd.com                    _insts.push_back(inst_num);
18411308Santhony.gutierrez@amd.com                    instructions.push_back(iptr);
18511308Santhony.gutierrez@amd.com                }
18611308Santhony.gutierrez@amd.com                ++inst_idx;
18711308Santhony.gutierrez@amd.com            } else if (entryPtr->kind >= BRIG_KIND_OPERAND_BEGIN &&
18811308Santhony.gutierrez@amd.com                       entryPtr->kind < BRIG_KIND_OPERAND_END) {
18911308Santhony.gutierrez@amd.com                warn("unexpected operand entry in code segment\n");
19011308Santhony.gutierrez@amd.com            } else {
19111308Santhony.gutierrez@amd.com                // there are surely some more cases we will need to handle,
19211308Santhony.gutierrez@amd.com                // but we'll deal with them as we find them.
19311308Santhony.gutierrez@amd.com                fatal("unexpected directive kind %d inside kernel scope\n",
19411308Santhony.gutierrez@amd.com                      entryPtr->kind);
19511308Santhony.gutierrez@amd.com            }
19611308Santhony.gutierrez@amd.com        }
19711308Santhony.gutierrez@amd.com
19811308Santhony.gutierrez@amd.com        entryPtr = brigNext(entryPtr);
19911308Santhony.gutierrez@amd.com    }
20011308Santhony.gutierrez@amd.com
20111308Santhony.gutierrez@amd.com    // compute Control Flow Graph for current kernel
20211308Santhony.gutierrez@amd.com    ControlFlowInfo::assignImmediatePostDominators(instructions);
20311308Santhony.gutierrez@amd.com
20411308Santhony.gutierrez@amd.com    max_sreg = SRegOperand::maxRegIdx;
20511308Santhony.gutierrez@amd.com    max_dreg = DRegOperand::maxRegIdx;
20611308Santhony.gutierrez@amd.com    max_creg = CRegOperand::maxRegIdx;
20711308Santhony.gutierrez@amd.com
20811308Santhony.gutierrez@amd.com    obj->currentCode = nullptr;
20911308Santhony.gutierrez@amd.com}
21011308Santhony.gutierrez@amd.com
21111308Santhony.gutierrez@amd.comHsailCode::HsailCode(const std::string &name_str,
21211308Santhony.gutierrez@amd.com                     const BrigDirectiveExecutable *code_dir,
21311308Santhony.gutierrez@amd.com                     const BrigObject *obj, StorageMap *objStorageMap)
21411308Santhony.gutierrez@amd.com    : HsaCode(name_str), private_size(-1), readonly_size(-1)
21511308Santhony.gutierrez@amd.com{
21611308Santhony.gutierrez@amd.com    init(code_dir, obj, objStorageMap);
21711308Santhony.gutierrez@amd.com}
21811308Santhony.gutierrez@amd.com
21911308Santhony.gutierrez@amd.comvoid
22011308Santhony.gutierrez@amd.comLabelMap::addLabel(const Brig::BrigDirectiveLabel *lblDir, int inst_index,
22111308Santhony.gutierrez@amd.com                   const BrigObject *obj)
22211308Santhony.gutierrez@amd.com{
22311308Santhony.gutierrez@amd.com    std::string lbl_name = obj->getString(lblDir->name);
22411308Santhony.gutierrez@amd.com    Label &lbl = map[lbl_name];
22511308Santhony.gutierrez@amd.com
22611308Santhony.gutierrez@amd.com    if (lbl.defined()) {
22711308Santhony.gutierrez@amd.com        fatal("Attempt to redefine existing label %s\n", lbl_name);
22811308Santhony.gutierrez@amd.com    }
22911308Santhony.gutierrez@amd.com
23011308Santhony.gutierrez@amd.com    lbl.define(lbl_name, inst_index);
23111308Santhony.gutierrez@amd.com    DPRINTF(HSAILObject, "label %s = %d\n", lbl_name, inst_index);
23211308Santhony.gutierrez@amd.com}
23311308Santhony.gutierrez@amd.com
23411308Santhony.gutierrez@amd.comLabel*
23511308Santhony.gutierrez@amd.comLabelMap::refLabel(const Brig::BrigDirectiveLabel *lblDir,
23611308Santhony.gutierrez@amd.com                   const BrigObject *obj)
23711308Santhony.gutierrez@amd.com{
23811308Santhony.gutierrez@amd.com    std::string name = obj->getString(lblDir->name);
23911308Santhony.gutierrez@amd.com    Label &lbl = map[name];
24011308Santhony.gutierrez@amd.com    lbl.checkName(name);
24111308Santhony.gutierrez@amd.com
24211308Santhony.gutierrez@amd.com    return &lbl;
24311308Santhony.gutierrez@amd.com}
24411308Santhony.gutierrez@amd.com
24511308Santhony.gutierrez@amd.comint
24611308Santhony.gutierrez@amd.comgetBrigDataTypeBytes(BrigType16_t t)
24711308Santhony.gutierrez@amd.com{
24811308Santhony.gutierrez@amd.com    switch (t) {
24911308Santhony.gutierrez@amd.com      case BRIG_TYPE_S8:
25011308Santhony.gutierrez@amd.com      case BRIG_TYPE_U8:
25111308Santhony.gutierrez@amd.com      case BRIG_TYPE_B8:
25211308Santhony.gutierrez@amd.com        return 1;
25311308Santhony.gutierrez@amd.com
25411308Santhony.gutierrez@amd.com      case BRIG_TYPE_S16:
25511308Santhony.gutierrez@amd.com      case BRIG_TYPE_U16:
25611308Santhony.gutierrez@amd.com      case BRIG_TYPE_B16:
25711308Santhony.gutierrez@amd.com      case BRIG_TYPE_F16:
25811308Santhony.gutierrez@amd.com        return 2;
25911308Santhony.gutierrez@amd.com
26011308Santhony.gutierrez@amd.com      case BRIG_TYPE_S32:
26111308Santhony.gutierrez@amd.com      case BRIG_TYPE_U32:
26211308Santhony.gutierrez@amd.com      case BRIG_TYPE_B32:
26311308Santhony.gutierrez@amd.com      case BRIG_TYPE_F32:
26411308Santhony.gutierrez@amd.com        return 4;
26511308Santhony.gutierrez@amd.com
26611308Santhony.gutierrez@amd.com      case BRIG_TYPE_S64:
26711308Santhony.gutierrez@amd.com      case BRIG_TYPE_U64:
26811308Santhony.gutierrez@amd.com      case BRIG_TYPE_B64:
26911308Santhony.gutierrez@amd.com      case BRIG_TYPE_F64:
27011308Santhony.gutierrez@amd.com        return 8;
27111308Santhony.gutierrez@amd.com
27211308Santhony.gutierrez@amd.com      case BRIG_TYPE_B1:
27311308Santhony.gutierrez@amd.com
27411308Santhony.gutierrez@amd.com      default:
27511308Santhony.gutierrez@amd.com        fatal("unhandled symbol data type %d", t);
27611308Santhony.gutierrez@amd.com        return 0;
27711308Santhony.gutierrez@amd.com    }
27811308Santhony.gutierrez@amd.com}
27911308Santhony.gutierrez@amd.com
28011308Santhony.gutierrez@amd.comStorageElement*
28111308Santhony.gutierrez@amd.comStorageSpace::addSymbol(const BrigDirectiveVariable *sym,
28211308Santhony.gutierrez@amd.com                        const BrigObject *obj)
28311308Santhony.gutierrez@amd.com{
28411308Santhony.gutierrez@amd.com    const char *sym_name = obj->getString(sym->name);
28511308Santhony.gutierrez@amd.com    uint64_t size = 0;
28611308Santhony.gutierrez@amd.com    uint64_t offset = 0;
28711308Santhony.gutierrez@amd.com
28811308Santhony.gutierrez@amd.com    if (sym->type & BRIG_TYPE_ARRAY) {
28911308Santhony.gutierrez@amd.com        size = getBrigDataTypeBytes(sym->type & ~BRIG_TYPE_ARRAY);
29011308Santhony.gutierrez@amd.com        size *= (((uint64_t)sym->dim.hi) << 32 | (uint64_t)sym->dim.lo);
29111308Santhony.gutierrez@amd.com
29211308Santhony.gutierrez@amd.com        offset = roundUp(nextOffset, getBrigDataTypeBytes(sym->type &
29311308Santhony.gutierrez@amd.com                         ~BRIG_TYPE_ARRAY));
29411308Santhony.gutierrez@amd.com    } else {
29511308Santhony.gutierrez@amd.com        size = getBrigDataTypeBytes(sym->type);
29611308Santhony.gutierrez@amd.com        offset = roundUp(nextOffset, getBrigDataTypeBytes(sym->type));
29711308Santhony.gutierrez@amd.com    }
29811308Santhony.gutierrez@amd.com
29911308Santhony.gutierrez@amd.com    nextOffset = offset + size;
30011308Santhony.gutierrez@amd.com
30111308Santhony.gutierrez@amd.com    DPRINTF(HSAILObject, "Adding %s SYMBOL %s size %d offset 0x%x, init: %d\n",
30211308Santhony.gutierrez@amd.com            segmentNames[segment], sym_name, size, offset, sym->init);
30311308Santhony.gutierrez@amd.com
30411308Santhony.gutierrez@amd.com    StorageElement* se = new StorageElement(sym_name, offset, size, sym);
30511308Santhony.gutierrez@amd.com    elements.push_back(se);
30611308Santhony.gutierrez@amd.com    elements_by_addr.insert(AddrRange(offset, offset + size - 1), se);
30711308Santhony.gutierrez@amd.com    elements_by_brigptr[sym] = se;
30811308Santhony.gutierrez@amd.com
30911308Santhony.gutierrez@amd.com    return se;
31011308Santhony.gutierrez@amd.com}
31111308Santhony.gutierrez@amd.com
31211308Santhony.gutierrez@amd.comStorageElement*
31311308Santhony.gutierrez@amd.comStorageSpace::findSymbol(std::string name)
31411308Santhony.gutierrez@amd.com{
31511308Santhony.gutierrez@amd.com    for (auto it : elements) {
31611308Santhony.gutierrez@amd.com        if (it->name == name) {
31711308Santhony.gutierrez@amd.com            return it;
31811308Santhony.gutierrez@amd.com        }
31911308Santhony.gutierrez@amd.com    }
32011308Santhony.gutierrez@amd.com
32111308Santhony.gutierrez@amd.com    return nullptr;
32211308Santhony.gutierrez@amd.com}
32311308Santhony.gutierrez@amd.com
32411308Santhony.gutierrez@amd.comStorageElement*
32511308Santhony.gutierrez@amd.comStorageSpace::findSymbol(uint64_t addr)
32611308Santhony.gutierrez@amd.com{
32711308Santhony.gutierrez@amd.com    assert(elements_by_addr.size() > 0);
32811308Santhony.gutierrez@amd.com
32911308Santhony.gutierrez@amd.com    auto se = elements_by_addr.find(addr);
33011308Santhony.gutierrez@amd.com
33111308Santhony.gutierrez@amd.com    if (se == elements_by_addr.end()) {
33211308Santhony.gutierrez@amd.com        return nullptr;
33311308Santhony.gutierrez@amd.com    } else {
33411308Santhony.gutierrez@amd.com        return se->second;
33511308Santhony.gutierrez@amd.com    }
33611308Santhony.gutierrez@amd.com}
33711308Santhony.gutierrez@amd.com
33811308Santhony.gutierrez@amd.comStorageElement*
33911308Santhony.gutierrez@amd.comStorageSpace::findSymbol(const BrigDirectiveVariable *brigptr)
34011308Santhony.gutierrez@amd.com{
34111308Santhony.gutierrez@amd.com    assert(elements_by_brigptr.size() > 0);
34211308Santhony.gutierrez@amd.com
34311308Santhony.gutierrez@amd.com    auto se = elements_by_brigptr.find(brigptr);
34411308Santhony.gutierrez@amd.com
34511308Santhony.gutierrez@amd.com    if (se == elements_by_brigptr.end()) {
34611308Santhony.gutierrez@amd.com        return nullptr;
34711308Santhony.gutierrez@amd.com    } else {
34811308Santhony.gutierrez@amd.com        return se->second;
34911308Santhony.gutierrez@amd.com    }
35011308Santhony.gutierrez@amd.com}
35111308Santhony.gutierrez@amd.com
35211308Santhony.gutierrez@amd.comStorageMap::StorageMap(StorageMap *outerScope)
35311308Santhony.gutierrez@amd.com    : outerScopeMap(outerScope)
35411308Santhony.gutierrez@amd.com{
35511308Santhony.gutierrez@amd.com    for (int i = 0; i < NumSegments; ++i)
35611308Santhony.gutierrez@amd.com        space[i] = new StorageSpace((BrigSegment)i);
35711308Santhony.gutierrez@amd.com}
35811308Santhony.gutierrez@amd.com
35911308Santhony.gutierrez@amd.comStorageElement*
36011308Santhony.gutierrez@amd.comStorageMap::addSymbol(const BrigDirectiveVariable *sym, const BrigObject *obj)
36111308Santhony.gutierrez@amd.com{
36211308Santhony.gutierrez@amd.com    BrigSegment8_t segment = sym->segment;
36311308Santhony.gutierrez@amd.com
36411308Santhony.gutierrez@amd.com    assert(segment >= Brig::BRIG_SEGMENT_FLAT);
36511308Santhony.gutierrez@amd.com    assert(segment < NumSegments);
36611308Santhony.gutierrez@amd.com
36711308Santhony.gutierrez@amd.com    return space[segment]->addSymbol(sym, obj);
36811308Santhony.gutierrez@amd.com}
36911308Santhony.gutierrez@amd.com
37011308Santhony.gutierrez@amd.comint
37111308Santhony.gutierrez@amd.comStorageMap::getSize(Brig::BrigSegment segment)
37211308Santhony.gutierrez@amd.com{
37311308Santhony.gutierrez@amd.com    assert(segment > Brig::BRIG_SEGMENT_GLOBAL);
37411308Santhony.gutierrez@amd.com    assert(segment < NumSegments);
37511308Santhony.gutierrez@amd.com
37611308Santhony.gutierrez@amd.com    if (segment != Brig::BRIG_SEGMENT_GROUP &&
37711308Santhony.gutierrez@amd.com        segment != Brig::BRIG_SEGMENT_READONLY) {
37811308Santhony.gutierrez@amd.com        return space[segment]->getSize();
37911308Santhony.gutierrez@amd.com    } else {
38011308Santhony.gutierrez@amd.com        int ret = space[segment]->getSize();
38111308Santhony.gutierrez@amd.com
38211308Santhony.gutierrez@amd.com        if (outerScopeMap) {
38311308Santhony.gutierrez@amd.com            ret += outerScopeMap->getSize(segment);
38411308Santhony.gutierrez@amd.com        }
38511308Santhony.gutierrez@amd.com
38611308Santhony.gutierrez@amd.com        return ret;
38711308Santhony.gutierrez@amd.com    }
38811308Santhony.gutierrez@amd.com}
38911308Santhony.gutierrez@amd.com
39011308Santhony.gutierrez@amd.comvoid
39111308Santhony.gutierrez@amd.comStorageMap::resetOffset(Brig::BrigSegment segment)
39211308Santhony.gutierrez@amd.com{
39311308Santhony.gutierrez@amd.com    space[segment]->resetOffset();
39411308Santhony.gutierrez@amd.com}
39511308Santhony.gutierrez@amd.com
39611308Santhony.gutierrez@amd.comStorageElement*
39711308Santhony.gutierrez@amd.comStorageMap::findSymbol(BrigSegment segment, std::string name)
39811308Santhony.gutierrez@amd.com{
39911308Santhony.gutierrez@amd.com    StorageElement *se = space[segment]->findSymbol(name);
40011308Santhony.gutierrez@amd.com
40111308Santhony.gutierrez@amd.com    if (se)
40211308Santhony.gutierrez@amd.com        return se;
40311308Santhony.gutierrez@amd.com
40411308Santhony.gutierrez@amd.com    if (outerScopeMap)
40511308Santhony.gutierrez@amd.com        return outerScopeMap->findSymbol(segment, name);
40611308Santhony.gutierrez@amd.com
40711308Santhony.gutierrez@amd.com    return nullptr;
40811308Santhony.gutierrez@amd.com}
40911308Santhony.gutierrez@amd.com
41011308Santhony.gutierrez@amd.comStorageElement*
41111308Santhony.gutierrez@amd.comStorageMap::findSymbol(Brig::BrigSegment segment, uint64_t addr)
41211308Santhony.gutierrez@amd.com{
41311308Santhony.gutierrez@amd.com    StorageSpace *sp = space[segment];
41411308Santhony.gutierrez@amd.com
41511308Santhony.gutierrez@amd.com    if (!sp) {
41611308Santhony.gutierrez@amd.com        // there is no memory in segment?
41711308Santhony.gutierrez@amd.com        return nullptr;
41811308Santhony.gutierrez@amd.com    }
41911308Santhony.gutierrez@amd.com
42011308Santhony.gutierrez@amd.com    StorageElement *se = sp->findSymbol(addr);
42111308Santhony.gutierrez@amd.com
42211308Santhony.gutierrez@amd.com    if (se)
42311308Santhony.gutierrez@amd.com        return se;
42411308Santhony.gutierrez@amd.com
42511308Santhony.gutierrez@amd.com    if (outerScopeMap)
42611308Santhony.gutierrez@amd.com        return outerScopeMap->findSymbol(segment, addr);
42711308Santhony.gutierrez@amd.com
42811308Santhony.gutierrez@amd.com    return nullptr;
42911308Santhony.gutierrez@amd.com
43011308Santhony.gutierrez@amd.com}
43111308Santhony.gutierrez@amd.com
43211308Santhony.gutierrez@amd.comStorageElement*
43311308Santhony.gutierrez@amd.comStorageMap::findSymbol(Brig::BrigSegment segment,
43411308Santhony.gutierrez@amd.com                       const BrigDirectiveVariable *brigptr)
43511308Santhony.gutierrez@amd.com{
43611308Santhony.gutierrez@amd.com    StorageSpace *sp = space[segment];
43711308Santhony.gutierrez@amd.com
43811308Santhony.gutierrez@amd.com    if (!sp) {
43911308Santhony.gutierrez@amd.com        // there is no memory in segment?
44011308Santhony.gutierrez@amd.com        return nullptr;
44111308Santhony.gutierrez@amd.com    }
44211308Santhony.gutierrez@amd.com
44311308Santhony.gutierrez@amd.com    StorageElement *se = sp->findSymbol(brigptr);
44411308Santhony.gutierrez@amd.com
44511308Santhony.gutierrez@amd.com    if (se)
44611308Santhony.gutierrez@amd.com        return se;
44711308Santhony.gutierrez@amd.com
44811308Santhony.gutierrez@amd.com    if (outerScopeMap)
44911308Santhony.gutierrez@amd.com        return outerScopeMap->findSymbol(segment, brigptr);
45011308Santhony.gutierrez@amd.com
45111308Santhony.gutierrez@amd.com    return nullptr;
45211308Santhony.gutierrez@amd.com
45311308Santhony.gutierrez@amd.com}
454