#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include "llvm/ADT/ArrayRef.h" #include "revng/ABI/Trait.h" #include "revng/Model/ABI.h" #include "revng/Support/EnumSwitch.h" namespace abi { constexpr bool areArgumentsPositionBased(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); return skippingEnumSwitch<1>(ABI, [&]() { return abi::Trait::ArgumentsArePositionBased; }); } constexpr bool canOnlyStartDoubleArgumentsFromAnEvenRegister(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); return skippingEnumSwitch<1>(ABI, [&]() { return abi::Trait::OnlyStartDoubleArgumentsFromAnEvenRegister; }); } constexpr bool canArgumentsBeSplitBetweenRegistersAndStack(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); return skippingEnumSwitch<1>(ABI, [&]() { return abi::Trait::ArgumentsCanBeSplitBetweenRegistersAndStack; }); } constexpr bool canOnlyUsePointerToCopyForStackArguments(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); return skippingEnumSwitch<1>(ABI, [&]() { return abi::Trait::UsePointerToCopyForStackArguments; }); } constexpr size_t countMaximumGPRsPerAggregateArgument(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); return skippingEnumSwitch<1>(ABI, [&]() { return abi::Trait::MaximumGPRsPerAggregateArgument; }); } constexpr size_t countMaximumGPRsPerAggregateReturnValue(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); return skippingEnumSwitch<1>(ABI, [&]() { return abi::Trait::MaximumGPRsPerAggregateReturnValue; }); } constexpr size_t countMaximumGPRsPerScalarArgument(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); return skippingEnumSwitch<1>(ABI, [&]() { return abi::Trait::MaximumGPRsPerScalarArgument; }); } constexpr size_t countMaximumGPRsPerScalarReturnValue(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); return skippingEnumSwitch<1>(ABI, [&]() { return abi::Trait::MaximumGPRsPerScalarReturnValue; }); } constexpr llvm::ArrayRef listGeneralPurposeArgumentRegisters(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); using Registers = llvm::ArrayRef; return skippingEnumSwitch<1>(ABI, [&]() -> Registers { return abi::Trait::GeneralPurposeArgumentRegisters; }); } constexpr llvm::ArrayRef listGeneralPurposeReturnValueRegisters(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); using Registers = llvm::ArrayRef; return skippingEnumSwitch<1>(ABI, [&]() -> Registers { return abi::Trait::GeneralPurposeReturnValueRegisters; }); } constexpr llvm::ArrayRef listVectorArgumentRegisters(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); using Registers = llvm::ArrayRef; return skippingEnumSwitch<1>(ABI, [&]() -> Registers { return abi::Trait::VectorArgumentRegisters; }); } constexpr llvm::ArrayRef listVectorReturnValueRegisters(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); using Registers = llvm::ArrayRef; return skippingEnumSwitch<1>(ABI, [&]() -> Registers { return abi::Trait::VectorReturnValueRegisters; }); } constexpr llvm::ArrayRef listCalleeSavedRegisters(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); using Registers = llvm::ArrayRef; return skippingEnumSwitch<1>(ABI, [&]() -> Registers { return abi::Trait::CalleeSavedRegisters; }); } constexpr model::Register::Values getReturnValueLocationRegister(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); return skippingEnumSwitch<1>(ABI, [&]() { return abi::Trait::ReturnValueLocationRegister; }); } constexpr bool isCalleeResponsibleForStackCleanup(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); return skippingEnumSwitch<1>(ABI, [&]() { return abi::Trait::CalleeIsResponsibleForStackCleanup; }); } constexpr size_t getStackAlignment(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); return skippingEnumSwitch<1>(ABI, [&]() { return abi::Trait::StackAlignment; }); } constexpr size_t getMinimumStackArgumentSize(model::ABI::Values ABI) { revng_assert(ABI != model::ABI::Invalid); return skippingEnumSwitch<1>(ABI, [&]() { return abi::Trait::MinimumStackArgumentSize; }); } } // namespace abi