2024.12.9-2024.12.15 学习内容
Published:
对代码中对指令进行解析的部分进行完善,主要是向量寄存器与指令类型。
1、InstType补充
1.1 向量寄存器Type
查看官方文档:Registers, vectors, lanes and elements
对于NEON扩展指令集,
vector
可以为128位或者64位,二者又分别可以拆分成若干个大小为B
、H
、S
或D
的元素。使用标量的指令指定通道索引来引用寄存器中的特定元素,例如,
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+IMM | GP = GP + IMM | PreIndexMemType |
Post-index addressing modes | [GP], IMM | GP | GP = GP + IMM | PostIndexMemType |
1.3 指令语义
所有的指令语义参考: Arm A-profile A64 Instruction Set Architecture文档
- LD1
关于该指令,参考官方文档:LD1 (multiple structures)
在该指令中,可以使用的vector
类型包括:
寄存器 | 宽度 |
---|---|
8B | 64 |
16B | 128 |
4H | 64 |
8H | 128 |
2S | 64 |
4S | 128 |
1D | 64 |
2D | 128 |
而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。
在Post-index下,根据Q字段的不同,后索引只有两个取值:
Q | imm |
---|---|
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
:
寄存器 | 宽度 |
---|---|
8B | 64 |
16B | 128 |
4H | 64 |
8H | 128 |
2S | 64 |
4S | 128 |
2D | 128 |
而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。
在Post-index下,根据Q字段的不同,后索引只有两个取值:
Q | imm |
---|---|
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
:
寄存器 | 宽度 |
---|---|
8B | 64 |
16B | 128 |
4H | 64 |
8H | 128 |
2S | 64 |
4S | 128 |
2D | 128 |
而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。
在Post-index下,根据Q字段的不同,后索引只有两个取值:
Q | imm |
---|---|
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
:
寄存器 | 宽度 |
---|---|
8B | 64 |
16B | 128 |
4H | 64 |
8H | 128 |
2S | 64 |
4S | 128 |
2D | 128 |
而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。
在Post-index下,根据Q字段的不同,后索引只有两个取值:
Q | imm |
---|---|
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类型包括:
寄存器 | 宽度 |
---|---|
8B | 64 |
16B | 128 |
4H | 64 |
8H | 128 |
2S | 64 |
4S | 128 |
1D | 64 |
2D | 128 |
而对于访存,总共支持两种访存模式,分别为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类型包括:
寄存器 | 宽度 |
---|---|
8B | 64 |
16B | 128 |
4H | 64 |
8H | 128 |
2S | 64 |
4S | 128 |
1D | 64 |
2D | 128 |
而对于访存,总共支持两种访存模式,分别为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类型包括:
寄存器 | 宽度 |
---|---|
8B | 64 |
16B | 128 |
4H | 64 |
8H | 128 |
2S | 64 |
4S | 128 |
1D | 64 |
2D | 128 |
而对于访存,总共支持两种访存模式,分别为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类型包括:
寄存器 | 宽度 |
---|---|
8B | 64 |
16B | 128 |
4H | 64 |
8H | 128 |
2S | 64 |
4S | 128 |
1D | 64 |
2D | 128 |
而对于访存,总共支持两种访存模式,分别为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类型包括:
寄存器 | 宽度 |
---|---|
8B | 64 |
16B | 128 |
4H | 64 |
8H | 128 |
2S | 64 |
4S | 128 |
1D | 64 |
2D | 128 |
而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。
在Post-index下,根据Q字段的不同,后索引只有两个取值:
Q | imm |
---|---|
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
:
寄存器 | 宽度 |
---|---|
8B | 64 |
16B | 128 |
4H | 64 |
8H | 128 |
2S | 64 |
4S | 128 |
2D | 128 |
而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。
在Post-index下,根据Q字段的不同,后索引只有两个取值:
Q | imm |
---|---|
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
:
寄存器 | 宽度 |
---|---|
8B | 64 |
16B | 128 |
4H | 64 |
8H | 128 |
2S | 64 |
4S | 128 |
2D | 128 |
而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。
在Post-index下,根据Q字段的不同,后索引只有两个取值:
Q | imm |
---|---|
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
:
寄存器 | 宽度 |
---|---|
8B | 64 |
16B | 128 |
4H | 64 |
8H | 128 |
2S | 64 |
4S | 128 |
2D | 128 |
而对于访存,总共支持两种访存模式,分别为No-Offset(也就是BaseROnlyMemType)和Post-index。
在Post-index下,根据Q字段的不同,后索引只有两个取值:
Q | imm |
---|---|
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.cpp
和a64emitter.h
两个文件中提取。
逻辑是从遍历a64emitter.h
,并且从a64instdb.cpp
得到处理寄存器类型、内存类型、立即数范围等信息,然后生成格式化的代码。
1.5 一些补充
- 实际上目的寄存器可以为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;
};