1package volatile 2 3// This file defines Register{8,16,32,64} types, which are convenience types for 4// volatile register accesses. 5 6// Special types that causes loads/stores to be volatile (necessary for 7// memory-mapped registers). 8type Register8 struct { 9 Reg uint8 10} 11 12// Get returns the value in the register. It is the volatile equivalent of: 13// 14// *r.Reg 15// 16//go:inline 17func (r *Register8) Get() uint8 { 18 return LoadUint8(&r.Reg) 19} 20 21// Set updates the register value. It is the volatile equivalent of: 22// 23// *r.Reg = value 24// 25//go:inline 26func (r *Register8) Set(value uint8) { 27 StoreUint8(&r.Reg, value) 28} 29 30// SetBits reads the register, sets the given bits, and writes it back. It is 31// the volatile equivalent of: 32// 33// r.Reg |= value 34// 35//go:inline 36func (r *Register8) SetBits(value uint8) { 37 StoreUint8(&r.Reg, LoadUint8(&r.Reg)|value) 38} 39 40// ClearBits reads the register, clears the given bits, and writes it back. It 41// is the volatile equivalent of: 42// 43// r.Reg &^= value 44// 45//go:inline 46func (r *Register8) ClearBits(value uint8) { 47 StoreUint8(&r.Reg, LoadUint8(&r.Reg)&^value) 48} 49 50// HasBits reads the register and then checks to see if the passed bits are set. It 51// is the volatile equivalent of: 52// 53// (*r.Reg & value) > 0 54// 55//go:inline 56func (r *Register8) HasBits(value uint8) bool { 57 return (r.Get() & value) > 0 58} 59 60// ReplaceBits is a helper to simplify setting multiple bits high and/or low at 61// once. It is the volatile equivalent of: 62// 63// r.Reg = (r.Reg & ^(mask << pos)) | value << pos 64// 65// go:inline 66func (r *Register8) ReplaceBits(value uint8, mask uint8, pos uint8) { 67 StoreUint8(&r.Reg, LoadUint8(&r.Reg)&^(mask<<pos)|value<<pos) 68} 69 70type Register16 struct { 71 Reg uint16 72} 73 74// Get returns the value in the register. It is the volatile equivalent of: 75// 76// *r.Reg 77// 78//go:inline 79func (r *Register16) Get() uint16 { 80 return LoadUint16(&r.Reg) 81} 82 83// Set updates the register value. It is the volatile equivalent of: 84// 85// *r.Reg = value 86// 87//go:inline 88func (r *Register16) Set(value uint16) { 89 StoreUint16(&r.Reg, value) 90} 91 92// SetBits reads the register, sets the given bits, and writes it back. It is 93// the volatile equivalent of: 94// 95// r.Reg |= value 96// 97//go:inline 98func (r *Register16) SetBits(value uint16) { 99 StoreUint16(&r.Reg, LoadUint16(&r.Reg)|value) 100} 101 102// ClearBits reads the register, clears the given bits, and writes it back. It 103// is the volatile equivalent of: 104// 105// r.Reg &^= value 106// 107//go:inline 108func (r *Register16) ClearBits(value uint16) { 109 StoreUint16(&r.Reg, LoadUint16(&r.Reg)&^value) 110} 111 112// HasBits reads the register and then checks to see if the passed bits are set. It 113// is the volatile equivalent of: 114// 115// (*r.Reg & value) > 0 116// 117//go:inline 118func (r *Register16) HasBits(value uint16) bool { 119 return (r.Get() & value) > 0 120} 121 122// ReplaceBits is a helper to simplify setting multiple bits high and/or low at 123// once. It is the volatile equivalent of: 124// 125// r.Reg = (r.Reg & ^(mask << pos)) | value << pos 126// 127// go:inline 128func (r *Register16) ReplaceBits(value uint16, mask uint16, pos uint8) { 129 StoreUint16(&r.Reg, LoadUint16(&r.Reg)&^(mask<<pos)|value<<pos) 130} 131 132type Register32 struct { 133 Reg uint32 134} 135 136// Get returns the value in the register. It is the volatile equivalent of: 137// 138// *r.Reg 139// 140//go:inline 141func (r *Register32) Get() uint32 { 142 return LoadUint32(&r.Reg) 143} 144 145// Set updates the register value. It is the volatile equivalent of: 146// 147// *r.Reg = value 148// 149//go:inline 150func (r *Register32) Set(value uint32) { 151 StoreUint32(&r.Reg, value) 152} 153 154// SetBits reads the register, sets the given bits, and writes it back. It is 155// the volatile equivalent of: 156// 157// r.Reg |= value 158// 159//go:inline 160func (r *Register32) SetBits(value uint32) { 161 StoreUint32(&r.Reg, LoadUint32(&r.Reg)|value) 162} 163 164// ClearBits reads the register, clears the given bits, and writes it back. It 165// is the volatile equivalent of: 166// 167// r.Reg &^= value 168// 169//go:inline 170func (r *Register32) ClearBits(value uint32) { 171 StoreUint32(&r.Reg, LoadUint32(&r.Reg)&^value) 172} 173 174// HasBits reads the register and then checks to see if the passed bits are set. It 175// is the volatile equivalent of: 176// 177// (*r.Reg & value) > 0 178// 179//go:inline 180func (r *Register32) HasBits(value uint32) bool { 181 return (r.Get() & value) > 0 182} 183 184// ReplaceBits is a helper to simplify setting multiple bits high and/or low at 185// once. It is the volatile equivalent of: 186// 187// r.Reg = (r.Reg & ^(mask << pos)) | value << pos 188// 189// go:inline 190func (r *Register32) ReplaceBits(value uint32, mask uint32, pos uint8) { 191 StoreUint32(&r.Reg, LoadUint32(&r.Reg)&^(mask<<pos)|value<<pos) 192} 193 194type Register64 struct { 195 Reg uint64 196} 197 198// Get returns the value in the register. It is the volatile equivalent of: 199// 200// *r.Reg 201// 202//go:inline 203func (r *Register64) Get() uint64 { 204 return LoadUint64(&r.Reg) 205} 206 207// Set updates the register value. It is the volatile equivalent of: 208// 209// *r.Reg = value 210// 211//go:inline 212func (r *Register64) Set(value uint64) { 213 StoreUint64(&r.Reg, value) 214} 215 216// SetBits reads the register, sets the given bits, and writes it back. It is 217// the volatile equivalent of: 218// 219// r.Reg |= value 220// 221//go:inline 222func (r *Register64) SetBits(value uint64) { 223 StoreUint64(&r.Reg, LoadUint64(&r.Reg)|value) 224} 225 226// ClearBits reads the register, clears the given bits, and writes it back. It 227// is the volatile equivalent of: 228// 229// r.Reg &^= value 230// 231//go:inline 232func (r *Register64) ClearBits(value uint64) { 233 StoreUint64(&r.Reg, LoadUint64(&r.Reg)&^value) 234} 235 236// HasBits reads the register and then checks to see if the passed bits are set. It 237// is the volatile equivalent of: 238// 239// (*r.Reg & value) > 0 240// 241//go:inline 242func (r *Register64) HasBits(value uint64) bool { 243 return (r.Get() & value) > 0 244} 245 246// ReplaceBits is a helper to simplify setting multiple bits high and/or low at 247// once. It is the volatile equivalent of: 248// 249// r.Reg = (r.Reg & ^(mask << pos)) | value << pos 250// 251// go:inline 252func (r *Register64) ReplaceBits(value uint64, mask uint64, pos uint8) { 253 StoreUint64(&r.Reg, LoadUint64(&r.Reg)&^(mask<<pos)|value<<pos) 254} 255