diff options
Diffstat (limited to 'vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go')
-rw-r--r-- | vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go | 391 |
1 files changed, 205 insertions, 186 deletions
diff --git a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go b/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go index c2b45a8e1..2969c3bba 100644 --- a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go +++ b/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go @@ -17,266 +17,285 @@ package abi import ( - `fmt` - `reflect` - `unsafe` + "fmt" + "reflect" + "unsafe" - . `github.com/cloudwego/iasm/x86_64` + x64 "github.com/bytedance/sonic/loader/internal/iasm/x86_64" +) + +type ( + Register = x64.Register + Register64 = x64.Register64 + XMMRegister = x64.XMMRegister + Program = x64.Program + MemoryOperand = x64.MemoryOperand + Label = x64.Label +) + +var ( + Ptr = x64.Ptr + DefaultArch = x64.DefaultArch + CreateLabel = x64.CreateLabel ) const ( - PtrSize = 8 // pointer size - PtrAlign = 8 // pointer alignment + RAX = x64.RAX + RSP = x64.RSP + RBP = x64.RBP + R12 = x64.R12 + R14 = x64.R14 + R15 = x64.R15 +) + +const ( + PtrSize = 8 // pointer size + PtrAlign = 8 // pointer alignment ) var iregOrderC = []Register{ - RDI, - RSI, - RDX, - RCX, - R8, - R9, + x64.RDI, + x64.RSI, + x64.RDX, + x64.RCX, + x64.R8, + x64.R9, } var xregOrderC = []Register{ - XMM0, - XMM1, - XMM2, - XMM3, - XMM4, - XMM5, - XMM6, - XMM7, + x64.XMM0, + x64.XMM1, + x64.XMM2, + x64.XMM3, + x64.XMM4, + x64.XMM5, + x64.XMM6, + x64.XMM7, } var ( - intType = reflect.TypeOf(0) - ptrType = reflect.TypeOf(unsafe.Pointer(nil)) + intType = reflect.TypeOf(0) + ptrType = reflect.TypeOf(unsafe.Pointer(nil)) ) func (self *Frame) argv(i int) *MemoryOperand { - return Ptr(RSP, int32(self.Prev() + self.desc.Args[i].Mem)) + return Ptr(RSP, int32(self.Prev()+self.desc.Args[i].Mem)) } // spillv is used for growstack spill registers func (self *Frame) spillv(i int) *MemoryOperand { - // remain one slot for caller return pc - return Ptr(RSP, PtrSize + int32(self.desc.Args[i].Mem)) + // remain one slot for caller return pc + return Ptr(RSP, PtrSize+int32(self.desc.Args[i].Mem)) } func (self *Frame) retv(i int) *MemoryOperand { - return Ptr(RSP, int32(self.Prev() + self.desc.Rets[i].Mem)) + return Ptr(RSP, int32(self.Prev()+self.desc.Rets[i].Mem)) } func (self *Frame) resv(i int) *MemoryOperand { - return Ptr(RSP, int32(self.Offs() - uint32((i+1) * PtrSize))) + return Ptr(RSP, int32(self.Offs()-uint32((i+1)*PtrSize))) } func (self *Frame) emitGrowStack(p *Program, entry *Label) { - // spill all register arguments - for i, v := range self.desc.Args { - if v.InRegister { - if v.IsFloat == floatKind64 { - p.MOVSD(v.Reg, self.spillv(i)) - } else if v.IsFloat == floatKind32 { - p.MOVSS(v.Reg, self.spillv(i)) - }else { - p.MOVQ(v.Reg, self.spillv(i)) - } - } - } - - // call runtime.morestack_noctxt - p.MOVQ(F_morestack_noctxt, R12) - p.CALLQ(R12) - // load all register arguments - for i, v := range self.desc.Args { - if v.InRegister { - if v.IsFloat == floatKind64 { - p.MOVSD(self.spillv(i), v.Reg) - } else if v.IsFloat == floatKind32 { - p.MOVSS(self.spillv(i), v.Reg) - }else { - p.MOVQ(self.spillv(i), v.Reg) - } - } - } - - // jump back to the function entry - p.JMP(entry) + // spill all register arguments + for i, v := range self.desc.Args { + if v.InRegister { + if v.IsFloat == floatKind64 { + p.MOVSD(v.Reg, self.spillv(i)) + } else if v.IsFloat == floatKind32 { + p.MOVSS(v.Reg, self.spillv(i)) + } else { + p.MOVQ(v.Reg, self.spillv(i)) + } + } + } + + // call runtime.morestack_noctxt + p.MOVQ(F_morestack_noctxt, R12) + p.CALLQ(R12) + // load all register arguments + for i, v := range self.desc.Args { + if v.InRegister { + if v.IsFloat == floatKind64 { + p.MOVSD(self.spillv(i), v.Reg) + } else if v.IsFloat == floatKind32 { + p.MOVSS(self.spillv(i), v.Reg) + } else { + p.MOVQ(self.spillv(i), v.Reg) + } + } + } + + // jump back to the function entry + p.JMP(entry) } func (self *Frame) GrowStackTextSize() uint32 { - p := DefaultArch.CreateProgram() - // spill all register arguments - for i, v := range self.desc.Args { - if v.InRegister { - if v.IsFloat == floatKind64 { - p.MOVSD(v.Reg, self.spillv(i)) - } else if v.IsFloat == floatKind32 { - p.MOVSS(v.Reg, self.spillv(i)) - }else { - p.MOVQ(v.Reg, self.spillv(i)) - } - } - } - - // call runtime.morestack_noctxt - p.MOVQ(F_morestack_noctxt, R12) - p.CALLQ(R12) - // load all register arguments - for i, v := range self.desc.Args { - if v.InRegister { - if v.IsFloat == floatKind64 { - p.MOVSD(self.spillv(i), v.Reg) - } else if v.IsFloat == floatKind32 { - p.MOVSS(self.spillv(i), v.Reg) - } else { - p.MOVQ(self.spillv(i), v.Reg) - } - } - } - - // jump back to the function entry - l := CreateLabel("") - p.Link(l) - p.JMP(l) - - return uint32(len(p.Assemble(0))) + p := DefaultArch.CreateProgram() + // spill all register arguments + for i, v := range self.desc.Args { + if v.InRegister { + if v.IsFloat == floatKind64 { + p.MOVSD(v.Reg, self.spillv(i)) + } else if v.IsFloat == floatKind32 { + p.MOVSS(v.Reg, self.spillv(i)) + } else { + p.MOVQ(v.Reg, self.spillv(i)) + } + } + } + + // call runtime.morestack_noctxt + p.MOVQ(F_morestack_noctxt, R12) + p.CALLQ(R12) + // load all register arguments + for i, v := range self.desc.Args { + if v.InRegister { + if v.IsFloat == floatKind64 { + p.MOVSD(self.spillv(i), v.Reg) + } else if v.IsFloat == floatKind32 { + p.MOVSS(self.spillv(i), v.Reg) + } else { + p.MOVQ(self.spillv(i), v.Reg) + } + } + } + + // jump back to the function entry + l := CreateLabel("") + p.Link(l) + p.JMP(l) + + return uint32(len(p.Assemble(0))) } func (self *Frame) emitPrologue(p *Program) { - p.SUBQ(self.Size(), RSP) - p.MOVQ(RBP, Ptr(RSP, int32(self.Offs()))) - p.LEAQ(Ptr(RSP, int32(self.Offs())), RBP) + p.SUBQ(self.Size(), RSP) + p.MOVQ(RBP, Ptr(RSP, int32(self.Offs()))) + p.LEAQ(Ptr(RSP, int32(self.Offs())), RBP) } func (self *Frame) emitEpilogue(p *Program) { - p.MOVQ(Ptr(RSP, int32(self.Offs())), RBP) - p.ADDQ(self.Size(), RSP) - p.RET() + p.MOVQ(Ptr(RSP, int32(self.Offs())), RBP) + p.ADDQ(self.Size(), RSP) + p.RET() } func (self *Frame) emitReserveRegs(p *Program) { - // spill reserved registers - for i, r := range ReservedRegs(self.ccall) { - switch r.(type) { - case Register64: - p.MOVQ(r, self.resv(i)) - case XMMRegister: - p.MOVSD(r, self.resv(i)) - default: - panic(fmt.Sprintf("unsupported register type %t to reserve", r)) - } - } + // spill reserved registers + for i, r := range ReservedRegs(self.ccall) { + switch r.(type) { + case Register64: + p.MOVQ(r, self.resv(i)) + case XMMRegister: + p.MOVSD(r, self.resv(i)) + default: + panic(fmt.Sprintf("unsupported register type %t to reserve", r)) + } + } } func (self *Frame) emitSpillPtrs(p *Program) { - // spill pointer argument registers - for i, r := range self.desc.Args { - if r.InRegister && r.IsPointer { - p.MOVQ(r.Reg, self.argv(i)) - } - } + // spill pointer argument registers + for i, r := range self.desc.Args { + if r.InRegister && r.IsPointer { + p.MOVQ(r.Reg, self.argv(i)) + } + } } func (self *Frame) emitClearPtrs(p *Program) { - // spill pointer argument registers - for i, r := range self.desc.Args { - if r.InRegister && r.IsPointer { - p.MOVQ(int64(0), self.argv(i)) - } - } + // spill pointer argument registers + for i, r := range self.desc.Args { + if r.InRegister && r.IsPointer { + p.MOVQ(int64(0), self.argv(i)) + } + } } func (self *Frame) emitCallC(p *Program, addr uintptr) { - p.MOVQ(addr, RAX) - p.CALLQ(RAX) + p.MOVQ(addr, RAX) + p.CALLQ(RAX) } type floatKind uint8 const ( - notFloatKind floatKind = iota - floatKind32 - floatKind64 + notFloatKind floatKind = iota + floatKind32 + floatKind64 ) type Parameter struct { - InRegister bool - IsPointer bool - IsFloat floatKind - Reg Register - Mem uint32 - Type reflect.Type + InRegister bool + IsPointer bool + IsFloat floatKind + Reg Register + Mem uint32 + Type reflect.Type } func mkIReg(vt reflect.Type, reg Register64) (p Parameter) { - p.Reg = reg - p.Type = vt - p.InRegister = true - p.IsPointer = isPointer(vt) - return + p.Reg = reg + p.Type = vt + p.InRegister = true + p.IsPointer = isPointer(vt) + return } func isFloat(vt reflect.Type) floatKind { - switch vt.Kind() { - case reflect.Float32: - return floatKind32 - case reflect.Float64: - return floatKind64 - default: - return notFloatKind - } + switch vt.Kind() { + case reflect.Float32: + return floatKind32 + case reflect.Float64: + return floatKind64 + default: + return notFloatKind + } } func mkXReg(vt reflect.Type, reg XMMRegister) (p Parameter) { - p.Reg = reg - p.Type = vt - p.InRegister = true - p.IsFloat = isFloat(vt) - return + p.Reg = reg + p.Type = vt + p.InRegister = true + p.IsFloat = isFloat(vt) + return } func mkStack(vt reflect.Type, mem uint32) (p Parameter) { - p.Mem = mem - p.Type = vt - p.InRegister = false - p.IsPointer = isPointer(vt) - p.IsFloat = isFloat(vt) - return + p.Mem = mem + p.Type = vt + p.InRegister = false + p.IsPointer = isPointer(vt) + p.IsFloat = isFloat(vt) + return } func (self Parameter) String() string { - if self.InRegister { - return fmt.Sprintf("[%%%s, Pointer(%v), Float(%v)]", self.Reg, self.IsPointer, self.IsFloat) - } else { - return fmt.Sprintf("[%d(FP), Pointer(%v), Float(%v)]", self.Mem, self.IsPointer, self.IsFloat) - } + if self.InRegister { + return fmt.Sprintf("[%%%s, Pointer(%v), Float(%v)]", self.Reg, self.IsPointer, self.IsFloat) + } else { + return fmt.Sprintf("[%d(FP), Pointer(%v), Float(%v)]", self.Mem, self.IsPointer, self.IsFloat) + } } func CallC(addr uintptr, fr Frame, maxStack uintptr) []byte { - p := DefaultArch.CreateProgram() - - stack := CreateLabel("_stack_grow") - entry := CreateLabel("_entry") - p.Link(entry) - fr.emitStackCheck(p, stack, maxStack) - fr.emitPrologue(p) - fr.emitReserveRegs(p) - fr.emitSpillPtrs(p) - fr.emitExchangeArgs(p) - fr.emitCallC(p, addr) - fr.emitExchangeRets(p) - fr.emitRestoreRegs(p) - fr.emitEpilogue(p) - p.Link(stack) - fr.emitGrowStack(p, entry) - - return p.Assemble(0) + p := DefaultArch.CreateProgram() + + stack := CreateLabel("_stack_grow") + entry := CreateLabel("_entry") + p.Link(entry) + fr.emitStackCheck(p, stack, maxStack) + fr.emitPrologue(p) + fr.emitReserveRegs(p) + fr.emitSpillPtrs(p) + fr.emitExchangeArgs(p) + fr.emitCallC(p, addr) + fr.emitExchangeRets(p) + fr.emitRestoreRegs(p) + fr.emitEpilogue(p) + p.Link(stack) + fr.emitGrowStack(p, entry) + + return p.Assemble(0) } - - -func (self *Frame) emitDebug(p *Program) { - p.INT(3) -}
\ No newline at end of file |