From d8a11eaba7ce0ebf923413ed0046463073e56aae Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 25 Oct 2022 10:13:12 -0400 Subject: [PATCH] Avoid explicit specialisation in non-namespace scope. --- InstructionSets/M68k/Decoder.hpp | 36 +++++++++------------------- InstructionSets/M68k/Instruction.hpp | 18 ++++++++++++++ 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/InstructionSets/M68k/Decoder.hpp b/InstructionSets/M68k/Decoder.hpp index 66be1d3d3..47815c2b0 100644 --- a/InstructionSets/M68k/Decoder.hpp +++ b/InstructionSets/M68k/Decoder.hpp @@ -11,6 +11,7 @@ #include "Instruction.hpp" #include "Model.hpp" +#include "../../Numeric/Sizes.hpp" namespace InstructionSet { namespace M68k { @@ -50,30 +51,15 @@ template class Predecoder { Preinstruction decodeE(uint16_t instruction); Preinstruction decodeF(uint16_t instruction); - template struct OperationProperties {}; - template <> struct OperationProperties { - using OpT = uint8_t; - static constexpr OpT OpMax = OpT(Operation::Max68000); - }; - template <> struct OperationProperties { - using OpT = uint8_t; - static constexpr OpT OpMax = OpT(Operation::Max68010); - }; - template <> struct OperationProperties { - using OpT = uint16_t; - static constexpr OpT OpMax = OpT(Operation::Max68020); - }; - template <> struct OperationProperties { - using OpT = uint16_t; - static constexpr OpT OpMax = OpT(Operation::Max68030); - }; - template <> struct OperationProperties { - using OpT = uint16_t; - static constexpr OpT OpMax = OpT(Operation::Max68040); - }; - - using OpT = typename OperationProperties::OpT; - static constexpr OpT OpMax = OperationProperties::OpMax; + // Yuckiness here: 67 is a count of the number of things contained below in + // ExtendedOperation; this acts to ensure ExtendedOperation is the minimum + // integer size large enough to hold all actual operations plus the ephemeral + // ones used here. Intention is to support table-based decoding, which will mean + // making those integers less ephemeral, hence the desire to pick a minimum size. + using OpT = typename MinIntTypeValue< + uint64_t(OperationMax::value) + 67 + >::type; + static constexpr auto OpMax = OpT(OperationMax::value); // Specific instruction decoders. template Preinstruction decode(uint16_t instruction); @@ -89,7 +75,7 @@ template class Predecoder { // time that's knowable from the Operation alone, hence the rather awkward // extension of @c Operation. enum ExtendedOperation: OpT { - MOVEPtoRl = OperationProperties::OpMax + 1, MOVEPtoRw, + MOVEPtoRl = OpMax + 1, MOVEPtoRw, MOVEPtoMl, MOVEPtoMw, MOVEQ, diff --git a/InstructionSets/M68k/Instruction.hpp b/InstructionSets/M68k/Instruction.hpp index a8942cc1e..a29d48bda 100644 --- a/InstructionSets/M68k/Instruction.hpp +++ b/InstructionSets/M68k/Instruction.hpp @@ -174,6 +174,24 @@ enum class Operation: uint8_t { Max68040 = PTESTW, }; +// Provide per-model max entries in Operation. +template struct OperationMax {}; +template <> struct OperationMax { + static constexpr Operation value = Operation::Max68000; +}; +template <> struct OperationMax { + static constexpr Operation value = Operation::Max68010; +}; +template <> struct OperationMax { + static constexpr Operation value = Operation::Max68020; +}; +template <> struct OperationMax { + static constexpr Operation value = Operation::Max68030; +}; +template <> struct OperationMax { + static constexpr Operation value = Operation::Max68040; +}; + const char *to_string(Operation op); template