mirror of
https://gitee.com/wa-lang/wa.git
synced 2025-12-06 09:18:53 +08:00
汇编器实现龙芯指令格式化和编解码
This commit is contained in:
@@ -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 // 立即数
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
// 解码寄存器
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user