在ARM Neon ISA中,这两条指令有区别吗?
vst1.32 {d12, d13, d14, d15}, [r4]
Run Code Online (Sandbox Code Playgroud)
和
vst1.8 {d12, d13, d14, d15}, [r4]
Run Code Online (Sandbox Code Playgroud)
基于文档中的伪代码:
case type of
when '0111'
regs = 1; if align<1> == '1' then UNDEFINED;
when '1010'
regs = 2; if align == '11' then UNDEFINED;
when '0110'
regs = 3; if align<1> == '1' then UNDEFINED;
when '0010'
regs = 4;
otherwise
SEE "Related encodings";
alignment = if align == '00' then 1 else 4 << UInt(align);
ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
wback = (m != 15); register_index = (m != 15 && m != 13);
if n == 15 || d+regs > 32 then UNPREDICTABLE;
if ConditionPassed() then
EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
for r = 0 to regs-1
for e = 0 to elements-1
if ebytes != 8 then
MemU[address,ebytes] = Elem[D[d+r],e,esize];
else
data =Elem[D[d+r],e,esize];
MemU[address,4] = if BigEndian() then data<63:32> else data<31:0>;
MemU[address+4,4] = if BigEndian() then data<31:0> else data<63:32>;
address = address + ebytes;
Run Code Online (Sandbox Code Playgroud)
其中size
是一个两位值,似乎无论指定什么大小,D 寄存器的整个值(64 位,8 字节)都会被复制到内存中。看起来无论指定的大小如何,vst1.32 和 vst1.8、vst1.16 都是等效的。
如果是这种情况,则大小参数将存储至少一位额外的信息(因为需要知道对于字节顺序特殊情况是否为 ebytes == 8)。我希望 ARM ISA 不会定义额外信息的存储,因此我的推理中一定存在缺陷,或者我的假设之一是错误的。
这两条指令在常见情况下(小端、对齐地址)实际上表现相同,但它们在两个方面有所不同:
对齐方式——由于两者都没有指定对齐方式,因此您得到了 Arm ARM 所称的“标准对齐方式”。这意味着“应与元素大小对齐,但仅当 SCTLR.A 为 1 时才会出错”。如果设置了 SCTLR.A 并且地址不是 4 对齐,vst1.32 将出现故障,但 vst1.8 不会。
字节顺序——如果设置了 CPSR.E,则存储的每个元素都将进行字节交换。这意味着,对于 vst1.8,没有字节被交换(它是一个字节数组),但对于 vst1.32,每个 4 字节元素的字节都被交换。
对这两件事的处理都隐藏在MemU[] 的伪代码中,这就是为什么仅查看指令的伪代码并不能立即明显看出。
归档时间: |
|
查看次数: |
117 次 |
最近记录: |