github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/internal/decoder/asm_stubs_amd64_go117.go (about) 1 //go:build go1.17 && !go1.21 2 // +build go1.17,!go1.21 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:linkname gcWriteBarrierAX runtime.gcWriteBarrier 33 func gcWriteBarrierAX() 34 35 var ( 36 _V_writeBarrier = jit.Imm(int64(uintptr(unsafe.Pointer(&_runtime_writeBarrier)))) 37 38 _F_gcWriteBarrierAX = jit.Func(gcWriteBarrierAX) 39 ) 40 41 func (self *_Assembler) WritePtrAX(i int, rec obj.Addr, saveDI bool) { 42 self.Emit("MOVQ", _V_writeBarrier, _R9) 43 self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0)) 44 self.Sjmp("JE", "_no_writeBarrier"+strconv.Itoa(i)+"_{n}") 45 if saveDI { 46 self.save(_DI) 47 } 48 self.Emit("LEAQ", rec, _DI) 49 self.call(_F_gcWriteBarrierAX) 50 if saveDI { 51 self.load(_DI) 52 } 53 self.Sjmp("JMP", "_end_writeBarrier"+strconv.Itoa(i)+"_{n}") 54 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 55 self.Emit("MOVQ", _AX, rec) 56 self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}") 57 } 58 59 func (self *_Assembler) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool, saveAX bool) { 60 if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX { 61 panic("rec contains AX!") 62 } 63 self.Emit("MOVQ", _V_writeBarrier, _R9) 64 self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0)) 65 self.Sjmp("JE", "_no_writeBarrier"+strconv.Itoa(i)+"_{n}") 66 if saveAX { 67 self.Emit("XCHGQ", ptr, _AX) 68 } else { 69 self.Emit("MOVQ", ptr, _AX) 70 } 71 if saveDI { 72 self.save(_DI) 73 } 74 self.Emit("LEAQ", rec, _DI) 75 self.call(_F_gcWriteBarrierAX) 76 if saveDI { 77 self.load(_DI) 78 } 79 if saveAX { 80 self.Emit("XCHGQ", ptr, _AX) 81 } 82 self.Sjmp("JMP", "_end_writeBarrier"+strconv.Itoa(i)+"_{n}") 83 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 84 self.Emit("MOVQ", ptr, rec) 85 self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}") 86 } 87 88 func (self *_ValueDecoder) WritePtrAX(i int, rec obj.Addr, saveDI bool) { 89 self.Emit("MOVQ", _V_writeBarrier, _R9) 90 self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0)) 91 self.Sjmp("JE", "_no_writeBarrier"+strconv.Itoa(i)+"_{n}") 92 if saveDI { 93 self.save(_DI) 94 } 95 self.Emit("LEAQ", rec, _DI) 96 self.call(_F_gcWriteBarrierAX) 97 if saveDI { 98 self.load(_DI) 99 } 100 self.Sjmp("JMP", "_end_writeBarrier"+strconv.Itoa(i)+"_{n}") 101 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 102 self.Emit("MOVQ", _AX, rec) 103 self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}") 104 } 105 106 func (self *_ValueDecoder) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool) { 107 if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX { 108 panic("rec contains AX!") 109 } 110 self.Emit("MOVQ", _V_writeBarrier, _AX) 111 self.Emit("CMPL", jit.Ptr(_AX, 0), jit.Imm(0)) 112 self.Sjmp("JE", "_no_writeBarrier"+strconv.Itoa(i)+"_{n}") 113 self.Emit("MOVQ", ptr, _AX) 114 if saveDI { 115 self.save(_DI) 116 } 117 self.Emit("LEAQ", rec, _DI) 118 self.call(_F_gcWriteBarrierAX) 119 if saveDI { 120 self.load(_DI) 121 } 122 self.Sjmp("JMP", "_end_writeBarrier"+strconv.Itoa(i)+"_{n}") 123 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 124 self.Emit("MOVQ", ptr, rec) 125 self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}") 126 }