You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
6.9 KiB
175 lines
6.9 KiB
// AsmJit - Machine code generation for C++
|
|
//
|
|
// * 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.
|
|
|
|
#ifndef ASMJIT_CORE_ARCHTRAITS_H_INCLUDED
|
|
#define ASMJIT_CORE_ARCHTRAITS_H_INCLUDED
|
|
|
|
#include "../core/environment.h"
|
|
#include "../core/operand.h"
|
|
#include "../core/type.h"
|
|
|
|
ASMJIT_BEGIN_NAMESPACE
|
|
|
|
//! \addtogroup asmjit_core
|
|
//! \{
|
|
|
|
// ============================================================================
|
|
// [asmjit::ArchTraits]
|
|
// ============================================================================
|
|
|
|
//! Architecture traits used by Function API and Compiler's register allocator.
|
|
struct ArchTraits {
|
|
//! ISA features for each register group.
|
|
enum IsaFeatures : uint32_t {
|
|
//! ISA features a register swap by using a single instruction.
|
|
kIsaFeatureSwap = 0x01u,
|
|
//! ISA features a push/pop like instruction for this register group.
|
|
kIsaFeaturePushPop = 0x02u,
|
|
};
|
|
|
|
//! Stack pointer register id.
|
|
uint8_t _spRegId;
|
|
//! Frame pointer register id.
|
|
uint8_t _fpRegId;
|
|
//! Link register id.
|
|
uint8_t _linkRegId;
|
|
//! Instruction pointer (or program counter) register id, if accessible.
|
|
uint8_t _ipRegId;
|
|
|
|
// Reserved.
|
|
uint8_t _reserved[3];
|
|
//! Hardware stack alignment requirement.
|
|
uint8_t _hwStackAlignment;
|
|
//! Minimum addressable offset on stack guaranteed for all instructions.
|
|
uint32_t _minStackOffset;
|
|
//! Maximum addressable offset on stack depending on specific instruction.
|
|
uint32_t _maxStackOffset;
|
|
|
|
//! Flags for each virtual register group (always covers GP and Vec groups).
|
|
uint8_t _isaFlags[BaseReg::kGroupVirt];
|
|
|
|
//! Maps register type into a signature, that provides group, size and can
|
|
//! be used to construct register operands.
|
|
RegInfo _regInfo[BaseReg::kTypeMax + 1];
|
|
//! Maps a register to type-id, see \ref Type::Id.
|
|
uint8_t _regTypeToTypeId[BaseReg::kTypeMax + 1];
|
|
//! Maps base TypeId values (from TypeId::_kIdBaseStart) to register types, see \ref Type::Id.
|
|
uint8_t _typeIdToRegType[32];
|
|
|
|
//! Resets all members to zeros.
|
|
inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
|
|
|
|
//! \name Accessors
|
|
//! \{
|
|
|
|
//! Returns stack pointer register id.
|
|
inline constexpr uint32_t spRegId() const noexcept { return _spRegId; }
|
|
//! Returns stack frame register id.
|
|
inline constexpr uint32_t fpRegId() const noexcept { return _fpRegId; }
|
|
//! Returns link register id, if the architecture provides it.
|
|
inline constexpr uint32_t linkRegId() const noexcept { return _linkRegId; }
|
|
//! Returns instruction pointer register id, if the architecture provides it.
|
|
inline constexpr uint32_t ipRegId() const noexcept { return _ipRegId; }
|
|
|
|
//! Returns a hardware stack alignment requirement.
|
|
//!
|
|
//! \note This is a hardware constraint. Architectures that don't constrain
|
|
//! it would return the lowest alignment (1), however, some architectures may
|
|
//! constrain the alignment, for example AArch64 requires 16-byte alignment.
|
|
inline constexpr uint32_t hwStackAlignment() const noexcept { return _hwStackAlignment; }
|
|
|
|
//! Tests whether the architecture provides link register, which is used across
|
|
//! function calls. If the link register is not provided then a function call
|
|
//! pushes the return address on stack (X86/X64).
|
|
inline constexpr bool hasLinkReg() const noexcept { return _linkRegId != BaseReg::kIdBad; }
|
|
|
|
//! Returns minimum addressable offset on stack guaranteed for all instructions.
|
|
inline constexpr uint32_t minStackOffset() const noexcept { return _minStackOffset; }
|
|
//! Returns maximum addressable offset on stack depending on specific instruction.
|
|
inline constexpr uint32_t maxStackOffset() const noexcept { return _maxStackOffset; }
|
|
|
|
//! Returns ISA flags of the given register `group`.
|
|
inline constexpr uint32_t isaFlags(uint32_t group) const noexcept { return _isaFlags[group]; }
|
|
//! Tests whether the given register `group` has the given `flag` set.
|
|
inline constexpr bool hasIsaFlag(uint32_t group, uint32_t flag) const noexcept { return (_isaFlags[group] & flag) != 0; }
|
|
//! Tests whether the ISA provides register swap instruction for the given register `group`.
|
|
inline constexpr bool hasSwap(uint32_t group) const noexcept { return hasIsaFlag(group, kIsaFeatureSwap); }
|
|
//! Tests whether the ISA provides push/pop instructions for the given register `group`.
|
|
inline constexpr bool hasPushPop(uint32_t group) const noexcept { return hasIsaFlag(group, kIsaFeaturePushPop); }
|
|
|
|
inline uint32_t hasRegType(uint32_t rType) const noexcept {
|
|
return rType <= BaseReg::kTypeMax && _regInfo[rType].signature() != 0;
|
|
}
|
|
|
|
inline uint32_t regTypeToSignature(uint32_t rType) const noexcept {
|
|
ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
|
|
return _regInfo[rType].signature();
|
|
}
|
|
|
|
inline uint32_t regTypeToGroup(uint32_t rType) const noexcept {
|
|
ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
|
|
return _regInfo[rType].group();
|
|
}
|
|
|
|
inline uint32_t regTypeToSize(uint32_t rType) const noexcept {
|
|
ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
|
|
return _regInfo[rType].size();
|
|
}
|
|
|
|
inline uint32_t regTypeToTypeId(uint32_t rType) const noexcept {
|
|
ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
|
|
return _regTypeToTypeId[rType];
|
|
}
|
|
|
|
//! \}
|
|
|
|
//! \name Statics
|
|
//! \{
|
|
|
|
//! Returns a const reference to `ArchTraits` for the given architecture `arch`.
|
|
static inline const ArchTraits& byArch(uint32_t arch) noexcept;
|
|
|
|
//! \}
|
|
};
|
|
|
|
ASMJIT_VARAPI const ArchTraits _archTraits[Environment::kArchCount];
|
|
|
|
inline const ArchTraits& ArchTraits::byArch(uint32_t arch) noexcept { return _archTraits[arch & ~Environment::kArchBigEndianMask]; }
|
|
|
|
// ============================================================================
|
|
// [asmjit::ArchUtils]
|
|
// ============================================================================
|
|
|
|
//! Architecture utilities.
|
|
namespace ArchUtils {
|
|
|
|
ASMJIT_API Error typeIdToRegInfo(uint32_t arch, uint32_t typeId, uint32_t* typeIdOut, RegInfo* regInfo) noexcept;
|
|
|
|
} // {ArchUtils}
|
|
|
|
//! \}
|
|
|
|
ASMJIT_END_NAMESPACE
|
|
|
|
#endif // ASMJIT_CORE_ARCHTRAITS_H_INCLUDED
|