Switch atmosphere's build target to C++20. (#952)

* ams: update to build with gcc10/c++20

* remove mno-outline-atomics

* ams: take care of most TODO C++20s

* fusee/sept: update for gcc10

* whoosh, your code now uses pre-compiled headers

* make: dependency fixes
This commit is contained in:
SciresM 2020-05-11 15:02:10 -07:00 committed by GitHub
parent 17b6bcfd37
commit 3a1ccdd919
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
258 changed files with 723 additions and 804 deletions

View file

@ -261,12 +261,11 @@ namespace ams::svc::codegen::impl {
/* TODO */
};
template<typename CodeGenerator, typename MetaCodeHolder>
static ALWAYS_INLINE void GenerateCodeForMetaCode(MetaCodeHolder) {
constexpr auto MetaCode = UNWRAP_TEMPLATE_CONSTANT(MetaCodeHolder);
template<typename CodeGenerator, auto MetaCode>
static ALWAYS_INLINE void GenerateCodeForMetaCode() {
constexpr size_t NumOperations = MetaCode.GetNumOperations();
static_assert(NumOperations <= 64);
#define SVC_CODEGEN_HANDLER(n) do { if constexpr (n < NumOperations) { constexpr auto Operation = MetaCode.GetOperation(n); GenerateCodeForOperation<CodeGenerator>(WRAP_TEMPLATE_CONSTANT(Operation)); } } while (0)
#define SVC_CODEGEN_HANDLER(n) do { if constexpr (n < NumOperations) { constexpr auto Operation = MetaCode.GetOperation(n); GenerateCodeForOperation<CodeGenerator, Operation>(); } } while (0)
SVC_CODEGEN_FOR_I_FROM_0_TO_64(SVC_CODEGEN_HANDLER)
#undef SVC_CODEGEN_HANDLER
}

View file

@ -143,7 +143,7 @@ namespace ams::svc::codegen::impl {
template<size_t N>
class RegisterAllocator {
private:
public:
std::array<bool, N> map;
public:
constexpr explicit RegisterAllocator() : map() { /* ... */ }

View file

@ -319,38 +319,43 @@ namespace ams::svc::codegen::impl {
template<typename... T>
struct TypeIndexFilter {
template<typename UseArrayHolder, typename HeadType, typename... TailType, size_t HeadIndex, size_t... TailIndex>
static constexpr auto GetFilteredTupleImpl(UseArrayHolder, std::tuple<HeadType, TailType...>, std::index_sequence<HeadIndex, TailIndex...>) {
constexpr auto UseArray = UNWRAP_TEMPLATE_CONSTANT(UseArrayHolder);
static_assert(sizeof...(TailType) == sizeof...(TailIndex));
static_assert(HeadIndex <= UseArray.size());
if constexpr (sizeof...(TailType) == 0) {
if constexpr (!UseArray[HeadIndex]) {
return std::tuple<HeadType>{};
} else {
return std::tuple<>{};
}
} else {
auto tail_tuple = GetFilteredTupleImpl(UseArrayHolder{}, std::tuple<TailType...>{}, std::index_sequence<TailIndex...>{});
if constexpr (!UseArray[HeadIndex]) {
return std::tuple_cat(std::tuple<HeadType>{}, tail_tuple);
} else {
return std::tuple_cat(std::tuple<>{}, tail_tuple);
}
}
}
template<auto UseArray, typename X, typename Y>
struct Helper;
template<typename UseArrayHolder>
static constexpr auto GetFilteredTuple(UseArrayHolder) {
return GetFilteredTupleImpl(UseArrayHolder{}, std::tuple<T...>{}, std::make_index_sequence<sizeof...(T)>());
}
template<auto UseArray, size_t...Index>
struct Helper<UseArray, std::tuple<>, std::index_sequence<Index...>> {
using Type = std::tuple<>;
};
template<auto UseArray, typename HeadType, typename... TailType, size_t HeadIndex, size_t... TailIndex>
struct Helper<UseArray, std::tuple<HeadType, TailType...>, std::index_sequence<HeadIndex, TailIndex...>> {
using LastHeadType = std::tuple<HeadType>;
using LastNullType = std::tuple<>;
using LastType = typename std::conditional<!UseArray[HeadIndex], LastHeadType, LastNullType>::type;
using NextTailType = std::tuple<TailType...>;
using NextTailSequence = std::index_sequence<TailIndex...>;
using NextType = typename std::conditional<!UseArray[HeadIndex],
decltype(std::tuple_cat(std::declval<LastHeadType>(), std::declval<typename Helper<UseArray, NextTailType, NextTailSequence>::Type>())),
decltype(std::tuple_cat(std::declval<LastNullType>(), std::declval<typename Helper<UseArray, NextTailType, NextTailSequence>::Type>()))
>::type;
using Type = typename std::conditional<sizeof...(TailType) == 0, LastType, NextType>::type;
};
template<auto UseArray>
using FilteredTupleType = typename Helper<UseArray, std::tuple<T...>, decltype(std::make_index_sequence<sizeof...(T)>())>::Type;
};
template<typename AllocatorHolder, typename FirstOperation, typename...OtherOperations>
static constexpr auto GetModifiedOperations(AllocatorHolder, std::tuple<FirstOperation, OtherOperations...> ops) {
template<auto Allocator, typename FirstOperation, typename...OtherOperations>
static constexpr auto GetModifiedOperations(std::tuple<FirstOperation, OtherOperations...> ops) {
constexpr size_t ModifyRegister = [] {
auto allocator = UNWRAP_TEMPLATE_CONSTANT(AllocatorHolder);
auto allocator = Allocator;
return allocator.AllocateFirstFree();
}();
@ -359,13 +364,13 @@ namespace ams::svc::codegen::impl {
return std::tuple<ModifiedFirstOperation, OtherOperations..., NewMoveOperation>{};
}
template<typename Conversion, typename AllocatorHolder, typename FirstOperation, typename... OtherOperations>
static constexpr auto GenerateBeforeOperations(MetaCodeGenerator &mcg, AllocatorHolder, std::tuple<FirstOperation, OtherOperations...> ops) -> RegisterAllocator<UNWRAP_TEMPLATE_CONSTANT(AllocatorHolder).GetRegisterCount()> {
template<typename Conversion, auto Allocator, typename FirstOperation, typename... OtherOperations>
static constexpr auto GenerateBeforeOperations(MetaCodeGenerator &mcg, std::tuple<FirstOperation, OtherOperations...> ops) -> RegisterAllocator<Allocator.GetRegisterCount()> {
constexpr size_t NumOperations = 1 + sizeof...(OtherOperations);
using OperationsTuple = decltype(ops);
using FilterHelper = TypeIndexFilter<FirstOperation, OtherOperations...>;
constexpr auto ProcessOperation = []<typename Operation>(MetaCodeGenerator &pr_mcg, auto &allocator, Operation) {
constexpr auto ProcessOperation = []<typename Operation>(MetaCodeGenerator &pr_mcg, auto &allocator) {
if (Conversion::template CanGenerateCode<Operation, CodeGenerationKind::SvcInvocationToKernelProcedure>(allocator)) {
Conversion::template GenerateCode<Operation, CodeGenerationKind::SvcInvocationToKernelProcedure>(pr_mcg, allocator);
return true;
@ -373,12 +378,12 @@ namespace ams::svc::codegen::impl {
return false;
};
constexpr auto ProcessResults = [ProcessOperation]<typename... Operations>(std::tuple<Operations...>) {
auto allocator = UNWRAP_TEMPLATE_CONSTANT(AllocatorHolder);
constexpr auto ProcessResults = []<auto AllocatorVal, auto ProcessOp, typename... Operations>(std::tuple<Operations...>) {
auto allocator = AllocatorVal;
MetaCodeGenerator pr_mcg;
auto use_array = std::array<bool, NumOperations>{ ProcessOperation(pr_mcg, allocator, Operations{})... };
auto use_array = std::array<bool, NumOperations>{ ProcessOp.template operator()<Operations>(pr_mcg, allocator)... };
return std::make_tuple(use_array, allocator, pr_mcg);
}(OperationsTuple{});
}.template operator()<Allocator, ProcessOperation>(OperationsTuple{});
constexpr auto CanGenerate = std::get<0>(ProcessResults);
constexpr auto AfterAllocator = std::get<1>(ProcessResults);
@ -388,15 +393,15 @@ namespace ams::svc::codegen::impl {
mcg.AddOperationDirectly(GeneratedCode.GetOperation(i));
}
constexpr auto FilteredOperations = FilterHelper::template GetFilteredTuple(WRAP_TEMPLATE_CONSTANT(CanGenerate));
static_assert(std::tuple_size<decltype(FilteredOperations)>::value <= NumOperations);
if constexpr (std::tuple_size<decltype(FilteredOperations)>::value > 0) {
if constexpr (std::tuple_size<decltype(FilteredOperations)>::value != NumOperations) {
return GenerateBeforeOperations<Conversion>(mcg, WRAP_TEMPLATE_CONSTANT(AfterAllocator), FilteredOperations);
using FilteredOperations = typename FilterHelper::FilteredTupleType<CanGenerate>;
static_assert(std::tuple_size<FilteredOperations>::value <= NumOperations);
if constexpr (std::tuple_size<FilteredOperations>::value > 0) {
if constexpr (std::tuple_size<FilteredOperations>::value != NumOperations) {
return GenerateBeforeOperations<Conversion, AfterAllocator>(mcg, FilteredOperations{});
} else {
/* No progress was made, so we need to make a change. */
constexpr auto ModifiedOperations = GetModifiedOperations(WRAP_TEMPLATE_CONSTANT(AfterAllocator), FilteredOperations);
return GenerateBeforeOperations<Conversion>(mcg, WRAP_TEMPLATE_CONSTANT(AfterAllocator), ModifiedOperations);
constexpr auto ModifiedOperations = GetModifiedOperations<AfterAllocator>(FilteredOperations{});
return GenerateBeforeOperations<Conversion, AfterAllocator>(mcg, ModifiedOperations);
}
} else {
return AfterAllocator;
@ -433,7 +438,7 @@ namespace ams::svc::codegen::impl {
/* Generate code for before operations. */
if constexpr (Conversion::NumBeforeOperations > 0) {
allocator = GenerateBeforeOperations<Conversion>(mcg, WRAP_TEMPLATE_CONSTANT(InitialAllocator), typename Conversion::BeforeOperations{});
allocator = GenerateBeforeOperations<Conversion, InitialAllocator>(mcg, typename Conversion::BeforeOperations{});
} else {
allocator = InitialAllocator;
}
@ -527,8 +532,8 @@ namespace ams::svc::codegen::impl {
static ALWAYS_INLINE void WrapSvcFunction() {
/* Generate appropriate assembly. */
GenerateCodeForMetaCode<CodeGenerator>(WRAP_TEMPLATE_CONSTANT(BeforeMetaCode));
ON_SCOPE_EXIT { GenerateCodeForMetaCode<CodeGenerator>(WRAP_TEMPLATE_CONSTANT(AfterMetaCode)); };
GenerateCodeForMetaCode<CodeGenerator, BeforeMetaCode>();
ON_SCOPE_EXIT { GenerateCodeForMetaCode<CodeGenerator, AfterMetaCode>(); };
return reinterpret_cast<void (*)()>(Function)();
}

View file

@ -24,7 +24,7 @@ namespace ams::svc::codegen::impl {
static constexpr size_t MaxParameters = 8;
private:
static constexpr size_t InvalidIndex = std::numeric_limits<size_t>::max();
private:
public:
/* ABI parameters. */
Abi abi;
@ -102,7 +102,7 @@ namespace ams::svc::codegen::impl {
};
class ProcedureLayout {
private:
public:
Abi abi;
ParameterLayout input;
ParameterLayout output;
@ -205,7 +205,7 @@ namespace ams::svc::codegen::impl {
};
class SvcInvocationLayout {
private:
public:
Abi abi;
ParameterLayout input;
ParameterLayout output;
@ -220,11 +220,7 @@ namespace ams::svc::codegen::impl {
}
for (size_t i = 1; i < num_parameters; i++) {
for (size_t j = i; j > 0 && param_layout.GetParameter(map[j-1]).GetLocation(0) > param_layout.GetParameter(map[j]).GetLocation(0); j--) {
/* std::swap is not constexpr until c++20 :( */
/* TODO: std::swap(map[j], map[j-1]); */
const size_t tmp = map[j];
map[j] = map[j-1];
map[j-1] = tmp;
std::swap(map[j], map[j-1]);
}
}

View file

@ -304,9 +304,8 @@ namespace ams::svc::codegen::impl {
static constexpr auto DetermineConversionOperations() {
[[maybe_unused]] constexpr auto Procedure = LayoutForKernel;
[[maybe_unused]] constexpr ParameterLayout Svc = Input ? LayoutForSvc.GetInputLayout() : LayoutForSvc.GetOutputLayout();
[[maybe_unused]] constexpr std::array<size_t, Svc.GetNumParameters()> ParameterMap = []<typename SvcHolder>(SvcHolder){
[[maybe_unused]] constexpr std::array<size_t, Svc.GetNumParameters()> ParameterMap = []<auto CapturedSvc>(){
/* We want to iterate over the parameters in sorted order. */
constexpr ParameterLayout CapturedSvc = UNWRAP_TEMPLATE_CONSTANT(SvcHolder);
std::array<size_t, CapturedSvc.GetNumParameters()> map{};
const size_t num_parameters = CapturedSvc.GetNumParameters();
for (size_t i = 0; i < num_parameters; i++) {
@ -314,15 +313,11 @@ namespace ams::svc::codegen::impl {
}
for (size_t i = 1; i < num_parameters; i++) {
for (size_t j = i; j > 0 && CapturedSvc.GetParameter(map[j-1]).GetLocation(0) > CapturedSvc.GetParameter(map[j]).GetLocation(0); j--) {
/* std::swap is not constexpr until c++20 :( */
/* TODO: std::swap(map[j], map[j-1]); */
const size_t tmp = map[j];
map[j] = map[j-1];
map[j-1] = tmp;
std::swap(map[j], map[j-1]);
}
}
return map;
}(WRAP_TEMPLATE_CONSTANT(Svc));
}.template operator()<Svc>();
if constexpr (ParameterIndex >= Svc.GetNumParameters()) {
/* Base case: we're done. */
@ -377,16 +372,13 @@ namespace ams::svc::codegen::impl {
constexpr size_t RegisterSize = SvcAbiType::RegisterSize;
constexpr size_t PassedSize = ProcedureParam.GetTypeSize();
/* TODO: C++20 templated lambdas. For now, use GCC extension syntax. */
constexpr auto SvcIndexSequence = []<typename SvcParamWrapper, size_t... Is>(SvcParamWrapper, std::index_sequence<Is...>) {
constexpr Parameter CapturedSvcParam = UNWRAP_TEMPLATE_CONSTANT(SvcParamWrapper);
constexpr auto SvcIndexSequence = []<auto CapturedSvcParam, size_t... Is>(std::index_sequence<Is...>) {
return std::index_sequence<CapturedSvcParam.GetLocation(Is).GetIndex()...>{};
}(WRAP_TEMPLATE_CONSTANT(SvcParam), std::make_index_sequence<SvcParam.GetNumLocations()>());
}.template operator()<SvcParam>(std::make_index_sequence<SvcParam.GetNumLocations()>());
constexpr auto OperationValue = []<typename ProcedureLocWrapper, size_t... Is>(ProcedureLocWrapper, std::index_sequence<Is...>) {
constexpr Location CapturedProcedureLoc = UNWRAP_TEMPLATE_CONSTANT(ProcedureLocWrapper);
constexpr auto OperationValue = []<auto CapturedProcedureLoc, size_t... Is>(std::index_sequence<Is...>) {
return LayoutConversionBase::OperationScatter<RegisterSize, PassedSize, StackIndex * KernelAbiType::RegisterSize, CapturedProcedureLoc.GetIndex(), Is...>{};
}(WRAP_TEMPLATE_CONSTANT(ProcedureLoc), SvcIndexSequence);
}.template operator()<ProcedureLoc>(SvcIndexSequence);
constexpr auto cur_op = std::make_tuple(OperationValue);

View file

@ -79,7 +79,7 @@ namespace ams::svc::codegen::impl {
return op;
}
private:
public:
size_t num_operations;
std::array<Operation, MaxOperations> operations;
public:
@ -98,15 +98,13 @@ namespace ams::svc::codegen::impl {
}
};
template<typename _OperationHolder>
template<auto Operation>
static constexpr auto GetOperationParameterSequence() {
constexpr auto _Operation = UNWRAP_TEMPLATE_CONSTANT(_OperationHolder);
constexpr size_t NumParameters = _Operation.num_parameters;
constexpr size_t NumParameters = Operation.num_parameters;
return []<typename OperationHolder, size_t... Is>(OperationHolder, std::index_sequence<Is...>) {
constexpr auto Operation = UNWRAP_TEMPLATE_CONSTANT(OperationHolder);
return []<size_t... Is>(std::index_sequence<Is...>) {
return std::index_sequence<Operation.parameters[Is]...>{};
}(_OperationHolder{}, std::make_index_sequence<NumParameters>());
}(std::make_index_sequence<NumParameters>());
}
template<typename CodeGenerator, MetaCode::OperationKind Kind, size_t... Parameters>
@ -130,10 +128,9 @@ namespace ams::svc::codegen::impl {
#undef META_CODE_OPERATION_KIND_GENERATE_CODE
}
template<typename CodeGenerator, typename OperationHolder>
static ALWAYS_INLINE void GenerateCodeForOperation(OperationHolder) {
constexpr auto Operation = UNWRAP_TEMPLATE_CONSTANT(OperationHolder);
GenerateCodeForOperationImpl<CodeGenerator, Operation.kind>(GetOperationParameterSequence<OperationHolder>());
template<typename CodeGenerator, auto Operation>
static ALWAYS_INLINE void GenerateCodeForOperation() {
GenerateCodeForOperationImpl<CodeGenerator, Operation.kind>(GetOperationParameterSequence<Operation>());
}
class MetaCodeGenerator {

View file

@ -27,7 +27,7 @@ namespace ams::svc::codegen::impl {
class Location {
private:
static constexpr size_t InvalidIndex = std::numeric_limits<size_t>::max();
private:
public:
Storage storage;
size_t index;
public:
@ -75,7 +75,7 @@ namespace ams::svc::codegen::impl {
static constexpr size_t MaxLocations = 8;
static constexpr size_t IdentifierLengthMax = 0x40;
class Identifier {
private:
public:
char name[IdentifierLengthMax];
size_t index;
public:
@ -99,7 +99,7 @@ namespace ams::svc::codegen::impl {
return !(*this == rhs);
}
};
private:
public:
Identifier identifier;
ArgumentType type;
size_t type_size;