{"id":18392164,"url":"https://github.com/lethalbit/wegistew-cc","last_synced_at":"2025-04-07T03:33:54.468Z","repository":{"id":47243092,"uuid":"362997040","full_name":"lethalbit/wegistew-cc","owner":"lethalbit","description":"Compile-time register grokking","archived":false,"fork":false,"pushed_at":"2021-09-07T07:18:19.000Z","size":27,"stargazers_count":12,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-22T12:24:20.107Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lethalbit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-04-30T01:51:00.000Z","updated_at":"2024-10-19T22:35:57.000Z","dependencies_parsed_at":"2022-09-04T18:12:29.687Z","dependency_job_id":null,"html_url":"https://github.com/lethalbit/wegistew-cc","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lethalbit%2Fwegistew-cc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lethalbit%2Fwegistew-cc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lethalbit%2Fwegistew-cc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lethalbit%2Fwegistew-cc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lethalbit","download_url":"https://codeload.github.com/lethalbit/wegistew-cc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247589557,"owners_count":20963019,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T01:54:32.614Z","updated_at":"2025-04-07T03:33:54.182Z","avatar_url":"https://github.com/lethalbit.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# wegistew - Compile-time register grokking\n\nwegistew is a single C++ header that allows for you to interact with hardware registers on embedded platforms in a near zero-cost way.\n\nWith wegistew, everything but the actual register access is done in the type system at compile time, meaning that only the actual calls to get or set the register are actually generated as machine code, the rest of  it is seamlessly optimized away.\n\n## Installing\n\nBecause wegistew is a single header library, to install it you can either just download a copy and drop it in your source tree.\n\nAlternatively use it as a meson subproject, it exports a `wegistew_dep` dependency you can just plop into your target.\n\nLastly, you can install it system-wide by using meson:\n\n```\nmeson build\nninja -C build install\n```\n\nThe default location is `/usr/local/include` but this can be changed by setting the environment variable `DESTDIR` to the prefix prior to running the `ninja -C build install` command.\n\n## Examples\n\nThe following examples so some uses for wegistew.\n\nAll of which are on [compiler explorer](https://godbolt.org/z/8EbfeGcxh) ([https://godbolt.org/z/8EbfeGcxh](https://godbolt.org/z/8EbfeGcxh)) for you to play with.\n\n### Defining a Register\n\nTo define a register with wegistew, you simply define a `wegistew_t` type templated with the register intrinsic, the address, and the fields for the register.\n\n```cpp\n#include \u003cwegistew.hh\u003e\n\nusing wegistew::wegistew_t;\nusing wegistew::bit_t;\nusing wegistew::bitspan_t;\n\nusing par_el1 = wegistew_t\u003c\n\t/* Register base type, dictates width */\n\tstd::uint64_t,\n\t/* Register address */\n\t0xFEEDACA7DEADBEEF,\n\t/* Register fields */\n\tbit_t\u003c0\u003e,\n\tbitspan_t\u003c1, 6\u003e,\n\tbitspan_t\u003c7, 8\u003e,\n\tbit_t\u003c9\u003e,\n\tbit_t\u003c10\u003e,\n\tbit_t\u003c22\u003e,\n\tbitspan_t\u003c12, 47\u003e,\n\tbitspan_t\u003c48, 51\u003e,\n\tbitspan_t\u003c52, 55\u003e,\n\tbitspan_t\u003c56, 63\u003e\n\u003e;\n```\n\nThere are two types you can use as a field in wegistew, the first is a `bitspan_t\u003clsb, msb\u003e` which takes the start and stop bit indices, the second is a `bit_t\u003cidx\u003e` which takes a single offset into the register.\n\nThe `bit_t\u003cidx\u003e` type is just a type alias for `bitspan_t\u003cidx, idx\u003e`, which is a bit span with the the start and stop bits set to be identical.\n\n### Accessing Fields\n\nTo access a field of a register, you have two options, access it via the type system, or access it via an object instance.\n\nTo get / set a field without an instance of the register one would do the following:\n\n```cpp\n/* Get the contents of the 6th field of the register */\nauto pa = par_el1::field\u003c6\u003e::get();\n\n/* Set the contents of the 3rd field of the register */\npar_el1::field\u003c3\u003e::set(0b10);\n\n```\n\nTo do the same, but with an instance of the register one would do the following:\n\n```cpp\n/* Create an instance of the register */\nauto reg = par_el1{};\n\n/* Get the contents of the 6th field of the register */\nauto pa = reg.get\u003c6\u003e();\n\n/* Set the contents of the 3rd field of the register */\nreg.set\u003c3\u003e(0b10);\n\n```\n\n### Tips and Tricks\n\nHere are some tips and tricks that you can use to make working with wegistew easier.\n\n#### Field Naming\n\nRather than defining a constant to name your register fields for access, simply create a new type with the name of that field.\n\n```cpp\n/* Alias the type */\nusing attr = typename par_el1::field\u003c9\u003e;\n\n/* Do things with it */\nauto current_attr = attr::get();\nattr::set(0b11110000);\n\n```\n\n#### Use an Enum to name Values\n\nYou can use an `enum class` to define named values for passing to `set` and retrieving from `get`.\n\n```cpp\n/* Let's alias the field for ease of use */\nusing sh = typename par_el1::field\u003c3\u003e;\n\n/* Define named values */\nenum class shareability : std::uint8_t {\n\tnon_shareable   = 0b00,\n\touter_shareable = 0b10,\n\tinner_shareable = 0b01,\n};\n/* Set it! */\nsh::set(shareability::outer_shareable);\n```\n\n## License\n\nwegistew is licensed under the [BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html) and can be found in [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flethalbit%2Fwegistew-cc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flethalbit%2Fwegistew-cc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flethalbit%2Fwegistew-cc/lists"}