2
0
Fork 0
mirror of https://github.com/ii64/sonic.git synced 2026-06-21 00:46:43 +08:00
sonic/decoder/generic_amd64.s
2021-06-10 17:14:25 +08:00

419 lines
8.7 KiB
ArmAsm
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Copyright 2021 ByteDance Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "go_asm.h"
#include "funcdata.h"
#include "textflag.h"
// Register Allocations:
// AX result index (if any), or negative for errors
// R9 result value (slice array pointer or map pointer)
// R12 parameter string buffer
// R13 parameter string length
// R14 parameter index
// R15 decoder flags
#define ST BX
#define RT R8
#define RV R9
#define RE R11
#define PS R12
#define PN R13
#define PI R14
#define FL R15
#define ERR_EOF $-1
#define ERR_INVALID_CHAR $-2
#define lspace(to) \
MOVQ PS, DI \
MOVQ PN, SI \
MOVQ PI, DX \
MOVQ github·combytedancesonicinternalnative·S_lspace(SB), AX \
CALL AX \
MOVQ AX, PI \
TESTQ AX, AX \
JNS to \
RET \
to:
#define match_eof(to) \
MOVQ ERR_EOF, AX \
CMPQ PI, PN \
JBE to \
MOVQ PN, PI \
RET \
to:
#define match_empty(to, ch) \
CMPB (PS)(PI*1), ch \
JNE to \
XORQ AX, AX \
XORQ RV, RV \
ADDQ $1, PI \
RET \
to:
#define match_delim(done, next, ch) \
MOVBLZX (PS)(PI*1), AX \
ADDQ $1, PI \
CMPL AX, ch \
JE done \
CMPL AX, $',' \
JE next \
MOVQ ERR_INVALID_CHAR, AX \
SUBQ $1, PI \
RET \
done:
#define check_char(to, ch) \
MOVBLZX (PS)(PI*1), CX \
ADDQ $1, PI \
MOVQ ERR_INVALID_CHAR, AX \
CMPL CX, ch \
JE to \
SUBQ $1, PI \
RET \
to:
#define check_empty(to, ch) \
match_eof(_check_empty) \
match_empty(to, ch)
#define check_delim(done, next, ch) \
match_eof(_check_delim) \
match_delim(done, next, ch) \
// Generic Array Decoder
#define ARR_st fl-80(SP)
#define ARR_fl fl-72(SP)
#define ARR_ps ps-64(SP)
#define ARR_pn ps-56(SP)
#define ARR_pi pi-48(SP)
#define ARR_sp sp-40(SP)
#define ARR_sl sl-32(SP)
#define ARR_sc sc-24(SP)
#define ARR_rt sl-16(SP)
#define ARR_rv sc-8(SP)
TEXT ·decodeArray(SB), NOSPLIT, $144 - 8
NO_LOCAL_POINTERS
lspace(_check_array_empty)
check_empty(_make_slice, $']')
// set slice initial capacity to 16
XORQ CX, CX
MOVL $16, DX
MOVQ CX, ARR_sl
MOVQ DX, ARR_sc
// allocate memory for slice
MOVQ ST, ARR_st
MOVQ FL, ARR_fl
MOVQ PS, ARR_ps
MOVQ PN, ARR_pn
MOVQ PI, ARR_pi
MOVQ ·_type_eface(SB), AX
MOVQ AX, (SP)
MOVQ CX, 8(SP)
MOVQ DX, 16(SP)
CALL runtime·makeslice(SB)
MOVQ 24(SP), AX
MOVQ AX, ARR_sp
MOVQ AX, ret+0(FP)
MOVQ ARR_st, ST
MOVQ ARR_fl, FL
MOVQ ARR_ps, PS
MOVQ ARR_pn, PN
MOVQ ARR_pi, PI
GO_RESULTS_INITIALIZED
_parse_loop:
MOVQ ·_subr_decode_value(SB), AX
CALL AX
TESTQ RE, RE
JNZ _parsing_error
// check for slice space
MOVQ ARR_sp, DI
MOVQ ARR_sl, CX
CMPQ CX, ARR_sc
JAE _more_space
_append_slice:
LEAQ (DI)(CX*8), DI
LEAQ (DI)(CX*8), DI
MOVQ RT, (DI)
MOVQ RV, 8(DI)
ADDQ $1, CX
MOVQ CX, ARR_sl
// check for the delimiter
lspace(_check_array_delim)
check_delim(_done, _parse_loop, $']')
// set the result register and length
MOVQ ARR_sp, RV
MOVQ ARR_sl, AX
RET
_parsing_error:
MOVQ RE, AX
NEGQ AX
RET
_more_space:
MOVQ ST, ARR_st
MOVQ FL, ARR_fl
MOVQ PS, ARR_ps
MOVQ PN, ARR_pn
MOVQ PI, ARR_pi
MOVQ RT, ARR_rt
MOVQ RV, ARR_rv
MOVQ ARR_sc, DX
MOVQ ·_type_eface(SB), AX
MOVQ AX, (SP)
MOVQ DI, 8(SP)
MOVQ CX, 16(SP)
MOVQ DX, 24(SP)
SHLQ $1, DX
MOVQ DX, 32(SP)
CALL runtime·growslice(SB)
MOVQ 40(SP), DI
MOVQ 48(SP), CX
MOVQ 56(SP), DX
MOVQ DI, ARR_sp
MOVQ CX, ARR_sl
MOVQ DX, ARR_sc
MOVQ ARR_st, ST
MOVQ ARR_fl, FL
MOVQ ARR_ps, PS
MOVQ ARR_pn, PN
MOVQ ARR_pi, PI
MOVQ ARR_rt, RT
MOVQ ARR_rv, RV
JMP _append_slice
// Generic Object Decoder
#define OBJ_ss OBJ_ss_Sp
#define OBJ_ss_Sp ss_Sp-72(SP)
#define OBJ_ss_Sn ss_Sn-64(SP)
#define OBJ_st ps-56(SP)
#define OBJ_fl ps-48(SP)
#define OBJ_ps ps-40(SP)
#define OBJ_pn ps-32(SP)
#define OBJ_pi pi-24(SP)
#define OBJ_vp vp-16(SP)
#define OBJ_mp mp-8(SP)
TEXT ·decodeObject(SB), NOSPLIT, $104 - 8
NO_LOCAL_POINTERS
lspace(_check_object_empty)
check_empty(_make_map, $'}')
// create the result map
MOVQ ST, OBJ_st
MOVQ FL, OBJ_fl
MOVQ PS, OBJ_ps
MOVQ PN, OBJ_pn
MOVQ PI, OBJ_pi
CALL runtime·makemap_small(SB)
MOVQ (SP), AX
MOVQ AX, OBJ_mp
MOVQ AX, ret+0(FP)
MOVQ OBJ_st, ST
MOVQ OBJ_fl, FL
MOVQ OBJ_ps, PS
MOVQ OBJ_pn, PN
MOVQ OBJ_pi, PI
GO_RESULTS_INITIALIZED
_parse_loop:
CALL decodeObjectKey(SB)
MOVQ DI, OBJ_ss_Sp
MOVQ SI, OBJ_ss_Sn
TESTQ AX, AX
JNS _value_delim
RET
_value_delim:
lspace(_check_value_delim)
check_char(_parse_value, $':')
// allocate a new slot in the map
MOVQ ST, OBJ_st
MOVQ FL, OBJ_fl
MOVQ PS, OBJ_ps
MOVQ PN, OBJ_pn
MOVQ PI, OBJ_pi
MOVQ ·_type_strmap(SB), AX
MOVQ OBJ_mp, CX
MOVOU OBJ_ss, X0
MOVQ AX, (SP)
MOVQ CX, 8(SP)
MOVOU X0, 16(SP)
CALL runtime·mapassign_faststr(SB)
MOVQ 32(SP), AX
MOVQ AX, OBJ_vp
MOVQ OBJ_st, ST
MOVQ OBJ_fl, FL
MOVQ OBJ_ps, PS
MOVQ OBJ_pn, PN
MOVQ OBJ_pi, PI
// decode the value
MOVQ ·_subr_decode_value(SB), AX
CALL AX
TESTQ RE, RE
JNZ _value_error
// set the map value
MOVQ OBJ_vp, AX
MOVQ RT, (AX)
MOVQ RV, 8(AX)
// check for the delimiter
lspace(_check_object_delim)
check_delim(_done, _parse_loop, $'}')
// set the result register and clear the errors
XORQ AX, AX
MOVQ OBJ_mp, RV
RET
_value_error:
MOVQ RE, AX
NEGQ AX
RET
// Object Key Parsing Helper
#define V_STRING $7
#define F_DISABLE_URC $2
#define B_UNICODE_REPLACE $1
#define VAR_in VAR_in_PS
#define VAR_in_ST in_PS-88(SP)
#define VAR_in_FL in_PS-80(SP)
#define VAR_in_PS in_PS-72(SP)
#define VAR_in_PN in_PN-64(SP)
#define VAR_in_PI in_PI-56(SP)
#define VAR_ss VAR_ss_Sp
#define VAR_ss_Sp ss_Sp-48(SP)
#define VAR_ss_Sn ss_Sp-40(SP)
#define VAR_vv VAR_vv_Vt
#define VAR_vv_Vt vv_Vt-32(SP)
#define VAR_vv_Dv vv_Dv-24(SP)
#define VAR_vv_Iv vv_Iv-16(SP)
#define VAR_vv_Ep vv_Ep-8(SP)
TEXT decodeObjectKey(SB), NOSPLIT, $120 - 0
NO_LOCAL_POINTERS
lspace(_parse_key_begin)
check_char(_parse_key_body, $'"')
// parse the string
MOVQ PS, VAR_in_PS
MOVQ PN, VAR_in_PN
MOVQ PI, VAR_in_PI
LEAQ VAR_in, DI
LEAQ VAR_in_PI, SI
LEAQ VAR_vv, DX
MOVQ github·combytedancesonicinternalnative·S_vstring(SB), AX
CALL AX
MOVQ VAR_in_PI, PI
// check for errors
MOVQ VAR_vv_Vt, AX
TESTQ AX, AX
JNS _check_quote
RET
_check_quote:
CMPQ AX, V_STRING
JNE _invalid_type
// extract the string
MOVQ VAR_vv_Iv, CX
MOVQ PS, DI
MOVQ PI, SI
ADDQ CX, DI
SUBQ CX, SI
SUBQ $1, SI
// check for quotes
CMPQ VAR_vv_Ep, $-1
JNE _unquote
MOVQ SI, AX
RET
_unquote:
XORQ AX, AX
MOVQ ST, VAR_in_ST
MOVQ FL, VAR_in_FL
MOVQ PS, VAR_in_PS
MOVQ PN, VAR_in_PN
MOVQ PI, VAR_in_PI
MOVQ ·_type_byte(SB), CX
MOVQ DI, VAR_ss_Sp
MOVQ SI, VAR_ss_Sn
// allocate space for unquoted string
MOVQ SI, (SP)
MOVQ CX, 8(SP)
MOVQ AX, 16(SP)
CALL runtime·mallocgc(SB)
MOVQ 24(SP), DX
MOVQ VAR_in_ST, ST
MOVQ VAR_in_FL, FL
MOVQ VAR_in_PS, PS
MOVQ VAR_in_PN, PN
MOVQ VAR_in_PI, PI
// unquote the string
MOVQ VAR_ss_Sp, DI
MOVQ VAR_ss_Sn, SI
MOVQ DX, VAR_ss_Sp
LEAQ VAR_vv_Ep, CX
XORQ R8, R8
BTQ F_DISABLE_URC, FL
SETCC R8
SHLQ B_UNICODE_REPLACE, R8
MOVQ github·combytedancesonicinternalnative·S_unquote(SB), AX
CALL AX
TESTQ AX, AX
JS _escape_error
MOVQ AX, SI
MOVQ VAR_ss_Sp, DI
RET
_escape_error:
MOVQ VAR_ss_Sn, CX
SUBQ VAR_vv_Ep, CX
SUBQ CX, PI
SUBQ $1, PI
RET
_invalid_type:
MOVQ AX, (SP)
CALL ·throw_invalid_type(SB)
BYTE $0xcc
WORD $0xfdeb