github.com/chenzhuoyu/iasm@v0.9.1/x86_64/utils.go (about)

     1  package x86_64
     2  
     3  import (
     4      `encoding/binary`
     5      `errors`
     6      `reflect`
     7      `strconv`
     8      `unicode/utf8`
     9      `unsafe`
    10  )
    11  
    12  const (
    13      _CC_digit = 1 << iota
    14      _CC_ident
    15      _CC_ident0
    16      _CC_number
    17  )
    18  
    19  func ispow2(v uint64) bool {
    20      return (v & (v - 1)) == 0
    21  }
    22  
    23  func isdigit(cc rune) bool {
    24      return '0' <= cc && cc <= '9'
    25  }
    26  
    27  func isalpha(cc rune) bool {
    28      return (cc >= 'a' && cc <= 'z') || (cc >= 'A' && cc <= 'Z')
    29  }
    30  
    31  func isident(cc rune) bool {
    32      return cc == '_' || isalpha(cc) || isdigit(cc)
    33  }
    34  
    35  func isident0(cc rune) bool {
    36      return cc == '_' || isalpha(cc)
    37  }
    38  
    39  func isnumber(cc rune) bool {
    40      return (cc == 'b' || cc == 'B') ||
    41             (cc == 'o' || cc == 'O') ||
    42             (cc == 'x' || cc == 'X') ||
    43             (cc >= '0' && cc <= '9') ||
    44             (cc >= 'a' && cc <= 'f') ||
    45             (cc >= 'A' && cc <= 'F')
    46  }
    47  
    48  func align(v int, n int) int {
    49      return (((v - 1) >> n) + 1) << n
    50  }
    51  
    52  func append8(m *[]byte, v byte) {
    53      *m = append(*m, v)
    54  }
    55  
    56  func append16(m *[]byte, v uint16) {
    57      p := len(*m)
    58      *m = append(*m, 0, 0)
    59      binary.LittleEndian.PutUint16((*m)[p:], v)
    60  }
    61  
    62  func append32(m *[]byte, v uint32) {
    63      p := len(*m)
    64      *m = append(*m, 0, 0, 0, 0)
    65      binary.LittleEndian.PutUint32((*m)[p:], v)
    66  }
    67  
    68  func append64(m *[]byte, v uint64) {
    69      p := len(*m)
    70      *m = append(*m, 0, 0, 0, 0, 0, 0, 0, 0)
    71      binary.LittleEndian.PutUint64((*m)[p:], v)
    72  }
    73  
    74  func expandmm(m *[]byte, n int, v byte) {
    75      sl := (*_GoSlice)(unsafe.Pointer(m))
    76      nb := sl.len + n
    77  
    78      /* grow as needed */
    79      if nb > cap(*m) {
    80          *m = growslice(byteType, *m, nb)
    81      }
    82  
    83      /* fill the new area */
    84      memset(unsafe.Pointer(uintptr(sl.ptr) + uintptr(sl.len)), v, uintptr(n))
    85      sl.len = nb
    86  }
    87  
    88  func memset(p unsafe.Pointer, c byte, n uintptr) {
    89      if c != 0 {
    90          memsetv(p, c, n)
    91      } else {
    92          memclrNoHeapPointers(p, n)
    93      }
    94  }
    95  
    96  func memsetv(p unsafe.Pointer, c byte, n uintptr) {
    97      for i := uintptr(0); i < n; i++ {
    98          *(*byte)(unsafe.Pointer(uintptr(p) + i)) = c
    99      }
   100  }
   101  
   102  func literal64(v string) (uint64, error) {
   103      var nb int
   104      var ch rune
   105      var ex error
   106      var mm [12]byte
   107  
   108      /* unquote the runes */
   109      for v != "" {
   110          if ch, _, v, ex = strconv.UnquoteChar(v, '\''); ex != nil {
   111              return 0, ex
   112          } else if nb += utf8.EncodeRune(mm[nb:], ch); nb > 8 {
   113              return 0, errors.New("multi-char constant too large")
   114          }
   115      }
   116  
   117      /* convert to uint64 */
   118      return *(*uint64)(unsafe.Pointer(&mm)), nil
   119  }
   120  
   121  var (
   122      byteWrap = reflect.TypeOf(byte(0))
   123      byteType = (*_GoType)(efaceOf(byteWrap).ptr)
   124  )
   125  
   126  //go:linkname growslice runtime.growslice
   127  func growslice(_ *_GoType, _ []byte, _ int) []byte
   128  
   129  //go:noescape
   130  //go:linkname memclrNoHeapPointers runtime.memclrNoHeapPointers
   131  func memclrNoHeapPointers(_ unsafe.Pointer, _ uintptr)