github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/internal/decoder/asm_stubs_amd64_go121.go (about) 1 //go:build go1.21 && !go1.22 2 // +build go1.21,!go1.22 3 4 // Copyright 2023 CloudWeGo Authors 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 package decoder 19 20 import ( 21 "strconv" 22 "unsafe" 23 24 "github.com/goshafaq/sonic/internal/jit" 25 "github.com/twitchyliquid64/golang-asm/obj" 26 "github.com/twitchyliquid64/golang-asm/obj/x86" 27 ) 28 29 //go:linkname _runtime_writeBarrier runtime.writeBarrier 30 var _runtime_writeBarrier uintptr 31 32 //go:nosplit 33 //go:linkname gcWriteBarrier2 runtime.gcWriteBarrier2 34 func gcWriteBarrier2() 35 36 // Notice: gcWriteBarrier must use R11 register!! 37 var _R11 = _IC 38 39 var ( 40 _V_writeBarrier = jit.Imm(int64(uintptr(unsafe.Pointer(&_runtime_writeBarrier)))) 41 42 _F_gcWriteBarrier2 = jit.Func(gcWriteBarrier2) 43 ) 44 45 func (self *_Assembler) WritePtrAX(i int, rec obj.Addr, saveDI bool) { 46 self.Emit("MOVQ", _V_writeBarrier, _R9) 47 self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0)) 48 self.Sjmp("JE", "_no_writeBarrier"+strconv.Itoa(i)+"_{n}") 49 if saveDI { 50 self.save(_DI, _R11) 51 } else { 52 self.save(_R11) 53 } 54 self.Emit("MOVQ", _F_gcWriteBarrier2, _R11) 55 self.Rjmp("CALL", _R11) 56 self.Emit("MOVQ", _AX, jit.Ptr(_R11, 0)) 57 self.Emit("MOVQ", rec, _DI) 58 self.Emit("MOVQ", _DI, jit.Ptr(_R11, 8)) 59 if saveDI { 60 self.load(_DI, _R11) 61 } else { 62 self.load(_R11) 63 } 64 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 65 self.Emit("MOVQ", _AX, rec) 66 } 67 68 func (self *_Assembler) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool, saveAX bool) { 69 if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX { 70 panic("rec contains AX!") 71 } 72 self.Emit("MOVQ", _V_writeBarrier, _R9) 73 self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0)) 74 self.Sjmp("JE", "_no_writeBarrier"+strconv.Itoa(i)+"_{n}") 75 if saveAX { 76 self.save(_AX, _R11) 77 } else { 78 self.save(_R11) 79 } 80 self.Emit("MOVQ", _F_gcWriteBarrier2, _R11) 81 self.Rjmp("CALL", _R11) 82 self.Emit("MOVQ", ptr, jit.Ptr(_R11, 0)) 83 self.Emit("MOVQ", rec, _AX) 84 self.Emit("MOVQ", _AX, jit.Ptr(_R11, 8)) 85 if saveAX { 86 self.load(_AX, _R11) 87 } else { 88 self.load(_R11) 89 } 90 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 91 self.Emit("MOVQ", ptr, rec) 92 } 93 94 func (self *_ValueDecoder) WritePtrAX(i int, rec obj.Addr, saveDI bool) { 95 self.Emit("MOVQ", _V_writeBarrier, _R9) 96 self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0)) 97 self.Sjmp("JE", "_no_writeBarrier"+strconv.Itoa(i)+"_{n}") 98 if saveDI { 99 self.save(_DI, _R11) 100 } else { 101 self.save(_R11) 102 } 103 self.Emit("MOVQ", _F_gcWriteBarrier2, _R11) 104 self.Rjmp("CALL", _R11) 105 self.Emit("MOVQ", _AX, jit.Ptr(_R11, 0)) 106 self.Emit("MOVQ", rec, _DI) 107 self.Emit("MOVQ", _DI, jit.Ptr(_R11, 8)) 108 if saveDI { 109 self.load(_DI, _R11) 110 } else { 111 self.load(_R11) 112 } 113 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 114 self.Emit("MOVQ", _AX, rec) 115 } 116 117 func (self *_ValueDecoder) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool) { 118 if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX { 119 panic("rec contains AX!") 120 } 121 self.Emit("MOVQ", _V_writeBarrier, _AX) 122 self.Emit("CMPL", jit.Ptr(_AX, 0), jit.Imm(0)) 123 self.Sjmp("JE", "_no_writeBarrier"+strconv.Itoa(i)+"_{n}") 124 self.save(_R11) 125 self.Emit("MOVQ", _F_gcWriteBarrier2, _R11) 126 self.Rjmp("CALL", _R11) 127 self.Emit("MOVQ", ptr, jit.Ptr(_R11, 0)) 128 self.Emit("MOVQ", rec, _AX) 129 self.Emit("MOVQ", _AX, jit.Ptr(_R11, 8)) 130 self.load(_R11) 131 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 132 self.Emit("MOVQ", ptr, rec) 133 }