mirror of
https://gitee.com/wa-lang/wa.git
synced 2025-12-06 17:19:15 +08:00
完善龙芯文本格式指令解析
This commit is contained in:
@@ -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 // 符号的修饰函数, 可能要重新计算(只用于跳转/加立即数部分)
|
||||
}
|
||||
|
||||
// 指令原生参数
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user