| /* |
| * Copyright (c) 2015 Advanced Micro Devices, Inc. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * 3. Neither the name of the copyright holder nor the names of its |
| * contributors may be used to endorse or promote products derived from this |
| * software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "gpu-compute/gpu_static_inst.hh" |
| |
| #include "debug/GPUInst.hh" |
| |
| namespace gem5 |
| { |
| |
| GPUStaticInst::GPUStaticInst(const std::string &opcode) |
| : executed_as(enums::SC_NONE), _opcode(opcode), |
| _instNum(0), _instAddr(0), srcVecDWords(-1), dstVecDWords(-1), |
| srcScalarDWords(-1), dstScalarDWords(-1), maxOpSize(-1) |
| { |
| } |
| |
| const std::string& |
| GPUStaticInst::disassemble() |
| { |
| if (disassembly.empty()) { |
| generateDisassembly(); |
| assert(!disassembly.empty()); |
| } |
| |
| return disassembly; |
| } |
| |
| void |
| GPUStaticInst::initDynOperandInfo(Wavefront *wf, ComputeUnit *cu) |
| { |
| // Lambda function, as this is only ever used here |
| auto generateVirtToPhysMap = [&](OperandInfo& op, |
| std::vector<OperandInfo>& opVec, |
| MapRegFn mapFn, OpType opType) |
| { |
| std::vector<int> virt_idxs; |
| std::vector<int> phys_idxs; |
| |
| int num_dwords = op.sizeInDWords(); |
| int virt_idx = op.registerIndex(wf->reservedScalarRegs); |
| |
| int phys_idx = -1; |
| for (int i = 0; i < num_dwords; i++){ |
| phys_idx = (cu->registerManager->*mapFn)(wf, virt_idx + i); |
| virt_idxs.push_back(virt_idx + i); |
| phys_idxs.push_back(phys_idx); |
| } |
| DPRINTF(GPUInst, "%s adding %s %s (%d->%d) operand that uses " |
| "%d registers.\n", disassemble(), |
| (opType == OpType::SRC_VEC || opType == OpType::DST_VEC) ? |
| "vector" : "scalar", |
| (opType == OpType::SRC_VEC || opType == OpType::SRC_SCALAR) ? |
| "src" : "dst", virt_idxs[0], phys_idxs[0], num_dwords); |
| |
| op.setVirtToPhysMapping(virt_idxs, phys_idxs); |
| |
| opVec.emplace_back(op); |
| }; |
| |
| for (auto& srcOp : srcOps) { |
| if (srcOp.isVectorReg()) { |
| generateVirtToPhysMap(srcOp, srcVecRegOps, |
| &RegisterManager::mapVgpr, OpType::SRC_VEC); |
| } else if (srcOp.isScalarReg()) { |
| generateVirtToPhysMap(srcOp, srcScalarRegOps, |
| &RegisterManager::mapSgpr, OpType::SRC_SCALAR); |
| } |
| } |
| |
| for (auto& dstOp : dstOps) { |
| if (dstOp.isVectorReg()) { |
| generateVirtToPhysMap(dstOp, dstVecRegOps, |
| &RegisterManager::mapVgpr, OpType::DST_VEC); |
| } else if (dstOp.isScalarReg()) { |
| generateVirtToPhysMap(dstOp, dstScalarRegOps, |
| &RegisterManager::mapSgpr, OpType::DST_SCALAR); |
| } |
| } |
| } |
| |
| int |
| GPUStaticInst::numSrcVecOperands() |
| { |
| return srcVecRegOps.size(); |
| } |
| |
| int |
| GPUStaticInst::numDstVecOperands() |
| { |
| return dstVecRegOps.size(); |
| } |
| |
| int |
| GPUStaticInst::numSrcVecDWords() |
| { |
| if (srcVecDWords != -1) { |
| return srcVecDWords; |
| } |
| |
| srcVecDWords = 0; |
| |
| for (const auto& srcOp : srcOps) |
| if (srcOp.isVectorReg()) |
| srcVecDWords += srcOp.sizeInDWords(); |
| |
| return srcVecDWords; |
| } |
| |
| int |
| GPUStaticInst::numDstVecDWords() |
| { |
| if (dstVecDWords != -1) { |
| return dstVecDWords; |
| } |
| |
| dstVecDWords = 0; |
| |
| for (const auto& dstOp : dstOps) |
| if (dstOp.isVectorReg()) |
| dstVecDWords += dstOp.sizeInDWords(); |
| |
| return dstVecDWords; |
| } |
| |
| int |
| GPUStaticInst::numSrcScalarOperands() |
| { |
| return srcScalarRegOps.size(); |
| } |
| |
| int |
| GPUStaticInst::numDstScalarOperands() |
| { |
| return dstScalarRegOps.size(); |
| } |
| |
| int |
| GPUStaticInst::numSrcScalarDWords() |
| { |
| if (srcScalarDWords != -1) |
| return srcScalarDWords; |
| |
| srcScalarDWords = 0; |
| |
| for (const auto& srcOp : srcOps) |
| if (srcOp.isScalarReg()) |
| srcScalarDWords += srcOp.sizeInDWords(); |
| |
| return srcScalarDWords; |
| } |
| |
| int |
| GPUStaticInst::numDstScalarDWords() |
| { |
| if (dstScalarDWords != -1) |
| return dstScalarDWords; |
| |
| dstScalarDWords = 0; |
| |
| for (const auto& dstOp : dstOps) |
| if (dstOp.isScalarReg()) |
| dstScalarDWords += dstOp.sizeInDWords(); |
| |
| return dstScalarDWords; |
| } |
| |
| int |
| GPUStaticInst::maxOperandSize() |
| { |
| if (maxOpSize != -1) |
| return maxOpSize; |
| |
| maxOpSize = 0; |
| |
| for (const auto& dstOp : dstOps) |
| if (dstOp.size() > maxOpSize) |
| maxOpSize = dstOp.size(); |
| |
| for (const auto& srcOp : srcOps) |
| if (srcOp.size() > maxOpSize) |
| maxOpSize = srcOp.size(); |
| |
| return maxOpSize; |
| } |
| |
| } // namespace gem5 |