2024.12.2-2024.12.8 学习内容

5 minute read

Published:

对于Arm指令集中的内容进行介绍。主要介绍Arm指令集中的向量指令集,特别是与访存有关的部分。同时对代码支持向量访存部分进行了分析。

1、 Arm指令集

asmjit库支持完备的Arm指令集,包括基础指令集与SIMD扩展。完整的指令可以参考官方文档。目前我们的系统支持大部分的基础指令,所以这里主要关注向量指令特别是访存指令。

1.1 SIMD指令和浮点指令

节选了部分指令,特别是涉及内存操作的模块。在asmjit库中,所有涉及mem的指令有且仅有如下所列的14+11条指令。

序号指令名称操作数类型指令语义
1abs(const Vec& o0, const Vec& o1) 
2add(const Vec& o0, const Vec& o1, const Vec& o2) 
3addhn(const Vec& o0, const Vec& o1, const Vec& o2) 
4addhn2(const Vec& o0, const Vec& o1, const Vec& o2) 
5addp(const Vec& o0, const Vec& o1) 
6addp(const Vec& o0, const Vec& o1, const Vec& o2) 
7addv(const Vec& o0, const Vec& o1) 
8and_(const Vec& o0, const Vec& o1, const Vec& o2) 
9bic(const Vec& o0, const Imm& o1) 
10bic(const Vec& o0, const Vec& o1, const Vec& o2) 
11bic(const Vec& o0, const Imm& o1, const Imm& o2) 
12bif(const Vec& o0, const Vec& o1, const Vec& o2) 
13bit(const Vec& o0, const Vec& o1, const Vec& o2) 
14bsl(const Vec& o0, const Vec& o1, const Vec& o2) 
137ld1(const Vec& o0, const Mem& o1) 
138ld1(const Vec& o0, const Vec& o1, const Mem& o2) 
139ld1(const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) 
140ld1r(const Vec& o0, const Mem& o1) 
141ld2(const Vec& o0, const Vec& o1, const Mem& o2) 
142ld2r(const Vec& o0, const Vec& o1, const Mem& o2) 
143ld3(const Vec& o0, const Vec& o1, const Vec& o2, const Mem& o3) 
144ld3r(const Vec& o0, const Vec& o1, const Vec& o2, const Mem& o3) 
145ld4(const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) 
146ld4r(const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) 
147ldnp(const Vec& o0, const Vec& o1, const Mem& o2) 
148ldp(const Vec& o0, const Vec& o1, const Mem& o2) 
149ldr(const Vec& o0, const Mem& o1) 
150ldur(const Vec& o0, const Mem& o1) 
262st1(const Vec& o0, const Mem& o1) 
263st1(const Vec& o0, const Vec& o1, const Mem& o2) 
264st1(const Vec& o0, const Vec& o1, const Vec& o2, const Mem& o3) 
265st1(const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) 
266st2(const Vec& o0, const Vec& o1, const Mem& o2) 
267st3(const Vec& o0, const Vec& o1, const Vec& o2, const Mem& o3) 
268st4(const Vec& o0, const Vec& o1, const Vec& o2, const Vec& o3, const Mem& o4) 
269stnp(const Vec& o0, const Vec& o1, const Mem& o2) 
270stp(const Vec& o0, const Vec& o1, const Mem& o2) 
271str(const Vec& o0, const Mem& o1) 
272stur(const Vec& o0, const Mem& o1) 
356zip2(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], IMMGPGP = GP + IMM
带前置偏移量的寄存器间接寻址[GP, IMM]!GP+IMMGP = GP + IMM
寄存器后更新寻址[GP1], GP2GP1GP1 = GP1 + GP2

2、代码确认

2.1部分向量指令的语法支持

部分涉及访存的向量指令还没有支持。在上述的指令列表中,如ldnpldp同时可以完成常量与向量的访存,故进行了支持,但是部分指令,如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中找不到符合条件的InstIdInstType的映射。