github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/runtime/volatile/register.go (about) 1 package 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). 8 type 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 17 func (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 26 func (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 36 func (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 46 func (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 56 func (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 66 func (r *Register8) ReplaceBits(value uint8, mask uint8, pos uint8) { 67 StoreUint8(&r.Reg, LoadUint8(&r.Reg)&^(mask<<pos)|value<<pos) 68 } 69 70 type 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 79 func (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 88 func (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 98 func (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 108 func (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 118 func (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 128 func (r *Register16) ReplaceBits(value uint16, mask uint16, pos uint8) { 129 StoreUint16(&r.Reg, LoadUint16(&r.Reg)&^(mask<<pos)|value<<pos) 130 } 131 132 type 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 141 func (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 150 func (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 160 func (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 170 func (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 180 func (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 190 func (r *Register32) ReplaceBits(value uint32, mask uint32, pos uint8) { 191 StoreUint32(&r.Reg, LoadUint32(&r.Reg)&^(mask<<pos)|value<<pos) 192 } 193 194 type 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 203 func (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 212 func (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 222 func (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 232 func (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 242 func (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 252 func (r *Register64) ReplaceBits(value uint64, mask uint64, pos uint8) { 253 StoreUint64(&r.Reg, LoadUint64(&r.Reg)&^(mask<<pos)|value<<pos) 254 }