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)