完善龙芯文本格式指令解析

This commit is contained in:
chai2010
2025-12-04 07:48:24 +08:00
parent ae6ecce64a
commit 56e2e20449
9 changed files with 402 additions and 128 deletions

View File

@@ -76,15 +76,13 @@ type AsArgument struct {
Imm2 int32 // 立即数2
// 参数的名字, 用于格式化
RdName string
Rs1Name string
Rs2Name string
Rs3Name string
ImmName string
Imm2Name string
RdName string
Rs1Name string
Rs2Name string
Rs3Name string
Symbol string // 可能是 Label/全局符号, 用于重定位和输出文本
SymbolDecor BuiltinFn // 符号的修饰函数, 可能要重新计算
Symbol string // 可能是 Label/全局符号, 用于重定位和输出文本(不支持Imm2)
SymbolDecor BuiltinFn // 符号的修饰函数, 可能要重新计算(只用于跳转/加立即数部分)
}
// 指令原生参数

View File

@@ -821,9 +821,9 @@ var _AOpContextTable = [...]_OpContextType{
AADDU16I_D: {mask: 0xfc000000, value: 0x10000000, op: AADDU16I_D, fmt: OpFormatType_2R_si14},
AADD_D: {mask: 0xffff8000, value: 0x00108000, op: AADD_D, fmt: OpFormatType_3R},
AADD_W: {mask: 0xffff8000, value: 0x00100000, op: AADD_W, fmt: OpFormatType_3R},
AALSL_D: {mask: 0xfffe0000, value: 0x002c0000, op: AALSL_D, fmt: OpFormatType_3R_s2},
AALSL_W: {mask: 0xfffe0000, value: 0x00040000, op: AALSL_W, fmt: OpFormatType_3R_s2},
AALSL_WU: {mask: 0xfffe0000, value: 0x00060000, op: AALSL_WU, fmt: OpFormatType_3R_s2},
AALSL_D: {mask: 0xfffe0000, value: 0x002c0000, op: AALSL_D, fmt: OpFormatType_3R_sa2},
AALSL_W: {mask: 0xfffe0000, value: 0x00040000, op: AALSL_W, fmt: OpFormatType_3R_sa2},
AALSL_WU: {mask: 0xfffe0000, value: 0x00060000, op: AALSL_WU, fmt: OpFormatType_3R_sa2},
AAMADD_B: {mask: 0xffff8000, value: 0x385d0000, op: AAMADD_B, fmt: OpFormatType_3R},
AAMADD_D: {mask: 0xffff8000, value: 0x38618000, op: AAMADD_D, fmt: OpFormatType_3R},
AAMADD_DB_B: {mask: 0xffff8000, value: 0x385f0000, op: AAMADD_DB_B, fmt: OpFormatType_3R},
@@ -898,12 +898,12 @@ var _AOpContextTable = [...]_OpContextType{
ABNE: {mask: 0xfc000000, value: 0x5c000000, op: ABNE, fmt: OpFormatType_rj_rd_offset},
ABNEZ: {mask: 0xfc000000, value: 0x44000000, op: ABNEZ, fmt: OpFormatType_rj_offset},
ABREAK: {mask: 0xffff8000, value: 0x002a0000, op: ABREAK, fmt: OpFormatType_code},
ABSTRINS_D: {mask: 0xffc00000, value: 0x00800000, op: ABSTRINS_D, fmt: OpFormatType_msbd_lsbd},
ABSTRINS_W: {mask: 0xffe08000, value: 0x00600000, op: ABSTRINS_W, fmt: OpFormatType_msbw_lsbw},
ABSTRPICK_D: {mask: 0xffc00000, value: 0x00c00000, op: ABSTRPICK_D, fmt: OpFormatType_msbd_lsbd},
ABSTRPICK_W: {mask: 0xffe08000, value: 0x00608000, op: ABSTRPICK_W, fmt: OpFormatType_msbw_lsbw},
ABYTEPICK_D: {mask: 0xfffc0000, value: 0x000c0000, op: ABYTEPICK_D, fmt: OpFormatType_3R_s3},
ABYTEPICK_W: {mask: 0xfffe0000, value: 0x00080000, op: ABYTEPICK_W, fmt: OpFormatType_3R_s2},
ABSTRINS_D: {mask: 0xffc00000, value: 0x00800000, op: ABSTRINS_D, fmt: OpFormatType_2R_msbd_lsbd},
ABSTRINS_W: {mask: 0xffe08000, value: 0x00600000, op: ABSTRINS_W, fmt: OpFormatType_2R_msbw_lsbw},
ABSTRPICK_D: {mask: 0xffc00000, value: 0x00c00000, op: ABSTRPICK_D, fmt: OpFormatType_2R_msbd_lsbd},
ABSTRPICK_W: {mask: 0xffe08000, value: 0x00608000, op: ABSTRPICK_W, fmt: OpFormatType_2R_msbw_lsbw},
ABYTEPICK_D: {mask: 0xfffc0000, value: 0x000c0000, op: ABYTEPICK_D, fmt: OpFormatType_3R_sa3},
ABYTEPICK_W: {mask: 0xfffe0000, value: 0x00080000, op: ABYTEPICK_W, fmt: OpFormatType_3R_sa2},
ACACOP: {mask: 0xffc00000, value: 0x06000000, op: ACACOP, fmt: OpFormatType_code_1R_si12},
ACLO_D: {mask: 0xfffffc00, value: 0x00002000, op: ACLO_D, fmt: OpFormatType_2R},
ACLO_W: {mask: 0xfffffc00, value: 0x00001000, op: ACLO_W, fmt: OpFormatType_2R},

View File

@@ -97,17 +97,17 @@ func (ctx *_OpContextType) asmSyntax(
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rd), formatAddr())
case OpFormatType_0_2R:
return fmt.Sprintf("%s %s, %s", asNameFn(as, asName), rName(arg.Rs1), rName(arg.Rs2))
case OpFormatType_3R_s2:
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)
case OpFormatType_3R_s3:
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)
case OpFormatType_code:
return fmt.Sprintf("%s %d", asNameFn(as, asName), arg.Imm)
case OpFormatType_code_1R_si12:
return fmt.Sprintf("%s %d, %s, %s", asNameFn(as, asName), arg.Imm, rName(arg.Rs1), formatImm())
case OpFormatType_msbw_lsbw:
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)
case OpFormatType_msbd_lsbd:
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)
case OpFormatType_fcsr_1R:
return fmt.Sprintf("%s %d, %s", asNameFn(as, asName), arg.Imm, rName(arg.Rs1))

View File

@@ -146,17 +146,17 @@ func (op _OpContextType) decodeInst(x uint32) (as abi.As, arg *abi.AsArgument, a
return
case OpFormatType_0_2R:
panic("TODO")
case OpFormatType_3R_s2:
case OpFormatType_3R_sa2:
panic("TODO")
case OpFormatType_3R_s3:
case OpFormatType_3R_sa3:
panic("TODO")
case OpFormatType_code:
panic("TODO")
case OpFormatType_code_1R_si12:
panic("TODO")
case OpFormatType_msbw_lsbw:
case OpFormatType_2R_msbw_lsbw:
panic("TODO")
case OpFormatType_msbd_lsbd:
case OpFormatType_2R_msbd_lsbd:
panic("TODO")
case OpFormatType_fcsr_1R:
panic("TODO")

View File

@@ -80,17 +80,17 @@ func (ctx *_OpContextType) encodeRaw(as abi.As, arg *abi.AsArgument) (x uint32,
panic("TODO")
case OpFormatType_0_2R:
panic("TODO")
case OpFormatType_3R_s2:
case OpFormatType_3R_sa2:
panic("TODO")
case OpFormatType_3R_s3:
case OpFormatType_3R_sa3:
panic("TODO")
case OpFormatType_code:
panic("TODO")
case OpFormatType_code_1R_si12:
panic("TODO")
case OpFormatType_msbw_lsbw:
case OpFormatType_2R_msbw_lsbw:
panic("TODO")
case OpFormatType_msbd_lsbd:
case OpFormatType_2R_msbd_lsbd:
panic("TODO")
case OpFormatType_fcsr_1R:
panic("TODO")

View File

@@ -32,12 +32,12 @@ const (
OpFormatType_2R_si16
OpFormatType_1R_si20
OpFormatType_0_2R
OpFormatType_3R_s2
OpFormatType_3R_s3
OpFormatType_3R_sa2
OpFormatType_3R_sa3
OpFormatType_code
OpFormatType_code_1R_si12
OpFormatType_msbw_lsbw
OpFormatType_msbd_lsbd
OpFormatType_2R_msbw_lsbw
OpFormatType_2R_msbd_lsbd
OpFormatType_fcsr_1R
OpFormatType_1R_fcsr
OpFormatType_cd_1R

View File

@@ -180,18 +180,18 @@ func getOpFormatType(as int, asArgs instArgs) OpFormatType {
panic("unreachable")
}
case Arg_sa2_16_15:
return OpFormatType_3R_s2
return OpFormatType_3R_sa2
case Arg_sa3_17_15:
return OpFormatType_3R_s3
return OpFormatType_3R_sa3
case Arg_code_4_0:
return OpFormatType_code_1R_si12
case Arg_code_14_0:
return OpFormatType_code
case Arg_lsbw, Arg_msbw:
return OpFormatType_msbw_lsbw
return OpFormatType_2R_msbw_lsbw
case Arg_lsbd, Arg_msbd:
return OpFormatType_msbd_lsbd
return OpFormatType_2R_msbd_lsbd
case Arg_fcsr_4_0:
if asArgs[0] == Arg_fcsr_4_0 {
@@ -345,18 +345,18 @@ func OpFormatTypeString(x OpFormatType) string {
return "OpFormatType_1R_si20"
case OpFormatType_0_2R:
return "OpFormatType_0_2R"
case OpFormatType_3R_s2:
return "OpFormatType_3R_s2"
case OpFormatType_3R_s3:
return "OpFormatType_3R_s3"
case OpFormatType_3R_sa2:
return "OpFormatType_3R_sa2"
case OpFormatType_3R_sa3:
return "OpFormatType_3R_sa3"
case OpFormatType_code:
return "OpFormatType_code"
case OpFormatType_code_1R_si12:
return "OpFormatType_code_1R_si12"
case OpFormatType_msbw_lsbw:
return "OpFormatType_msbw_lsbw"
case OpFormatType_msbd_lsbd:
return "OpFormatType_msbd_lsbd"
case OpFormatType_2R_msbw_lsbw:
return "OpFormatType_2R_msbw_lsbw"
case OpFormatType_2R_msbd_lsbd:
return "OpFormatType_2R_msbd_lsbd"
case OpFormatType_fcsr_1R:
return "OpFormatType_fcsr_1R"
case OpFormatType_1R_fcsr:

View File

@@ -77,12 +77,12 @@ const (
OpFormatType_2R_si16
OpFormatType_1R_si20
OpFormatType_0_2R
OpFormatType_3R_s2
OpFormatType_3R_s3
OpFormatType_3R_sa2
OpFormatType_3R_sa3
OpFormatType_code
OpFormatType_code_1R_si12
OpFormatType_msbw_lsbw
OpFormatType_msbd_lsbd
OpFormatType_2R_msbw_lsbw
OpFormatType_2R_msbd_lsbd
OpFormatType_fcsr_1R
OpFormatType_1R_fcsr
OpFormatType_cd_1R
@@ -170,18 +170,18 @@ func (x OpFormatType) String() string {
return "OpFormatType_1R_si20"
case OpFormatType_0_2R:
return "OpFormatType_0_2R"
case OpFormatType_3R_s2:
return "OpFormatType_3R_s2"
case OpFormatType_3R_s3:
return "OpFormatType_3R_s3"
case OpFormatType_3R_sa2:
return "OpFormatType_3R_sa2"
case OpFormatType_3R_sa3:
return "OpFormatType_3R_sa3"
case OpFormatType_code:
return "OpFormatType_code"
case OpFormatType_code_1R_si12:
return "OpFormatType_code_1R_si12"
case OpFormatType_msbw_lsbw:
return "OpFormatType_msbw_lsbw"
case OpFormatType_msbd_lsbd:
return "OpFormatType_msbd_lsbd"
case OpFormatType_2R_msbw_lsbw:
return "OpFormatType_2R_msbw_lsbw"
case OpFormatType_2R_msbd_lsbd:
return "OpFormatType_2R_msbd_lsbd"
case OpFormatType_fcsr_1R:
return "OpFormatType_fcsr_1R"
case OpFormatType_1R_fcsr:

View File

@@ -43,136 +43,268 @@ func (p *parser) parseInst_loong(fn *ast.Func) (inst *ast.Instruction) {
// 查询指令的参数格式
if !loong64.AsValid(inst.As) {
p.errorf(p.pos, "%v is not loong instruction", inst.As)
p.errorf(p.pos, "%v is not loongarch instruction", inst.As)
}
switch loong64.AsFormatType(inst.As) {
case loong64.OpFormatType_NULL:
return inst
case loong64.OpFormatType_2R:
inst.Arg.Rd = p.parseRegister()
rd := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs1 = p.parseRegister()
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
return inst
case loong64.OpFormatType_2F:
panic("TODO")
fd := p.parseRegister()
p.acceptToken(token.COMMA)
fj := p.parseRegister()
p.checkRegF_loong(fd, fj)
inst.Arg.Rd = fd
inst.Arg.Rs1 = fj
return inst
case loong64.OpFormatType_1F_1R:
panic("TODO")
fd := p.parseRegister()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegF_loong(fd)
p.checkRegI_loong(rj)
inst.Arg.Rd = fd
inst.Arg.Rs1 = rj
return inst
case loong64.OpFormatType_1R_1F:
panic("TODO")
rd := p.parseRegister()
p.acceptToken(token.COMMA)
fj := p.parseRegister()
p.checkRegI_loong(rd)
p.checkRegF_loong(fj)
inst.Arg.Rd = rd
inst.Arg.Rs1 = fj
return inst
case loong64.OpFormatType_3R:
inst.Arg.Rd = p.parseRegister()
rd := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs1 = p.parseRegister()
rj := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs2 = p.parseRegister()
rk := p.parseRegister()
p.checkRegI_loong(rd, rj, rk)
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
return inst
case loong64.OpFormatType_3F:
panic("TODO")
fd := p.parseRegister()
p.acceptToken(token.COMMA)
fj := p.parseRegister()
p.acceptToken(token.COMMA)
fk := p.parseRegister()
p.checkRegF_loong(fd, fj, fk)
inst.Arg.Rd = fd
inst.Arg.Rs1 = fj
inst.Arg.Rs2 = fk
return inst
case loong64.OpFormatType_1F_2R:
panic("TODO")
fd := p.parseRegister()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.acceptToken(token.COMMA)
rk := p.parseRegister()
p.checkRegF_loong(fd)
p.checkRegI_loong(rj, rk)
inst.Arg.Rd = fd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
return inst
case loong64.OpFormatType_4F:
inst.Arg.Rd = p.parseRegister()
fd := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs1 = p.parseRegister()
fj := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs2 = p.parseRegister()
fk := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs3 = p.parseRegister()
fa := p.parseRegister()
p.checkRegF_loong(fd, fj, fk, fa)
inst.Arg.Rd = fd
inst.Arg.Rs1 = fj
inst.Arg.Rs2 = fk
inst.Arg.Rs3 = fa
return inst
case loong64.OpFormatType_2R_ui5:
inst.Arg.Rd = p.parseRegister()
rd := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs1 = p.parseRegister()
p.acceptToken(token.COMMA)
p.parseInst_loong_imm(inst)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
ui5, ui5Symbol, ui5SymbolDecor := 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:
panic("TODO")
case loong64.OpFormatType_2R_si12:
inst.Arg.Rd = p.parseRegister()
rd := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs1 = p.parseRegister()
p.acceptToken(token.COMMA)
p.parseInst_loong_imm(inst)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
ui6, ui6Symbol, ui6SymbolDecor := 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()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
si12, si12Symbol, si12SymbolDecor := 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:
panic("TODO")
rd := p.parseRegister()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
ui12, ui12Symbol, ui12SymbolDecor := p.parseInst_loong_imm_ui12()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Imm = ui12
inst.Arg.Symbol = ui12Symbol
inst.Arg.SymbolDecor = ui12SymbolDecor
return inst
case loong64.OpFormatType_2R_si14:
inst.Arg.Rd = p.parseRegister()
rd := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs1 = p.parseRegister()
p.acceptToken(token.COMMA)
p.parseInst_loong_imm(inst)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
si14, si14Symbol, si14SymbolDecor := 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:
panic("TODO")
rd := p.parseRegister()
p.acceptToken(token.COMMA)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
si16, si16Symbol, si16SymbolDecor := 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:
inst.Arg.Rd = p.parseRegister()
rd := p.parseRegister()
p.acceptToken(token.COMMA)
p.parseInst_loong_immAddr(inst)
rj := p.parseRegister()
p.checkRegI_loong(rd, rj)
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:
// 没有Rd
inst.Arg.Rs1 = p.parseRegister()
rj := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs2 = p.parseRegister()
rk := p.parseRegister()
p.checkRegI_loong(rj, rk)
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
return inst
case loong64.OpFormatType_3R_s2:
inst.Arg.Rd = p.parseRegister()
case loong64.OpFormatType_3R_sa2:
rd := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs1 = p.parseRegister()
rj := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs2 = p.parseRegister()
p.acceptToken(token.COMMA)
p.parseInst_loong_imm(inst)
rk := p.parseRegister()
p.checkRegI_loong(rd, rj, rk)
sa2, sa2Symbol := p.parseInst_loong_imm_sa2()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
inst.Arg.Imm = sa2
inst.Arg.Symbol = sa2Symbol
return inst
case loong64.OpFormatType_3R_s3:
inst.Arg.Rd = p.parseRegister()
case loong64.OpFormatType_3R_sa3:
rd := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs1 = p.parseRegister()
rj := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs2 = p.parseRegister()
p.acceptToken(token.COMMA)
p.parseInst_loong_imm(inst)
rk := p.parseRegister()
p.checkRegI_loong(rd, rj, rk)
sa3, sa3Symbol := p.parseInst_loong_imm_sa3()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = rk
inst.Arg.Imm = sa3
inst.Arg.Symbol = sa3Symbol
return inst
case loong64.OpFormatType_code:
p.parseInst_loong_imm(inst)
code, codeSymbol := p.parseInst_loong_imm_code_5bit()
inst.Arg.Imm = code
inst.Arg.Symbol = codeSymbol
return inst
case loong64.OpFormatType_code_1R_si12:
// TODO: 可能需要通过名字解析code
code := p.parseInt32Lit()
inst.Arg.Rd = abi.RegType(code) + loong64.REG_R0
code, codeSymbol := p.parseInst_loong_imm_code_15bit()
p.acceptToken(token.COMMA)
inst.Arg.Rs1 = p.parseRegister()
rj := p.parseRegister()
p.checkRegI_loong(rj)
p.acceptToken(token.COMMA)
p.parseInst_loong_imm(inst)
si12, si12Symbol, si12SymbolDecor := p.parseInst_loong_imm_si12()
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_msbw_lsbw:
inst.Arg.Rd = p.parseRegister()
case loong64.OpFormatType_2R_msbw_lsbw:
rd := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs1 = p.parseRegister()
rj := p.parseRegister()
p.acceptToken(token.COMMA)
p.parseInst_loong_imm(inst)
p.checkRegI_loong(rd, rj)
msbw, msbwSymbol := p.parseInst_loong_imm_msbw_5bit()
p.acceptToken(token.COMMA)
inst.Arg.Imm2 = p.parseInt32Lit()
lsbw, lsbwSymbol := p.parseInst_loong_imm_msbw_5bit()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = abi.RegType(msbw) // Rs1 寄存器参数位置用于记录 msbw
inst.Arg.Rs2Name = msbwSymbol
inst.Arg.Rs2 = abi.RegType(lsbw) // Rs2 寄存器参数位置用于记录 lsbw
inst.Arg.Rs2Name = lsbwSymbol
return inst
case loong64.OpFormatType_msbd_lsbd:
inst.Arg.Rd = p.parseRegister()
case loong64.OpFormatType_2R_msbd_lsbd:
rd := p.parseRegister()
p.acceptToken(token.COMMA)
inst.Arg.Rs1 = p.parseRegister()
rj := p.parseRegister()
p.acceptToken(token.COMMA)
p.parseInst_loong_imm(inst)
p.checkRegI_loong(rd, rj)
msbd, msbdSymbol := p.parseInst_loong_imm_msbd_6bit()
p.acceptToken(token.COMMA)
inst.Arg.Imm2 = p.parseInt32Lit()
lsbd, lsbdSymbol := p.parseInst_loong_imm_msbd_6bit()
inst.Arg.Rd = rd
inst.Arg.Rs1 = rj
inst.Arg.Rs2 = abi.RegType(msbd) // Rs1 寄存器参数位置用于记录 msbd
inst.Arg.Rs2Name = msbdSymbol
inst.Arg.Rs2 = abi.RegType(lsbd) // Rs2 寄存器参数位置用于记录 lsbd
inst.Arg.Rs2Name = lsbdSymbol
return inst
case loong64.OpFormatType_fcsr_1R:
// TODO: 解析 fcsr
inst.Arg.Imm = p.parseInt32Lit()
@@ -302,14 +434,158 @@ 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) 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) parseInst_loong_imm_ui5() (ui5 int32, symbol string, symbolDecor abi.BuiltinFn) {
return p.parseInst_loong_imm_v2()
}
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_si12() (s12 int32, symbol string, symbolDecor abi.BuiltinFn) {
return p.parseInst_loong_imm_v2()
}
func (p *parser) parseInst_loong_imm_ui12() (ui12 int32, symbol string, symbolDecor abi.BuiltinFn) {
return p.parseInst_loong_imm_v2()
}
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_si16() (si16 int32, symbol string, symbolDecor abi.BuiltinFn) {
return p.parseInst_loong_imm_v2()
}
func (p *parser) parseInst_loong_imm_si20() (si20 int32, symbol string, symbolDecor abi.BuiltinFn) {
return p.parseInst_loong_imm_v2()
}
func (p *parser) parseInst_loong_imm_sa2() (sa2 int32, symbol string) {
return p.parseInst_loong_imm_sa()
}
func (p *parser) parseInst_loong_imm_sa3() (sa3 int32, symbol string) {
return p.parseInst_loong_imm_sa()
}
func (p *parser) parseInst_loong_imm_code_5bit() (code int32, symbol string) {
return p.parseInst_loong_imm_sa() // todo: 检查整数的范围
}
func (p *parser) parseInst_loong_imm_code_15bit() (code int32, symbol string) {
return p.parseInst_loong_imm_sa() // todo: 检查整数的范围
}
func (p *parser) parseInst_loong_imm_msbw_5bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
}
func (p *parser) parseInst_loong_imm_lsbw_5bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
}
func (p *parser) parseInst_loong_imm_msbd_6bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
}
func (p *parser) parseInst_loong_imm_lsbd_6bit() (x int32, symbol string) {
return p.parseInst_loong_imm_sa()
}
func (p *parser) parseInst_loong_imm_sa() (imm int32, symbol string) {
switch p.tok {
case token.INT:
imm = p.parseInt32Lit()
return
case token.IDENT:
symbol = p.parseIdent()
return
default:
p.errorf(p.pos, "expect label or int, got %v", p.tok)
}
panic("unreachable")
}
func (p *parser) parseInst_loong_imm_v2() (imm int32, symbol string, symbolDecor abi.BuiltinFn) {
if p.tok == token.INT {
imm = p.parseInt32Lit()
return
}
if p.tok != token.IDENT {
p.errorf(p.pos, "export IDENT, got %v", p.tok)
}
pos := p.pos
symbolOrDecor := p.parseIdent()
// 没有重定位修饰函数
if p.tok != token.LPAREN {
symbol = symbolOrDecor
return
}
// 判断重定位修饰函数
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:
p.errorf(pos, "unknow symbol decorator %s", symbolOrDecor)
}
p.acceptToken(token.LPAREN)
symbol = p.parseIdent()
p.acceptToken(token.RPAREN)
switch p.tok {
case token.INT:
imm = p.parseInt32Lit()
return
case token.IDENT:
symbol = p.parseIdent()
return
default:
p.errorf(p.pos, "expect label or int, got %v", p.tok)
}
panic("unreachable")
}
func (p *parser) parseInst_loong_imm(inst *ast.Instruction) {
switch p.tok {
case token.IDENT:
inst.Arg.Symbol = p.parseIdent()
return
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)
}