Skip to content

Commit 9b786b3

Browse files
committed
read(_field)/write(_field): Make incurred implementations overridable
In particular, added documentation to note what the relevant template is to override the `write_register`/`read_register` implementations (which are no longer internal).
1 parent fb9d4e9 commit 9b786b3

File tree

2 files changed

+49
-23
lines changed

2 files changed

+49
-23
lines changed

RELEASENOTES-1.4.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,3 +401,6 @@
401401
402402
Note that as a consequence of these semantics, any reference to `_` in code
403403
will _always_ resolve to the discard reference.
404+
- `note 6` The method implementations that may be incurred by instantiating the
405+
`read_field`, `write_field`, `read`, or `write` templates have all been made
406+
overridable. See the documentation of these templates for more details.

lib/1.4/dml-builtins.dml

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3576,9 +3576,16 @@ order for a method override to have effect.
35763576
in most cases, it is easier to express read operations using the
35773577
`read` template.
35783578

3579-
Note that instantiating `read_field` on a register means that
3580-
register reads behave as if the register consists of one single field; a
3581-
read access will ignore any actual field subobjects in the register.
3579+
Note that instantiating `read_field` on a register incurs a `read_register`
3580+
implementation such that reads behave as if the register consists of one single
3581+
field; a read access will ignore any actual field subobjects in the register.
3582+
3583+
This `read_register` implementation is provided by the automatically
3584+
instantiated `read_register_impl_from_read_field` template, which you may need
3585+
to reference in order to override the implementation — for example in
3586+
order to resolve implementation conflicts (through the use of
3587+
[Template-Qualified Method Implementation
3588+
Calls](language.html#template-qualified-method-implementation-calls).
35823589
*/
35833590
template read_field {
35843591
shared method read_field(uint64 enabled_bits, void *aux) -> (uint64);
@@ -3601,36 +3608,48 @@ override to have effect. `write_field` is the interface used for
36013608
access by registers; in most cases, it is easier to express write
36023609
operations using the `write` template.
36033610

3604-
Note that instantiating `write_field` on a register means that
3605-
register writes behave as if the register consists of one single
3606-
field; a write access will ignore any actual field subobjects in the
3607-
register. This is often useful in read-only registers, as it allows
3608-
reads to propagate to fields, while a violating write can be handled
3609-
centrally for the whole register.
3611+
Note that instantiating `write_field` on a register incurs a `write_register`
3612+
implementation such that register writes behave as if the register consists
3613+
of one single field; a write access will ignore any actual field subobjects in
3614+
the register. This is often useful in read-only registers, as it allows reads
3615+
to propagate to fields, while a violating write can be handled centrally for
3616+
the whole register.
3617+
3618+
This `write_register` implementation is provided through the automatically
3619+
instantiated `write_register_impl_from_write_field` template, which you may
3620+
need to reference in order to override the implementation — for example
3621+
in order to resolve implementation conflicts (through the use of
3622+
[Template-Qualified Method Implementation
3623+
Calls](language.html#template-qualified-method-implementation-calls).
36103624
*/
36113625
template write_field {
36123626
shared method write_field(uint64 val, uint64 enabled_bits, void *aux);
36133627
}
36143628

3615-
template _reg_read_as_field is (register, read_register, read_field) {
3629+
3630+
template read_register_impl_from_read_field is (register, read_register,
3631+
read_field) {
36163632
shared method read_register(uint64 enabled_bytes, void *aux)
3617-
-> (uint64) {
3633+
-> (uint64) default {
36183634
return enabled_bytes == 0 ? 0
36193635
: this.read_field(enabled_bytes, aux) & enabled_bytes;
36203636
}
36213637
}
36223638

3623-
in each (read_field, register) { is _reg_read_as_field; }
3639+
in each (read_field, register) { is read_register_impl_from_read_field; }
36243640

3625-
template _reg_write_as_field is (register, write_register, write_field) {
3626-
shared method write_register(uint64 val, uint64 enabled_bytes, void *aux) {
3641+
template write_register_impl_from_write_field is (register, write_register,
3642+
write_field) {
3643+
shared method write_register(uint64 val, uint64 enabled_bytes, void *aux)
3644+
default {
36273645
if (enabled_bytes != 0) {
36283646
this.write_field(val & enabled_bytes, enabled_bytes, aux);
36293647
}
36303648
}
36313649
}
36323650

3633-
in each (write_field, register) { is _reg_write_as_field; }
3651+
in each (write_field, register) { is write_register_impl_from_write_field; }
3652+
36343653

36353654
template _bitsize {
36363655
// Must be a multiple of 8 for registers, but not for fields.
@@ -3653,12 +3672,14 @@ The `read` template is *not* implemented by fields or registers by
36533672
default, and must be explicitly instantiated in order for a method
36543673
override to have effect.
36553674

3656-
Note that instantiating `read` on a register means that register reads
3657-
behave as if the register consists of one single field; a read access
3658-
will ignore any actual field subobjects in the register.
3675+
Note that instantiating `read` on a register incurs a `read_register`
3676+
implementation such that register reads behave as if the register consists of
3677+
one single field; a read access will ignore any actual field subobjects in the
3678+
register. For more information, see [`read_field`](#read_field).
36593679
*/
36603680
template read is (read_field, _get) {
3661-
shared method read_field(uint64 enabled_bits, void *aux) -> (uint64) {
3681+
shared method read_field(uint64 enabled_bits, void *aux) -> (uint64)
3682+
default {
36623683
return enabled_bits == 0 ? 0 : this.read() & enabled_bits;
36633684
}
36643685
// convenience method for simple whole-field access
@@ -3684,12 +3705,14 @@ The `write` template is *not* implemented by fields or registers by
36843705
default, and must be explicitly instantiated in order for a method
36853706
override to have effect.
36863707

3687-
Note that instantiating `write` on a register means that register
3688-
writes behave as if the register consists of one single field; a write
3689-
access will ignore any actual field subobjects in the register.
3708+
Note that instantiating `write` on a register incurs a `write_register`
3709+
implementation such that register writes behave as if the register consists of
3710+
one single field; a write access will ignore any actual field subobjects in
3711+
the register. For more information, see [`write_field`](#write_field).
36903712
*/
36913713
template write is (write_field, _get, _set) {
3692-
shared method write_field(uint64 val, uint64 enabled_bits, void *aux) {
3714+
shared method write_field(uint64 val, uint64 enabled_bits, void *aux)
3715+
default {
36933716
if (enabled_bits != 0) {
36943717
local uint64 patched = this.get() & ~enabled_bits;
36953718
this.write(patched | (val & enabled_bits));

0 commit comments

Comments
 (0)