register.mx raw

   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  }
 255