utils.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. //
  2. // Copyright 2024 CloudWeGo Authors
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. package x86_64
  17. import (
  18. `encoding/binary`
  19. `errors`
  20. `reflect`
  21. `strconv`
  22. `unicode/utf8`
  23. `unsafe`
  24. )
  25. const (
  26. _CC_digit = 1 << iota
  27. _CC_ident
  28. _CC_ident0
  29. _CC_number
  30. )
  31. func ispow2(v uint64) bool {
  32. return (v & (v - 1)) == 0
  33. }
  34. func isdigit(cc rune) bool {
  35. return '0' <= cc && cc <= '9'
  36. }
  37. func isalpha(cc rune) bool {
  38. return (cc >= 'a' && cc <= 'z') || (cc >= 'A' && cc <= 'Z')
  39. }
  40. func isident(cc rune) bool {
  41. return cc == '_' || isalpha(cc) || isdigit(cc)
  42. }
  43. func isident0(cc rune) bool {
  44. return cc == '_' || isalpha(cc)
  45. }
  46. func isnumber(cc rune) bool {
  47. return (cc == 'b' || cc == 'B') ||
  48. (cc == 'o' || cc == 'O') ||
  49. (cc == 'x' || cc == 'X') ||
  50. (cc >= '0' && cc <= '9') ||
  51. (cc >= 'a' && cc <= 'f') ||
  52. (cc >= 'A' && cc <= 'F')
  53. }
  54. func align(v int, n int) int {
  55. return (((v - 1) >> n) + 1) << n
  56. }
  57. func append8(m *[]byte, v byte) {
  58. *m = append(*m, v)
  59. }
  60. func append16(m *[]byte, v uint16) {
  61. p := len(*m)
  62. *m = append(*m, 0, 0)
  63. binary.LittleEndian.PutUint16((*m)[p:], v)
  64. }
  65. func append32(m *[]byte, v uint32) {
  66. p := len(*m)
  67. *m = append(*m, 0, 0, 0, 0)
  68. binary.LittleEndian.PutUint32((*m)[p:], v)
  69. }
  70. func append64(m *[]byte, v uint64) {
  71. p := len(*m)
  72. *m = append(*m, 0, 0, 0, 0, 0, 0, 0, 0)
  73. binary.LittleEndian.PutUint64((*m)[p:], v)
  74. }
  75. func expandmm(m *[]byte, n int, v byte) {
  76. sl := (*_GoSlice)(unsafe.Pointer(m))
  77. nb := sl.len + n
  78. /* grow as needed */
  79. if nb > cap(*m) {
  80. *m = growslice(byteType, *m, nb)
  81. }
  82. /* fill the new area */
  83. memset(unsafe.Pointer(uintptr(sl.ptr) + uintptr(sl.len)), v, uintptr(n))
  84. sl.len = nb
  85. }
  86. func memset(p unsafe.Pointer, c byte, n uintptr) {
  87. if c != 0 {
  88. memsetv(p, c, n)
  89. } else {
  90. memclrNoHeapPointers(p, n)
  91. }
  92. }
  93. func memsetv(p unsafe.Pointer, c byte, n uintptr) {
  94. for i := uintptr(0); i < n; i++ {
  95. *(*byte)(unsafe.Pointer(uintptr(p) + i)) = c
  96. }
  97. }
  98. func literal64(v string) (uint64, error) {
  99. var nb int
  100. var ch rune
  101. var ex error
  102. var mm [12]byte
  103. /* unquote the runes */
  104. for v != "" {
  105. if ch, _, v, ex = strconv.UnquoteChar(v, '\''); ex != nil {
  106. return 0, ex
  107. } else if nb += utf8.EncodeRune(mm[nb:], ch); nb > 8 {
  108. return 0, errors.New("multi-char constant too large")
  109. }
  110. }
  111. /* convert to uint64 */
  112. return *(*uint64)(unsafe.Pointer(&mm)), nil
  113. }
  114. var (
  115. byteWrap = reflect.TypeOf(byte(0))
  116. byteType = (*_GoType)(efaceOf(byteWrap).ptr)
  117. )
  118. //go:linkname growslice runtime.growslice
  119. func growslice(_ *_GoType, _ []byte, _ int) []byte
  120. //go:noescape
  121. //go:linkname memclrNoHeapPointers runtime.memclrNoHeapPointers
  122. func memclrNoHeapPointers(_ unsafe.Pointer, _ uintptr)