汇编器实现龙芯指令格式化和编解码

This commit is contained in:
chai2010
2025-12-05 21:23:18 +08:00
parent 9c03ddf840
commit 4ff4c87fbb
10 changed files with 754 additions and 562 deletions

View File

@@ -55,27 +55,30 @@ type As int16
type BuiltinFn int16
const (
BuiltinFn_HI = iota + 1 // %hi(symbol) # 绝对地址 HI20, 指令 lui
BuiltinFn_LO // %lo(symbol) # 绝对地址 LO12, 指令 load/store/add
BuiltinFn_HI = iota + 1 // %hi(symbol) # 绝对地址 HI20
BuiltinFn_LO // %lo(symbol) # 绝对地址 LO12
BuiltinFn_HI52 // %hi52(symbol) # 绝对地址 32-51 bit 部分, 总地址宽度 52bit
BuiltinFn_PCREL_HI // %pcrel_hi(symbol) # PC相对地址 HI20, auipc
BuiltinFn_PCREL // %pcrel(symbol) # PC相对地址
BuiltinFn_PCREL_HI // %pcrel_hi(symbol) # PC相对地址 HI20
BuiltinFn_PCREL_LO // %pcrel_lo(label) # label 对应的指令中, 计算出的PC相对地址的 LO12 部分, 参数必须是 label
BuiltinFn_HI_zh
BuiltinFn_LO_zh
BuiltinFn_HI52_zh
BuiltinFn_PCREL_zh
BuiltinFn_PCREL_HI_zh
BuiltinFn_PCREL_LO_zh
BuiltinFn_Max // 标记结束
)
// 指令参数
type AsArgument struct {
Rd RegType // 目标寄存器
Rs1 RegType // 原寄存器1
Rs2 RegType // 原寄存器2
Rs3 RegType // 原寄存器3
Imm int32 // 立即数
Imm2 int32 // 立即数2
Rd RegType // 目标寄存器
Rs1 RegType // 原寄存器1
Rs2 RegType // 原寄存器2
Rs3 RegType // 原寄存器3
Imm int32 // 立即数
// 参数的名字, 用于格式化
RdName string
@@ -89,10 +92,9 @@ type AsArgument struct {
// 指令原生参数
type AsRawArgument struct {
Rd uint32 // 目标寄存器
Rs1 uint32 // 原寄存器1
Rs2 uint32 // 原寄存器2
Rs3 uint32 // 原寄存器3
Imm int32 // 立即数
Imm2 int32 // 立即数2
Rd uint32 // 目标寄存器
Rs1 uint32 // 原寄存器1
Rs2 uint32 // 原寄存器2
Rs3 uint32 // 原寄存器3
Imm int32 // 立即数
}

View File

@@ -25,6 +25,8 @@ func (fn BuiltinFn) String() string {
return "%lo"
case BuiltinFn_HI52:
return "%hi52"
case BuiltinFn_PCREL:
return "%pcrel"
case BuiltinFn_PCREL_HI:
return "%pcrel_hi"
case BuiltinFn_PCREL_LO:
@@ -36,6 +38,8 @@ func (fn BuiltinFn) String() string {
return "%低位"
case BuiltinFn_HI52_zh:
return "%高位五二"
case BuiltinFn_PCREL_zh:
return "%相对偏移"
case BuiltinFn_PCREL_HI_zh:
return "%相对高位"
case BuiltinFn_PCREL_LO_zh:

View File

@@ -1,4 +1,5 @@
// Code generated by stringer -i a.out.go -o anames.go -p loong64; DO NOT EDIT.
// Copyright (C) 2025 武汉凹语言科技有限公司
// SPDX-License-Identifier: AGPL-3.0-or-later
package loong64

View File

@@ -1,3 +1,6 @@
// Copyright (C) 2025 武汉凹语言科技有限公司
// SPDX-License-Identifier: AGPL-3.0-or-later
package loong64
import (
@@ -27,39 +30,12 @@ func (ctx *_OpContextType) asmSyntax(
rName func(r abi.RegType) string,
asNameFn func(x abi.As, xName string) string,
) string {
symbol := arg.Symbol
immValue := arg.Symbol
if arg.SymbolDecor != 0 {
symbol = fmt.Sprintf("%v(%s)", arg.SymbolDecor, arg.Symbol)
immValue = fmt.Sprintf("%v(%s)", arg.SymbolDecor, arg.Symbol)
}
// 辅助函数:处理 Imm/Symbol 作为偏移量 (Offset) 的格式,如 Imm(Rs1)
formatOffset := func(rs1 abi.RegType) string {
if symbol != "" {
return fmt.Sprintf("%v(%s)", symbol, rName(rs1))
} else {
// 假设 Arg.Imm 是一个整数偏移量
return fmt.Sprintf("%d(%s)", arg.Imm, rName(rs1))
}
}
// 辅助函数:处理 Imm/Symbol 作为立即数 (Immediate) 或目标 (Target) 的格式
formatImm := func() string {
if symbol != "" {
return symbol
} else {
// 默认以十进制格式化立即数,如需十六进制请自行调整
return fmt.Sprintf("%d", arg.Imm)
}
}
// 辅助函数:处理 Imm/Symbol 作为地址 (Address) 的格式
formatAddr := func() string {
if symbol != "" {
return symbol
} else {
// 地址或大立即数通常用十六进制表示
return fmt.Sprintf("0x%X", arg.Imm)
}
if arg.Symbol == "" {
immValue = fmt.Sprint(arg.Imm)
}
switch ctx.fmt {
@@ -82,77 +58,141 @@ func (ctx *_OpContextType) asmSyntax(
case OpFormatType_4F:
return fmt.Sprintf("%s %s, %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), rName(arg.Rs2), rName(arg.Rs3))
case OpFormatType_2R_ui5:
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rd), formatOffset(arg.Rs1))
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), immValue)
case OpFormatType_2R_ui6:
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), formatImm())
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), immValue)
case OpFormatType_2R_si12:
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), formatImm())
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), immValue)
case OpFormatType_2R_ui12:
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), formatImm())
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), immValue)
case OpFormatType_2R_si14:
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), formatImm())
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), immValue)
case OpFormatType_2R_si16:
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), formatImm())
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), immValue)
case OpFormatType_1R_si20:
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rd), formatAddr())
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rd), immValue)
case OpFormatType_0_2R:
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rs1), rName(arg.Rs2))
case OpFormatType_3R_sa2:
return fmt.Sprintf("%s %s, %s, %s, %d", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), rName(arg.Rs2), arg.Imm)
return fmt.Sprintf("%s %s, %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), rName(arg.Rs2), immValue)
case OpFormatType_3R_sa3:
return fmt.Sprintf("%s %s, %s, %s, %d", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), rName(arg.Rs2), arg.Imm)
return fmt.Sprintf("%s %s, %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), rName(arg.Rs2), immValue)
case OpFormatType_code:
return fmt.Sprintf("%s %d", asNameFn(as, asName), arg.Imm)
return fmt.Sprintf("%s %s", asNameFn(as, asName), immValue)
case OpFormatType_code_1R_si12:
return fmt.Sprintf("%s %d, %s, %s", asNameFn(as, asName), arg.Imm, rName(arg.Rs1), formatImm())
codeString := arg.RdName
if codeString == "" {
codeString = fmt.Sprint(int(arg.Rd))
}
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), codeString, rName(arg.Rs1), immValue)
case OpFormatType_2R_msbw_lsbw:
return fmt.Sprintf("%s %s, %s, %d, %d", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), arg.Imm, arg.Imm2)
msbw := arg.Rs2Name
lsbw := arg.Rs3Name
if msbw == "" {
msbw = fmt.Sprint(int(arg.Rs2))
}
if lsbw == "" {
lsbw = fmt.Sprint(int(arg.Rs3))
}
return fmt.Sprintf("%s %s, %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), msbw, lsbw)
case OpFormatType_2R_msbd_lsbd:
return fmt.Sprintf("%s %s, %s, %d, %d", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), arg.Imm, arg.Imm2)
msbd := arg.Rs2Name
lsbd := arg.Rs3Name
if msbd == "" {
msbd = fmt.Sprint(int(arg.Rs2))
}
if lsbd == "" {
lsbd = fmt.Sprint(int(arg.Rs3))
}
return fmt.Sprintf("%s %s, %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), msbd, lsbd)
case OpFormatType_fcsr_1R:
return fmt.Sprintf("%s %d, %s", asNameFn(as, asName), arg.Imm, rName(arg.Rs1))
fcsrSymbol := arg.RdName
if fcsrSymbol == "" {
fcsrSymbol = fmt.Sprint(int(arg.Rd))
}
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), fcsrSymbol, rName(arg.Rs1))
case OpFormatType_1R_fcsr:
return fmt.Sprintf("%s %s, %d", asNameFn(as, asName), rName(arg.Rd), arg.Imm)
fcsrSymbol := arg.Rs1Name
if fcsrSymbol == "" {
fcsrSymbol = fmt.Sprint(int(arg.Rs1))
}
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rd), fcsrSymbol)
case OpFormatType_cd_1R:
return fmt.Sprintf("%s %d, %s", asNameFn(as, asName), arg.Imm, rName(arg.Rs1))
cdSymbol := arg.RdName
if cdSymbol == "" {
cdSymbol = fmt.Sprint(int(arg.Imm))
}
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), cdSymbol, rName(arg.Rs1))
case OpFormatType_cd_1F:
return fmt.Sprintf("%s %d, %s", asNameFn(as, asName), arg.Imm, rName(arg.Rs1))
cdSymbol := arg.RdName
if cdSymbol == "" {
cdSymbol = fmt.Sprint(int(arg.Imm))
}
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), cdSymbol, rName(arg.Rs1))
case OpFormatType_cd_2F:
return fmt.Sprintf("%s %d, %s, %s", asNameFn(as, asName), arg.Imm, rName(arg.Rs1), rName(arg.Rs2))
cdSymbol := arg.RdName
if cdSymbol == "" {
cdSymbol = fmt.Sprint(int(arg.Imm))
}
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), cdSymbol, rName(arg.Rs1), rName(arg.Rs2))
case OpFormatType_1R_cj:
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rd), formatAddr())
cjSymbol := arg.Rs1Name
if cjSymbol == "" {
cjSymbol = fmt.Sprint(int(arg.Rs1))
}
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rd), cjSymbol)
case OpFormatType_1F_cj:
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rd), formatAddr())
cjSymbol := arg.Rs1Name
if cjSymbol == "" {
cjSymbol = fmt.Sprint(int(arg.Rs1))
}
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rd), cjSymbol)
case OpFormatType_1R_csr:
return fmt.Sprintf("%s %s, %d", asNameFn(as, asName), rName(arg.Rd), arg.Imm)
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rd), immValue)
case OpFormatType_2R_csr:
return fmt.Sprintf("%s %s, %s, %d", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), arg.Imm)
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), immValue)
case OpFormatType_2R_level:
return fmt.Sprintf("%s %s, %s, %d", asNameFn(as, asName), rName(arg.Rs1), rName(arg.Rs2), arg.Imm)
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), immValue)
case OpFormatType_level:
return fmt.Sprintf("%s %d", asNameFn(as, asName), arg.Imm)
return fmt.Sprintf("%s %s", asNameFn(as, asName), immValue)
case OpFormatType_0_1R_seq:
return fmt.Sprintf("%s %s, %d", asNameFn(as, asName), rName(arg.Rs1), arg.Imm)
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rs1), immValue)
case OpFormatType_op_2R:
return fmt.Sprintf("%s %d, %s, %s", asNameFn(as, asName), arg.Imm, rName(arg.Rs1), rName(arg.Rs2))
opSymbol := arg.RdName
if opSymbol == "" {
opSymbol = fmt.Sprint(int(arg.Rd))
}
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), opSymbol, rName(arg.Rs1), rName(arg.Rs2))
case OpFormatType_3F_ca:
return fmt.Sprintf("%s %s, %s, %s, %d", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), rName(arg.Rs2), arg.Imm)
case OpFormatType_hint_1R_si12:
return fmt.Sprintf("%s %d, %s, %s", asNameFn(as, asName), arg.Imm, rName(arg.Rs1), formatImm())
hintSymbol := arg.RdName
if hintSymbol == "" {
hintSymbol = fmt.Sprint(int(arg.Rd))
}
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), hintSymbol, rName(arg.Rs1), immValue)
case OpFormatType_hint_2R:
return fmt.Sprintf("%s %d, %s, %s", asNameFn(as, asName), arg.Imm, rName(arg.Rs1), rName(arg.Rs2))
hintSymbol := arg.RdName
if hintSymbol == "" {
hintSymbol = fmt.Sprint(int(arg.Rd))
}
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), hintSymbol, rName(arg.Rs1), rName(arg.Rs2))
case OpFormatType_hint:
return fmt.Sprintf("%s %d", asNameFn(as, asName), arg.Imm)
return fmt.Sprintf("%s %s", asNameFn(as, asName), immValue)
case OpFormatType_cj_offset:
return fmt.Sprintf("%s %s", asNameFn(as, asName), formatAddr())
cjSymbol := arg.Rs1Name
if cjSymbol == "" {
cjSymbol = fmt.Sprint(int(arg.Rs1))
}
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), cjSymbol, immValue)
case OpFormatType_rj_offset:
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rs1), formatOffset(arg.Rs1))
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rs1), immValue)
case OpFormatType_rj_rd_offset:
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), formatOffset(arg.Rs1))
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rs1), rName(arg.Rd), immValue)
case OpFormatType_rd_rj_offset:
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), formatOffset(arg.Rs1))
return fmt.Sprintf("%s %s, %s, %s", asNameFn(as, asName), rName(arg.Rd), rName(arg.Rs1), immValue)
case OpFormatType_offset:
return fmt.Sprintf("%s %s", asNameFn(as, asName), formatAddr())
return fmt.Sprintf("%s %s", asNameFn(as, asName), immValue)
default:
panic("unreachable")

View File

@@ -1,3 +1,6 @@
// Copyright (C) 2025 武汉凹语言科技有限公司
// SPDX-License-Identifier: AGPL-3.0-or-later
package loong64
import (
@@ -45,11 +48,15 @@ func (op _OpContextType) decodeInst(x uint32) (as abi.As, arg *abi.AsArgument, a
return
case OpFormatType_2R:
argRaw.Rd = rd
argRaw.Rs1 = rj
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = op.decodeRegI(rj)
return
case OpFormatType_2F:
argRaw.Rd = rd
argRaw.Rs1 = rj
arg.Rd = op.decodeRegF(rd)
arg.Rs1 = op.decodeRegF(rj)
return
case OpFormatType_1F_1R:
argRaw.Rd = rd
@@ -98,116 +105,291 @@ func (op _OpContextType) decodeInst(x uint32) (as abi.As, arg *abi.AsArgument, a
arg.Rs3 = op.decodeRegF(fa)
return
case OpFormatType_2R_ui5:
imm := int32(uimm(x, 10, 5))
argRaw.Rd = rd
argRaw.Rs1 = rj
arg.Rd = op.decodeRegF(rd)
arg.Rs1 = op.decodeRegF(rj)
arg.Imm = simm(x, 10, 5)
argRaw.Imm = imm
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Imm = imm
return
case OpFormatType_2R_ui6:
imm := int32(uimm(x, 10, 6))
argRaw.Rd = rd
argRaw.Rs1 = rj
arg.Rd = op.decodeRegF(rd)
arg.Rs1 = op.decodeRegF(rj)
arg.Imm = simm(x, 10, 6)
argRaw.Imm = imm
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Imm = imm
return
case OpFormatType_2R_si12:
imm := simm(x, 10, 12)
argRaw.Rd = rd
argRaw.Rs1 = rj
arg.Rd = op.decodeRegF(rd)
arg.Rs1 = op.decodeRegF(rj)
arg.Imm = simm(x, 10, 12)
argRaw.Imm = imm
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Imm = imm
return
case OpFormatType_2R_ui12:
imm := int32(uimm(x, 10, 12))
argRaw.Rd = rd
argRaw.Rs1 = rj
arg.Rd = op.decodeRegF(rd)
arg.Rs1 = op.decodeRegF(rj)
arg.Imm = simm(x, 10, 12)
argRaw.Imm = imm
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Imm = imm
return
case OpFormatType_2R_si14:
imm := int32(uimm(x, 10, 14))
argRaw.Rd = rd
argRaw.Rs1 = rj
arg.Rd = op.decodeRegF(rd)
arg.Rs1 = op.decodeRegF(rj)
arg.Imm = simm(x, 10, 14)
argRaw.Imm = imm
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Imm = imm
return
case OpFormatType_2R_si16:
imm := int32(uimm(x, 10, 16))
argRaw.Rd = rd
argRaw.Rs1 = rj
argRaw.Imm = imm
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Imm = imm
return
case OpFormatType_1R_si20:
imm := int32(uimm(x, 5, 20))
argRaw.Rd = rd
argRaw.Imm = imm
arg.Rd = op.decodeRegF(rd)
arg.Imm = imm
return
case OpFormatType_0_2R:
argRaw.Rs1 = rj
argRaw.Rs2 = rk
arg.Rs1 = op.decodeRegI(rj)
arg.Rs2 = op.decodeRegI(rk)
return
case OpFormatType_3R_sa2:
imm := int32(uimm(x, 10, 2))
argRaw.Rd = rd
argRaw.Rs1 = rj
argRaw.Rs2 = rk
argRaw.Imm = imm
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Rs2 = op.decodeRegI(rk)
arg.Imm = imm
return
case OpFormatType_3R_sa3:
imm := int32(uimm(x, 10, 3))
argRaw.Rd = rd
argRaw.Rs1 = rj
argRaw.Rs2 = rk
argRaw.Imm = imm
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Rs2 = op.decodeRegI(rk)
arg.Imm = imm
return
case OpFormatType_code:
imm := int32(uimm(x, 0, 15))
argRaw.Imm = imm
arg.Imm = imm
return
case OpFormatType_code_1R_si12:
code := rd
imm := int32(uimm(x, 10, 12))
argRaw.Rd = code
argRaw.Rs1 = rj
argRaw.Imm = imm
arg.Rd = abi.RegType(code)
argRaw.Rs1 = rj
arg.Imm = imm
return
case OpFormatType_2R_msbw_lsbw:
argRaw.Rd = rd
argRaw.Rs1 = rj
argRaw.Rs2 = rk
argRaw.Rs3 = fa
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Rs2 = abi.RegType(rk)
arg.Rs3 = abi.RegType(fa)
return
case OpFormatType_2R_msbd_lsbd:
argRaw.Rd = rd
argRaw.Rs1 = rj
argRaw.Rs2 = rk
argRaw.Rs3 = fa
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Rs2 = abi.RegType(rk)
arg.Rs3 = abi.RegType(fa)
return
case OpFormatType_fcsr_1R:
argRaw.Rd = rd
argRaw.Rs1 = rj
arg.Rd = abi.RegType(rd)
arg.Rs1 = op.decodeRegI(rj)
return
case OpFormatType_1R_fcsr:
argRaw.Rd = rd
argRaw.Rs1 = rj
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = abi.RegType(rj)
return
case OpFormatType_cd_1R:
argRaw.Rd = rd
argRaw.Rs1 = rj
arg.Rd = abi.RegType(rd)
arg.Rs1 = op.decodeRegI(rj)
return
case OpFormatType_cd_1F:
argRaw.Rd = rd
argRaw.Rs1 = rj
arg.Rd = abi.RegType(rd)
arg.Rs1 = op.decodeRegF(rj)
return
case OpFormatType_cd_2F:
argRaw.Rd = rd
argRaw.Rs1 = rj
argRaw.Rs2 = rk
arg.Rd = abi.RegType(rd)
arg.Rs1 = op.decodeRegF(rj)
arg.Rs2 = op.decodeRegF(rk)
return
case OpFormatType_1R_cj:
argRaw.Rd = rd
argRaw.Rs1 = rj
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = abi.RegType(rj)
return
case OpFormatType_1F_cj:
argRaw.Rd = rd
argRaw.Rs1 = rj
arg.Rd = op.decodeRegF(rd)
arg.Rs1 = op.decodeRegF(rj)
arg.Imm = simm(x, 10, 16)
arg.Rs1 = abi.RegType(rj)
return
case OpFormatType_1R_si20:
argRaw.Rd = rd
arg.Rd = op.decodeRegF(rd)
arg.Imm = simm(x, 10, 20)
return
case OpFormatType_0_2R:
panic("TODO")
case OpFormatType_3R_sa2:
panic("TODO")
case OpFormatType_3R_sa3:
panic("TODO")
case OpFormatType_code:
panic("TODO")
case OpFormatType_code_1R_si12:
panic("TODO")
case OpFormatType_2R_msbw_lsbw:
panic("TODO")
case OpFormatType_2R_msbd_lsbd:
panic("TODO")
case OpFormatType_fcsr_1R:
panic("TODO")
case OpFormatType_1R_fcsr:
panic("TODO")
case OpFormatType_cd_1R:
panic("TODO")
case OpFormatType_cd_1F:
panic("TODO")
case OpFormatType_cd_2F:
panic("TODO")
case OpFormatType_1R_cj:
panic("TODO")
case OpFormatType_1F_cj:
panic("TODO")
case OpFormatType_1R_csr:
panic("TODO")
imm := int32(uimm(x, 10, 14))
argRaw.Rd = rd
argRaw.Imm = imm
arg.Rd = op.decodeRegI(rd)
arg.Imm = imm
return
case OpFormatType_2R_csr:
panic("TODO")
imm := int32(uimm(x, 10, 14))
argRaw.Rd = rd
argRaw.Rs1 = rj
argRaw.Imm = imm
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Imm = imm
return
case OpFormatType_2R_level:
panic("TODO")
imm := int32(uimm(x, 10, 8))
argRaw.Rd = rd
argRaw.Rs1 = rj
argRaw.Imm = imm
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Imm = imm
return
case OpFormatType_level:
panic("TODO")
imm := int32(uimm(x, 0, 15))
argRaw.Imm = imm
arg.Imm = imm
return
case OpFormatType_0_1R_seq:
panic("TODO")
imm := int32(uimm(x, 10, 8))
argRaw.Rs1 = rj
argRaw.Imm = imm
arg.Rs1 = op.decodeRegI(rj)
arg.Imm = imm
return
case OpFormatType_op_2R:
panic("TODO")
argRaw.Rd = rd
argRaw.Rs1 = rj
argRaw.Rs2 = rk
arg.Rd = abi.RegType(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Rs2 = abi.RegType(rk)
return
case OpFormatType_3F_ca:
panic("TODO")
imm := int32(uimm(x, 15, 3))
argRaw.Rd = rd
argRaw.Rs1 = rj
argRaw.Rs2 = rk
argRaw.Imm = imm
arg.Rd = op.decodeRegF(rd)
arg.Rs1 = op.decodeRegF(rj)
arg.Rs2 = op.decodeRegF(rk)
arg.Imm = imm
return
case OpFormatType_hint_1R_si12:
panic("TODO")
imm := int32(uimm(x, 10, 12))
argRaw.Rd = rd
argRaw.Rs1 = rj
argRaw.Imm = imm
arg.Rd = abi.RegType(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Imm = imm
return
case OpFormatType_hint_2R:
panic("TODO")
argRaw.Rd = rd
argRaw.Rs1 = rj
argRaw.Rs2 = rk
arg.Rd = abi.RegType(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Rs2 = op.decodeRegI(rk)
return
case OpFormatType_hint:
panic("TODO")
imm := int32(uimm(x, 0, 15))
argRaw.Imm = imm
arg.Imm = imm
return
case OpFormatType_cj_offset:
panic("TODO")
imm := int32(rd | (uimm(x, 10, 16) << 16))
argRaw.Rs1 = rj
argRaw.Imm = imm
arg.Rs1 = abi.RegType(rj)
arg.Imm = imm
return
case OpFormatType_rj_offset:
panic("TODO")
imm := int32(rd | (uimm(x, 10, 16) << 16))
argRaw.Rs1 = rj
argRaw.Imm = imm
arg.Rs1 = op.decodeRegI(rj)
arg.Imm = imm
return
case OpFormatType_rj_rd_offset:
panic("TODO")
imm := int32(uimm(x, 10, 16))
argRaw.Rs1 = rj
argRaw.Rd = rd
argRaw.Imm = imm
arg.Rs1 = op.decodeRegI(rj)
arg.Rd = op.decodeRegI(rd)
arg.Imm = imm
return
case OpFormatType_rd_rj_offset:
panic("TODO")
imm := int32(uimm(x, 10, 16))
argRaw.Rd = rd
argRaw.Rs1 = rj
argRaw.Imm = imm
arg.Rd = op.decodeRegI(rd)
arg.Rs1 = op.decodeRegI(rj)
arg.Imm = imm
return
case OpFormatType_offset:
panic("TODO")
imm := int32((uimm(x, 0, 10) << 10) | (uimm(x, 10, 16)))
argRaw.Imm = imm
arg.Imm = imm
return
default:
panic("unreachable")
}
// 成功解码所有参数后,返回结果
return as, arg, argRaw, nil
}
// 解码寄存器

View File

@@ -1,3 +1,6 @@
// Copyright (C) 2025 武汉凹语言科技有限公司
// SPDX-License-Identifier: AGPL-3.0-or-later
package loong64
import (
@@ -49,96 +52,256 @@ func (ctx *_OpContextType) encodeRaw(as abi.As, arg *abi.AsArgument) (x uint32,
case OpFormatType_NULL:
return
case OpFormatType_2R:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
x |= (rj << 5) | rd
return
case OpFormatType_2F:
panic("TODO")
fd := ctx.regF(arg.Rd)
fj := ctx.regF(arg.Rs1)
x |= (fj << 5) | fd
return
case OpFormatType_1F_1R:
panic("TODO")
fd := ctx.regF(arg.Rd)
rj := ctx.regI(arg.Rs1)
x |= (rj << 5) | fd
return
case OpFormatType_1R_1F:
panic("TODO")
rd := ctx.regI(arg.Rd)
fj := ctx.regF(arg.Rs1)
x |= (fj << 5) | rd
return
case OpFormatType_3R:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
rk := ctx.regI(arg.Rs2)
x |= (rk << 10) | (rj << 5) | rd
return
case OpFormatType_3F:
panic("TODO")
fd := ctx.regF(arg.Rd)
fj := ctx.regF(arg.Rs1)
fk := ctx.regF(arg.Rs2)
x |= (fk << 10) | (fj << 5) | fd
return
case OpFormatType_1F_2R:
panic("TODO")
fd := ctx.regF(arg.Rd)
rj := ctx.regI(arg.Rs1)
rk := ctx.regI(arg.Rs2)
x |= (rk << 10) | (rj << 5) | fd
return
case OpFormatType_4F:
panic("TODO")
fd := ctx.regF(arg.Rd)
fj := ctx.regF(arg.Rs1)
fk := ctx.regF(arg.Rs2)
fa := ctx.regF(arg.Rs3)
x |= (fa << 15) | (fk << 10) | (fj << 5) | fd
return
case OpFormatType_2R_ui5:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
ui5 := arg.Imm & 0x1F
x |= (uint32(ui5) << 10) | (rj << 5) | rd
return
case OpFormatType_2R_ui6:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
ui5 := arg.Imm & 0x3F
x |= (uint32(ui5) << 10) | (rj << 5) | rd
return
case OpFormatType_2R_si12:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
si12 := arg.Imm & 0xFFF // TODO: 符号位
x |= (uint32(si12) << 10) | (rj << 5) | rd
return
case OpFormatType_2R_ui12:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
ui12 := arg.Imm & 0xFFF
x |= (uint32(ui12) << 10) | (rj << 5) | rd
return
case OpFormatType_2R_si14:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
si14 := arg.Imm & 0x3FFF // TODO: 符号位
x |= (uint32(si14) << 10) | (rj << 5) | rd
return
case OpFormatType_2R_si16:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
si16 := arg.Imm & 0xFFFF // TODO: 符号位
x |= (uint32(si16) << 10) | (rj << 5) | rd
return
case OpFormatType_1R_si20:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
si20 := arg.Imm & 0xFFFFF // TODO: 符号位
x |= (uint32(si20) << 10) | (rj << 5) | rd
return
case OpFormatType_0_2R:
panic("TODO")
rj := ctx.regI(arg.Rs1)
rk := ctx.regI(arg.Rs2)
x |= (rk << 10) | (rj << 5)
return
case OpFormatType_3R_sa2:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
rk := ctx.regI(arg.Rs2)
sa2 := arg.Imm & 0xF
x |= (rk << 14) | (uint32(sa2) << 10) | (rj << 5) | rd
return
case OpFormatType_3R_sa3:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
rk := ctx.regI(arg.Rs2)
sa2 := arg.Imm & 0x1F
x |= (rk << 14) | (uint32(sa2) << 10) | (rj << 5) | rd
return
case OpFormatType_code:
panic("TODO")
code := arg.Imm & 0x7FFF
x |= uint32(code)
return
case OpFormatType_code_1R_si12:
panic("TODO")
code := uint32(arg.Rd) & 0b_1_1111
rj := ctx.regI(arg.Rs1)
si12 := arg.Imm & 0xFFF // TODO: 符号位
x |= (uint32(si12) << 10) | (rj << 5) | code
return
case OpFormatType_2R_msbw_lsbw:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
msbw := uint32(arg.Rs2) & 0b_0_1_1111
lsbw := uint32(arg.Rs3) & 0b_0_1_1111
x |= (msbw << 16) | (lsbw << 10) | (rj << 5) | rd
return
case OpFormatType_2R_msbd_lsbd:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
msbd := uint32(arg.Rs2) & 0b_1_1_1111
lsbd := uint32(arg.Rs3) & 0b_1_1_1111
x |= (msbd << 16) | (lsbd << 10) | (rj << 5) | rd
return
case OpFormatType_fcsr_1R:
panic("TODO")
fcsr := uint32(arg.Rd)
rj := ctx.regI(arg.Rs1)
x |= (rj << 5) | fcsr
return
case OpFormatType_1R_fcsr:
panic("TODO")
rd := ctx.regI(arg.Rd)
fcsr := uint32(arg.Rs1)
x |= (fcsr << 5) | rd
return
case OpFormatType_cd_1R:
panic("TODO")
cd := uint32(arg.Rd) & 0b_111
rj := ctx.regI(arg.Rs1)
x |= (rj << 5) | cd
return
case OpFormatType_cd_1F:
panic("TODO")
cd := uint32(arg.Rd) & 0b_111
fj := ctx.regF(arg.Rs1)
x |= (fj << 5) | cd
return
case OpFormatType_cd_2F:
panic("TODO")
cd := uint32(arg.Rd) & 0b_111
fj := ctx.regF(arg.Rs1)
fk := ctx.regF(arg.Rs1)
x |= (fk << 10) | (fj << 5) | cd
return
case OpFormatType_1R_cj:
panic("TODO")
rd := ctx.regI(arg.Rd)
cj := uint32(arg.Rs1) & 0b_111
x |= (cj << 5) | rd
return
case OpFormatType_1F_cj:
panic("TODO")
fd := ctx.regF(arg.Rd)
cj := uint32(arg.Rs1) & 0b_111
x |= (cj << 5) | fd
return
case OpFormatType_1R_csr:
panic("TODO")
rd := ctx.regI(arg.Rd)
csr := uint32(arg.Imm) & 0x3FFF
x |= (csr << 10) | rd
return
case OpFormatType_2R_csr:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
csr := uint32(arg.Imm) & 0x3FFF
x |= (csr << 10) | (rj << 5) | rd
return
case OpFormatType_2R_level:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
level := uint32(arg.Imm) & 0xFFFF
x |= (level << 10) | (rj << 5) | rd
return
case OpFormatType_level:
panic("TODO")
level := uint32(arg.Imm) & 0x7FFF
x |= level
return
case OpFormatType_0_1R_seq:
panic("TODO")
rj := ctx.regI(arg.Rs1)
seq := uint32(arg.Imm) & 0xFFFF
x |= (seq << 10) | (rj << 5)
return
case OpFormatType_op_2R:
panic("TODO")
op := uint32(arg.Rd) & 0b_1_1111
rj := ctx.regI(arg.Rs1)
rk := ctx.regI(arg.Rs2)
x |= (rk << 10) | (rj << 5) | op
return
case OpFormatType_3F_ca:
panic("TODO")
fd := ctx.regF(arg.Rd)
fj := ctx.regF(arg.Rs1)
fk := ctx.regF(arg.Rs2)
ca := uint32(arg.Imm) & 0b_111
x |= (ca << 15) | (fk << 10) | (fj << 5) | fd
return
case OpFormatType_hint_1R_si12:
panic("TODO")
hint := uint32(arg.Rd) & 0b_1_1111
rj := ctx.regI(arg.Rs1)
si12 := uint32(arg.Imm) & 0xFFF
x |= (si12 << 10) | (rj << 5) | hint
return
case OpFormatType_hint_2R:
panic("TODO")
hint := uint32(arg.Rd) & 0b_1_1111
rj := ctx.regI(arg.Rs1)
rk := ctx.regI(arg.Rs2)
x |= (rk << 10) | (rj << 5) | hint
return
case OpFormatType_hint:
panic("TODO")
hint := uint32(arg.Imm) & 0x7FFF
x |= hint
return
case OpFormatType_cj_offset:
panic("TODO")
off16_20 := (uint32(arg.Imm) >> 16) & 0b_1_1111
cj := uint32(arg.Rs1) & 0b_111
off0_15 := uint32(arg.Imm) & 0xFFFF
x |= (off0_15 << 10) | (cj << 5) | off16_20
return
case OpFormatType_rj_offset:
panic("TODO")
off16_20 := (uint32(arg.Imm) >> 16) & 0b_1_1111
rj := ctx.regI(arg.Rs1)
off0_15 := uint32(arg.Imm) & 0xFFFF
x |= (off0_15 << 10) | (rj << 5) | off16_20
return
case OpFormatType_rj_rd_offset:
panic("TODO")
rj := ctx.regI(arg.Rs1)
rd := ctx.regI(arg.Rd)
offset := uint32(arg.Imm) & 0xFFFF
x |= (offset << 10) | (rj << 5) | rd
return
case OpFormatType_rd_rj_offset:
panic("TODO")
rd := ctx.regI(arg.Rd)
rj := ctx.regI(arg.Rs1)
offset := uint32(arg.Imm) & 0xFFFF
x |= (offset << 10) | (rj << 5) | rd
return
case OpFormatType_offset:
panic("TODO")
off16_25 := (uint32(arg.Imm) >> 16) & 0b_11_1111_1111
off0_15 := uint32(arg.Imm) & 0xFFFF
x |= (off0_15 << 10) | off16_25
return
default:
panic("unreachable")
}
return x, nil
}

View File

@@ -4,7 +4,6 @@
package loong64
import (
"fmt"
"unicode"
"unicode/utf8"
)
@@ -15,10 +14,6 @@ func assert(ok bool) {
}
}
func newU32(v uint32) *uint32 {
return &v
}
// 提取无符号立即数 (unsigned immediate)
func uimm(x uint32, startBit, width uint32) uint32 {
mask := (uint32(1) << width) - 1
@@ -28,66 +23,13 @@ func uimm(x uint32, startBit, width uint32) uint32 {
// 提取有符号立即数 (signed immediate)
func simm(x uint32, startBit, width uint32) int32 {
val := uimm(x, startBit, width)
if (val >> (width - 1)) == 1 {
// 符号位为1进行符号扩展
if signBit := uint32(1 << (width - 1)); (val & signBit) != 0 {
return int32(val) - (int32(1) << width)
}
return int32(val)
}
// 输入一个 32 位有符号立即数 imm, 输出 low(12bit)/high(20bit)
// 满足 imm 约等于 (high << 12) + low, 以便于进行长地址跳转的拆分
func split32BitImmediate(imm int64) (low12bit, high20bit int64, err error) {
// 确保 imm 在 32 位有符号整数范围内
if err := immIFitsIntN(imm, 32); err != nil {
return 0, 0, err
}
// 如果 imm 能直接放进 12 位 signed 范围([-2048, 2047])
// 则没必要分拆, low=imm, high=0
if err := immIFitsIntN(imm, 12); err == nil {
return imm, 0, nil
}
// 先粗略地取高 20 位
high20bit = imm >> 12
// 低 12 位是有符号数, 可能是负的
// 当 imm 的 bit[11]=1 时, 说明低 12 位是负数, 这时 high++ 来补偿
if imm&(1<<11) != 0 {
high20bit++
}
// 把 low 作为 12 位有符号数扩展
low12bit = i64SignExtend(imm, 12)
// 把 high 作为 20 位有符号数扩展
high20bit = i64SignExtend(high20bit, 20)
return low12bit, high20bit, nil
}
// 检查 x 是否能装进 nbits 位的有符号整数
func immIFitsIntN(x int64, nbits uint) error {
nbits--
min := int64(-1) << nbits
max := int64(1)<<nbits - 1
if x < min || x > max {
if nbits <= 16 {
return fmt.Errorf("signed immediate %d must be in range [%d, %d] (%d bits)", x, min, max, nbits)
}
return fmt.Errorf("signed immediate %#x must be in range [%#x, %#x] (%d bits)", x, min, max, nbits)
}
return nil
}
// 把 val 的低 bit 位当作一个有符号数扩展成 int64
func i64SignExtend(val int64, bit uint) int64 {
// 1. 先左移, 把符号位移到最高位
// 2. 再算术右移(保持符号), 补全剩余的高位
return val << (64 - bit) >> (64 - bit)
}
// 忽略大小写
// 下划线和"."视作相同
func strEqualFold(s, t string) bool {

View File

@@ -50,82 +50,71 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
case loong64.OpFormatType_NULL:
return inst
case loong64.OpFormatType_2R:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
rj := p.parseRegI_loong()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
return inst
case loong64.OpFormatType_2F:
fd := p.parseRegister()
fd := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fj := p.parseRegister()
p.checkRegF_loong(fd, fj)
fj := p.parseRegF_loong()
inst.Arg.Rd = fd
inst.Arg.Rs1 = fj
return inst
case loong64.OpFormatType_1F_1R:
fd := p.parseRegister()
fd := p.parseRegF_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegF_loong(fd)
p.checkRegI_loong(rj)
rj := p.parseRegI_loong()
inst.Arg.Rd = fd
inst.Arg.Rs1 = rj
return inst
case loong64.OpFormatType_1R_1F:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
fj := p.parseRegister()
p.checkRegI_loong(rd)
p.checkRegF_loong(fj)
fj := p.parseRegF_loong()
inst.Arg.Rd = rd
inst.Arg.Rs1 = fj
return inst
case loong64.OpFormatType_3R:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rk := p.parseRegister()
p.checkRegI_loong(rd, rj, rk)
rk := p.parseRegI_loong()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
return inst
case loong64.OpFormatType_3F:
fd := p.parseRegister()
fd := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fj := p.parseRegister()
fj := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fk := p.parseRegister()
p.checkRegF_loong(fd, fj, fk)
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.parseRegister()
fd := p.parseRegF_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rk := p.parseRegister()
p.checkRegF_loong(fd)
p.checkRegI_loong(rj, rk)
rk := p.parseRegI_loong()
inst.Arg.Rd = fd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
return inst
case loong64.OpFormatType_4F:
fd := p.parseRegister()
fd := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fj := p.parseRegister()
fj := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fk := p.parseRegister()
fk := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fa := p.parseRegister()
p.checkRegF_loong(fd, fj, fk, fa)
fa := p.parseRegF_loong()
inst.Arg.Rd = fd
inst.Arg.Rs1 = fj
inst.Arg.Rs2 = fk
@@ -133,50 +122,43 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
return inst
case loong64.OpFormatType_2R_ui5:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
ui5, ui5Symbol, ui5SymbolDecor := p.parseInst_loong_imm_ui5()
ui5, ui5Symbol := p.parseInst_loong_imm_ui5()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = ui5
inst.Arg.Symbol = ui5Symbol
inst.Arg.SymbolDecor = ui5SymbolDecor
return inst
case loong64.OpFormatType_2R_ui6:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
ui6, ui6Symbol, ui6SymbolDecor := p.parseInst_loong_imm_ui6()
ui6, ui6Symbol := p.parseInst_loong_imm_ui6()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = ui6
inst.Arg.Symbol = ui6Symbol
inst.Arg.SymbolDecor = ui6SymbolDecor
return inst
case loong64.OpFormatType_2R_si12:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
si12, si12Symbol, si12SymbolDecor := p.parseInst_loong_imm_si12()
si12, si12Symbol := p.parseInst_loong_imm_si12()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = si12
inst.Arg.Symbol = si12Symbol
inst.Arg.SymbolDecor = si12SymbolDecor
return inst
case loong64.OpFormatType_2R_ui12:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
ui12, ui12Symbol, ui12SymbolDecor := p.parseInst_loong_imm_ui12()
inst.Arg.Rd = rd
@@ -186,59 +168,50 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
inst.Arg.SymbolDecor = ui12SymbolDecor
return inst
case loong64.OpFormatType_2R_si14:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
si14, si14Symbol, si14SymbolDecor := p.parseInst_loong_imm_si14()
si14, si14Symbol := p.parseInst_loong_imm_si14()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = si14
inst.Arg.Symbol = si14Symbol
inst.Arg.SymbolDecor = si14SymbolDecor
return inst
case loong64.OpFormatType_2R_si16:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
si16, si16Symbol, si16SymbolDecor := p.parseInst_loong_imm_si16()
si16, si16Symbol := p.parseInst_loong_imm_si16()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = si16
inst.Arg.Symbol = si16Symbol
inst.Arg.SymbolDecor = si16SymbolDecor
return inst
case loong64.OpFormatType_1R_si20:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
p.acceptToken(token.COMMA)
si20, si20Symbol, si20SymbolDecor := p.parseInst_loong_imm_si20()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = si20
inst.Arg.Symbol = si20Symbol
inst.Arg.SymbolDecor = si20SymbolDecor
return inst
case loong64.OpFormatType_0_2R:
rj := p.parseRegister()
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rk := p.parseRegister()
p.checkRegI_loong(rj, rk)
rk := p.parseRegI_loong()
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
return inst
case loong64.OpFormatType_3R_sa2:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rk := p.parseRegister()
p.checkRegI_loong(rd, rj, rk)
rk := p.parseRegI_loong()
p.acceptToken(token.COMMA)
sa2, sa2Symbol := p.parseInst_loong_imm_sa2()
inst.Arg.Rd = rd
@@ -248,12 +221,11 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
inst.Arg.Symbol = sa2Symbol
return inst
case loong64.OpFormatType_3R_sa3:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rk := p.parseRegister()
p.checkRegI_loong(rd, rj, rk)
rk := p.parseRegI_loong()
p.acceptToken(token.COMMA)
sa3, sa3Symbol := p.parseInst_loong_imm_sa3()
inst.Arg.Rd = rd
@@ -271,61 +243,56 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
case loong64.OpFormatType_code_1R_si12:
code, codeSymbol := p.parseInst_loong_imm_code_5bit()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rj)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
si12, si12Symbol, si12SymbolDecor := p.parseInst_loong_imm_si12()
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
inst.Arg.SymbolDecor = si12SymbolDecor
return inst
case loong64.OpFormatType_2R_msbw_lsbw:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
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_msbw_5bit()
lsbw, lsbwSymbol := p.parseInst_loong_imm_lsbw_5bit()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = abi.RegType(msbw) // Rs1 寄存器参数位置用于记录 msbw
inst.Arg.Rs2 = abi.RegType(msbw) // Rs2 寄存器参数位置用于记录 msbw
inst.Arg.Rs2Name = msbwSymbol
inst.Arg.Rs2 = abi.RegType(lsbw) // Rs2 寄存器参数位置用于记录 lsbw
inst.Arg.Rs2Name = lsbwSymbol
inst.Arg.Rs3 = abi.RegType(lsbw) // Rs3 寄存器参数位置用于记录 lsbw
inst.Arg.Rs3Name = lsbwSymbol
return inst
case loong64.OpFormatType_2R_msbd_lsbd:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
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_msbd_6bit()
lsbd, lsbdSymbol := p.parseInst_loong_imm_lsbd_6bit()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = abi.RegType(msbd) // Rs1 寄存器参数位置用于记录 msbd
inst.Arg.Rs2 = abi.RegType(msbd) // Rs2 寄存器参数位置用于记录 msbd
inst.Arg.Rs2Name = msbdSymbol
inst.Arg.Rs2 = abi.RegType(lsbd) // Rs2 寄存器参数位置用于记录 lsbd
inst.Arg.Rs2Name = lsbdSymbol
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.parseRegister()
p.checkRegI_loong(rj)
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.parseRegister()
p.checkRegI_loong(rd)
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
fcsr, fcsrSymbol := p.parseInst_loong_imm_fcsr_5bit()
inst.Arg.Rd = rd
@@ -336,8 +303,7 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
case loong64.OpFormatType_cd_1R:
cd, cdSymbol := p.parseInst_loong_imm_cd_2bit()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rj)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
inst.Arg.Rd = abi.RegType(cd) // Rd 寄存器参数位置用于记录 cd
inst.Arg.RdName = cdSymbol
@@ -346,8 +312,7 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
case loong64.OpFormatType_cd_1F:
cd, cdSymbol := p.parseInst_loong_imm_cd_2bit()
p.acceptToken(token.COMMA)
fj := p.parseRegister()
p.checkRegF_loong(fj)
fj := p.parseRegF_loong()
p.acceptToken(token.COMMA)
inst.Arg.Rd = abi.RegType(cd) // Rd 寄存器参数位置用于记录 cd
inst.Arg.RdName = cdSymbol
@@ -356,10 +321,9 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
case loong64.OpFormatType_cd_2F:
cd, cdSymbol := p.parseInst_loong_imm_cd_2bit()
p.acceptToken(token.COMMA)
fj := p.parseRegister()
fj := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fk := p.parseRegister()
p.checkRegF_loong(fj, fk)
fk := p.parseRegF_loong()
p.acceptToken(token.COMMA)
inst.Arg.Rd = abi.RegType(cd) // Rd 寄存器参数位置用于记录 cd
inst.Arg.RdName = cdSymbol
@@ -367,8 +331,7 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
inst.Arg.Rs2 = fk
return inst
case loong64.OpFormatType_1R_cj:
rd := p.parseRegister()
p.checkRegI_loong(rd)
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
cj, cjSymbol := p.parseInst_loong_imm_cj_3bit()
inst.Arg.Rd = rd
@@ -376,8 +339,7 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
inst.Arg.Rs1Name = cjSymbol
return inst
case loong64.OpFormatType_1F_cj:
fd := p.parseRegister()
p.checkRegF_loong(fd)
fd := p.parseRegF_loong()
p.acceptToken(token.COMMA)
cj, cjSymbol := p.parseInst_loong_imm_cj_3bit()
inst.Arg.Rd = fd
@@ -385,8 +347,7 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
inst.Arg.Rs1Name = cjSymbol
return inst
case loong64.OpFormatType_1R_csr:
rd := p.parseRegister()
p.checkRegI_loong(rd)
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
csr, csrSymbol := p.parseInst_loong_imm_csr_14bit()
inst.Arg.Rd = rd
@@ -394,10 +355,9 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
inst.Arg.Symbol = csrSymbol
return inst
case loong64.OpFormatType_2R_csr:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
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 {
@@ -409,10 +369,9 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
inst.Arg.Symbol = csrSymbol
return inst
case loong64.OpFormatType_2R_level:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
level, levelSymbol := p.parseInst_loong_imm_level_8bit()
inst.Arg.Rd = rd
@@ -426,33 +385,31 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
inst.Arg.Symbol = levelSymbol
return inst
case loong64.OpFormatType_0_1R_seq:
rd := p.parseRegister()
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
p.checkRegI_loong(rd)
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.parseRegister()
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rk := p.parseRegister()
p.checkRegI_loong(rj, rk)
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.parseRegister()
fd := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fj := p.parseRegister()
fj := p.parseRegF_loong()
p.acceptToken(token.COMMA)
fk := p.parseRegister()
fk := p.parseRegF_loong()
p.acceptToken(token.COMMA)
p.checkRegF_loong(fd, fj, fk)
ca, caSymbol := p.parseInst_loong_imm_ca_3bit()
inst.Arg.Rd = fd
inst.Arg.Rs1 = fj
@@ -463,24 +420,21 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
case loong64.OpFormatType_hint_1R_si12:
hint, hintSymbol := p.parseInst_loong_imm_hint_5bit()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rj)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
si12, si12Symbol, si12SymbolDecor := p.parseInst_loong_imm_si12()
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
inst.Arg.SymbolDecor = si12SymbolDecor
return inst
case loong64.OpFormatType_hint_2R:
hint, hintSymbol := p.parseInst_loong_imm_hint_5bit()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rk := p.parseRegister()
p.checkRegI_loong(rj, rk)
rk := p.parseRegI_loong()
p.acceptToken(token.COMMA)
inst.Arg.Rd = abi.RegType(hint) // Rd 寄存器保存 hint
inst.Arg.RdName = hintSymbol
@@ -496,54 +450,41 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
case loong64.OpFormatType_cj_offset:
cj, cjSymbol := p.parseInst_loong_imm_cj_3bit()
p.acceptToken(token.COMMA)
off, offSymbol, offSymbolDecor := p.parseInst_loong_imm_offset_21bit()
offSymbol := p.parseInst_loong_imm_offset()
inst.Arg.Rs1 = abi.RegType(cj) // Rs1 寄存器保存 cj
inst.Arg.Rs1Name = cjSymbol
inst.Arg.Imm = off
inst.Arg.Symbol = offSymbol
inst.Arg.SymbolDecor = offSymbolDecor
return inst
case loong64.OpFormatType_rj_offset:
rj := p.parseRegister()
p.checkRegI_loong(rj)
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
off, offSymbol, offSymbolDecor := p.parseInst_loong_imm_offset_21bit()
offSymbol := p.parseInst_loong_imm_offset()
inst.Arg.Rs1 = rj
inst.Arg.Imm = off
inst.Arg.Symbol = offSymbol
inst.Arg.SymbolDecor = offSymbolDecor
return inst
case loong64.OpFormatType_rj_rd_offset:
rj := p.parseRegister()
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
p.checkRegI_loong(rj, rd)
off, offSymbol, offSymbolDecor := p.parseInst_loong_imm_offset_21bit()
offSymbol := p.parseInst_loong_imm_offset()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = off
inst.Arg.Symbol = offSymbol
inst.Arg.SymbolDecor = offSymbolDecor
return inst
case loong64.OpFormatType_rd_rj_offset:
rd := p.parseRegister()
rd := p.parseRegI_loong()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
rj := p.parseRegI_loong()
p.acceptToken(token.COMMA)
p.checkRegI_loong(rd, rj)
off, offSymbol, offSymbolDecor := p.parseInst_loong_imm_offset_21bit()
offSymbol := p.parseInst_loong_imm_offset()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = off
inst.Arg.Symbol = offSymbol
inst.Arg.SymbolDecor = offSymbolDecor
return inst
case loong64.OpFormatType_offset:
off, offSymbol, offSymbolDecor := p.parseInst_loong_imm_offset_21bit()
inst.Arg.Imm = off
offSymbol := p.parseInst_loong_imm_offset()
inst.Arg.Symbol = offSymbol
inst.Arg.SymbolDecor = offSymbolDecor
return inst
default:
@@ -551,115 +492,119 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
}
}
// 检查普通寄存器类型
func (p *parser) checkRegI_loong(regs ...abi.RegType) {
for _, x := range regs {
if x < loong64.REG_R0 || x > loong64.REG_R31 {
p.errorf(p.pos, "%v is not loongarch int register", x)
}
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) checkRegF_loong(regs ...abi.RegType) {
for _, x := range regs {
if x < loong64.REG_F0 || x > loong64.REG_F31 {
p.errorf(p.pos, "%v is not loongarch float register", 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, symbolDecor abi.BuiltinFn) {
return p.parseInst_loong_imm_v2()
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, symbolDecor abi.BuiltinFn) {
return p.parseInst_loong_imm_v2()
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, symbolDecor abi.BuiltinFn) {
return p.parseInst_loong_imm_v2()
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_imm_v2()
return p.parseInst_loong_immOrSymbolDecor()
}
func (p *parser) parseInst_loong_imm_si14() (si14 int32, symbol string, symbolDecor abi.BuiltinFn) {
return p.parseInst_loong_imm_v2()
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, symbolDecor abi.BuiltinFn) {
return p.parseInst_loong_imm_v2()
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_imm_v2()
return p.parseInst_loong_immOrSymbolDecor()
}
func (p *parser) parseInst_loong_imm_offset_21bit() (x int32, symbol string, symbolDecor abi.BuiltinFn) {
return p.parseInst_loong_imm_v2()
// 汇编程序中跳转地址必须用符号表示(因为很难手工获取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_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_sa3() (sa3 int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_code_5bit() (code int32, symbol string) {
return p.parseInst_loong_imm_sa() // todo: 检查整数的范围
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_code_15bit() (code int32, symbol string) {
return p.parseInst_loong_imm_sa() // todo: 检查整数的范围
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_msbw_5bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_lsbw_5bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_msbd_6bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_lsbd_6bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_fcsr_5bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_cd_2bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_cj_3bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_csr_14bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_level_8bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_level_15bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_seq_8bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_op_5bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_ca_3bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_hint_5bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_hint_15bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
return p.parseInst_loong_immOrSymbol()
}
func (p *parser) parseInst_loong_imm_sa() (imm int32, symbol string) {
func (p *parser) parseInst_loong_immOrSymbol() (imm int32, symbol string) {
switch p.tok {
case token.INT:
imm = p.parseInt32Lit()
@@ -673,7 +618,7 @@ func (p *parser) parseInst_loong_imm_sa() (imm int32, symbol string) {
panic("unreachable")
}
func (p *parser) parseInst_loong_imm_v2() (imm int32, symbol string, symbolDecor abi.BuiltinFn) {
func (p *parser) parseInst_loong_immOrSymbolDecor() (imm int32, symbol string, symbolDecor abi.BuiltinFn) {
if p.tok == token.INT {
imm = p.parseInt32Lit()
return
@@ -693,25 +638,9 @@ func (p *parser) parseInst_loong_imm_v2() (imm int32, symbol string, symbolDecor
}
// 判断重定位修饰函数
switch symbolOrDecor {
case "%hi":
symbolDecor = abi.BuiltinFn_HI
case "%lo":
symbolDecor = abi.BuiltinFn_LO
case "%pcrel_hi":
symbolDecor = abi.BuiltinFn_PCREL_HI
case "%pcrel_lo":
symbolDecor = abi.BuiltinFn_PCREL_LO
case "%高位":
symbolDecor = abi.BuiltinFn_HI_zh
case "%低位":
symbolDecor = abi.BuiltinFn_LO_zh
case "%相对高位":
symbolDecor = abi.BuiltinFn_PCREL_HI_zh
case "%相对低位":
symbolDecor = abi.BuiltinFn_PCREL_LO_zh
default:
if fn := lookupBuiltinFn(symbolOrDecor); fn != 0 {
symbolDecor = lookupBuiltinFn(symbolOrDecor)
} else {
p.errorf(pos, "unknow symbol decorator %s", symbolOrDecor)
}
@@ -731,69 +660,3 @@ func (p *parser) parseInst_loong_imm_v2() (imm int32, symbol string, symbolDecor
}
panic("unreachable")
}
func (p *parser) parseInst_loong_imm(inst *ast.Instruction) {
switch p.tok {
case token.INT:
inst.Arg.Imm = p.parseInt32Lit()
return
case token.IDENT:
inst.Arg.Symbol = p.parseIdent()
return
default:
p.errorf(p.pos, "expect label or int, got %v", p.tok)
}
panic("unreachable")
}
// 解析地址立即数
// 不涉及寄存器解析
// 12
// _start
// %lo(_start)
func (p *parser) parseInst_loong_immAddr(inst *ast.Instruction) {
if p.tok == token.INT {
inst.Arg.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 {
inst.Arg.Symbol = symbolOrDecor
return
}
// 判断重定位修饰函数
switch symbolOrDecor {
case "%hi":
inst.Arg.SymbolDecor = abi.BuiltinFn_HI
case "%lo":
inst.Arg.SymbolDecor = abi.BuiltinFn_LO
case "%pcrel_hi":
inst.Arg.SymbolDecor = abi.BuiltinFn_PCREL_HI
case "%pcrel_lo":
inst.Arg.SymbolDecor = abi.BuiltinFn_PCREL_LO
case "%高位":
inst.Arg.SymbolDecor = abi.BuiltinFn_HI_zh
case "%低位":
inst.Arg.SymbolDecor = abi.BuiltinFn_LO_zh
case "%相对高位":
inst.Arg.SymbolDecor = abi.BuiltinFn_PCREL_HI_zh
case "%相对低位":
inst.Arg.SymbolDecor = abi.BuiltinFn_PCREL_LO_zh
default:
p.errorf(pos, "unknow symbol decorator %s", symbolOrDecor)
}
p.acceptToken(token.LPAREN)
inst.Arg.Symbol = p.parseIdent()
p.acceptToken(token.RPAREN)
}

View File

@@ -1263,25 +1263,9 @@ func (p *parser) parseInst_riscv_immAddr(inst *ast.Instruction) {
}
// 判断重定位修饰函数
switch symbolOrDecor {
case "%hi":
inst.Arg.SymbolDecor = abi.BuiltinFn_HI
case "%lo":
inst.Arg.SymbolDecor = abi.BuiltinFn_LO
case "%pcrel_hi":
inst.Arg.SymbolDecor = abi.BuiltinFn_PCREL_HI
case "%pcrel_lo":
inst.Arg.SymbolDecor = abi.BuiltinFn_PCREL_LO
case "%高位":
inst.Arg.SymbolDecor = abi.BuiltinFn_HI_zh
case "%低位":
inst.Arg.SymbolDecor = abi.BuiltinFn_LO_zh
case "%相对高位":
inst.Arg.SymbolDecor = abi.BuiltinFn_PCREL_HI_zh
case "%相对低位":
inst.Arg.SymbolDecor = abi.BuiltinFn_PCREL_LO_zh
default:
if fn := lookupBuiltinFn(symbolOrDecor); fn != 0 {
inst.Arg.SymbolDecor = lookupBuiltinFn(symbolOrDecor)
} else {
p.errorf(pos, "unknow symbol decorator %s", symbolOrDecor)
}

View File

@@ -5,6 +5,8 @@ package parser
import (
"fmt"
"wa-lang.org/wa/internal/native/abi"
)
func assert(ok bool, message ...interface{}) {
@@ -16,3 +18,12 @@ func assert(ok bool, message ...interface{}) {
}
}
}
func lookupBuiltinFn(s string) abi.BuiltinFn {
for fn := abi.BuiltinFn(1); fn < abi.BuiltinFn_Max; fn++ {
if s == fn.String() {
return fn
}
}
return 0
}