Files
wa/internal/native/parser/parser_inst_loong_x.go
2025-12-05 21:23:47 +08:00

663 lines
19 KiB
Go

// Copyright (C) 2025 武汉凹语言科技有限公司
// SPDX-License-Identifier: AGPL-3.0-or-later
package parser
import (
"wa-lang.org/wa/internal/native/abi"
"wa-lang.org/wa/internal/native/ast"
"wa-lang.org/wa/internal/native/loong64"
"wa-lang.org/wa/internal/native/token"
)
func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
assert(p.cpu == abi.LOONG64)
inst = new(ast.Instruction)
inst.Arg = new(abi.AsArgument)
inst.Doc = p.parseDocComment(&fn.Body.Comments, inst.Pos)
if inst.Doc != nil {
fn.Body.Objects = fn.Body.Objects[:len(fn.Body.Objects)-1]
}
defer func() {
inst.Comment = p.parseTailComment(inst.Pos)
p.consumeSemicolonList()
}()
if p.tok == token.IDENT {
inst.Pos = p.pos
inst.Label = p.parseIdent()
p.acceptToken(token.COLON)
// 后续如果不是指令则结束
if !p.tok.IsAs() {
return inst
}
}
inst.Pos = p.pos
inst.AsName = p.lit
inst.As = p.parseAs()
// 查询指令的参数格式
if !loong64.AsValid(inst.As) {
p.errorf(p.pos, "%v is not loongarch instruction", inst.As)
}
switch loong64.AsFormatType(inst.As) {
case loong64.OpFormatType_NULL:
return inst
case loong64.OpFormatType_2R:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
return inst
case loong64.OpFormatType_2F:
fd := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fj := p.parseRegF_loong()
inst.Arg.Rd = fd
inst.Arg.Rs1 = fj
return inst
case loong64.OpFormatType_1F_1R:
fd := p.parseRegF_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
inst.Arg.Rd = fd
inst.Arg.Rs1 = rj
return inst
case loong64.OpFormatType_1R_1F:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
fj := p.parseRegF_loong()
inst.Arg.Rd = rd
inst.Arg.Rs1 = fj
return inst
case loong64.OpFormatType_3R:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rk := p.parseRegI_loong()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
return inst
case loong64.OpFormatType_3F:
fd := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fj := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fk := p.parseRegF_loong()
inst.Arg.Rd = fd
inst.Arg.Rs1 = fj
inst.Arg.Rs2 = fk
return inst
case loong64.OpFormatType_1F_2R:
fd := p.parseRegF_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rk := p.parseRegI_loong()
inst.Arg.Rd = fd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
return inst
case loong64.OpFormatType_4F:
fd := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fj := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fk := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fa := p.parseRegF_loong()
inst.Arg.Rd = fd
inst.Arg.Rs1 = fj
inst.Arg.Rs2 = fk
inst.Arg.Rs3 = fa
return inst
case loong64.OpFormatType_2R_ui5:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
ui5, ui5Symbol := p.parseInst_loong_imm_ui5()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = ui5
inst.Arg.Symbol = ui5Symbol
return inst
case loong64.OpFormatType_2R_ui6:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
ui6, ui6Symbol := p.parseInst_loong_imm_ui6()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = ui6
inst.Arg.Symbol = ui6Symbol
return inst
case loong64.OpFormatType_2R_si12:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
si12, si12Symbol := p.parseInst_loong_imm_si12()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = si12
inst.Arg.Symbol = si12Symbol
return inst
case loong64.OpFormatType_2R_ui12:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
ui12, ui12Symbol, ui12SymbolDecor := p.parseInst_loong_imm_ui12()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = ui12
inst.Arg.Symbol = ui12Symbol
inst.Arg.SymbolDecor = ui12SymbolDecor
return inst
case loong64.OpFormatType_2R_si14:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
si14, si14Symbol := p.parseInst_loong_imm_si14()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = si14
inst.Arg.Symbol = si14Symbol
return inst
case loong64.OpFormatType_2R_si16:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
si16, si16Symbol := p.parseInst_loong_imm_si16()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = si16
inst.Arg.Symbol = si16Symbol
return inst
case loong64.OpFormatType_1R_si20:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
p.acceptToken(token.COMMA)
si20, si20Symbol, si20SymbolDecor := p.parseInst_loong_imm_si20()
inst.Arg.Rd = rd
inst.Arg.Imm = si20
inst.Arg.Symbol = si20Symbol
inst.Arg.SymbolDecor = si20SymbolDecor
return inst
case loong64.OpFormatType_0_2R:
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rk := p.parseRegI_loong()
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
return inst
case loong64.OpFormatType_3R_sa2:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rk := p.parseRegI_loong()
p.acceptToken(token.COMMA)
sa2, sa2Symbol := p.parseInst_loong_imm_sa2()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
inst.Arg.Imm = sa2
inst.Arg.Symbol = sa2Symbol
return inst
case loong64.OpFormatType_3R_sa3:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rk := p.parseRegI_loong()
p.acceptToken(token.COMMA)
sa3, sa3Symbol := p.parseInst_loong_imm_sa3()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
inst.Arg.Imm = sa3
inst.Arg.Symbol = sa3Symbol
return inst
case loong64.OpFormatType_code:
code, codeSymbol := p.parseInst_loong_imm_code_15bit()
inst.Arg.Imm = code
inst.Arg.Symbol = codeSymbol
return inst
case loong64.OpFormatType_code_1R_si12:
code, codeSymbol := p.parseInst_loong_imm_code_5bit()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
si12, si12Symbol := p.parseInst_loong_imm_si12()
inst.Arg.Rs1 = rj
inst.Arg.Rd = abi.RegType(code) // Rd 寄存器参数位置用于记录 code
inst.Arg.RdName = codeSymbol
inst.Arg.Imm = si12
inst.Arg.Symbol = si12Symbol
return inst
case loong64.OpFormatType_2R_msbw_lsbw:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
msbw, msbwSymbol := p.parseInst_loong_imm_msbw_5bit()
p.acceptToken(token.COMMA)
lsbw, lsbwSymbol := p.parseInst_loong_imm_lsbw_5bit()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = abi.RegType(msbw) // Rs2 寄存器参数位置用于记录 msbw
inst.Arg.Rs2Name = msbwSymbol
inst.Arg.Rs3 = abi.RegType(lsbw) // Rs3 寄存器参数位置用于记录 lsbw
inst.Arg.Rs3Name = lsbwSymbol
return inst
case loong64.OpFormatType_2R_msbd_lsbd:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
msbd, msbdSymbol := p.parseInst_loong_imm_msbd_6bit()
p.acceptToken(token.COMMA)
lsbd, lsbdSymbol := p.parseInst_loong_imm_lsbd_6bit()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = abi.RegType(msbd) // Rs2 寄存器参数位置用于记录 msbd
inst.Arg.Rs2Name = msbdSymbol
inst.Arg.Rs3 = abi.RegType(lsbd) // Rs3 寄存器参数位置用于记录 lsbd
inst.Arg.Rs3Name = lsbdSymbol
return inst
case loong64.OpFormatType_fcsr_1R:
fcsr, fcsrSymbol := p.parseInst_loong_imm_fcsr_5bit()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
inst.Arg.Rd = abi.RegType(fcsr) // Rd 寄存器参数位置用于记录 fscr
inst.Arg.RdName = fcsrSymbol
inst.Arg.Rs1 = rj
return inst
case loong64.OpFormatType_1R_fcsr:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
fcsr, fcsrSymbol := p.parseInst_loong_imm_fcsr_5bit()
inst.Arg.Rd = rd
inst.Arg.Rs1 = abi.RegType(fcsr) // Rs1 寄存器参数位置用于记录 fscr
inst.Arg.Rs1Name = fcsrSymbol
return inst
case loong64.OpFormatType_cd_1R:
cd, cdSymbol := p.parseInst_loong_imm_cd_2bit()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
inst.Arg.Rd = abi.RegType(cd) // Rd 寄存器参数位置用于记录 cd
inst.Arg.RdName = cdSymbol
inst.Arg.Rs1 = rj
return inst
case loong64.OpFormatType_cd_1F:
cd, cdSymbol := p.parseInst_loong_imm_cd_2bit()
p.acceptToken(token.COMMA)
fj := p.parseRegF_loong()
p.acceptToken(token.COMMA)
inst.Arg.Rd = abi.RegType(cd) // Rd 寄存器参数位置用于记录 cd
inst.Arg.RdName = cdSymbol
inst.Arg.Rs1 = fj
return inst
case loong64.OpFormatType_cd_2F:
cd, cdSymbol := p.parseInst_loong_imm_cd_2bit()
p.acceptToken(token.COMMA)
fj := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fk := p.parseRegF_loong()
p.acceptToken(token.COMMA)
inst.Arg.Rd = abi.RegType(cd) // Rd 寄存器参数位置用于记录 cd
inst.Arg.RdName = cdSymbol
inst.Arg.Rs1 = fj
inst.Arg.Rs2 = fk
return inst
case loong64.OpFormatType_1R_cj:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
cj, cjSymbol := p.parseInst_loong_imm_cj_3bit()
inst.Arg.Rd = rd
inst.Arg.Rs1 = abi.RegType(cj) // Rs1 寄存器参数位置用于记录 cj
inst.Arg.Rs1Name = cjSymbol
return inst
case loong64.OpFormatType_1F_cj:
fd := p.parseRegF_loong()
p.acceptToken(token.COMMA)
cj, cjSymbol := p.parseInst_loong_imm_cj_3bit()
inst.Arg.Rd = fd
inst.Arg.Rs1 = abi.RegType(cj) // Rs1 寄存器参数位置用于记录 cj
inst.Arg.Rs1Name = cjSymbol
return inst
case loong64.OpFormatType_1R_csr:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
csr, csrSymbol := p.parseInst_loong_imm_csr_14bit()
inst.Arg.Rd = rd
inst.Arg.Imm = csr // CSR 作为 imm 记录, 没有宏修饰
inst.Arg.Symbol = csrSymbol
return inst
case loong64.OpFormatType_2R_csr:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
csr, csrSymbol := p.parseInst_loong_imm_csr_14bit()
if rj == loong64.REG_R0 || rj != loong64.REG_R1 {
p.errorf(p.pos, "%v: rj(%v) can notequal 0 or 1", inst.As, rj)
}
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = csr // CSR 作为 imm 记录, 没有宏修饰
inst.Arg.Symbol = csrSymbol
return inst
case loong64.OpFormatType_2R_level:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
level, levelSymbol := p.parseInst_loong_imm_level_8bit()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = level
inst.Arg.Symbol = levelSymbol
return inst
case loong64.OpFormatType_level:
level, levelSymbol := p.parseInst_loong_imm_level_15bit()
inst.Arg.Imm = level
inst.Arg.Symbol = levelSymbol
return inst
case loong64.OpFormatType_0_1R_seq:
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
seq, seqSymbol := p.parseInst_loong_imm_seq_8bit()
inst.Arg.Rs1 = rj
inst.Arg.Imm = seq
inst.Arg.Symbol = seqSymbol
return inst
case loong64.OpFormatType_op_2R:
op, opSymbol := p.parseInst_loong_imm_op_5bit()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rk := p.parseRegI_loong()
inst.Arg.Rd = abi.RegType(op) // Rd 寄存器存放 op
inst.Arg.RdName = opSymbol
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
return inst
case loong64.OpFormatType_3F_ca:
fd := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fj := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fk := p.parseRegF_loong()
p.acceptToken(token.COMMA)
ca, caSymbol := p.parseInst_loong_imm_ca_3bit()
inst.Arg.Rd = fd
inst.Arg.Rs1 = fj
inst.Arg.Rs2 = fk
inst.Arg.Imm = ca
inst.Arg.Symbol = caSymbol
return inst
case loong64.OpFormatType_hint_1R_si12:
hint, hintSymbol := p.parseInst_loong_imm_hint_5bit()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
si12, si12Symbol := p.parseInst_loong_imm_si12()
inst.Arg.Rd = abi.RegType(hint) // Rd 寄存器保存 hint
inst.Arg.RdName = hintSymbol
inst.Arg.Rs1 = rj
inst.Arg.Imm = si12
inst.Arg.Symbol = si12Symbol
return inst
case loong64.OpFormatType_hint_2R:
hint, hintSymbol := p.parseInst_loong_imm_hint_5bit()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rk := p.parseRegI_loong()
p.acceptToken(token.COMMA)
inst.Arg.Rd = abi.RegType(hint) // Rd 寄存器保存 hint
inst.Arg.RdName = hintSymbol
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
return inst
case loong64.OpFormatType_hint:
hint, hintSymbol := p.parseInst_loong_imm_hint_15bit()
inst.Arg.Imm = hint
inst.Arg.Symbol = hintSymbol
return inst
case loong64.OpFormatType_cj_offset:
cj, cjSymbol := p.parseInst_loong_imm_cj_3bit()
p.acceptToken(token.COMMA)
offSymbol := p.parseInst_loong_imm_offset()
inst.Arg.Rs1 = abi.RegType(cj) // Rs1 寄存器保存 cj
inst.Arg.Rs1Name = cjSymbol
inst.Arg.Symbol = offSymbol
return inst
case loong64.OpFormatType_rj_offset:
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
offSymbol := p.parseInst_loong_imm_offset()
inst.Arg.Rs1 = rj
inst.Arg.Symbol = offSymbol
return inst
case loong64.OpFormatType_rj_rd_offset:
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
offSymbol := p.parseInst_loong_imm_offset()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Symbol = offSymbol
return inst
case loong64.OpFormatType_rd_rj_offset:
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
offSymbol := p.parseInst_loong_imm_offset()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Symbol = offSymbol
return inst
case loong64.OpFormatType_offset:
offSymbol := p.parseInst_loong_imm_offset()
inst.Arg.Symbol = offSymbol
return inst
default:
panic("unreachable")
}
}
func (p *parser) parseRegI_loong() abi.RegType {
x := p.parseRegister()
if x < loong64.REG_R0 || x > loong64.REG_R31 {
p.errorf(p.pos, "%v is not loongarch int register", x)
}
return x
}
func (p *parser) parseRegF_loong() abi.RegType {
x := p.parseRegister()
if x < loong64.REG_F0 || x > loong64.REG_F31 {
p.errorf(p.pos, "%v is not loongarch float register", x)
}
return x
}
func (p *parser) parseInst_loong_imm_ui5() (ui5 int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_ui6() (ui6 int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_si12() (s12 int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
// 只有 ui12 和 si20 指令支持宏修饰函数
func (p *parser) parseInst_loong_imm_ui12() (ui12 int32, symbol string, symbolDecor abi.BuiltinFn) {
return p.parseInst_loong_immOrSymbolDecor()
}
func (p *parser) parseInst_loong_imm_si14() (si14 int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_si16() (si16 int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
// 只有 ui12 和 si20 指令支持宏修饰函数
func (p *parser) parseInst_loong_imm_si20() (si20 int32, symbol string, symbolDecor abi.BuiltinFn) {
return p.parseInst_loong_immOrSymbolDecor()
}
// 汇编程序中跳转地址必须用符号表示(因为很难手工获取PC相对地址)
func (p *parser) parseInst_loong_imm_offset() (symbol string) {
return p.parseIdent()
}
func (p *parser) parseInst_loong_imm_sa2() (sa2 int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_sa3() (sa3 int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_code_5bit() (code int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_code_15bit() (code int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_msbw_5bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_lsbw_5bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_msbd_6bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_lsbd_6bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_fcsr_5bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_cd_2bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_cj_3bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_csr_14bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_level_8bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_level_15bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_seq_8bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_op_5bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_ca_3bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_hint_5bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_hint_15bit() (x int32, symbol string) {
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_immOrSymbol() (imm int32, symbol string) {
switch p.tok {
case token.INT:
imm = p.parseInt32Lit()
return
case token.IDENT:
symbol = p.parseIdent()
return
default:
p.errorf(p.pos, "expect label or int, got %v", p.tok)
}
panic("unreachable")
}
func (p *parser) parseInst_loong_immOrSymbolDecor() (imm int32, symbol string, symbolDecor abi.BuiltinFn) {
if p.tok == token.INT {
imm = p.parseInt32Lit()
return
}
if p.tok != token.IDENT {
p.errorf(p.pos, "export IDENT, got %v", p.tok)
}
pos := p.pos
symbolOrDecor := p.parseIdent()
// 没有重定位修饰函数
if p.tok != token.LPAREN {
symbol = symbolOrDecor
return
}
// 判断重定位修饰函数
if fn := lookupBuiltinFn(symbolOrDecor); fn != 0 {
symbolDecor = lookupBuiltinFn(symbolOrDecor)
} else {
p.errorf(pos, "unknow symbol decorator %s", symbolOrDecor)
}
p.acceptToken(token.LPAREN)
symbol = p.parseIdent()
p.acceptToken(token.RPAREN)
switch p.tok {
case token.INT:
imm = p.parseInt32Lit()
return
case token.IDENT:
symbol = p.parseIdent()
return
default:
p.errorf(p.pos, "expect label or int, got %v", p.tok)
}
panic("unreachable")
}