Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/asmjit/asmjit.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/asmjit/core/funcargscontext.cpp')
-rw-r--r--src/asmjit/core/funcargscontext.cpp97
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);
}