diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/bit_field.h | 24 | ||||
-rw-r--r-- | src/common/register_set.h | 14 | ||||
-rw-r--r-- | src/common/scm_rev_gen.js | 9 |
3 files changed, 39 insertions, 8 deletions
diff --git a/src/common/bit_field.h b/src/common/bit_field.h index dfd00d198..b6f0179c6 100644 --- a/src/common/bit_field.h +++ b/src/common/bit_field.h @@ -124,14 +124,35 @@ public: // so that we can use this within unions BitField() = default; +#ifndef _WIN32 + // We explicitly delete the copy assigment operator here, because the + // default copy assignment would copy the full storage value, rather than + // just the bits relevant to this particular bit field. + // Ideally, we would just implement the copy assignment to copy only the + // relevant bits, but this requires compiler support for unrestricted + // unions. + // MSVC 2013 has no support for this, hence we disable this code on + // Windows (so that the default copy assignment operator will be used). + // For any C++11 conformant compiler we delete the operator to make sure + // we never use this inappropriate operator to begin with. + // TODO: Implement this operator properly once all target compilers + // support unrestricted unions. + BitField& operator=(const BitField&) = delete; +#endif + __forceinline BitField& operator=(T val) { - storage = (storage & ~GetMask()) | ((val << position) & GetMask()); + storage = (storage & ~GetMask()) | (((StorageType)val << position) & GetMask()); return *this; } __forceinline operator T() const { + return Value(); + } + + __forceinline T Value() const + { if (std::numeric_limits<T>::is_signed) { std::size_t shift = 8 * sizeof(T)-bits; @@ -168,5 +189,6 @@ private: static_assert(position < 8 * sizeof(T), "Invalid position"); static_assert(bits <= 8 * sizeof(T), "Invalid number of bits"); static_assert(bits > 0, "Invalid number of bits"); + static_assert(std::is_standard_layout<T>::value, "Invalid base type"); }; #pragma pack() diff --git a/src/common/register_set.h b/src/common/register_set.h index 0418551b3..ba19a2614 100644 --- a/src/common/register_set.h +++ b/src/common/register_set.h @@ -34,7 +34,7 @@ /* * Standardized way to define a group of registers and corresponding data structures. To define * a new register set, first define struct containing an enumeration called "Id" containing - * all register IDs and a template union called "Struct". Specialize the Struct union for any + * all register IDs and a template struct called "Struct". Specialize the Struct struct for any * register ID which needs to be accessed in a specialized way. You can then declare the object * containing all register values using the RegisterSet<BaseType, DefiningStruct> type, where * BaseType is the underlying type of each register (e.g. u32). @@ -54,7 +54,7 @@ * * // declare register definition structures * template<Id id> - * union Struct; + * struct Struct; * }; * * // Define register set object @@ -62,9 +62,11 @@ * * // define register definition structures * template<> - * union Regs::Struct<Regs::Value1> { - * BitField<0, 4, u32> some_field; - * BitField<4, 3, u32> some_other_field; + * struct Regs::Struct<Regs::Value1> { + * union { + * BitField<0, 4, u32> some_field; + * BitField<4, 3, u32> some_other_field; + * }; * }; * * Usage in external code (within SomeNamespace scope): @@ -77,7 +79,7 @@ * * * @tparam BaseType Base type used for storing individual registers, e.g. u32 - * @tparam RegDefinition Class defining an enumeration called "Id" and a template<Id id> union, as described above. + * @tparam RegDefinition Class defining an enumeration called "Id" and a template<Id id> struct, as described above. * @note RegDefinition::Id needs to have an enum value called NumIds defining the number of registers to be allocated. */ template<typename BaseType, typename RegDefinition> diff --git a/src/common/scm_rev_gen.js b/src/common/scm_rev_gen.js index 29c913b85..98313e376 100644 --- a/src/common/scm_rev_gen.js +++ b/src/common/scm_rev_gen.js @@ -6,8 +6,15 @@ var cmd_revision = " rev-parse HEAD"; var cmd_describe = " describe --always --long --dirty"; var cmd_branch = " rev-parse --abbrev-ref HEAD"; +var git_search_paths = { + "git.cmd": 1, + "git": 1, + "C:\\Program Files (x86)\\Git\\bin\\git.exe": 1, + "C:\\Program Files\\Git\\bin\\git.exe": 1 +}; + function GetGitExe() { - for (var gitexe in { "git.cmd": 1, "git": 1 }) { + for (var gitexe in git_search_paths) { try { wshShell.Exec(gitexe); return gitexe; |