2024.12.2-2024.12.8 学习内容
Published:
对于Arm指令集中的内容进行介绍。主要介绍Arm指令集中的向量指令集,特别是与访存有关的部分。同时对代码支持向量访存部分进行了分析。
1、 Arm指令集
asmjit
库支持完备的Arm
指令集,包括基础指令集与SIMD
扩展。完整的指令可以参考官方文档。目前我们的系统支持大部分的基础指令,所以这里主要关注向量指令特别是访存指令。
1.1 SIMD指令和浮点指令
节选了部分指令,特别是涉及内存操作的模块。在asmjit
库中,所有涉及mem
的指令有且仅有如下所列的14+11条指令。
序号 | 指令名称 | 操作数类型 | 指令语义 |
---|---|---|---|
1 | abs | (const Vec& o0, const Vec& o1) | |
2 | add | (const Vec& o0, const Vec& o1, const Vec& o2) | |
3 | addhn | (const Vec& o0, const Vec& o1, const Vec& o2) | |
4 | addhn2 | (const Vec& o0, const Vec& o1, const Vec& o2) | |
5 | addp | (const Vec& o0, const Vec& o1) | |
6 | addp | (const Vec& o0, const Vec& o1, const Vec& o2) | |
7 | addv | (const Vec& o0, const Vec& o1) | |
8 | and_ | (const Vec& o0, const Vec& o1, const Vec& o2) | |
9 | bic | (const Vec& o0, const Imm& o1) | |
10 | bic | (const Vec& o0, const Vec& o1, const Vec& o2) | |
11 | bic | (const Vec& o0, const Imm& o1, const Imm& o2) | |
12 | bif | (const Vec& o0, const Vec& o1, const Vec& o2) | |
13 | bit | (const Vec& o0, const Vec& o1, const Vec& o2) | |
14 | bsl | (const Vec& o0, const Vec& o1, const Vec& o2) | |
… | … | … | … |
137 | ld1 | (const Vec& o0, const Mem& o1) | |
138 | ld1 | (const Vec& o0, const Vec& o1, const Mem& o2) | |
139 | ld1 | (const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) | |
140 | ld1r | (const Vec& o0, const Mem& o1) | |
141 | ld2 | (const Vec& o0, const Vec& o1, const Mem& o2) | |
142 | ld2r | (const Vec& o0, const Vec& o1, const Mem& o2) | |
143 | ld3 | (const Vec& o0, const Vec& o1, const Vec& o2, const Mem& o3) | |
144 | ld3r | (const Vec& o0, const Vec& o1, const Vec& o2, const Mem& o3) | |
145 | ld4 | (const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) | |
146 | ld4r | (const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) | |
147 | ldnp | (const Vec& o0, const Vec& o1, const Mem& o2) | |
148 | ldp | (const Vec& o0, const Vec& o1, const Mem& o2) | |
149 | ldr | (const Vec& o0, const Mem& o1) | |
150 | ldur | (const Vec& o0, const Mem& o1) | |
… | … | … | … |
262 | st1 | (const Vec& o0, const Mem& o1) | |
263 | st1 | (const Vec& o0, const Vec& o1, const Mem& o2) | |
264 | st1 | (const Vec& o0, const Vec& o1, const Vec& o2, const Mem& o3) | |
265 | st1 | (const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) | |
266 | st2 | (const Vec& o0, const Vec& o1, const Mem& o2) | |
267 | st3 | (const Vec& o0, const Vec& o1, const Vec& o2, const Mem& o3) | |
268 | st4 | (const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) | |
269 | stnp | (const Vec& o0, const Vec& o1, const Mem& o2) | |
270 | stp | (const Vec& o0, const Vec& o1, const Mem& o2) | |
271 | str | (const Vec& o0, const Mem& o1) | |
272 | stur | (const Vec& o0, const Mem& o1) | |
… | … | … | … |
356 | zip2 | (const Vec& o0, const Vec& o1, const Vec& o2) |
1.2 寻址方式总结
节选了部分常见寻址方式,列表如下。
see:官方文档
寻址方式 | 操作数 | 计算模式 | 副作用 |
---|---|---|---|
寄存器间接寻址 | [GP] | GP | |
带偏移量的寄存器间接寻址 | [GP, IMM] | GP+IMM | |
位移寻址 | [GP1, GP2, LSL IMM] | GP1 + (GP2 « IMM) | |
带后续偏移量的寄存器间接寻址 | [GP], IMM | GP | GP = GP + IMM |
带前置偏移量的寄存器间接寻址 | [GP, IMM]! | GP+IMM | GP = GP + IMM |
寄存器后更新寻址 | [GP1], GP2 | GP1 | GP1 = GP1 + GP2 |
2、代码确认
2.1部分向量指令的语法支持
部分涉及访存的向量指令还没有支持。在上述的指令列表中,如ldnp
、ldp
同时可以完成常量与向量的访存,故进行了支持,但是部分指令,如ld1
~ld4
,由于仅仅在SIMD
中使用,目前在语法分析暂时没有支持(但是后续的parser
等阶段有支持)。
还没支持的指令列表如下。
ld1 | (const Vec& o0, const Mem& o1) | |
---|---|---|
ld1 | (const Vec& o0, const Vec& o1, const Mem& o2) | |
ld1 | (const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) | |
ld1r | (const Vec& o0, const Mem& o1) | |
ld2 | (const Vec& o0, const Vec& o1, const Mem& o2) | |
ld2r | (const Vec& o0, const Vec& o1, const Mem& o2) | |
ld3 | (const Vec& o0, const Vec& o1, const Vec& o2, const Mem& o3) | |
ld3r | (const Vec& o0, const Vec& o1, const Vec& o2, const Mem& o3) | |
ld4 | (const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) | |
ld4r | (const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) | |
st1 | (const Vec& o0, const Mem& o1) | |
st1 | (const Vec& o0, const Vec& o1, const Mem& o2) | |
st1 | (const Vec& o0, const Vec& o1, const Vec& o2, const Mem& o3) | |
st1 | (const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) | |
st2 | (const Vec& o0, const Vec& o1, const Mem& o2) | |
st3 | (const Vec& o0, const Vec& o1, const Vec& o2, const Mem& o3) | |
st4 | (const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) |
2.2 向量寄存器的语法分析
在向量寄存器相关的寻址中,向量寄存器可能由大括号包裹起来,但是编写的antlr
语法规则暂不支持这种指令中的向量寄存器格式。
ld1 {v0.4s}, [x0]
如果直接添加语法规则:
fragment REGISTER_VEC
: REG_VEC_NAME ('.' REG_VEC_REINTERPRET)?
| REG_VEC_NAME '.' REG_VEC_REINTERPRET REG_VEC_ACCESS
| '{'? REG_VEC_NAME ('.' REG_VEC_REINTERPRET)? '}'? ;//添加此规则
则会导致语义分析阶段,无法识别“{v0
”为一个合法寄存器。
2.3 向量访存指令的单条指令解析
在调用ProgramReader::enterInstruction()方法解析单条向量访存指令时,会出现got_only_type
变量为flase
,导致parse
失败的情况。目前看来,原因是因为类似ld1
的指令,暂时无法被匹配到合适的InstType
。具体到代码中,也就是legal_inst_type_multimap
中找不到符合条件的InstId
→InstType
的映射。