2024.12.9-2024.12.15 学习内容

12 minute read

Published:

对代码中对指令进行解析的部分进行完善,主要是向量寄存器与指令类型。

1、InstType补充

1.1 向量寄存器Type

查看官方文档:Registers, vectors, lanes and elements

  • 对于NEON扩展指令集,vector可以为128位或者64位,二者又分别可以拆分成若干个大小为BHSD的元素。

  • 使用标量的指令指定通道索引来引用寄存器中的特定元素,例如,V3.S[2]相当于一个32位标量寄存器

1.2 访存模式回顾与系统支持访存模式

参考官方文档:Loads and stores

整体上主要有四种,目前我们的系统均支持,对应的类型为:

寻址方式操作数计算模式副作用对应Type
Base register[GP]GP BaseROnlyMemType
Offset addressing modes[GP, IMM]GP+IMM BasePlusOffsetMemType
Pre-index addressing modes[GP, IMM]!GP+IMMGP = GP + IMMPreIndexMemType
Post-index addressing modes[GP], IMMGPGP = GP + IMMPostIndexMemType

1.3 指令语义

所有的指令语义参考: Arm A-profile A64 Instruction Set Architecture文档

  • LD1

关于该指令,参考官方文档:LD1 (multiple structures)

在该指令中,可以使用的vector类型包括:

寄存器宽度
8B64
16B128
4H64
8H128
2S64
4S128
1D64
2D128

而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。

在Post-index下,根据Q字段的不同,后索引只有两个取值:

Qimm
0#8
1#16

其实在实际的指令中,<T>字段与Q字段强关联,因此实际上不存在这么多的post-index。例如,对于ld1,当为8B时,Q一定为0,因此post-index一定是8,不会是16

因此,该指令需要补充的代码为(目前只补充一个寄存器的情况):

// No-Offset部分
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(64, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(128, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(64, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(128, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(64, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(128, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(64, "d"), BaseROnlyMemType::get())},
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(128, "d"), BaseROnlyMemType::get())},
// Post-index部分
// For the "One register, immediate offset" variant: is the post-index immediate offset, encoded in Q:
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(64, "b"), PostIndexMemType::get(8, 8))},
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(128, "b"), PostIndexMemType::get(16, 16))},
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(64, "h"), PostIndexMemType::get(8, 8))},
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(128, "h"), PostIndexMemType::get(16, 16))},
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(64, "s"), PostIndexMemType::get(8, 8))},
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(128, "s"), PostIndexMemType::get(16, 16))},
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(64, "d"), PostIndexMemType::get(8, 8))},
{Inst::kIdLd1_v, InstType::get(REG_VEC_WID_RES(128, "d"), PostIndexMemType::get(16, 16))},

关于多个寄存器的情况,参见1.5 一些补充

  • LD2

关于该指令,参考官方文档:LD2 (multiple structures)

在该指令中,可以使用的vector类型如下所示,注意不包括1D

寄存器宽度
8B64
16B128
4H64
8H128
2S64
4S128
2D128

而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。

在Post-index下,根据Q字段的不同,后索引只有两个取值:

Qimm
0#16
1#32

因此,该指令需要补充的代码为:

// No-Offset部分
{Inst::kIdLd2_v, InstType::get(REG_VEC_WID_RES(64, "b"), REG_VEC_WID_RES(64, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd2_v, InstType::get(REG_VEC_WID_RES(128, "b"),REG_VEC_WID_RES(128, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd2_v, InstType::get(REG_VEC_WID_RES(64, "h"), REG_VEC_WID_RES(64, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd2_v, InstType::get(REG_VEC_WID_RES(128, "h"),REG_VEC_WID_RES(128, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd2_v, InstType::get(REG_VEC_WID_RES(64, "s"), REG_VEC_WID_RES(64, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd2_v, InstType::get(REG_VEC_WID_RES(128, "s"),REG_VEC_WID_RES(128, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd2_v, InstType::get(REG_VEC_WID_RES(128, "d"),REG_VEC_WID_RES(128, "d"), BaseROnlyMemType::get())},
// Post-index部分
{Inst::kIdLd2_v, InstType::get(REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), PostIndexMemType::get(16, 16))},
{Inst::kIdLd2_v, InstType::get(REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), PostIndexMemType::get(32, 32))},
{Inst::kIdLd2_v, InstType::get(REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), PostIndexMemType::get(16, 16))},
{Inst::kIdLd2_v, InstType::get(REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), PostIndexMemType::get(32, 32))},
{Inst::kIdLd2_v, InstType::get(REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), PostIndexMemType::get(16, 16))},
{Inst::kIdLd2_v, InstType::get(REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), PostIndexMemType::get(32, 32))},
{Inst::kIdLd2_v, InstType::get(REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), PostIndexMemType::get(32, 32))},
  • LD3

关于该指令,参考官方文档:LD3 (multiple structures))

在该指令中,可以使用的vector类型如下所示,注意也不包括1D

寄存器宽度
8B64
16B128
4H64
8H128
2S64
4S128
2D128

而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。

在Post-index下,根据Q字段的不同,后索引只有两个取值:

Qimm
0#24
1#48

因此,该指令需要补充的代码为:

// No-Offset部分
{Inst::kIdLd3_v, InstType::get(REG_VEC_WID_RES(64, "b"), REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd3_v, InstType::get(REG_VEC_WID_RES(128, "b"),REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd3_v, InstType::get(REG_VEC_WID_RES(64, "h"), REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd3_v, InstType::get(REG_VEC_WID_RES(128, "h"),REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd3_v, InstType::get(REG_VEC_WID_RES(64, "s"), REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd3_v, InstType::get(REG_VEC_WID_RES(128, "s"),REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd3_v, InstType::get(REG_VEC_WID_RES(128, "d"),REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), BaseROnlyMemType::get())},
// Post-index部分
{Inst::kIdLd3_v, InstType::get(REG_VEC_WID_RES(64, "b"), REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), PostIndexMemType::get(24, 24))},
{Inst::kIdLd3_v, InstType::get(REG_VEC_WID_RES(128, "b"),REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), PostIndexMemType::get(48, 48))},
{Inst::kIdLd3_v, InstType::get(REG_VEC_WID_RES(64, "h"), REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), PostIndexMemType::get(24, 24))},
{Inst::kIdLd3_v, InstType::get(REG_VEC_WID_RES(128, "h"),REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), PostIndexMemType::get(48, 48))},
{Inst::kIdLd3_v, InstType::get(REG_VEC_WID_RES(64, "s"), REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), PostIndexMemType::get(24, 24))},
{Inst::kIdLd3_v, InstType::get(REG_VEC_WID_RES(128, "s"),REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), PostIndexMemType::get(48, 48))},
{Inst::kIdLd3_v, InstType::get(REG_VEC_WID_RES(128, "d"),REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), PostIndexMemType::get(48, 48))},
  • LD4

关于该指令,参考官方文档:LD4 (multiple structures))

在该指令中,可以使用的vector类型如下所示,注意也不包括1D

寄存器宽度
8B64
16B128
4H64
8H128
2S64
4S128
2D128

而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。

在Post-index下,根据Q字段的不同,后索引只有两个取值:

Qimm
0#32
1#64

因此,该指令需要补充的代码为:

// No-Offset部分
{Inst::kIdLd4_v, InstType::get(REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd4_v, InstType::get(REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"),REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd4_v, InstType::get(REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd4_v, InstType::get(REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"),REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd4_v, InstType::get(REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd4_v, InstType::get(REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"),REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd4_v, InstType::get(REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"),REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), BaseROnlyMemType::get())},
// Post-index部分
{Inst::kIdLd4_v, InstType::get(REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), PostIndexMemType::get(32, 32))},
{Inst::kIdLd4_v, InstType::get(REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"),REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), PostIndexMemType::get(64, 64))},
{Inst::kIdLd4_v, InstType::get(REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), PostIndexMemType::get(32, 32))},
{Inst::kIdLd4_v, InstType::get(REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"),REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), PostIndexMemType::get(64, 64))},
{Inst::kIdLd4_v, InstType::get(REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), PostIndexMemType::get(32, 32))},
{Inst::kIdLd4_v, InstType::get(REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"),REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), PostIndexMemType::get(64, 64))},
{Inst::kIdLd4_v, InstType::get(REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"),REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), PostIndexMemType::get(64, 64))},
  • LD1R

关于该指令,参考官方文档:LD1R

在该指令中,可以使用的vector类型包括:

寄存器宽度
8B64
16B128
4H64
8H128
2S64
4S128
1D64
2D128

而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。

在Post-index下,根据size字段或寄存器宽度的不同,后索引有4个取值:

<T>imm
B#1
H#2
S#4
D#8

因此,该指令需要补充的代码为(目前只补充一个寄存器的情况):

// No-Offset部分
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(64, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(128, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(64, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(128, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(64, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(128, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(64, "d"), BaseROnlyMemType::get())},
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(128, "d"), BaseROnlyMemType::get())},
// Post-index部分
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(64, "b"), PostIndexMemType::get(1, 1))},
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(128, "b"), PostIndexMemType::get(1, 1))},
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(64, "h"), PostIndexMemType::get(2, 2))},
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(128, "h"), PostIndexMemType::get(2, 2))},
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(64, "s"), PostIndexMemType::get(4, 4))},
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(128, "s"), PostIndexMemType::get(4, 4))},
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(64, "d"), PostIndexMemType::get(8, 8))},
{Inst::kIdLd1r_v, InstType::get(REG_VEC_WID_RES(128, "d"), PostIndexMemType::get(8, 8))},
  • LD2R

关于该指令,参考官方文档:LD2R

在该指令中,可以使用的vector类型包括:

寄存器宽度
8B64
16B128
4H64
8H128
2S64
4S128
1D64
2D128

而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。

在Post-index下,根据size字段或寄存器宽度的不同,后索引有4个取值:

<T>imm
B#2
H#4
S#8
D#16

因此,该指令需要补充的代码为(目前只补充一个寄存器的情况):

// No-Offset部分
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(64, "b"), REG_VEC_WID_RES(64, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(128, "b"),REG_VEC_WID_RES(128, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(64, "h"), REG_VEC_WID_RES(64, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(128, "h"),REG_VEC_WID_RES(128, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(64, "s"), REG_VEC_WID_RES(64, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(128, "s"),REG_VEC_WID_RES(128, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(64, "d"), REG_VEC_WID_RES(64, "d"), BaseROnlyMemType::get())},
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(128, "d"),REG_VEC_WID_RES(128, "d"), BaseROnlyMemType::get())},
// Post-index部分
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), PostIndexMemType::get(2, 2) )},
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), PostIndexMemType::get(2, 2 ))},
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), PostIndexMemType::get(4, 4) )},
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), PostIndexMemType::get(4, 4 ))},
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), PostIndexMemType::get(8, 8) )},
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), PostIndexMemType::get(8, 8 ))},
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(64, "d"),  REG_VEC_WID_RES(64, "d"), PostIndexMemType::get(16, 16))},
{Inst::kIdLd2r_v, InstType::get(REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), PostIndexMemType::get(16, 16))},
  • LD3R

关于该指令,参考官方文档:LD3R

在该指令中,可以使用的vector类型包括:

寄存器宽度
8B64
16B128
4H64
8H128
2S64
4S128
1D64
2D128

而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。

在Post-index下,根据size字段或寄存器宽度的不同,后索引有4个取值:

<T>imm
B#3
H#6
S#12
D#24

因此,该指令需要补充的代码为(目前只补充一个寄存器的情况):

// No-Offset部分
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), REG_VEC_WID_RES(64, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"),REG_VEC_WID_RES(128, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), REG_VEC_WID_RES(64, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"),REG_VEC_WID_RES(128, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), REG_VEC_WID_RES(64, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"),REG_VEC_WID_RES(128, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(64, "d"),  REG_VEC_WID_RES(64, "d"), REG_VEC_WID_RES(64, "d"), BaseROnlyMemType::get())},
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"),REG_VEC_WID_RES(128, "d"), BaseROnlyMemType::get())},
// Post-index部分
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), PostIndexMemType::get(3, 3)  )},
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), PostIndexMemType::get(3, 3  ))},
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), PostIndexMemType::get(6, 6)  )},
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), PostIndexMemType::get(6, 6  ))},
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), PostIndexMemType::get(12, 12 ))},
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), PostIndexMemType::get(12, 12))},
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(64, "d"),  REG_VEC_WID_RES(64, "d"),  REG_VEC_WID_RES(64, "d"), PostIndexMemType::get(24, 24))},
{Inst::kIdLd3r_v, InstType::get(REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), PostIndexMemType::get(24, 24))},
  • LD4R

关于该指令,参考官方文档:LD4R

在该指令中,可以使用的vector类型包括:

寄存器宽度
8B64
16B128
4H64
8H128
2S64
4S128
1D64
2D128

而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。

在Post-index下,根据size字段或寄存器宽度的不同,后索引有4个取值:

<T>imm
B#4
H#8
S#16
D#32

因此,该指令需要补充的代码为(目前只补充一个寄存器的情况):

// No-Offset部分
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), REG_VEC_WID_RES(64, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"),REG_VEC_WID_RES(128, "b"), BaseROnlyMemType::get())},
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), REG_VEC_WID_RES(64, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"),REG_VEC_WID_RES(128, "h"), BaseROnlyMemType::get())},
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), REG_VEC_WID_RES(64, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"),REG_VEC_WID_RES(128, "s"), BaseROnlyMemType::get())},
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(64, "d"),  REG_VEC_WID_RES(64, "d"),  REG_VEC_WID_RES(64, "d"), REG_VEC_WID_RES(64, "d"), BaseROnlyMemType::get())},
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"),REG_VEC_WID_RES(128, "d"), BaseROnlyMemType::get())},
// Post-index部分
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), PostIndexMemType::get(4, 4))},
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), PostIndexMemType::get(4, 4))},
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), PostIndexMemType::get(8, 8))},
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), PostIndexMemType::get(8, 8))},
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), PostIndexMemType::get(16, 16))},
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), PostIndexMemType::get(16, 16))},
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(64, "d"),  REG_VEC_WID_RES(64, "d"),  REG_VEC_WID_RES(64, "d"),  REG_VEC_WID_RES(64, "d"), PostIndexMemType::get(32, 32))},
{Inst::kIdLd4r_v, InstType::get(REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), PostIndexMemType::get(32, 32))},
  • ST1

关于该指令,参考官方文档:ST1 (multiple structures))

在该指令中,可以使用的vector类型包括:

寄存器宽度
8B64
16B128
4H64
8H128
2S64
4S128
1D64
2D128

而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。

在Post-index下,根据Q字段的不同,后索引只有两个取值:

Qimm
0#8
1#16

其实在实际的指令中,<T>字段与Q字段强关联,因此实际上不存在这么多的post-index。例如,对于ld1,当为8B时,Q一定为0,因此post-index一定是8,不会是16。

因此,该指令需要补充的代码为(目前只补充一个寄存器的情况):

// No-Offset部分
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(64, "b"), BaseROnlyMemType::get())},
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(128, "b"), BaseROnlyMemType::get())},
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(64, "h"), BaseROnlyMemType::get())},
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(128, "h"), BaseROnlyMemType::get())},
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(64, "s"), BaseROnlyMemType::get())},
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(128, "s"), BaseROnlyMemType::get())},
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(64, "d"), BaseROnlyMemType::get())},
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(128, "d"), BaseROnlyMemType::get())},
// Post-index部分
// For the "One register, immediate offset" variant: is the post-index immediate offset, encoded in Q:
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(64, "b"), PostIndexMemType::get(8, 8))},
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(128, "b"), PostIndexMemType::get(16, 16))},
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(64, "h"), PostIndexMemType::get(8, 8))},
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(128, "h"), PostIndexMemType::get(16, 16))},
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(64, "s"), PostIndexMemType::get(8, 8))},
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(128, "s"), PostIndexMemType::get(16, 16))},
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(64, "d"), PostIndexMemType::get(8, 8))},
{Inst::kIdSt1_v, InstType::get(REG_VEC_WID_RES(128, "d"), PostIndexMemType::get(16, 16))},

关于多个寄存器的情况,参见1.5 一些补充

  • ST2

关于该指令,参考官方文档:ST2 (multiple structures)

在该指令中,可以使用的vector类型如下所示,注意不包括1D

寄存器宽度
8B64
16B128
4H64
8H128
2S64
4S128
2D128

而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。

在Post-index下,根据Q字段的不同,后索引只有两个取值:

Qimm
0#16
1#32

因此,该指令需要补充的代码为:

// No-Offset部分
{Inst::kIdSt2_v, InstType::get(REG_VEC_WID_RES(64, "b"), REG_VEC_WID_RES(64, "b"), BaseROnlyMemType::get())},
{Inst::kIdSt2_v, InstType::get(REG_VEC_WID_RES(128, "b"),REG_VEC_WID_RES(128, "b"), BaseROnlyMemType::get())},
{Inst::kIdSt2_v, InstType::get(REG_VEC_WID_RES(64, "h"), REG_VEC_WID_RES(64, "h"), BaseROnlyMemType::get())},
{Inst::kIdSt2_v, InstType::get(REG_VEC_WID_RES(128, "h"),REG_VEC_WID_RES(128, "h"), BaseROnlyMemType::get())},
{Inst::kIdSt2_v, InstType::get(REG_VEC_WID_RES(64, "s"), REG_VEC_WID_RES(64, "s"), BaseROnlyMemType::get())},
{Inst::kIdSt2_v, InstType::get(REG_VEC_WID_RES(128, "s"),REG_VEC_WID_RES(128, "s"), BaseROnlyMemType::get())},
{Inst::kIdSt2_v, InstType::get(REG_VEC_WID_RES(128, "d"),REG_VEC_WID_RES(128, "d"), BaseROnlyMemType::get())},
// Post-index部分
{Inst::kIdSt2_v, InstType::get(REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), PostIndexMemType::get(16, 16))},
{Inst::kIdSt2_v, InstType::get(REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), PostIndexMemType::get(32, 32))},
{Inst::kIdSt2_v, InstType::get(REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), PostIndexMemType::get(16, 16))},
{Inst::kIdSt2_v, InstType::get(REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), PostIndexMemType::get(32, 32))},
{Inst::kIdSt2_v, InstType::get(REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), PostIndexMemType::get(16, 16))},
{Inst::kIdSt2_v, InstType::get(REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), PostIndexMemType::get(32, 32))},
{Inst::kIdSt2_v, InstType::get(REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), PostIndexMemType::get(32, 32))},
  • ST3

关于该指令,参考官方文档:ST3 (multiple structures))

在该指令中,可以使用的vector类型如下所示,注意也不包括1D

寄存器宽度
8B64
16B128
4H64
8H128
2S64
4S128
2D128

而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。

在Post-index下,根据Q字段的不同,后索引只有两个取值:

Qimm
0#24
1#48

因此,该指令需要补充的代码为:

// No-Offset部分
{Inst::kIdSt3_v, InstType::get(REG_VEC_WID_RES(64, "b"), REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), BaseROnlyMemType::get())},
{Inst::kIdSt3_v, InstType::get(REG_VEC_WID_RES(128, "b"),REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), BaseROnlyMemType::get())},
{Inst::kIdSt3_v, InstType::get(REG_VEC_WID_RES(64, "h"), REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), BaseROnlyMemType::get())},
{Inst::kIdSt3_v, InstType::get(REG_VEC_WID_RES(128, "h"),REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), BaseROnlyMemType::get())},
{Inst::kIdSt3_v, InstType::get(REG_VEC_WID_RES(64, "s"), REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), BaseROnlyMemType::get())},
{Inst::kIdSt3_v, InstType::get(REG_VEC_WID_RES(128, "s"),REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), BaseROnlyMemType::get())},
{Inst::kIdSt3_v, InstType::get(REG_VEC_WID_RES(128, "d"),REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), BaseROnlyMemType::get())},
// Post-index部分
{Inst::kIdSt3_v, InstType::get(REG_VEC_WID_RES(64, "b"), REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), PostIndexMemType::get(24, 24))},
{Inst::kIdSt3_v, InstType::get(REG_VEC_WID_RES(128, "b"),REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), PostIndexMemType::get(48, 48))},
{Inst::kIdSt3_v, InstType::get(REG_VEC_WID_RES(64, "h"), REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), PostIndexMemType::get(24, 24))},
{Inst::kIdSt3_v, InstType::get(REG_VEC_WID_RES(128, "h"),REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), PostIndexMemType::get(48, 48))},
{Inst::kIdSt3_v, InstType::get(REG_VEC_WID_RES(64, "s"), REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), PostIndexMemType::get(24, 24))},
{Inst::kIdSt3_v, InstType::get(REG_VEC_WID_RES(128, "s"),REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), PostIndexMemType::get(48, 48))},
{Inst::kIdSt3_v, InstType::get(REG_VEC_WID_RES(128, "d"),REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), PostIndexMemType::get(48, 48))},
  • ST4

关于该指令,参考官方文档:ST4 (multiple structures))

在该指令中,可以使用的vector类型如下所示,注意也不包括1D

寄存器宽度
8B64
16B128
4H64
8H128
2S64
4S128
2D128

而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。

在Post-index下,根据Q字段的不同,后索引只有两个取值:

Qimm
0#32
1#64

因此,该指令需要补充的代码为:

// No-Offset部分
{Inst::kIdSt4_v, InstType::get(REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), BaseROnlyMemType::get())},
{Inst::kIdSt4_v, InstType::get(REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"),REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), BaseROnlyMemType::get())},
{Inst::kIdSt4_v, InstType::get(REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), BaseROnlyMemType::get())},
{Inst::kIdSt4_v, InstType::get(REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"),REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), BaseROnlyMemType::get())},
{Inst::kIdSt4_v, InstType::get(REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), BaseROnlyMemType::get())},
{Inst::kIdSt4_v, InstType::get(REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"),REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), BaseROnlyMemType::get())},
{Inst::kIdSt4_v, InstType::get(REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"),REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), BaseROnlyMemType::get())},
// Post-index部分
{Inst::kIdSt4_v, InstType::get(REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), REG_VEC_WID_RES(64, "b"),  REG_VEC_WID_RES(64, "b"), PostIndexMemType::get(32, 32))},
{Inst::kIdSt4_v, InstType::get(REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"),REG_VEC_WID_RES(128, "b"), REG_VEC_WID_RES(128, "b"), PostIndexMemType::get(64, 64))},
{Inst::kIdSt4_v, InstType::get(REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), REG_VEC_WID_RES(64, "h"),  REG_VEC_WID_RES(64, "h"), PostIndexMemType::get(32, 32))},
{Inst::kIdSt4_v, InstType::get(REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"),REG_VEC_WID_RES(128, "h"), REG_VEC_WID_RES(128, "h"), PostIndexMemType::get(64, 64))},
{Inst::kIdSt4_v, InstType::get(REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), REG_VEC_WID_RES(64, "s"),  REG_VEC_WID_RES(64, "s"), PostIndexMemType::get(32, 32))},
{Inst::kIdSt4_v, InstType::get(REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"),REG_VEC_WID_RES(128, "s"), REG_VEC_WID_RES(128, "s"), PostIndexMemType::get(64, 64))},
{Inst::kIdSt4_v, InstType::get(REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"),REG_VEC_WID_RES(128, "d"), REG_VEC_WID_RES(128, "d"), PostIndexMemType::get(64, 64))},

1.4 附录:原有生成脚本的逻辑简介

SY姐之前使用python脚本,从Asmjit库中的a64instdb.cppa64emitter.h两个文件中提取。

逻辑是从遍历a64emitter.h,并且从a64instdb.cpp得到处理寄存器类型、内存类型、立即数范围等信息,然后生成格式化的代码。

1.5 一些补充

对于ld1st1,实际上还会有一些复杂的情况。

  • 实际上目的寄存器可以为1-4个,当然在超过一个时,必须为连续的几个寄存器。例如,对于ld1,以下格式均合法:
# One register (opcode == 0111)
LD1 { <Vt>.<T> }, [<Xn|SP>]

# Two registers (opcode == 1010)
LD1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]

# Three registers (opcode == 0110)
LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]

# Four registers (opcode == 0010)
LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]
  • 当寄存器很多时,需要复制粘贴非常多组情况,因此暂时没有考虑。

2、寄存器格式解析

对于’{‘的处理是较为简单的,我们的处理是定义一个lambda函数,在每次使用到reg的str时,进行一个处理。

auto remove_curly_braces = [](string s) {
    if (s.find('{') != std::string::npos) {
        if(s.find('}') != std::string::npos){
            s = s.substr(s.find('{') + 1, s.find('}') - s.find('{') - 1);
        }
        s = s.substr(s.find('{') + 1);
    }
    return s;
};