func (self *_Assembler) add_char(ch byte) {
    self.Emit("MOVB", jit.Imm(int64(ch)), jit.Sib(_RP, _RL, 1, 0))   
    self.Emit("ADDQ", jit.Imm(1), _RL)                               
}
Buffer Helpers *
package encoder
import (
    `fmt`
    `reflect`
    `strconv`
    `unsafe`
    `github.com/bytedance/sonic/internal/cpu`
    `github.com/bytedance/sonic/internal/jit`
    `github.com/bytedance/sonic/internal/native/types`
    `github.com/twitchyliquid64/golang-asm/obj`
    `github.com/twitchyliquid64/golang-asm/obj/x86`
    `github.com/bytedance/sonic/internal/native`
    `github.com/bytedance/sonic/internal/rt`
)
const (
    _S_cond = iota
    _S_init
)
const (
    _FP_args   = 48      
    _FP_fargs  = 64      
    _FP_saves  = 64      
    _FP_locals = 16      
)
const (
    _FP_offs = _FP_fargs + _FP_saves + _FP_locals
    _FP_size = _FP_offs + 8      
    _FP_base = _FP_size + 8      
)
const (
    _FM_exp32 = 0x7f800000
    _FM_exp64 = 0x7ff0000000000000
)
const (
    _IM_null = 0x6c6c756e            
    _IM_true = 0x65757274            
    _IM_fals = 0x736c6166            
    _IM_open = 0x00225c22            
    _IM_mulv = -0x5555555555555555
)
const (
    _LB_more_space        = "_more_space"
    _LB_more_space_return = "_more_space_return_"
)
const (
    _LB_error                 = "_error"
    _LB_error_too_deep        = "_error_too_deep"
    _LB_error_invalid_number  = "_error_invalid_number"
    _LB_error_nan_or_infinite = "_error_nan_or_infinite"
)
var (
    _AX = jit.Reg("AX")
    _CX = jit.Reg("CX")
    _DX = jit.Reg("DX")
    _DI = jit.Reg("DI")
    _SI = jit.Reg("SI")
    _BP = jit.Reg("BP")
    _SP = jit.Reg("SP")
    _R8 = jit.Reg("R8")
)
var (
    _X0 = jit.Reg("X0")
    _Y0 = jit.Reg("Y0")
)
var (
	_ST = jit.Reg("BX")
	_RP = jit.Reg("DI")
	_RL = jit.Reg("SI")
	_RC = jit.Reg("DX")
)
var (
    _LR = jit.Reg("R9")
	_ET = jit.Reg("R10")
	_EP = jit.Reg("R11")
)
var (
    _SP_p = jit.Reg("R12")
    _SP_q = jit.Reg("R13")
    _SP_x = jit.Reg("R14")
    _SP_f = jit.Reg("R15")
)
var (
    _ARG_rb = jit.Ptr(_SP, _FP_base)
    _ARG_vp = jit.Ptr(_SP, _FP_base + 8)
    _ARG_sb = jit.Ptr(_SP, _FP_base + 16)
    _ARG_fv = jit.Ptr(_SP, _FP_base + 24)
)
var (
    _RET_et = jit.Ptr(_SP, _FP_base + 32)
    _RET_ep = jit.Ptr(_SP, _FP_base + 40)
)
var (
    _VAR_sp = jit.Ptr(_SP, _FP_fargs + _FP_saves)
    _VAR_dn = jit.Ptr(_SP, _FP_fargs + _FP_saves + 8)
)
var (
    _REG_ffi = []obj.Addr{_RP, _RL, _RC}
    _REG_enc = []obj.Addr{_ST, _SP_x, _SP_f, _SP_p, _SP_q}
    _REG_jsr = []obj.Addr{_ST, _SP_x, _SP_f, _SP_p, _SP_q, _LR}
    _REG_all = []obj.Addr{_ST, _SP_x, _SP_f, _SP_p, _SP_q, _RP, _RL, _RC}
)
type _Assembler struct {
    jit.BaseAssembler
    p _Program
    x int
}
func newAssembler(p _Program) *_Assembler {
    return new(_Assembler).Init(p)
}
func (self *_Assembler) Load() _Encoder {
    return ptoenc(self.BaseAssembler.Load("json_encoder", _FP_size, _FP_args))
}
func (self *_Assembler) Init(p _Program) *_Assembler {
    self.p = p
    self.BaseAssembler.Init(self.compile)
    return self
}
func (self *_Assembler) compile() {
    self.prologue()
    self.instrs()
    self.epilogue()
    self.builtins()
}
var _OpFuncTab = [256]func(*_Assembler, *_Instr) {
    _OP_null           : (*_Assembler)._asm_OP_null,
    _OP_bool           : (*_Assembler)._asm_OP_bool,
    _OP_i8             : (*_Assembler)._asm_OP_i8,
    _OP_i16            : (*_Assembler)._asm_OP_i16,
    _OP_i32            : (*_Assembler)._asm_OP_i32,
    _OP_i64            : (*_Assembler)._asm_OP_i64,
    _OP_u8             : (*_Assembler)._asm_OP_u8,
    _OP_u16            : (*_Assembler)._asm_OP_u16,
    _OP_u32            : (*_Assembler)._asm_OP_u32,
    _OP_u64            : (*_Assembler)._asm_OP_u64,
    _OP_f32            : (*_Assembler)._asm_OP_f32,
    _OP_f64            : (*_Assembler)._asm_OP_f64,
    _OP_str            : (*_Assembler)._asm_OP_str,
    _OP_bin            : (*_Assembler)._asm_OP_bin,
    _OP_quote          : (*_Assembler)._asm_OP_quote,
    _OP_number         : (*_Assembler)._asm_OP_number,
    _OP_eface          : (*_Assembler)._asm_OP_eface,
    _OP_iface          : (*_Assembler)._asm_OP_iface,
    _OP_byte           : (*_Assembler)._asm_OP_byte,
    _OP_text           : (*_Assembler)._asm_OP_text,
    _OP_deref          : (*_Assembler)._asm_OP_deref,
    _OP_index          : (*_Assembler)._asm_OP_index,
    _OP_load           : (*_Assembler)._asm_OP_load,
    _OP_save           : (*_Assembler)._asm_OP_save,
    _OP_drop           : (*_Assembler)._asm_OP_drop,
    _OP_drop_2         : (*_Assembler)._asm_OP_drop_2,
    _OP_recurse        : (*_Assembler)._asm_OP_recurse,
    _OP_is_nil         : (*_Assembler)._asm_OP_is_nil,
    _OP_is_nil_p1      : (*_Assembler)._asm_OP_is_nil_p1,
    _OP_is_zero_1      : (*_Assembler)._asm_OP_is_zero_1,
    _OP_is_zero_2      : (*_Assembler)._asm_OP_is_zero_2,
    _OP_is_zero_4      : (*_Assembler)._asm_OP_is_zero_4,
    _OP_is_zero_8      : (*_Assembler)._asm_OP_is_zero_8,
    _OP_is_zero_map    : (*_Assembler)._asm_OP_is_zero_map,
    _OP_goto           : (*_Assembler)._asm_OP_goto,
    _OP_map_iter       : (*_Assembler)._asm_OP_map_iter,
    _OP_map_stop       : (*_Assembler)._asm_OP_map_stop,
    _OP_map_check_key  : (*_Assembler)._asm_OP_map_check_key,
    _OP_map_write_key  : (*_Assembler)._asm_OP_map_write_key,
    _OP_map_value_next : (*_Assembler)._asm_OP_map_value_next,
    _OP_slice_len      : (*_Assembler)._asm_OP_slice_len,
    _OP_slice_next     : (*_Assembler)._asm_OP_slice_next,
    _OP_marshal        : (*_Assembler)._asm_OP_marshal,
    _OP_marshal_p      : (*_Assembler)._asm_OP_marshal_p,
    _OP_marshal_text   : (*_Assembler)._asm_OP_marshal_text,
    _OP_marshal_text_p : (*_Assembler)._asm_OP_marshal_text_p,
    _OP_cond_set       : (*_Assembler)._asm_OP_cond_set,
    _OP_cond_testc     : (*_Assembler)._asm_OP_cond_testc,
}
func (self *_Assembler) instr(v *_Instr) {
    if fn := _OpFuncTab[v.op()]; fn != nil {
        fn(self, v)
    } else {
        panic(fmt.Sprintf("invalid opcode: %d", v.op()))
    }
}
func (self *_Assembler) instrs() {
    for i, v := range self.p {
        self.Mark(i)
        self.instr(&v)
    }
}
func (self *_Assembler) builtins() {
    self.more_space()
    self.error_too_deep()
    self.error_invalid_number()
    self.error_nan_or_infinite()
}
func (self *_Assembler) epilogue() {
    self.Mark(len(self.p))
    self.Emit("XORL", _ET, _ET)
    self.Emit("XORL", _EP, _EP)
    self.Link(_LB_error)
    self.Emit("MOVQ", _ARG_rb, _AX)                  
    self.Emit("MOVQ", _RL, jit.Ptr(_AX, 8))          
    self.Emit("MOVQ", _ET, _RET_et)                  
    self.Emit("MOVQ", _EP, _RET_ep)                  
    self.Emit("MOVQ", jit.Ptr(_SP, _FP_offs), _BP)   
    self.Emit("ADDQ", jit.Imm(_FP_size), _SP)        
    self.Emit("RET")                                 
}
func (self *_Assembler) prologue() {
    self.Emit("SUBQ", jit.Imm(_FP_size), _SP)        
    self.Emit("MOVQ", _BP, jit.Ptr(_SP, _FP_offs))   
    self.Emit("LEAQ", jit.Ptr(_SP, _FP_offs), _BP)   
    self.load_buffer()                               
    self.Emit("MOVQ", _ARG_vp, _SP_p)                
    self.Emit("MOVQ", _ARG_sb, _ST)                  
    self.Emit("XORL", _SP_x, _SP_x)                  
    self.Emit("XORL", _SP_f, _SP_f)                  
    self.Emit("XORL", _SP_q, _SP_q)                  
}
func (self *_Assembler) xsave(reg ...obj.Addr) {
    for i, v := range reg {
        if i > _FP_saves / 8 - 1 {
            panic("too many registers to save")
        } else {
            self.Emit("MOVQ", v, jit.Ptr(_SP, _FP_fargs + int64(i) * 8))
        }
    }
}
func (self *_Assembler) xload(reg ...obj.Addr) {
    for i, v := range reg {
        if i > _FP_saves / 8 - 1 {
            panic("too many registers to load")
        } else {
            self.Emit("MOVQ", jit.Ptr(_SP, _FP_fargs + int64(i) * 8), v)
        }
    }
}
func (self *_Assembler) rbuf_di() {
    if _RP.Reg != x86.REG_DI {
        panic("register allocation messed up: RP != DI")
    } else {
        self.Emit("ADDQ", _RL, _RP)
    }
}
func (self *_Assembler) store_int(nd int, fn obj.Addr, ins string) {
    self.check_size(nd)
    self.save_c()                            
    self.rbuf_di()                           
    self.Emit(ins, jit.Ptr(_SP_p, 0), _SI)   
    self.call_c(fn)                          
    self.Emit("ADDQ", _AX, _RL)              
}
func (self *_Assembler) store_str(s string) {
    i := 0
    m := rt.Str2Mem(s)
    for i <= len(m) - 8 {
        self.Emit("MOVQ", jit.Imm(rt.Get64(m[i:])), _AX)         
        self.Emit("MOVQ", _AX, jit.Sib(_RP, _RL, 1, int64(i)))   
        i += 8
    }
    if i <= len(m) - 4 {
        self.Emit("MOVL", jit.Imm(int64(rt.Get32(m[i:]))), jit.Sib(_RP, _RL, 1, int64(i)))   
        i += 4
    }
    if i <= len(m) - 2 {
        self.Emit("MOVW", jit.Imm(int64(rt.Get16(m[i:]))), jit.Sib(_RP, _RL, 1, int64(i)))   
        i += 2
    }
    if i < len(m) {
        self.Emit("MOVB", jit.Imm(int64(m[i])), jit.Sib(_RP, _RL, 1, int64(i)))      
    }
}
func (self *_Assembler) check_size(n int) {
    self.check_size_rl(jit.Ptr(_RL, int64(n)))
}
func (self *_Assembler) check_size_r(r obj.Addr, d int) {
    self.check_size_rl(jit.Sib(_RL, r, 1, int64(d)))
}
func (self *_Assembler) check_size_rl(v obj.Addr) {
    idx := self.x
    key := _LB_more_space_return + strconv.Itoa(idx)
    if _LR.Reg != x86.REG_R9 {
        panic("register allocation messed up: LR != R9")
    }
    self.x++
    self.Emit("LEAQ", v, _AX)        
    self.Emit("CMPQ", _AX, _RC)      
    self.Sjmp("JBE" , key)           
    self.slice_grow_ax(key)          
    self.Link(key)                   
}
func (self *_Assembler) slice_grow_ax(ret string) {
    self.Byte(0x4c, 0x8d, 0x0d)          
    self.Sref(ret, 4)                    
    self.Sjmp("JMP" , _LB_more_space)    
}
const (
    _StateSize  = int64(unsafe.Sizeof(_State{}))
    _StackLimit = _MaxStack * _StateSize
)
func (self *_Assembler) save_state() {
    self.Emit("MOVQ", jit.Ptr(_ST, 0), _AX)              
    self.Emit("LEAQ", jit.Ptr(_AX, _StateSize), _R8)     
    self.Emit("CMPQ", _R8, jit.Imm(_StackLimit))         
    self.Sjmp("JA"  , _LB_error_too_deep)                
    self.Emit("MOVQ", _SP_x, jit.Sib(_ST, _AX, 1, 8))    
    self.Emit("MOVQ", _SP_f, jit.Sib(_ST, _AX, 1, 16))   
    self.Emit("MOVQ", _SP_p, jit.Sib(_ST, _AX, 1, 24))   
    self.Emit("MOVQ", _SP_q, jit.Sib(_ST, _AX, 1, 32))   
    self.Emit("MOVQ", _R8, jit.Ptr(_ST, 0))              
}
func (self *_Assembler) drop_state(decr int64) {
    self.Emit("MOVQ" , jit.Ptr(_ST, 0), _AX)                 
    self.Emit("SUBQ" , jit.Imm(decr), _AX)                   
    self.Emit("MOVQ" , _AX, jit.Ptr(_ST, 0))                 
    self.Emit("MOVQ" , jit.Sib(_ST, _AX, 1, 8), _SP_x)       
    self.Emit("MOVQ" , jit.Sib(_ST, _AX, 1, 16), _SP_f)      
    self.Emit("MOVQ" , jit.Sib(_ST, _AX, 1, 24), _SP_p)      
    self.Emit("MOVQ" , jit.Sib(_ST, _AX, 1, 32), _SP_q)      
    self.Emit("PXOR" , _X0, _X0)                             
    self.Emit("MOVOU", _X0, jit.Sib(_ST, _AX, 1, 8))         
    self.Emit("MOVOU", _X0, jit.Sib(_ST, _AX, 1, 24))        
}