operand.hh 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#ifndef __ARCH_HSAIL_OPERAND_HH__ 3711308Santhony.gutierrez@amd.com#define __ARCH_HSAIL_OPERAND_HH__ 3811308Santhony.gutierrez@amd.com 3911308Santhony.gutierrez@amd.com/** 4011308Santhony.gutierrez@amd.com * @file operand.hh 4111308Santhony.gutierrez@amd.com * 4211308Santhony.gutierrez@amd.com * Defines classes encapsulating HSAIL instruction operands. 4311308Santhony.gutierrez@amd.com */ 4411308Santhony.gutierrez@amd.com 4511308Santhony.gutierrez@amd.com#include <string> 4611308Santhony.gutierrez@amd.com 4711308Santhony.gutierrez@amd.com#include "arch/hsail/Brig.h" 4811308Santhony.gutierrez@amd.com#include "base/trace.hh" 4911308Santhony.gutierrez@amd.com#include "base/types.hh" 5011308Santhony.gutierrez@amd.com#include "debug/GPUReg.hh" 5111308Santhony.gutierrez@amd.com#include "enums/RegisterType.hh" 5211308Santhony.gutierrez@amd.com#include "gpu-compute/brig_object.hh" 5311308Santhony.gutierrez@amd.com#include "gpu-compute/compute_unit.hh" 5411308Santhony.gutierrez@amd.com#include "gpu-compute/hsail_code.hh" 5511308Santhony.gutierrez@amd.com#include "gpu-compute/shader.hh" 5611308Santhony.gutierrez@amd.com#include "gpu-compute/vector_register_file.hh" 5711308Santhony.gutierrez@amd.com#include "gpu-compute/wavefront.hh" 5811308Santhony.gutierrez@amd.com 5911308Santhony.gutierrez@amd.comclass Label; 6011308Santhony.gutierrez@amd.comclass StorageElement; 6111308Santhony.gutierrez@amd.com 6211308Santhony.gutierrez@amd.comclass BaseOperand 6311308Santhony.gutierrez@amd.com{ 6411308Santhony.gutierrez@amd.com public: 6511308Santhony.gutierrez@amd.com Enums::RegisterType registerType; 6611308Santhony.gutierrez@amd.com uint32_t regOperandSize; 6711308Santhony.gutierrez@amd.com BaseOperand() { registerType = Enums::RT_NONE; regOperandSize = 0; } 6811308Santhony.gutierrez@amd.com bool isVectorRegister() { return registerType == Enums::RT_VECTOR; } 6911308Santhony.gutierrez@amd.com bool isScalarRegister() { return registerType == Enums::RT_SCALAR; } 7011308Santhony.gutierrez@amd.com bool isCondRegister() { return registerType == Enums::RT_CONDITION; } 7111308Santhony.gutierrez@amd.com unsigned int regIndex() { return 0; } 7211308Santhony.gutierrez@amd.com uint32_t opSize() { return regOperandSize; } 7311308Santhony.gutierrez@amd.com virtual ~BaseOperand() { } 7411308Santhony.gutierrez@amd.com}; 7511308Santhony.gutierrez@amd.com 7611308Santhony.gutierrez@amd.comclass BrigRegOperandInfo 7711308Santhony.gutierrez@amd.com{ 7811308Santhony.gutierrez@amd.com public: 7911308Santhony.gutierrez@amd.com Brig::BrigKind16_t kind; 8011308Santhony.gutierrez@amd.com Brig::BrigType type; 8111308Santhony.gutierrez@amd.com Brig::BrigRegisterKind regKind; 8211308Santhony.gutierrez@amd.com 8311308Santhony.gutierrez@amd.com BrigRegOperandInfo(Brig::BrigKind16_t _kind, 8411308Santhony.gutierrez@amd.com Brig::BrigRegisterKind _regKind) 8511308Santhony.gutierrez@amd.com : kind(_kind), regKind(_regKind) 8611308Santhony.gutierrez@amd.com { 8711308Santhony.gutierrez@amd.com } 8811308Santhony.gutierrez@amd.com 8911308Santhony.gutierrez@amd.com BrigRegOperandInfo(Brig::BrigKind16_t _kind, Brig::BrigType _type) 9011308Santhony.gutierrez@amd.com : kind(_kind), type(_type) 9111308Santhony.gutierrez@amd.com { 9211308Santhony.gutierrez@amd.com } 9311308Santhony.gutierrez@amd.com 9411308Santhony.gutierrez@amd.com BrigRegOperandInfo() : kind(Brig::BRIG_KIND_OPERAND_CONSTANT_BYTES), 9511308Santhony.gutierrez@amd.com type(Brig::BRIG_TYPE_NONE) 9611308Santhony.gutierrez@amd.com { 9711308Santhony.gutierrez@amd.com } 9811308Santhony.gutierrez@amd.com}; 9911308Santhony.gutierrez@amd.com 10011308Santhony.gutierrez@amd.comBrigRegOperandInfo findRegDataType(unsigned opOffset, const BrigObject *obj); 10111308Santhony.gutierrez@amd.com 10211308Santhony.gutierrez@amd.comclass BaseRegOperand : public BaseOperand 10311308Santhony.gutierrez@amd.com{ 10411308Santhony.gutierrez@amd.com public: 10511308Santhony.gutierrez@amd.com unsigned regIdx; 10611308Santhony.gutierrez@amd.com char regFileChar; 10711308Santhony.gutierrez@amd.com 10811308Santhony.gutierrez@amd.com bool init(unsigned opOffset, const BrigObject *obj, 10911308Santhony.gutierrez@amd.com unsigned &maxRegIdx, char _regFileChar); 11011308Santhony.gutierrez@amd.com 11111308Santhony.gutierrez@amd.com bool init_from_vect(unsigned opOffset, const BrigObject *obj, int at, 11211308Santhony.gutierrez@amd.com unsigned &maxRegIdx, char _regFileChar); 11311308Santhony.gutierrez@amd.com 11411308Santhony.gutierrez@amd.com void initWithStrOffset(unsigned strOffset, const BrigObject *obj, 11511308Santhony.gutierrez@amd.com unsigned &maxRegIdx, char _regFileChar); 11611308Santhony.gutierrez@amd.com unsigned int regIndex() { return regIdx; } 11711308Santhony.gutierrez@amd.com}; 11811308Santhony.gutierrez@amd.com 11911308Santhony.gutierrez@amd.comclass SRegOperand : public BaseRegOperand 12011308Santhony.gutierrez@amd.com{ 12111308Santhony.gutierrez@amd.com public: 12211308Santhony.gutierrez@amd.com static unsigned maxRegIdx; 12311308Santhony.gutierrez@amd.com 12411308Santhony.gutierrez@amd.com bool 12511308Santhony.gutierrez@amd.com init(unsigned opOffset, const BrigObject *obj) 12611308Santhony.gutierrez@amd.com { 12711308Santhony.gutierrez@amd.com regOperandSize = sizeof(uint32_t); 12811308Santhony.gutierrez@amd.com registerType = Enums::RT_VECTOR; 12911308Santhony.gutierrez@amd.com 13011308Santhony.gutierrez@amd.com return BaseRegOperand::init(opOffset, obj, maxRegIdx, 's'); 13111308Santhony.gutierrez@amd.com } 13211308Santhony.gutierrez@amd.com 13311308Santhony.gutierrez@amd.com bool 13411308Santhony.gutierrez@amd.com init_from_vect(unsigned opOffset, const BrigObject *obj, int at) 13511308Santhony.gutierrez@amd.com { 13611308Santhony.gutierrez@amd.com regOperandSize = sizeof(uint32_t); 13711308Santhony.gutierrez@amd.com registerType = Enums::RT_VECTOR; 13811308Santhony.gutierrez@amd.com 13911308Santhony.gutierrez@amd.com return BaseRegOperand::init_from_vect(opOffset, obj, at, maxRegIdx, 14011308Santhony.gutierrez@amd.com 's'); 14111308Santhony.gutierrez@amd.com } 14211308Santhony.gutierrez@amd.com 14311308Santhony.gutierrez@amd.com void 14411308Santhony.gutierrez@amd.com initWithStrOffset(unsigned strOffset, const BrigObject *obj) 14511308Santhony.gutierrez@amd.com { 14611308Santhony.gutierrez@amd.com regOperandSize = sizeof(uint32_t); 14711308Santhony.gutierrez@amd.com registerType = Enums::RT_VECTOR; 14811308Santhony.gutierrez@amd.com 14911308Santhony.gutierrez@amd.com return BaseRegOperand::initWithStrOffset(strOffset, obj, maxRegIdx, 15011308Santhony.gutierrez@amd.com 's'); 15111308Santhony.gutierrez@amd.com } 15211308Santhony.gutierrez@amd.com 15311308Santhony.gutierrez@amd.com template<typename OperandType> 15411308Santhony.gutierrez@amd.com OperandType 15511308Santhony.gutierrez@amd.com get(Wavefront *w, int lane) 15611308Santhony.gutierrez@amd.com { 15711308Santhony.gutierrez@amd.com assert(sizeof(OperandType) <= sizeof(uint32_t)); 15811308Santhony.gutierrez@amd.com assert(regIdx < w->maxSpVgprs); 15911308Santhony.gutierrez@amd.com // if OperandType is smaller than 32-bit, we truncate the value 16011308Santhony.gutierrez@amd.com OperandType ret; 16111308Santhony.gutierrez@amd.com uint32_t vgprIdx; 16211308Santhony.gutierrez@amd.com 16311308Santhony.gutierrez@amd.com switch (sizeof(OperandType)) { 16411308Santhony.gutierrez@amd.com case 1: // 1 byte operand 16511308Santhony.gutierrez@amd.com vgprIdx = w->remap(regIdx, 1, 1); 16611308Santhony.gutierrez@amd.com ret = (w->computeUnit->vrf[w->simdId]-> 16711308Santhony.gutierrez@amd.com read<uint32_t>(vgprIdx, lane)) & 0xff; 16811308Santhony.gutierrez@amd.com break; 16911308Santhony.gutierrez@amd.com case 2: // 2 byte operand 17011308Santhony.gutierrez@amd.com vgprIdx = w->remap(regIdx, 2, 1); 17111308Santhony.gutierrez@amd.com ret = (w->computeUnit->vrf[w->simdId]-> 17211308Santhony.gutierrez@amd.com read<uint32_t>(vgprIdx, lane)) & 0xffff; 17311308Santhony.gutierrez@amd.com break; 17411308Santhony.gutierrez@amd.com case 4: // 4 byte operand 17511308Santhony.gutierrez@amd.com vgprIdx = w->remap(regIdx,sizeof(OperandType), 1); 17611308Santhony.gutierrez@amd.com ret = w->computeUnit->vrf[w->simdId]-> 17711308Santhony.gutierrez@amd.com read<OperandType>(vgprIdx, lane); 17811308Santhony.gutierrez@amd.com break; 17911308Santhony.gutierrez@amd.com default: 18011308Santhony.gutierrez@amd.com panic("Bad OperandType\n"); 18111308Santhony.gutierrez@amd.com break; 18211308Santhony.gutierrez@amd.com } 18311308Santhony.gutierrez@amd.com 18411308Santhony.gutierrez@amd.com return (OperandType)ret; 18511308Santhony.gutierrez@amd.com } 18611308Santhony.gutierrez@amd.com 18711308Santhony.gutierrez@amd.com // special get method for compatibility with LabelOperand 18811308Santhony.gutierrez@amd.com uint32_t 18911308Santhony.gutierrez@amd.com getTarget(Wavefront *w, int lane) 19011308Santhony.gutierrez@amd.com { 19111308Santhony.gutierrez@amd.com return get<uint32_t>(w, lane); 19211308Santhony.gutierrez@amd.com } 19311308Santhony.gutierrez@amd.com 19411308Santhony.gutierrez@amd.com template<typename OperandType> 19511308Santhony.gutierrez@amd.com void set(Wavefront *w, int lane, OperandType &val); 19611308Santhony.gutierrez@amd.com std::string disassemble(); 19711308Santhony.gutierrez@amd.com}; 19811308Santhony.gutierrez@amd.com 19911308Santhony.gutierrez@amd.comtemplate<typename OperandType> 20011308Santhony.gutierrez@amd.comvoid 20111308Santhony.gutierrez@amd.comSRegOperand::set(Wavefront *w, int lane, OperandType &val) 20211308Santhony.gutierrez@amd.com{ 20311308Santhony.gutierrez@amd.com DPRINTF(GPUReg, "CU%d, WF[%d][%d], lane %d: $s%d <- %d\n", 20411308Santhony.gutierrez@amd.com w->computeUnit->cu_id, w->simdId, w->wfSlotId, lane, regIdx, val); 20511308Santhony.gutierrez@amd.com 20611308Santhony.gutierrez@amd.com assert(sizeof(OperandType) == sizeof(uint32_t)); 20711308Santhony.gutierrez@amd.com assert(regIdx < w->maxSpVgprs); 20811308Santhony.gutierrez@amd.com uint32_t vgprIdx = w->remap(regIdx, sizeof(OperandType), 1); 20911308Santhony.gutierrez@amd.com w->computeUnit->vrf[w->simdId]->write<OperandType>(vgprIdx,val,lane); 21011308Santhony.gutierrez@amd.com} 21111308Santhony.gutierrez@amd.com 21211308Santhony.gutierrez@amd.comtemplate<> 21311308Santhony.gutierrez@amd.cominline void 21411308Santhony.gutierrez@amd.comSRegOperand::set(Wavefront *w, int lane, uint64_t &val) 21511308Santhony.gutierrez@amd.com{ 21611308Santhony.gutierrez@amd.com DPRINTF(GPUReg, "CU%d, WF[%d][%d], lane %d: $s%d <- %d\n", 21711308Santhony.gutierrez@amd.com w->computeUnit->cu_id, w->simdId, w->wfSlotId, lane, regIdx, val); 21811308Santhony.gutierrez@amd.com 21911308Santhony.gutierrez@amd.com assert(regIdx < w->maxSpVgprs); 22011308Santhony.gutierrez@amd.com uint32_t vgprIdx = w->remap(regIdx, sizeof(uint32_t), 1); 22111308Santhony.gutierrez@amd.com w->computeUnit->vrf[w->simdId]->write<uint32_t>(vgprIdx, val, lane); 22211308Santhony.gutierrez@amd.com} 22311308Santhony.gutierrez@amd.com 22411308Santhony.gutierrez@amd.comclass DRegOperand : public BaseRegOperand 22511308Santhony.gutierrez@amd.com{ 22611308Santhony.gutierrez@amd.com public: 22711308Santhony.gutierrez@amd.com static unsigned maxRegIdx; 22811308Santhony.gutierrez@amd.com 22911308Santhony.gutierrez@amd.com bool 23011308Santhony.gutierrez@amd.com init(unsigned opOffset, const BrigObject *obj) 23111308Santhony.gutierrez@amd.com { 23211308Santhony.gutierrez@amd.com regOperandSize = sizeof(uint64_t); 23311308Santhony.gutierrez@amd.com registerType = Enums::RT_VECTOR; 23411308Santhony.gutierrez@amd.com 23511308Santhony.gutierrez@amd.com return BaseRegOperand::init(opOffset, obj, maxRegIdx, 'd'); 23611308Santhony.gutierrez@amd.com } 23711308Santhony.gutierrez@amd.com 23811308Santhony.gutierrez@amd.com bool 23911308Santhony.gutierrez@amd.com init_from_vect(unsigned opOffset, const BrigObject *obj, int at) 24011308Santhony.gutierrez@amd.com { 24111308Santhony.gutierrez@amd.com regOperandSize = sizeof(uint64_t); 24211308Santhony.gutierrez@amd.com registerType = Enums::RT_VECTOR; 24311308Santhony.gutierrez@amd.com 24411308Santhony.gutierrez@amd.com return BaseRegOperand::init_from_vect(opOffset, obj, at, maxRegIdx, 24511308Santhony.gutierrez@amd.com 'd'); 24611308Santhony.gutierrez@amd.com } 24711308Santhony.gutierrez@amd.com 24811308Santhony.gutierrez@amd.com void 24911308Santhony.gutierrez@amd.com initWithStrOffset(unsigned strOffset, const BrigObject *obj) 25011308Santhony.gutierrez@amd.com { 25111308Santhony.gutierrez@amd.com regOperandSize = sizeof(uint64_t); 25211308Santhony.gutierrez@amd.com registerType = Enums::RT_VECTOR; 25311308Santhony.gutierrez@amd.com 25411308Santhony.gutierrez@amd.com return BaseRegOperand::initWithStrOffset(strOffset, obj, maxRegIdx, 25511308Santhony.gutierrez@amd.com 'd'); 25611308Santhony.gutierrez@amd.com } 25711308Santhony.gutierrez@amd.com 25811308Santhony.gutierrez@amd.com template<typename OperandType> 25911308Santhony.gutierrez@amd.com OperandType 26011308Santhony.gutierrez@amd.com get(Wavefront *w, int lane) 26111308Santhony.gutierrez@amd.com { 26211308Santhony.gutierrez@amd.com assert(sizeof(OperandType) <= sizeof(uint64_t)); 26311308Santhony.gutierrez@amd.com // TODO: this check is valid only for HSAIL 26411308Santhony.gutierrez@amd.com assert(regIdx < w->maxDpVgprs); 26511308Santhony.gutierrez@amd.com uint32_t vgprIdx = w->remap(regIdx, sizeof(OperandType), 1); 26611308Santhony.gutierrez@amd.com 26711308Santhony.gutierrez@amd.com return w->computeUnit->vrf[w->simdId]->read<OperandType>(vgprIdx,lane); 26811308Santhony.gutierrez@amd.com } 26911308Santhony.gutierrez@amd.com 27011308Santhony.gutierrez@amd.com template<typename OperandType> 27111308Santhony.gutierrez@amd.com void 27211308Santhony.gutierrez@amd.com set(Wavefront *w, int lane, OperandType &val) 27311308Santhony.gutierrez@amd.com { 27411308Santhony.gutierrez@amd.com DPRINTF(GPUReg, "CU%d, WF[%d][%d], lane %d: $d%d <- %d\n", 27511308Santhony.gutierrez@amd.com w->computeUnit->cu_id, w->simdId, w->wfSlotId, lane, regIdx, 27611308Santhony.gutierrez@amd.com val); 27711308Santhony.gutierrez@amd.com 27811308Santhony.gutierrez@amd.com assert(sizeof(OperandType) <= sizeof(uint64_t)); 27911308Santhony.gutierrez@amd.com // TODO: this check is valid only for HSAIL 28011308Santhony.gutierrez@amd.com assert(regIdx < w->maxDpVgprs); 28111308Santhony.gutierrez@amd.com uint32_t vgprIdx = w->remap(regIdx, sizeof(OperandType), 1); 28211308Santhony.gutierrez@amd.com w->computeUnit->vrf[w->simdId]->write<OperandType>(vgprIdx,val,lane); 28311308Santhony.gutierrez@amd.com } 28411308Santhony.gutierrez@amd.com 28511308Santhony.gutierrez@amd.com std::string disassemble(); 28611308Santhony.gutierrez@amd.com}; 28711308Santhony.gutierrez@amd.com 28811308Santhony.gutierrez@amd.comclass CRegOperand : public BaseRegOperand 28911308Santhony.gutierrez@amd.com{ 29011308Santhony.gutierrez@amd.com public: 29111308Santhony.gutierrez@amd.com static unsigned maxRegIdx; 29211308Santhony.gutierrez@amd.com 29311308Santhony.gutierrez@amd.com bool 29411308Santhony.gutierrez@amd.com init(unsigned opOffset, const BrigObject *obj) 29511308Santhony.gutierrez@amd.com { 29611308Santhony.gutierrez@amd.com regOperandSize = sizeof(uint8_t); 29711308Santhony.gutierrez@amd.com registerType = Enums::RT_CONDITION; 29811308Santhony.gutierrez@amd.com 29911308Santhony.gutierrez@amd.com return BaseRegOperand::init(opOffset, obj, maxRegIdx, 'c'); 30011308Santhony.gutierrez@amd.com } 30111308Santhony.gutierrez@amd.com 30211308Santhony.gutierrez@amd.com bool 30311308Santhony.gutierrez@amd.com init_from_vect(unsigned opOffset, const BrigObject *obj, int at) 30411308Santhony.gutierrez@amd.com { 30511308Santhony.gutierrez@amd.com regOperandSize = sizeof(uint8_t); 30611308Santhony.gutierrez@amd.com registerType = Enums::RT_CONDITION; 30711308Santhony.gutierrez@amd.com 30811308Santhony.gutierrez@amd.com return BaseRegOperand::init_from_vect(opOffset, obj, at, maxRegIdx, 30911308Santhony.gutierrez@amd.com 'c'); 31011308Santhony.gutierrez@amd.com } 31111308Santhony.gutierrez@amd.com 31211308Santhony.gutierrez@amd.com void 31311308Santhony.gutierrez@amd.com initWithStrOffset(unsigned strOffset, const BrigObject *obj) 31411308Santhony.gutierrez@amd.com { 31511308Santhony.gutierrez@amd.com regOperandSize = sizeof(uint8_t); 31611308Santhony.gutierrez@amd.com registerType = Enums::RT_CONDITION; 31711308Santhony.gutierrez@amd.com 31811308Santhony.gutierrez@amd.com return BaseRegOperand::initWithStrOffset(strOffset, obj, maxRegIdx, 31911308Santhony.gutierrez@amd.com 'c'); 32011308Santhony.gutierrez@amd.com } 32111308Santhony.gutierrez@amd.com 32211308Santhony.gutierrez@amd.com template<typename OperandType> 32311308Santhony.gutierrez@amd.com OperandType 32411308Santhony.gutierrez@amd.com get(Wavefront *w, int lane) 32511308Santhony.gutierrez@amd.com { 32611308Santhony.gutierrez@amd.com assert(regIdx < w->condRegState->numRegs()); 32711308Santhony.gutierrez@amd.com 32811308Santhony.gutierrez@amd.com return w->condRegState->read<OperandType>((int)regIdx, lane); 32911308Santhony.gutierrez@amd.com } 33011308Santhony.gutierrez@amd.com 33111308Santhony.gutierrez@amd.com template<typename OperandType> 33211308Santhony.gutierrez@amd.com void 33311308Santhony.gutierrez@amd.com set(Wavefront *w, int lane, OperandType &val) 33411308Santhony.gutierrez@amd.com { 33511308Santhony.gutierrez@amd.com DPRINTF(GPUReg, "CU%d, WF[%d][%d], lane %d: $c%d <- %d\n", 33611308Santhony.gutierrez@amd.com w->computeUnit->cu_id, w->simdId, w->wfSlotId, lane, regIdx, 33711308Santhony.gutierrez@amd.com val); 33811308Santhony.gutierrez@amd.com 33911308Santhony.gutierrez@amd.com assert(regIdx < w->condRegState->numRegs()); 34011308Santhony.gutierrez@amd.com w->condRegState->write<OperandType>(regIdx,lane,val); 34111308Santhony.gutierrez@amd.com } 34211308Santhony.gutierrez@amd.com 34311308Santhony.gutierrez@amd.com std::string disassemble(); 34411308Santhony.gutierrez@amd.com}; 34511308Santhony.gutierrez@amd.com 34611308Santhony.gutierrez@amd.comtemplate<typename T> 34711308Santhony.gutierrez@amd.comclass ImmOperand : public BaseOperand 34811308Santhony.gutierrez@amd.com{ 34911308Santhony.gutierrez@amd.com public: 35011308Santhony.gutierrez@amd.com T bits; 35111308Santhony.gutierrez@amd.com 35211308Santhony.gutierrez@amd.com bool init(unsigned opOffset, const BrigObject *obj); 35311308Santhony.gutierrez@amd.com bool init_from_vect(unsigned opOffset, const BrigObject *obj, int at); 35411308Santhony.gutierrez@amd.com std::string disassemble(); 35511308Santhony.gutierrez@amd.com 35611308Santhony.gutierrez@amd.com template<typename OperandType> 35711308Santhony.gutierrez@amd.com OperandType 35811308Santhony.gutierrez@amd.com get() 35911308Santhony.gutierrez@amd.com { 36011308Santhony.gutierrez@amd.com assert(sizeof(OperandType) <= sizeof(T)); 36111308Santhony.gutierrez@amd.com 36211308Santhony.gutierrez@amd.com return *(OperandType*)&bits; 36311308Santhony.gutierrez@amd.com } 36411308Santhony.gutierrez@amd.com 36511308Santhony.gutierrez@amd.com // This version of get() takes a WF* and a lane id for 36611308Santhony.gutierrez@amd.com // compatibility with the register-based get() methods. 36711308Santhony.gutierrez@amd.com template<typename OperandType> 36811308Santhony.gutierrez@amd.com OperandType 36911308Santhony.gutierrez@amd.com get(Wavefront *w, int lane) 37011308Santhony.gutierrez@amd.com { 37111308Santhony.gutierrez@amd.com return get<OperandType>(); 37211308Santhony.gutierrez@amd.com } 37311308Santhony.gutierrez@amd.com}; 37411308Santhony.gutierrez@amd.com 37511308Santhony.gutierrez@amd.comtemplate<typename T> 37611308Santhony.gutierrez@amd.combool 37711308Santhony.gutierrez@amd.comImmOperand<T>::init(unsigned opOffset, const BrigObject *obj) 37811308Santhony.gutierrez@amd.com{ 37911308Santhony.gutierrez@amd.com const Brig::BrigOperand *brigOp = obj->getOperand(opOffset); 38011308Santhony.gutierrez@amd.com 38111308Santhony.gutierrez@amd.com switch (brigOp->kind) { 38211308Santhony.gutierrez@amd.com // this is immediate operand 38311308Santhony.gutierrez@amd.com case Brig::BRIG_KIND_OPERAND_CONSTANT_BYTES: 38411308Santhony.gutierrez@amd.com { 38511308Santhony.gutierrez@amd.com DPRINTF(GPUReg, "sizeof(T): %lu, byteCount: %d\n", sizeof(T), 38611308Santhony.gutierrez@amd.com brigOp->byteCount); 38711308Santhony.gutierrez@amd.com 38811308Santhony.gutierrez@amd.com auto cbptr = (Brig::BrigOperandConstantBytes*)brigOp; 38911308Santhony.gutierrez@amd.com 39011308Santhony.gutierrez@amd.com bits = *((T*)(obj->getData(cbptr->bytes + 4))); 39111308Santhony.gutierrez@amd.com 39211308Santhony.gutierrez@amd.com return true; 39311308Santhony.gutierrez@amd.com } 39411308Santhony.gutierrez@amd.com break; 39511308Santhony.gutierrez@amd.com 39611308Santhony.gutierrez@amd.com case Brig::BRIG_KIND_OPERAND_WAVESIZE: 39711308Santhony.gutierrez@amd.com bits = VSZ; 39811308Santhony.gutierrez@amd.com return true; 39911308Santhony.gutierrez@amd.com 40011308Santhony.gutierrez@amd.com default: 40111308Santhony.gutierrez@amd.com return false; 40211308Santhony.gutierrez@amd.com } 40311308Santhony.gutierrez@amd.com} 40411308Santhony.gutierrez@amd.com 40511308Santhony.gutierrez@amd.comtemplate <typename T> 40611308Santhony.gutierrez@amd.combool 40711308Santhony.gutierrez@amd.comImmOperand<T>::init_from_vect(unsigned opOffset, const BrigObject *obj, int at) 40811308Santhony.gutierrez@amd.com{ 40911308Santhony.gutierrez@amd.com const Brig::BrigOperand *brigOp = obj->getOperand(opOffset); 41011308Santhony.gutierrez@amd.com 41111308Santhony.gutierrez@amd.com if (brigOp->kind != Brig::BRIG_KIND_OPERAND_OPERAND_LIST) { 41211308Santhony.gutierrez@amd.com return false; 41311308Santhony.gutierrez@amd.com } 41411308Santhony.gutierrez@amd.com 41511308Santhony.gutierrez@amd.com 41611308Santhony.gutierrez@amd.com const Brig::BrigOperandOperandList *brigVecOp = 41711308Santhony.gutierrez@amd.com (const Brig::BrigOperandOperandList *)brigOp; 41811308Santhony.gutierrez@amd.com 41911308Santhony.gutierrez@amd.com unsigned *data_offset = 42011308Santhony.gutierrez@amd.com (unsigned *)obj->getData(brigVecOp->elements + 4 * (at + 1)); 42111308Santhony.gutierrez@amd.com 42211308Santhony.gutierrez@amd.com const Brig::BrigOperand *p = 42311308Santhony.gutierrez@amd.com (const Brig::BrigOperand *)obj->getOperand(*data_offset); 42411308Santhony.gutierrez@amd.com 42511308Santhony.gutierrez@amd.com if (p->kind != Brig::BRIG_KIND_OPERAND_CONSTANT_BYTES) { 42611308Santhony.gutierrez@amd.com return false; 42711308Santhony.gutierrez@amd.com } 42811308Santhony.gutierrez@amd.com 42911308Santhony.gutierrez@amd.com return init(*data_offset, obj); 43011308Santhony.gutierrez@amd.com} 43111308Santhony.gutierrez@amd.comtemplate<typename T> 43211308Santhony.gutierrez@amd.comstd::string 43311308Santhony.gutierrez@amd.comImmOperand<T>::disassemble() 43411308Santhony.gutierrez@amd.com{ 43511308Santhony.gutierrez@amd.com return csprintf("0x%08x", bits); 43611308Santhony.gutierrez@amd.com} 43711308Santhony.gutierrez@amd.com 43811308Santhony.gutierrez@amd.comtemplate<typename RegOperand, typename T> 43911308Santhony.gutierrez@amd.comclass RegOrImmOperand : public BaseOperand 44011308Santhony.gutierrez@amd.com{ 44111308Santhony.gutierrez@amd.com private: 44211308Santhony.gutierrez@amd.com bool is_imm; 44311308Santhony.gutierrez@amd.com 44411308Santhony.gutierrez@amd.com public: 44511308Santhony.gutierrez@amd.com void setImm(const bool value) { is_imm = value; } 44611308Santhony.gutierrez@amd.com 44711308Santhony.gutierrez@amd.com ImmOperand<T> imm_op; 44811308Santhony.gutierrez@amd.com RegOperand reg_op; 44911308Santhony.gutierrez@amd.com 45011308Santhony.gutierrez@amd.com RegOrImmOperand() { is_imm = false; } 45111308Santhony.gutierrez@amd.com void init(unsigned opOffset, const BrigObject *obj); 45211308Santhony.gutierrez@amd.com void init_from_vect(unsigned opOffset, const BrigObject *obj, int at); 45311308Santhony.gutierrez@amd.com std::string disassemble(); 45411308Santhony.gutierrez@amd.com 45511308Santhony.gutierrez@amd.com template<typename OperandType> 45611308Santhony.gutierrez@amd.com OperandType 45711308Santhony.gutierrez@amd.com get(Wavefront *w, int lane) 45811308Santhony.gutierrez@amd.com { 45911308Santhony.gutierrez@amd.com return is_imm ? imm_op.template get<OperandType>() : 46011308Santhony.gutierrez@amd.com reg_op.template get<OperandType>(w, lane); 46111308Santhony.gutierrez@amd.com } 46211308Santhony.gutierrez@amd.com 46311308Santhony.gutierrez@amd.com uint32_t 46411308Santhony.gutierrez@amd.com opSize() 46511308Santhony.gutierrez@amd.com { 46611308Santhony.gutierrez@amd.com if (!is_imm) { 46711308Santhony.gutierrez@amd.com return reg_op.opSize(); 46811308Santhony.gutierrez@amd.com } 46911308Santhony.gutierrez@amd.com 47011308Santhony.gutierrez@amd.com return 0; 47111308Santhony.gutierrez@amd.com } 47211308Santhony.gutierrez@amd.com 47311308Santhony.gutierrez@amd.com bool 47411308Santhony.gutierrez@amd.com isVectorRegister() 47511308Santhony.gutierrez@amd.com { 47611308Santhony.gutierrez@amd.com if (!is_imm) { 47711308Santhony.gutierrez@amd.com return reg_op.registerType == Enums::RT_VECTOR; 47811308Santhony.gutierrez@amd.com } 47911308Santhony.gutierrez@amd.com return false; 48011308Santhony.gutierrez@amd.com } 48111308Santhony.gutierrez@amd.com 48211308Santhony.gutierrez@amd.com bool 48311308Santhony.gutierrez@amd.com isCondRegister() 48411308Santhony.gutierrez@amd.com { 48511308Santhony.gutierrez@amd.com if (!is_imm) { 48611308Santhony.gutierrez@amd.com return reg_op.registerType == Enums::RT_CONDITION; 48711308Santhony.gutierrez@amd.com } 48811308Santhony.gutierrez@amd.com 48911308Santhony.gutierrez@amd.com return false; 49011308Santhony.gutierrez@amd.com } 49111308Santhony.gutierrez@amd.com 49211308Santhony.gutierrez@amd.com bool 49311308Santhony.gutierrez@amd.com isScalarRegister() 49411308Santhony.gutierrez@amd.com { 49511308Santhony.gutierrez@amd.com if (!is_imm) { 49611308Santhony.gutierrez@amd.com return reg_op.registerType == Enums::RT_SCALAR; 49711308Santhony.gutierrez@amd.com } 49811308Santhony.gutierrez@amd.com 49911308Santhony.gutierrez@amd.com return false; 50011308Santhony.gutierrez@amd.com } 50111308Santhony.gutierrez@amd.com 50211308Santhony.gutierrez@amd.com unsigned int 50311308Santhony.gutierrez@amd.com regIndex() 50411308Santhony.gutierrez@amd.com { 50511308Santhony.gutierrez@amd.com if (!is_imm) { 50611308Santhony.gutierrez@amd.com return reg_op.regIndex(); 50711308Santhony.gutierrez@amd.com } 50811308Santhony.gutierrez@amd.com return 0; 50911308Santhony.gutierrez@amd.com } 51011308Santhony.gutierrez@amd.com}; 51111308Santhony.gutierrez@amd.com 51211308Santhony.gutierrez@amd.comtemplate<typename RegOperand, typename T> 51311308Santhony.gutierrez@amd.comvoid 51411308Santhony.gutierrez@amd.comRegOrImmOperand<RegOperand, T>::init(unsigned opOffset, const BrigObject *obj) 51511308Santhony.gutierrez@amd.com{ 51611308Santhony.gutierrez@amd.com is_imm = false; 51711308Santhony.gutierrez@amd.com 51811308Santhony.gutierrez@amd.com if (reg_op.init(opOffset, obj)) { 51911308Santhony.gutierrez@amd.com return; 52011308Santhony.gutierrez@amd.com } 52111308Santhony.gutierrez@amd.com 52211308Santhony.gutierrez@amd.com if (imm_op.init(opOffset, obj)) { 52311308Santhony.gutierrez@amd.com is_imm = true; 52411308Santhony.gutierrez@amd.com return; 52511308Santhony.gutierrez@amd.com } 52611308Santhony.gutierrez@amd.com 52711308Santhony.gutierrez@amd.com fatal("RegOrImmOperand::init(): bad operand kind %d\n", 52811308Santhony.gutierrez@amd.com obj->getOperand(opOffset)->kind); 52911308Santhony.gutierrez@amd.com} 53011308Santhony.gutierrez@amd.com 53111308Santhony.gutierrez@amd.comtemplate<typename RegOperand, typename T> 53211308Santhony.gutierrez@amd.comvoid 53311308Santhony.gutierrez@amd.comRegOrImmOperand<RegOperand, T>::init_from_vect(unsigned opOffset, 53411308Santhony.gutierrez@amd.com const BrigObject *obj, int at) 53511308Santhony.gutierrez@amd.com{ 53611308Santhony.gutierrez@amd.com if (reg_op.init_from_vect(opOffset, obj, at)) { 53711308Santhony.gutierrez@amd.com is_imm = false; 53811308Santhony.gutierrez@amd.com 53911308Santhony.gutierrez@amd.com return; 54011308Santhony.gutierrez@amd.com } 54111308Santhony.gutierrez@amd.com 54211308Santhony.gutierrez@amd.com if (imm_op.init_from_vect(opOffset, obj, at)) { 54311308Santhony.gutierrez@amd.com is_imm = true; 54411308Santhony.gutierrez@amd.com 54511308Santhony.gutierrez@amd.com return; 54611308Santhony.gutierrez@amd.com } 54711308Santhony.gutierrez@amd.com 54811308Santhony.gutierrez@amd.com fatal("RegOrImmOperand::init(): bad operand kind %d\n", 54911308Santhony.gutierrez@amd.com obj->getOperand(opOffset)->kind); 55011308Santhony.gutierrez@amd.com} 55111308Santhony.gutierrez@amd.com 55211308Santhony.gutierrez@amd.comtemplate<typename RegOperand, typename T> 55311308Santhony.gutierrez@amd.comstd::string 55411308Santhony.gutierrez@amd.comRegOrImmOperand<RegOperand, T>::disassemble() 55511308Santhony.gutierrez@amd.com{ 55611308Santhony.gutierrez@amd.com return is_imm ? imm_op.disassemble() : reg_op.disassemble(); 55711308Santhony.gutierrez@amd.com} 55811308Santhony.gutierrez@amd.com 55911308Santhony.gutierrez@amd.comtypedef RegOrImmOperand<SRegOperand, uint32_t> SRegOrImmOperand; 56011308Santhony.gutierrez@amd.comtypedef RegOrImmOperand<DRegOperand, uint64_t> DRegOrImmOperand; 56111308Santhony.gutierrez@amd.comtypedef RegOrImmOperand<CRegOperand, bool> CRegOrImmOperand; 56211308Santhony.gutierrez@amd.com 56311308Santhony.gutierrez@amd.comclass AddrOperandBase : public BaseOperand 56411308Santhony.gutierrez@amd.com{ 56511308Santhony.gutierrez@amd.com protected: 56611308Santhony.gutierrez@amd.com // helper function for init() 56711308Santhony.gutierrez@amd.com void parseAddr(const Brig::BrigOperandAddress *op, const BrigObject *obj); 56811308Santhony.gutierrez@amd.com 56911308Santhony.gutierrez@amd.com // helper function for disassemble() 57011308Santhony.gutierrez@amd.com std::string disassemble(std::string reg_disassembly); 57111308Santhony.gutierrez@amd.com uint64_t calcUniformBase(); 57211308Santhony.gutierrez@amd.com 57311308Santhony.gutierrez@amd.com public: 57411308Santhony.gutierrez@amd.com virtual void calcVector(Wavefront *w, uint64_t *addrVec) = 0; 57511308Santhony.gutierrez@amd.com virtual uint64_t calcLane(Wavefront *w, int lane=0) = 0; 57611308Santhony.gutierrez@amd.com 57711308Santhony.gutierrez@amd.com uint64_t offset; 57811308Santhony.gutierrez@amd.com const char *name = nullptr; 57911308Santhony.gutierrez@amd.com StorageElement *storageElement; 58011308Santhony.gutierrez@amd.com}; 58111308Santhony.gutierrez@amd.com 58211308Santhony.gutierrez@amd.comtemplate<typename RegOperandType> 58311308Santhony.gutierrez@amd.comclass RegAddrOperand : public AddrOperandBase 58411308Santhony.gutierrez@amd.com{ 58511308Santhony.gutierrez@amd.com public: 58611308Santhony.gutierrez@amd.com RegOperandType reg; 58711308Santhony.gutierrez@amd.com void init(unsigned opOffset, const BrigObject *obj); 58811308Santhony.gutierrez@amd.com uint64_t calcUniform(); 58911308Santhony.gutierrez@amd.com void calcVector(Wavefront *w, uint64_t *addrVec); 59011308Santhony.gutierrez@amd.com uint64_t calcLane(Wavefront *w, int lane=0); 59111308Santhony.gutierrez@amd.com uint32_t opSize() { return reg.opSize(); } 59211308Santhony.gutierrez@amd.com bool isVectorRegister() { return reg.registerType == Enums::RT_VECTOR; } 59311308Santhony.gutierrez@amd.com bool isCondRegister() { return reg.registerType == Enums::RT_CONDITION; } 59411308Santhony.gutierrez@amd.com bool isScalarRegister() { return reg.registerType == Enums::RT_SCALAR; } 59511308Santhony.gutierrez@amd.com unsigned int regIndex() { return reg.regIndex(); } 59611308Santhony.gutierrez@amd.com std::string disassemble(); 59711308Santhony.gutierrez@amd.com}; 59811308Santhony.gutierrez@amd.com 59911308Santhony.gutierrez@amd.comtemplate<typename RegOperandType> 60011308Santhony.gutierrez@amd.comvoid 60111308Santhony.gutierrez@amd.comRegAddrOperand<RegOperandType>::init(unsigned opOffset, const BrigObject *obj) 60211308Santhony.gutierrez@amd.com{ 60311308Santhony.gutierrez@amd.com using namespace Brig; 60411308Santhony.gutierrez@amd.com 60511308Santhony.gutierrez@amd.com const BrigOperand *baseOp = obj->getOperand(opOffset); 60611308Santhony.gutierrez@amd.com 60711308Santhony.gutierrez@amd.com switch (baseOp->kind) { 60811308Santhony.gutierrez@amd.com case BRIG_KIND_OPERAND_ADDRESS: 60911308Santhony.gutierrez@amd.com { 61011308Santhony.gutierrez@amd.com const BrigOperandAddress *op = (BrigOperandAddress*)baseOp; 61111308Santhony.gutierrez@amd.com storageElement = nullptr; 61211308Santhony.gutierrez@amd.com 61311308Santhony.gutierrez@amd.com offset = (uint64_t(op->offset.hi) << 32) | uint64_t(op->offset.lo); 61411308Santhony.gutierrez@amd.com reg.init(op->reg, obj); 61511308Santhony.gutierrez@amd.com 61611308Santhony.gutierrez@amd.com if (reg.regFileChar == 's') { 61711308Santhony.gutierrez@amd.com reg.regOperandSize = sizeof(uint32_t); 61811308Santhony.gutierrez@amd.com registerType = Enums::RT_VECTOR; 61911308Santhony.gutierrez@amd.com } 62011308Santhony.gutierrez@amd.com else if (reg.regFileChar == 'd') { 62111308Santhony.gutierrez@amd.com reg.regOperandSize = sizeof(uint64_t); 62211308Santhony.gutierrez@amd.com registerType = Enums::RT_VECTOR; 62311308Santhony.gutierrez@amd.com } 62411308Santhony.gutierrez@amd.com } 62511308Santhony.gutierrez@amd.com break; 62611308Santhony.gutierrez@amd.com 62711308Santhony.gutierrez@amd.com default: 62811308Santhony.gutierrez@amd.com fatal("RegAddrOperand: bad operand kind %d\n", baseOp->kind); 62911308Santhony.gutierrez@amd.com break; 63011308Santhony.gutierrez@amd.com } 63111308Santhony.gutierrez@amd.com} 63211308Santhony.gutierrez@amd.com 63311308Santhony.gutierrez@amd.comtemplate<typename RegOperandType> 63411308Santhony.gutierrez@amd.comuint64_t 63511308Santhony.gutierrez@amd.comRegAddrOperand<RegOperandType>::calcUniform() 63611308Santhony.gutierrez@amd.com{ 63711308Santhony.gutierrez@amd.com fatal("can't do calcUniform() on register-based address\n"); 63811308Santhony.gutierrez@amd.com 63911308Santhony.gutierrez@amd.com return 0; 64011308Santhony.gutierrez@amd.com} 64111308Santhony.gutierrez@amd.com 64211308Santhony.gutierrez@amd.comtemplate<typename RegOperandType> 64311308Santhony.gutierrez@amd.comvoid 64411308Santhony.gutierrez@amd.comRegAddrOperand<RegOperandType>::calcVector(Wavefront *w, uint64_t *addrVec) 64511308Santhony.gutierrez@amd.com{ 64611308Santhony.gutierrez@amd.com Addr address = calcUniformBase(); 64711308Santhony.gutierrez@amd.com 64811308Santhony.gutierrez@amd.com for (int lane = 0; lane < VSZ; ++lane) { 64911308Santhony.gutierrez@amd.com if (w->execMask(lane)) { 65011308Santhony.gutierrez@amd.com if (reg.regFileChar == 's') { 65111308Santhony.gutierrez@amd.com addrVec[lane] = address + reg.template get<uint32_t>(w, lane); 65211308Santhony.gutierrez@amd.com } else { 65311308Santhony.gutierrez@amd.com addrVec[lane] = address + reg.template get<Addr>(w, lane); 65411308Santhony.gutierrez@amd.com } 65511308Santhony.gutierrez@amd.com } 65611308Santhony.gutierrez@amd.com } 65711308Santhony.gutierrez@amd.com} 65811308Santhony.gutierrez@amd.com 65911308Santhony.gutierrez@amd.comtemplate<typename RegOperandType> 66011308Santhony.gutierrez@amd.comuint64_t 66111308Santhony.gutierrez@amd.comRegAddrOperand<RegOperandType>::calcLane(Wavefront *w, int lane) 66211308Santhony.gutierrez@amd.com{ 66311308Santhony.gutierrez@amd.com Addr address = calcUniformBase(); 66411308Santhony.gutierrez@amd.com 66511308Santhony.gutierrez@amd.com return address + reg.template get<Addr>(w, lane); 66611308Santhony.gutierrez@amd.com} 66711308Santhony.gutierrez@amd.com 66811308Santhony.gutierrez@amd.comtemplate<typename RegOperandType> 66911308Santhony.gutierrez@amd.comstd::string 67011308Santhony.gutierrez@amd.comRegAddrOperand<RegOperandType>::disassemble() 67111308Santhony.gutierrez@amd.com{ 67211308Santhony.gutierrez@amd.com return AddrOperandBase::disassemble(reg.disassemble()); 67311308Santhony.gutierrez@amd.com} 67411308Santhony.gutierrez@amd.com 67511308Santhony.gutierrez@amd.comtypedef RegAddrOperand<SRegOperand> SRegAddrOperand; 67611308Santhony.gutierrez@amd.comtypedef RegAddrOperand<DRegOperand> DRegAddrOperand; 67711308Santhony.gutierrez@amd.com 67811308Santhony.gutierrez@amd.comclass NoRegAddrOperand : public AddrOperandBase 67911308Santhony.gutierrez@amd.com{ 68011308Santhony.gutierrez@amd.com public: 68111308Santhony.gutierrez@amd.com void init(unsigned opOffset, const BrigObject *obj); 68211308Santhony.gutierrez@amd.com uint64_t calcUniform(); 68311308Santhony.gutierrez@amd.com void calcVector(Wavefront *w, uint64_t *addrVec); 68411308Santhony.gutierrez@amd.com uint64_t calcLane(Wavefront *w, int lane=0); 68511308Santhony.gutierrez@amd.com std::string disassemble(); 68611308Santhony.gutierrez@amd.com}; 68711308Santhony.gutierrez@amd.com 68811308Santhony.gutierrez@amd.cominline uint64_t 68911308Santhony.gutierrez@amd.comNoRegAddrOperand::calcUniform() 69011308Santhony.gutierrez@amd.com{ 69111308Santhony.gutierrez@amd.com return AddrOperandBase::calcUniformBase(); 69211308Santhony.gutierrez@amd.com} 69311308Santhony.gutierrez@amd.com 69411308Santhony.gutierrez@amd.cominline uint64_t 69511308Santhony.gutierrez@amd.comNoRegAddrOperand::calcLane(Wavefront *w, int lane) 69611308Santhony.gutierrez@amd.com{ 69711308Santhony.gutierrez@amd.com return calcUniform(); 69811308Santhony.gutierrez@amd.com} 69911308Santhony.gutierrez@amd.com 70011308Santhony.gutierrez@amd.cominline void 70111308Santhony.gutierrez@amd.comNoRegAddrOperand::calcVector(Wavefront *w, uint64_t *addrVec) 70211308Santhony.gutierrez@amd.com{ 70311308Santhony.gutierrez@amd.com uint64_t address = calcUniformBase(); 70411308Santhony.gutierrez@amd.com 70511308Santhony.gutierrez@amd.com for (int lane = 0; lane < VSZ; ++lane) 70611308Santhony.gutierrez@amd.com addrVec[lane] = address; 70711308Santhony.gutierrez@amd.com} 70811308Santhony.gutierrez@amd.com 70911308Santhony.gutierrez@amd.comclass LabelOperand : public BaseOperand 71011308Santhony.gutierrez@amd.com{ 71111308Santhony.gutierrez@amd.com public: 71211308Santhony.gutierrez@amd.com Label *label; 71311308Santhony.gutierrez@amd.com 71411308Santhony.gutierrez@amd.com void init(unsigned opOffset, const BrigObject *obj); 71511308Santhony.gutierrez@amd.com std::string disassemble(); 71611308Santhony.gutierrez@amd.com 71711308Santhony.gutierrez@amd.com // special get method for compatibility with SRegOperand 71811308Santhony.gutierrez@amd.com uint32_t getTarget(Wavefront *w, int lane); 71911308Santhony.gutierrez@amd.com 72011308Santhony.gutierrez@amd.com}; 72111308Santhony.gutierrez@amd.com 72211308Santhony.gutierrez@amd.comclass ListOperand : public BaseOperand 72311308Santhony.gutierrez@amd.com{ 72411308Santhony.gutierrez@amd.com public: 72511308Santhony.gutierrez@amd.com int elementCount; 72611308Santhony.gutierrez@amd.com std::vector<StorageElement*> callArgs; 72711308Santhony.gutierrez@amd.com 72811308Santhony.gutierrez@amd.com int 72911308Santhony.gutierrez@amd.com getSrcOperand(int idx) 73011308Santhony.gutierrez@amd.com { 73111308Santhony.gutierrez@amd.com DPRINTF(GPUReg, "getSrcOperand, idx: %d, sz_args: %d\n", idx, 73211308Santhony.gutierrez@amd.com callArgs.size()); 73311308Santhony.gutierrez@amd.com 73411308Santhony.gutierrez@amd.com return callArgs.at(idx)->offset; 73511308Santhony.gutierrez@amd.com } 73611308Santhony.gutierrez@amd.com 73711308Santhony.gutierrez@amd.com void init(unsigned opOffset, const BrigObject *obj); 73811308Santhony.gutierrez@amd.com 73911308Santhony.gutierrez@amd.com std::string disassemble(); 74011308Santhony.gutierrez@amd.com 74111308Santhony.gutierrez@amd.com template<typename OperandType> 74211308Santhony.gutierrez@amd.com OperandType 74311308Santhony.gutierrez@amd.com get(Wavefront *w, int lane, int arg_idx) 74411308Santhony.gutierrez@amd.com { 74511308Santhony.gutierrez@amd.com return w->readCallArgMem<OperandType>(lane, getSrcOperand(arg_idx)); 74611308Santhony.gutierrez@amd.com } 74711308Santhony.gutierrez@amd.com 74811308Santhony.gutierrez@amd.com template<typename OperandType> 74911308Santhony.gutierrez@amd.com void 75011308Santhony.gutierrez@amd.com set(Wavefront *w, int lane, OperandType val) 75111308Santhony.gutierrez@amd.com { 75211308Santhony.gutierrez@amd.com w->writeCallArgMem<OperandType>(lane, getSrcOperand(0), val); 75311308Santhony.gutierrez@amd.com DPRINTF(GPUReg, "CU%d, WF[%d][%d], lane %d: arg[%d] <- %d\n", 75411308Santhony.gutierrez@amd.com w->computeUnit->cu_id, w->simdId, w->wfSlotId, lane, 75511308Santhony.gutierrez@amd.com getSrcOperand(0), val); 75611308Santhony.gutierrez@amd.com } 75711308Santhony.gutierrez@amd.com}; 75811308Santhony.gutierrez@amd.com 75911308Santhony.gutierrez@amd.comclass FunctionRefOperand : public BaseOperand 76011308Santhony.gutierrez@amd.com{ 76111308Santhony.gutierrez@amd.com public: 76211308Santhony.gutierrez@amd.com const char *func_name; 76311308Santhony.gutierrez@amd.com 76411308Santhony.gutierrez@amd.com void init(unsigned opOffset, const BrigObject *obj); 76511308Santhony.gutierrez@amd.com std::string disassemble(); 76611308Santhony.gutierrez@amd.com}; 76711308Santhony.gutierrez@amd.com 76811308Santhony.gutierrez@amd.com#endif // __ARCH_HSAIL_OPERAND_HH__ 769