diff --git a/ioreg/builder/accessors.rs b/ioreg/builder/accessors.rs index 6e0aa1f2..83f0f9da 100644 --- a/ioreg/builder/accessors.rs +++ b/ioreg/builder/accessors.rs @@ -34,8 +34,10 @@ pub struct BuildAccessors<'a, 'b, 'c> { impl<'a, 'b, 'c> node::RegVisitor for BuildAccessors<'a, 'b, 'c> { fn visit_prim_reg(&mut self, path: &Vec, reg: &node::Reg, _width: node::RegWidth, fields: &Vec) { - let item = build_get_fn(self.cx, path, reg); - self.builder.push_item(item); + if fields.iter().any(|f| f.access != node::WriteOnly) { + let item = build_get_fn(self.cx, path, reg); + self.builder.push_item(item); + } for field in fields.iter() { match build_field_accessors(self.cx, path, reg, field) { diff --git a/ioreg/builder/setter.rs b/ioreg/builder/setter.rs index 9068b8a7..c8b371be 100644 --- a/ioreg/builder/setter.rs +++ b/ioreg/builder/setter.rs @@ -122,6 +122,15 @@ fn build_drop<'a>(cx: &'a ExtCtxt, path: &Vec, } } + // no need to read write-only registers + let wo_reg: bool = fields.iter().all(|f| f.access == node::WriteOnly); + let initial_value = + if wo_reg { + quote_expr!(cx, 0) + } else { + quote_expr!(cx, self.reg.value.get()) + }; + let item = quote_item!(cx, #[unsafe_destructor] #[doc = "This performs the register update"] @@ -129,7 +138,7 @@ fn build_drop<'a>(cx: &'a ExtCtxt, path: &Vec, fn drop(&mut self) { let clear_mask: $unpacked_ty = $clear as $unpacked_ty; if self.mask != 0 { - let v: $unpacked_ty = self.reg.value.get() & ! clear_mask & ! self.mask; + let v: $unpacked_ty = $initial_value & ! clear_mask & ! self.mask; self.reg.value.set(self.value | v); } }