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  }