operand.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 "arch/hsail/operand.hh"
3711308Santhony.gutierrez@amd.com
3811308Santhony.gutierrez@amd.comusing namespace Brig;
3911308Santhony.gutierrez@amd.com
4011308Santhony.gutierrez@amd.combool
4111308Santhony.gutierrez@amd.comBaseRegOperand::init(unsigned opOffset, const BrigObject *obj,
4211308Santhony.gutierrez@amd.com                     unsigned &maxRegIdx, char _regFileChar)
4311308Santhony.gutierrez@amd.com{
4411308Santhony.gutierrez@amd.com    regFileChar = _regFileChar;
4511308Santhony.gutierrez@amd.com    const BrigOperand *brigOp = obj->getOperand(opOffset);
4611308Santhony.gutierrez@amd.com
4711308Santhony.gutierrez@amd.com    if (brigOp->kind != BRIG_KIND_OPERAND_REGISTER)
4811308Santhony.gutierrez@amd.com        return false;
4911308Santhony.gutierrez@amd.com
5011308Santhony.gutierrez@amd.com    const BrigOperandRegister *brigRegOp = (const BrigOperandRegister*)brigOp;
5111308Santhony.gutierrez@amd.com
5211308Santhony.gutierrez@amd.com    regIdx = brigRegOp->regNum;
5311308Santhony.gutierrez@amd.com
5411308Santhony.gutierrez@amd.com    DPRINTF(GPUReg, "Operand: regNum: %d, kind: %d\n", regIdx,
5511308Santhony.gutierrez@amd.com            brigRegOp->regKind);
5611308Santhony.gutierrez@amd.com
5711308Santhony.gutierrez@amd.com    maxRegIdx = std::max(maxRegIdx, regIdx);
5811308Santhony.gutierrez@amd.com
5911308Santhony.gutierrez@amd.com    return true;
6011308Santhony.gutierrez@amd.com}
6111308Santhony.gutierrez@amd.com
6211308Santhony.gutierrez@amd.comvoid
6311308Santhony.gutierrez@amd.comListOperand::init(unsigned opOffset, const BrigObject *obj)
6411308Santhony.gutierrez@amd.com{
6511308Santhony.gutierrez@amd.com    const BrigOperand *brigOp = (const BrigOperand*)obj->getOperand(opOffset);
6611308Santhony.gutierrez@amd.com
6711308Santhony.gutierrez@amd.com    switch (brigOp->kind) {
6811308Santhony.gutierrez@amd.com      case BRIG_KIND_OPERAND_CODE_LIST:
6911308Santhony.gutierrez@amd.com        {
7011308Santhony.gutierrez@amd.com            const BrigOperandCodeList *opList =
7111308Santhony.gutierrez@amd.com                (const BrigOperandCodeList*)brigOp;
7211308Santhony.gutierrez@amd.com
7311308Santhony.gutierrez@amd.com            const Brig::BrigData *oprnd_data =
7411308Santhony.gutierrez@amd.com                obj->getBrigBaseData(opList->elements);
7511308Santhony.gutierrez@amd.com
7611308Santhony.gutierrez@amd.com            // Note: for calls Dest list of operands could be size of 0.
7711308Santhony.gutierrez@amd.com            elementCount = oprnd_data->byteCount / 4;
7811308Santhony.gutierrez@amd.com
7911308Santhony.gutierrez@amd.com            DPRINTF(GPUReg, "Operand Code List: # elements: %d\n",
8011308Santhony.gutierrez@amd.com                    elementCount);
8111308Santhony.gutierrez@amd.com
8211308Santhony.gutierrez@amd.com            for (int i = 0; i < elementCount; ++i) {
8311308Santhony.gutierrez@amd.com                unsigned *data_offset =
8411308Santhony.gutierrez@amd.com                    (unsigned*)obj->getData(opList->elements + 4 * (i + 1));
8511308Santhony.gutierrez@amd.com
8611308Santhony.gutierrez@amd.com                const BrigDirectiveVariable *p =
8711308Santhony.gutierrez@amd.com                    (const BrigDirectiveVariable*)obj->
8811308Santhony.gutierrez@amd.com                    getCodeSectionEntry(*data_offset);
8911308Santhony.gutierrez@amd.com
9011308Santhony.gutierrez@amd.com                StorageElement *se = obj->currentCode->storageMap->
9111308Santhony.gutierrez@amd.com                    findSymbol(BRIG_SEGMENT_ARG, p);
9211308Santhony.gutierrez@amd.com
9311308Santhony.gutierrez@amd.com                assert(se);
9411308Santhony.gutierrez@amd.com                callArgs.push_back(se);
9511308Santhony.gutierrez@amd.com            }
9611308Santhony.gutierrez@amd.com        }
9711308Santhony.gutierrez@amd.com        break;
9811308Santhony.gutierrez@amd.com      default:
9911308Santhony.gutierrez@amd.com        fatal("ListOperand: bad operand kind %d\n", brigOp->kind);
10011308Santhony.gutierrez@amd.com    }
10111308Santhony.gutierrez@amd.com}
10211308Santhony.gutierrez@amd.com
10311308Santhony.gutierrez@amd.comstd::string
10411308Santhony.gutierrez@amd.comListOperand::disassemble()
10511308Santhony.gutierrez@amd.com{
10611308Santhony.gutierrez@amd.com    std::string res_str("");
10711308Santhony.gutierrez@amd.com
10811308Santhony.gutierrez@amd.com    for (auto it : callArgs) {
10911308Santhony.gutierrez@amd.com        res_str += csprintf("%s ", it->name.c_str());
11011308Santhony.gutierrez@amd.com    }
11111308Santhony.gutierrez@amd.com
11211308Santhony.gutierrez@amd.com    return res_str;
11311308Santhony.gutierrez@amd.com}
11411308Santhony.gutierrez@amd.com
11511308Santhony.gutierrez@amd.comvoid
11611308Santhony.gutierrez@amd.comFunctionRefOperand::init(unsigned opOffset, const BrigObject *obj)
11711308Santhony.gutierrez@amd.com{
11811308Santhony.gutierrez@amd.com    const BrigOperand *baseOp = obj->getOperand(opOffset);
11911308Santhony.gutierrez@amd.com
12011308Santhony.gutierrez@amd.com    if (baseOp->kind != BRIG_KIND_OPERAND_CODE_REF) {
12111308Santhony.gutierrez@amd.com        fatal("FunctionRefOperand: bad operand kind %d\n", baseOp->kind);
12211308Santhony.gutierrez@amd.com    }
12311308Santhony.gutierrez@amd.com
12411308Santhony.gutierrez@amd.com    const BrigOperandCodeRef *brigOp = (const BrigOperandCodeRef*)baseOp;
12511308Santhony.gutierrez@amd.com
12611308Santhony.gutierrez@amd.com    const BrigDirectiveExecutable *p =
12711308Santhony.gutierrez@amd.com        (const BrigDirectiveExecutable*)obj->getCodeSectionEntry(brigOp->ref);
12811308Santhony.gutierrez@amd.com
12911308Santhony.gutierrez@amd.com    func_name = obj->getString(p->name);
13011308Santhony.gutierrez@amd.com}
13111308Santhony.gutierrez@amd.com
13211308Santhony.gutierrez@amd.comstd::string
13311308Santhony.gutierrez@amd.comFunctionRefOperand::disassemble()
13411308Santhony.gutierrez@amd.com{
13511308Santhony.gutierrez@amd.com    DPRINTF(GPUReg, "Operand Func-ref name: %s\n", func_name);
13611308Santhony.gutierrez@amd.com
13711308Santhony.gutierrez@amd.com    return csprintf("%s", func_name);
13811308Santhony.gutierrez@amd.com}
13911308Santhony.gutierrez@amd.com
14011308Santhony.gutierrez@amd.combool
14111308Santhony.gutierrez@amd.comBaseRegOperand::init_from_vect(unsigned opOffset, const BrigObject *obj,
14211308Santhony.gutierrez@amd.com                               int at, unsigned &maxRegIdx, char _regFileChar)
14311308Santhony.gutierrez@amd.com{
14411308Santhony.gutierrez@amd.com    regFileChar = _regFileChar;
14511308Santhony.gutierrez@amd.com    const BrigOperand *brigOp = obj->getOperand(opOffset);
14611308Santhony.gutierrez@amd.com
14711308Santhony.gutierrez@amd.com    if (brigOp->kind != BRIG_KIND_OPERAND_OPERAND_LIST)
14811308Santhony.gutierrez@amd.com        return false;
14911308Santhony.gutierrez@amd.com
15011308Santhony.gutierrez@amd.com
15111308Santhony.gutierrez@amd.com    const Brig::BrigOperandOperandList *brigRegVecOp =
15211308Santhony.gutierrez@amd.com         (const Brig::BrigOperandOperandList*)brigOp;
15311308Santhony.gutierrez@amd.com
15411308Santhony.gutierrez@amd.com    unsigned *data_offset =
15511308Santhony.gutierrez@amd.com        (unsigned*)obj->getData(brigRegVecOp->elements + 4 * (at + 1));
15611308Santhony.gutierrez@amd.com
15711308Santhony.gutierrez@amd.com    const BrigOperand *p =
15811308Santhony.gutierrez@amd.com        (const BrigOperand*)obj->getOperand(*data_offset);
15911308Santhony.gutierrez@amd.com    if (p->kind != BRIG_KIND_OPERAND_REGISTER) {
16011308Santhony.gutierrez@amd.com        return false;
16111308Santhony.gutierrez@amd.com    }
16211308Santhony.gutierrez@amd.com
16311308Santhony.gutierrez@amd.com    const BrigOperandRegister *brigRegOp =(const BrigOperandRegister*)p;
16411308Santhony.gutierrez@amd.com
16511308Santhony.gutierrez@amd.com    regIdx = brigRegOp->regNum;
16611308Santhony.gutierrez@amd.com
16711308Santhony.gutierrez@amd.com    DPRINTF(GPUReg, "Operand: regNum: %d, kind: %d \n", regIdx,
16811308Santhony.gutierrez@amd.com            brigRegOp->regKind);
16911308Santhony.gutierrez@amd.com
17011308Santhony.gutierrez@amd.com    maxRegIdx = std::max(maxRegIdx, regIdx);
17111308Santhony.gutierrez@amd.com
17211308Santhony.gutierrez@amd.com    return true;
17311308Santhony.gutierrez@amd.com}
17411308Santhony.gutierrez@amd.com
17511308Santhony.gutierrez@amd.comvoid
17611308Santhony.gutierrez@amd.comBaseRegOperand::initWithStrOffset(unsigned strOffset, const BrigObject *obj,
17711308Santhony.gutierrez@amd.com                     unsigned &maxRegIdx, char _regFileChar)
17811308Santhony.gutierrez@amd.com{
17911308Santhony.gutierrez@amd.com    const char *name = obj->getString(strOffset);
18011308Santhony.gutierrez@amd.com    char *endptr;
18111308Santhony.gutierrez@amd.com    regIdx = strtoul(name + 2, &endptr, 10);
18211308Santhony.gutierrez@amd.com
18311308Santhony.gutierrez@amd.com    if (name[0] != '$' || name[1] != _regFileChar) {
18411308Santhony.gutierrez@amd.com        fatal("register operand parse error on \"%s\"\n", name);
18511308Santhony.gutierrez@amd.com    }
18611308Santhony.gutierrez@amd.com
18711308Santhony.gutierrez@amd.com    maxRegIdx = std::max(maxRegIdx, regIdx);
18811308Santhony.gutierrez@amd.com}
18911308Santhony.gutierrez@amd.com
19011308Santhony.gutierrez@amd.comunsigned SRegOperand::maxRegIdx;
19111308Santhony.gutierrez@amd.comunsigned DRegOperand::maxRegIdx;
19211308Santhony.gutierrez@amd.comunsigned CRegOperand::maxRegIdx;
19311308Santhony.gutierrez@amd.com
19411308Santhony.gutierrez@amd.comstd::string
19511308Santhony.gutierrez@amd.comSRegOperand::disassemble()
19611308Santhony.gutierrez@amd.com{
19711308Santhony.gutierrez@amd.com    return csprintf("$s%d", regIdx);
19811308Santhony.gutierrez@amd.com}
19911308Santhony.gutierrez@amd.com
20011308Santhony.gutierrez@amd.comstd::string
20111308Santhony.gutierrez@amd.comDRegOperand::disassemble()
20211308Santhony.gutierrez@amd.com{
20311308Santhony.gutierrez@amd.com    return csprintf("$d%d", regIdx);
20411308Santhony.gutierrez@amd.com}
20511308Santhony.gutierrez@amd.com
20611308Santhony.gutierrez@amd.comstd::string
20711308Santhony.gutierrez@amd.comCRegOperand::disassemble()
20811308Santhony.gutierrez@amd.com{
20911308Santhony.gutierrez@amd.com    return csprintf("$c%d", regIdx);
21011308Santhony.gutierrez@amd.com}
21111308Santhony.gutierrez@amd.com
21211308Santhony.gutierrez@amd.comBrigRegOperandInfo
21311308Santhony.gutierrez@amd.comfindRegDataType(unsigned opOffset, const BrigObject *obj)
21411308Santhony.gutierrez@amd.com{
21511308Santhony.gutierrez@amd.com    const BrigOperand *baseOp = obj->getOperand(opOffset);
21611308Santhony.gutierrez@amd.com
21711308Santhony.gutierrez@amd.com    switch (baseOp->kind) {
21811308Santhony.gutierrez@amd.com      case BRIG_KIND_OPERAND_REGISTER:
21911308Santhony.gutierrez@amd.com        {
22011308Santhony.gutierrez@amd.com            const BrigOperandRegister *op = (BrigOperandRegister*)baseOp;
22111308Santhony.gutierrez@amd.com
22211308Santhony.gutierrez@amd.com            return BrigRegOperandInfo((BrigKind16_t)baseOp->kind,
22311308Santhony.gutierrez@amd.com                                      (BrigRegisterKind)op->regKind);
22411308Santhony.gutierrez@amd.com        }
22511308Santhony.gutierrez@amd.com        break;
22611308Santhony.gutierrez@amd.com
22711308Santhony.gutierrez@amd.com      case BRIG_KIND_OPERAND_OPERAND_LIST:
22811308Santhony.gutierrez@amd.com        {
22911308Santhony.gutierrez@amd.com             const BrigOperandOperandList *op =
23011308Santhony.gutierrez@amd.com                (BrigOperandOperandList*)baseOp;
23111308Santhony.gutierrez@amd.com             const BrigData *data_p = (BrigData*)obj->getData(op->elements);
23211308Santhony.gutierrez@amd.com
23311308Santhony.gutierrez@amd.com
23411308Santhony.gutierrez@amd.com             int num_operands = 0;
23511308Santhony.gutierrez@amd.com             BrigRegisterKind reg_kind = (BrigRegisterKind)0;
23611308Santhony.gutierrez@amd.com             for (int offset = 0; offset < data_p->byteCount; offset += 4) {
23711308Santhony.gutierrez@amd.com                 const BrigOperand *op_p = (const BrigOperand *)
23811308Santhony.gutierrez@amd.com                    obj->getOperand(((int *)data_p->bytes)[offset/4]);
23911308Santhony.gutierrez@amd.com
24011308Santhony.gutierrez@amd.com                 if (op_p->kind == BRIG_KIND_OPERAND_REGISTER) {
24111308Santhony.gutierrez@amd.com                     const BrigOperandRegister *brigRegOp =
24211308Santhony.gutierrez@amd.com                        (const BrigOperandRegister*)op_p;
24311308Santhony.gutierrez@amd.com                     reg_kind = (BrigRegisterKind)brigRegOp->regKind;
24411308Santhony.gutierrez@amd.com                 } else if (op_p->kind == BRIG_KIND_OPERAND_CONSTANT_BYTES) {
24511308Santhony.gutierrez@amd.com                     uint16_t num_bytes =
24611308Santhony.gutierrez@amd.com                        ((Brig::BrigOperandConstantBytes*)op_p)->base.byteCount
24711308Santhony.gutierrez@amd.com                            - sizeof(BrigBase);
24811308Santhony.gutierrez@amd.com                     if (num_bytes == sizeof(uint32_t)) {
24911308Santhony.gutierrez@amd.com                         reg_kind = BRIG_REGISTER_KIND_SINGLE;
25011308Santhony.gutierrez@amd.com                     } else if (num_bytes == sizeof(uint64_t)) {
25111308Santhony.gutierrez@amd.com                         reg_kind = BRIG_REGISTER_KIND_DOUBLE;
25211308Santhony.gutierrez@amd.com                     } else {
25311308Santhony.gutierrez@amd.com                         fatal("OperandList: bad operand size %d\n", num_bytes);
25411308Santhony.gutierrez@amd.com                     }
25511308Santhony.gutierrez@amd.com                 } else {
25611308Santhony.gutierrez@amd.com                     fatal("OperandList: bad operand kind %d\n", op_p->kind);
25711308Santhony.gutierrez@amd.com                 }
25811308Santhony.gutierrez@amd.com
25911308Santhony.gutierrez@amd.com                 num_operands++;
26011308Santhony.gutierrez@amd.com             }
26111308Santhony.gutierrez@amd.com             assert(baseOp->kind == BRIG_KIND_OPERAND_OPERAND_LIST);
26211308Santhony.gutierrez@amd.com
26311308Santhony.gutierrez@amd.com             return BrigRegOperandInfo((BrigKind16_t)baseOp->kind, reg_kind);
26411308Santhony.gutierrez@amd.com        }
26511308Santhony.gutierrez@amd.com        break;
26611308Santhony.gutierrez@amd.com
26711308Santhony.gutierrez@amd.com      case BRIG_KIND_OPERAND_ADDRESS:
26811308Santhony.gutierrez@amd.com        {
26911308Santhony.gutierrez@amd.com            const BrigOperandAddress *op = (BrigOperandAddress*)baseOp;
27011308Santhony.gutierrez@amd.com
27111308Santhony.gutierrez@amd.com            if (!op->reg) {
27211308Santhony.gutierrez@amd.com                BrigType type = BRIG_TYPE_NONE;
27311308Santhony.gutierrez@amd.com
27411308Santhony.gutierrez@amd.com                if (op->symbol) {
27511308Santhony.gutierrez@amd.com                    const BrigDirective *dir = (BrigDirective*)
27611308Santhony.gutierrez@amd.com                        obj->getCodeSectionEntry(op->symbol);
27711308Santhony.gutierrez@amd.com
27811308Santhony.gutierrez@amd.com                    assert(dir->kind == BRIG_KIND_DIRECTIVE_VARIABLE);
27911308Santhony.gutierrez@amd.com
28011308Santhony.gutierrez@amd.com                    const BrigDirectiveVariable *sym =
28111308Santhony.gutierrez@amd.com                       (const BrigDirectiveVariable*)dir;
28211308Santhony.gutierrez@amd.com
28311308Santhony.gutierrez@amd.com                    type = (BrigType)sym->type;
28411308Santhony.gutierrez@amd.com                }
28511308Santhony.gutierrez@amd.com                return BrigRegOperandInfo(BRIG_KIND_OPERAND_ADDRESS,
28611308Santhony.gutierrez@amd.com                                          (BrigType)type);
28711308Santhony.gutierrez@amd.com            } else {
28811308Santhony.gutierrez@amd.com                const BrigOperandAddress *b = (const BrigOperandAddress*)baseOp;
28911308Santhony.gutierrez@amd.com                const BrigOperand *reg = obj->getOperand(b->reg);
29011308Santhony.gutierrez@amd.com                const BrigOperandRegister *rop = (BrigOperandRegister*)reg;
29111308Santhony.gutierrez@amd.com
29211308Santhony.gutierrez@amd.com                return BrigRegOperandInfo(BRIG_KIND_OPERAND_REGISTER,
29311308Santhony.gutierrez@amd.com                                          (BrigRegisterKind)rop->regKind);
29411308Santhony.gutierrez@amd.com            }
29511308Santhony.gutierrez@amd.com        }
29611308Santhony.gutierrez@amd.com        break;
29711308Santhony.gutierrez@amd.com
29811308Santhony.gutierrez@amd.com     default:
29911308Santhony.gutierrez@amd.com       fatal("AddrOperand: bad operand kind %d\n", baseOp->kind);
30011308Santhony.gutierrez@amd.com       break;
30111308Santhony.gutierrez@amd.com   }
30211308Santhony.gutierrez@amd.com}
30311308Santhony.gutierrez@amd.com
30411308Santhony.gutierrez@amd.comvoid
30511308Santhony.gutierrez@amd.comAddrOperandBase::parseAddr(const BrigOperandAddress *op, const BrigObject *obj)
30611308Santhony.gutierrez@amd.com{
30711308Santhony.gutierrez@amd.com    assert(op->base.kind == BRIG_KIND_OPERAND_ADDRESS);
30811308Santhony.gutierrez@amd.com
30911308Santhony.gutierrez@amd.com    const BrigDirective *d =
31011308Santhony.gutierrez@amd.com        (BrigDirective*)obj->getCodeSectionEntry(op->symbol);
31111308Santhony.gutierrez@amd.com
31211308Santhony.gutierrez@amd.com    assert(d->kind == BRIG_KIND_DIRECTIVE_VARIABLE);
31311308Santhony.gutierrez@amd.com    const BrigDirectiveVariable *sym = (BrigDirectiveVariable*)d;
31411308Santhony.gutierrez@amd.com    name = obj->getString(sym->name);
31511308Santhony.gutierrez@amd.com
31611308Santhony.gutierrez@amd.com    if (sym->segment != BRIG_SEGMENT_ARG) {
31711308Santhony.gutierrez@amd.com        storageElement =
31811308Santhony.gutierrez@amd.com            obj->currentCode->storageMap->findSymbol(sym->segment, name);
31911308Santhony.gutierrez@amd.com        assert(storageElement);
32011308Santhony.gutierrez@amd.com        offset = 0;
32111308Santhony.gutierrez@amd.com    } else {
32211308Santhony.gutierrez@amd.com        // sym->name does not work for BRIG_SEGMENT_ARG for the following case:
32311308Santhony.gutierrez@amd.com        //
32411308Santhony.gutierrez@amd.com        //     void foo(int a);
32511308Santhony.gutierrez@amd.com        //     void bar(double a);
32611308Santhony.gutierrez@amd.com        //
32711308Santhony.gutierrez@amd.com        //     foo(...) --> arg_u32 %param_p0;
32811308Santhony.gutierrez@amd.com        //                  st_arg_u32 $s0, [%param_p0];
32911308Santhony.gutierrez@amd.com        //                  call &foo (%param_p0);
33011308Santhony.gutierrez@amd.com        //     bar(...) --> arg_f64 %param_p0;
33111308Santhony.gutierrez@amd.com        //                  st_arg_u64 $d0, [%param_p0];
33211308Santhony.gutierrez@amd.com        //                  call &foo (%param_p0);
33311308Santhony.gutierrez@amd.com        //
33411308Santhony.gutierrez@amd.com        //  Both functions use the same variable name (param_p0)!!!
33511308Santhony.gutierrez@amd.com        //
33611308Santhony.gutierrez@amd.com        //  Maybe this is a bug in the compiler (I don't know).
33711308Santhony.gutierrez@amd.com        //
33811308Santhony.gutierrez@amd.com        // Solution:
33911308Santhony.gutierrez@amd.com        // Use directive pointer (BrigDirectiveVariable) to differentiate 2
34011308Santhony.gutierrez@amd.com        // versions of param_p0.
34111308Santhony.gutierrez@amd.com        //
34211308Santhony.gutierrez@amd.com        // Note this solution is kind of stupid, because we are pulling stuff
34311308Santhony.gutierrez@amd.com        // out of the brig binary via the directive pointer and putting it into
34411308Santhony.gutierrez@amd.com        // the symbol table, but now we are indexing the symbol table by the
34511308Santhony.gutierrez@amd.com        // brig directive pointer! It makes the symbol table sort of pointless.
34611308Santhony.gutierrez@amd.com        // But I don't want to mess with the rest of the infrastructure, so
34711308Santhony.gutierrez@amd.com        // let's go with this for now.
34811308Santhony.gutierrez@amd.com        //
34911308Santhony.gutierrez@amd.com        // When we update the compiler again, we should see if this problem goes
35011308Santhony.gutierrez@amd.com        // away. If so, we can fold some of this functionality into the code for
35111308Santhony.gutierrez@amd.com        // kernel arguments. If not, maybe we can index the symbol name on a
35211308Santhony.gutierrez@amd.com        // hash of the variable AND function name
35311308Santhony.gutierrez@amd.com        storageElement = obj->currentCode->
35411308Santhony.gutierrez@amd.com                 storageMap->findSymbol((Brig::BrigSegment)sym->segment, sym);
35511308Santhony.gutierrez@amd.com
35611308Santhony.gutierrez@amd.com        assert(storageElement);
35711308Santhony.gutierrez@amd.com    }
35811308Santhony.gutierrez@amd.com}
35911308Santhony.gutierrez@amd.com
36011308Santhony.gutierrez@amd.comuint64_t
36111308Santhony.gutierrez@amd.comAddrOperandBase::calcUniformBase()
36211308Santhony.gutierrez@amd.com{
36311308Santhony.gutierrez@amd.com    // start with offset, will be 0 if not specified
36411308Santhony.gutierrez@amd.com    uint64_t address = offset;
36511308Santhony.gutierrez@amd.com
36611308Santhony.gutierrez@amd.com    // add in symbol value if specified
36711308Santhony.gutierrez@amd.com    if (storageElement) {
36811308Santhony.gutierrez@amd.com        address += storageElement->offset;
36911308Santhony.gutierrez@amd.com    }
37011308Santhony.gutierrez@amd.com
37111308Santhony.gutierrez@amd.com    return address;
37211308Santhony.gutierrez@amd.com}
37311308Santhony.gutierrez@amd.com
37411308Santhony.gutierrez@amd.comstd::string
37511308Santhony.gutierrez@amd.comAddrOperandBase::disassemble(std::string reg_disassembly)
37611308Santhony.gutierrez@amd.com{
37711308Santhony.gutierrez@amd.com    std::string disasm;
37811308Santhony.gutierrez@amd.com
37911308Santhony.gutierrez@amd.com    if (offset || reg_disassembly != "") {
38011308Santhony.gutierrez@amd.com        disasm += "[";
38111308Santhony.gutierrez@amd.com
38211308Santhony.gutierrez@amd.com        if (reg_disassembly != "") {
38311308Santhony.gutierrez@amd.com            disasm += reg_disassembly;
38411308Santhony.gutierrez@amd.com
38511308Santhony.gutierrez@amd.com            if (offset > 0) {
38611308Santhony.gutierrez@amd.com                disasm += "+";
38711308Santhony.gutierrez@amd.com            }
38811308Santhony.gutierrez@amd.com        }
38911308Santhony.gutierrez@amd.com
39011308Santhony.gutierrez@amd.com        if (offset) {
39111308Santhony.gutierrez@amd.com            disasm += csprintf("%d", offset);
39211308Santhony.gutierrez@amd.com        }
39311308Santhony.gutierrez@amd.com
39411308Santhony.gutierrez@amd.com        disasm += "]";
39511308Santhony.gutierrez@amd.com    } else if (name) {
39611308Santhony.gutierrez@amd.com        disasm += csprintf("[%s]", name);
39711308Santhony.gutierrez@amd.com    }
39811308Santhony.gutierrez@amd.com
39911308Santhony.gutierrez@amd.com    return disasm;
40011308Santhony.gutierrez@amd.com}
40111308Santhony.gutierrez@amd.com
40211308Santhony.gutierrez@amd.comvoid
40311308Santhony.gutierrez@amd.comNoRegAddrOperand::init(unsigned opOffset, const BrigObject *obj)
40411308Santhony.gutierrez@amd.com{
40511308Santhony.gutierrez@amd.com    const BrigOperand *baseOp = obj->getOperand(opOffset);
40611308Santhony.gutierrez@amd.com
40711308Santhony.gutierrez@amd.com    if (baseOp->kind == BRIG_KIND_OPERAND_ADDRESS) {
40811308Santhony.gutierrez@amd.com        BrigOperandAddress *addrOp = (BrigOperandAddress*)baseOp;
40911308Santhony.gutierrez@amd.com        parseAddr(addrOp, obj);
41011308Santhony.gutierrez@amd.com        offset = (uint64_t(addrOp->offset.hi) << 32) |
41111308Santhony.gutierrez@amd.com                  uint64_t(addrOp->offset.lo);
41211308Santhony.gutierrez@amd.com    } else {
41311308Santhony.gutierrez@amd.com        fatal("NoRegAddrOperand: bad operand kind %d\n", baseOp->kind);
41411308Santhony.gutierrez@amd.com    }
41511308Santhony.gutierrez@amd.com
41611308Santhony.gutierrez@amd.com}
41711308Santhony.gutierrez@amd.com
41811308Santhony.gutierrez@amd.comstd::string
41911308Santhony.gutierrez@amd.comNoRegAddrOperand::disassemble()
42011308Santhony.gutierrez@amd.com{
42111308Santhony.gutierrez@amd.com    return AddrOperandBase::disassemble(std::string(""));
42211308Santhony.gutierrez@amd.com}
42311308Santhony.gutierrez@amd.com
42411308Santhony.gutierrez@amd.comvoid
42511308Santhony.gutierrez@amd.comLabelOperand::init(unsigned opOffset, const BrigObject *obj)
42611308Santhony.gutierrez@amd.com{
42711308Santhony.gutierrez@amd.com    const BrigOperandCodeRef *op =
42811308Santhony.gutierrez@amd.com        (const BrigOperandCodeRef*)obj->getOperand(opOffset);
42911308Santhony.gutierrez@amd.com
43011308Santhony.gutierrez@amd.com    assert(op->base.kind == BRIG_KIND_OPERAND_CODE_REF);
43111308Santhony.gutierrez@amd.com
43211308Santhony.gutierrez@amd.com    const BrigDirective *dir =
43311308Santhony.gutierrez@amd.com        (const BrigDirective*)obj->getCodeSectionEntry(op->ref);
43411308Santhony.gutierrez@amd.com
43511308Santhony.gutierrez@amd.com    assert(dir->kind == BRIG_KIND_DIRECTIVE_LABEL);
43611308Santhony.gutierrez@amd.com    label = obj->currentCode->refLabel((BrigDirectiveLabel*)dir, obj);
43711308Santhony.gutierrez@amd.com}
43811308Santhony.gutierrez@amd.com
43911308Santhony.gutierrez@amd.comuint32_t
44011308Santhony.gutierrez@amd.comLabelOperand::getTarget(Wavefront *w, int lane)
44111308Santhony.gutierrez@amd.com{
44211308Santhony.gutierrez@amd.com    return label->get();
44311308Santhony.gutierrez@amd.com}
44411308Santhony.gutierrez@amd.com
44511308Santhony.gutierrez@amd.comstd::string
44611308Santhony.gutierrez@amd.comLabelOperand::disassemble()
44711308Santhony.gutierrez@amd.com{
44811308Santhony.gutierrez@amd.com    return label->name;
44911308Santhony.gutierrez@amd.com}
450