From 4ff4c87fbb796550f165e4e2adcb4bc0caf2108f Mon Sep 17 00:00:00 2001 From: chai2010 Date: Fri, 5 Dec 2025 21:23:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B1=87=E7=BC=96=E5=99=A8=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E9=BE=99=E8=8A=AF=E6=8C=87=E4=BB=A4=E6=A0=BC=E5=BC=8F=E5=8C=96?= =?UTF-8?q?=E5=92=8C=E7=BC=96=E8=A7=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/native/abi/abi.go | 32 +- internal/native/abi/stringer.go | 4 + internal/native/loong64/anames.go | 3 +- internal/native/loong64/asm.go | 170 ++++--- internal/native/loong64/decode.go | 318 ++++++++++--- internal/native/loong64/encode.go | 255 ++++++++-- internal/native/loong64/utils.go | 62 +-- internal/native/parser/parser_inst_loong_x.go | 439 ++++++------------ internal/native/parser/parser_inst_riscv_x.go | 22 +- internal/native/parser/utils.go | 11 + 10 files changed, 754 insertions(+), 562 deletions(-) diff --git a/internal/native/abi/abi.go b/internal/native/abi/abi.go index 59387fe6..14d9c48d 100644 --- a/internal/native/abi/abi.go +++ b/internal/native/abi/abi.go @@ -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 // 立即数 } diff --git a/internal/native/abi/stringer.go b/internal/native/abi/stringer.go index 83074be6..fad5cd15 100644 --- a/internal/native/abi/stringer.go +++ b/internal/native/abi/stringer.go @@ -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: diff --git a/internal/native/loong64/anames.go b/internal/native/loong64/anames.go index 6d7b4764..7909ab70 100644 --- a/internal/native/loong64/anames.go +++ b/internal/native/loong64/anames.go @@ -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 diff --git a/internal/native/loong64/asm.go b/internal/native/loong64/asm.go index 8765c7c4..ac050a95 100644 --- a/internal/native/loong64/asm.go +++ b/internal/native/loong64/asm.go @@ -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") diff --git a/internal/native/loong64/decode.go b/internal/native/loong64/decode.go index 0cd71ff5..5073c5d2 100644 --- a/internal/native/loong64/decode.go +++ b/internal/native/loong64/decode.go @@ -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 } // 解码寄存器 diff --git a/internal/native/loong64/encode.go b/internal/native/loong64/encode.go index 7a1e7458..1eaf8d5e 100644 --- a/internal/native/loong64/encode.go +++ b/internal/native/loong64/encode.go @@ -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 } diff --git a/internal/native/loong64/utils.go b/internal/native/loong64/utils.go index dd95bb49..5f30219e 100644 --- a/internal/native/loong64/utils.go +++ b/internal/native/loong64/utils.go @@ -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)< 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 { diff --git a/internal/native/parser/parser_inst_loong_x.go b/internal/native/parser/parser_inst_loong_x.go index 5650a981..3c65a106 100644 --- a/internal/native/parser/parser_inst_loong_x.go +++ b/internal/native/parser/parser_inst_loong_x.go @@ -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) -} diff --git a/internal/native/parser/parser_inst_riscv_x.go b/internal/native/parser/parser_inst_riscv_x.go index c2073dc8..9cd36a0f 100644 --- a/internal/native/parser/parser_inst_riscv_x.go +++ b/internal/native/parser/parser_inst_riscv_x.go @@ -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) } diff --git a/internal/native/parser/utils.go b/internal/native/parser/utils.go index ee141e74..269cdba8 100644 --- a/internal/native/parser/utils.go +++ b/internal/native/parser/utils.go @@ -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 +}