diff options
Diffstat (limited to 'src/asmjit/core/funcargscontext.cpp')
-rw-r--r-- | src/asmjit/core/funcargscontext.cpp | 97 |
1 files changed, 37 insertions, 60 deletions
diff --git a/src/asmjit/core/funcargscontext.cpp b/src/asmjit/core/funcargscontext.cpp index 331e205..8ce806f 100644 --- a/src/asmjit/core/funcargscontext.cpp +++ b/src/asmjit/core/funcargscontext.cpp @@ -1,25 +1,7 @@ -// AsmJit - Machine code generation for C++ +// This file is part of AsmJit project <https://asmjit.com> // -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. +// See asmjit.h or LICENSE.md for license and copyright information +// SPDX-License-Identifier: Zlib #include "../core/api-build_p.h" #include "../core/funcargscontext_p.h" @@ -31,29 +13,24 @@ ASMJIT_BEGIN_NAMESPACE //! \{ FuncArgsContext::FuncArgsContext() noexcept { - for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) - _workData[group].reset(); + for (RegGroup group : RegGroupVirtValues{}) + _workData[size_t(group)].reset(); } ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, const FuncArgsAssignment& args, const RAConstraints* constraints) noexcept { - // The code has to be updated if this changes. - ASMJIT_ASSERT(BaseReg::kGroupVirt == 4); - - uint32_t i; - - uint32_t arch = frame.arch(); + Arch arch = frame.arch(); const FuncDetail& func = *args.funcDetail(); _archTraits = &ArchTraits::byArch(arch); _constraints = constraints; - _arch = uint8_t(arch); + _arch = arch; // Initialize `_archRegs`. - for (i = 0; i < BaseReg::kGroupVirt; i++) - _workData[i]._archRegs = _constraints->availableRegs(i); + for (RegGroup group : RegGroupVirtValues{}) + _workData[group]._archRegs = _constraints->availableRegs(group); if (frame.hasPreservedFP()) - _workData[BaseReg::kGroupGp]._archRegs &= ~Support::bitMask(archTraits().fpRegId()); + _workData[size_t(RegGroup::kGp)]._archRegs &= ~Support::bitMask(archTraits().fpRegId()); // Extract information from all function arguments/assignments and build Var[] array. uint32_t varId = 0; @@ -73,7 +50,7 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co FuncValue& src = var.cur; FuncValue& dst = var.out; - uint32_t dstGroup = 0xFFFFFFFFu; + RegGroup dstGroup = RegGroup::kMaxValue; uint32_t dstId = BaseReg::kIdBad; WorkData* dstWd = nullptr; @@ -82,18 +59,17 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co return DebugUtils::errored(kErrorInvalidAssignment); if (dst.isReg()) { - uint32_t dstType = dst.regType(); + RegType dstType = dst.regType(); if (ASMJIT_UNLIKELY(!archTraits().hasRegType(dstType))) return DebugUtils::errored(kErrorInvalidRegType); - // Copy TypeId from source if the destination doesn't have it. The RA - // used by BaseCompiler would never leave TypeId undefined, but users - // of FuncAPI can just assign phys regs without specifying the type. + // Copy TypeId from source if the destination doesn't have it. The RA used by BaseCompiler would never + // leave TypeId undefined, but users of FuncAPI can just assign phys regs without specifying the type. if (!dst.hasTypeId()) dst.setTypeId(archTraits().regTypeToTypeId(dst.regType())); dstGroup = archTraits().regTypeToGroup(dstType); - if (ASMJIT_UNLIKELY(dstGroup >= BaseReg::kGroupVirt)) + if (ASMJIT_UNLIKELY(dstGroup > RegGroup::kMaxVirt)) return DebugUtils::errored(kErrorInvalidRegGroup); dstWd = &_workData[dstGroup]; @@ -112,15 +88,15 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co if (!dst.hasTypeId()) dst.setTypeId(src.typeId()); - RegInfo regInfo = getSuitableRegForMemToMemMove(arch, dst.typeId(), src.typeId()); - if (ASMJIT_UNLIKELY(!regInfo.isValid())) + OperandSignature signature = getSuitableRegForMemToMemMove(arch, dst.typeId(), src.typeId()); + if (ASMJIT_UNLIKELY(!signature.isValid())) return DebugUtils::errored(kErrorInvalidState); - _stackDstMask = uint8_t(_stackDstMask | Support::bitMask(regInfo.group())); + _stackDstMask = uint8_t(_stackDstMask | Support::bitMask(signature.regGroup())); } if (src.isReg()) { uint32_t srcId = src.regId(); - uint32_t srcGroup = archTraits().regTypeToGroup(src.regType()); + RegGroup srcGroup = archTraits().regTypeToGroup(src.regType()); if (dstGroup == srcGroup) { dstWd->assign(varId, srcId); @@ -130,10 +106,10 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co var.markDone(); } else { - if (ASMJIT_UNLIKELY(srcGroup >= BaseReg::kGroupVirt)) + if (ASMJIT_UNLIKELY(srcGroup > RegGroup::kMaxVirt)) return DebugUtils::errored(kErrorInvalidState); - WorkData& srcData = _workData[srcGroup]; + WorkData& srcData = _workData[size_t(srcGroup)]; srcData.assign(varId, srcId); } } @@ -148,14 +124,15 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co } // Initialize WorkData::workRegs. - for (i = 0; i < BaseReg::kGroupVirt; i++) { - _workData[i]._workRegs = (_workData[i].archRegs() & (frame.dirtyRegs(i) | ~frame.preservedRegs(i))) | _workData[i].dstRegs() | _workData[i].assignedRegs(); + for (RegGroup group : RegGroupVirtValues{}) { + _workData[group]._workRegs = + (_workData[group].archRegs() & (frame.dirtyRegs(group) | ~frame.preservedRegs(group))) | _workData[group].dstRegs() | _workData[group].assignedRegs(); } // Create a variable that represents `SARegId` if necessary. bool saRegRequired = _hasStackSrc && frame.hasDynamicAlignment() && !frame.hasPreservedFP(); - WorkData& gpRegs = _workData[BaseReg::kGroupGp]; + WorkData& gpRegs = _workData[RegGroup::kGp]; uint32_t saCurRegId = frame.saRegId(); uint32_t saOutRegId = args.saRegId(); @@ -173,8 +150,8 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co } if (saRegRequired) { - uint32_t ptrTypeId = Environment::is32Bit(arch) ? Type::kIdU32 : Type::kIdU64; - uint32_t ptrRegType = Environment::is32Bit(arch) ? BaseReg::kTypeGp32 : BaseReg::kTypeGp64; + TypeId ptrTypeId = Environment::is32Bit(arch) ? TypeId::kUInt32 : TypeId::kUInt64; + RegType ptrRegType = Environment::is32Bit(arch) ? RegType::kGp32 : RegType::kGp64; _saVarId = uint8_t(varId); _hasPreservedFP = frame.hasPreservedFP(); @@ -187,7 +164,7 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co saCurRegId = saOutRegId; } else { - uint32_t availableRegs = gpRegs.availableRegs(); + RegMask availableRegs = gpRegs.availableRegs(); if (!availableRegs) availableRegs = gpRegs.archRegs() & ~gpRegs.workRegs(); @@ -223,7 +200,7 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co uint32_t srcId = var.cur.regId(); uint32_t dstId = var.out.regId(); - uint32_t group = archTraits().regTypeToGroup(var.cur.regType()); + RegGroup group = archTraits().regTypeToGroup(var.cur.regType()); if (group != archTraits().regTypeToGroup(var.out.regType())) continue; @@ -242,12 +219,12 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co } ASMJIT_FAVOR_SIZE Error FuncArgsContext::markDstRegsDirty(FuncFrame& frame) noexcept { - for (uint32_t i = 0; i < BaseReg::kGroupVirt; i++) { - WorkData& wd = _workData[i]; + for (RegGroup group : RegGroupVirtValues{}) { + WorkData& wd = _workData[group]; uint32_t regs = wd.usedRegs() | wd._dstShuf; wd._workRegs |= regs; - frame.addDirtyRegs(i, regs); + frame.addDirtyRegs(group, regs); } return kErrorOk; @@ -260,19 +237,19 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::markScratchRegs(FuncFrame& frame) noexc groupMask |= _stackDstMask; // Handle register swaps. - groupMask |= _regSwapsMask & ~Support::bitMask(BaseReg::kGroupGp); + groupMask |= _regSwapsMask & ~Support::bitMask(RegGroup::kGp); if (!groupMask) return kErrorOk; // Selects one dirty register per affected group that can be used as a scratch register. - for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) { + for (RegGroup group : RegGroupVirtValues{}) { if (Support::bitTest(groupMask, group)) { WorkData& wd = _workData[group]; // Initially, pick some clobbered or dirty register. - uint32_t workRegs = wd.workRegs(); - uint32_t regs = workRegs & ~(wd.usedRegs() | wd._dstShuf); + RegMask workRegs = wd.workRegs(); + RegMask regs = workRegs & ~(wd.usedRegs() | wd._dstShuf); // If that didn't work out pick some register which is not in 'used'. if (!regs) @@ -288,7 +265,7 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::markScratchRegs(FuncFrame& frame) noexc if (!regs) continue; - uint32_t regMask = Support::blsi(regs); + RegMask regMask = Support::blsi(regs); wd._workRegs |= regMask; frame.addDirtyRegs(group, regMask); } |