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