utils.go 2.7 KB

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