在ARM neon 伊萨中,这两个指令之间有区别吗?
vst1.32 {d12, d13, d14, d15}, [r4]
字符串
和/或
vst1.8 {d12, d13, d14, d15}, [r4]
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;
型
其中size
是一个两位值,看起来无论指定什么大小,D寄存器的整个值(64位,8字节)都将复制到内存中。看起来不管指定的大小如何,vst1.32和vst1.8、vst1.16都是等效的。
如果是这种情况,则大小参数将存储至少一个额外的信息位(因为需要知道对于字节顺序特殊情况是否ebytes == 8)。我希望ARM伊萨不会定义额外信息的存储,所以我的推理中一定有什么地方有缺陷,或者我的假设之一是错误的。
1条答案
按热度按时间9q78igpj1#
这两条指令在常见情况下(小端,对齐地址)实际上表现相同,但它们在两个方面有所不同:
对齐-由于两者都没有指定对齐,因此您将获得Arm ARM称之为“标准对齐”的对齐。这意味着“应与元素大小对齐,但仅在SCTLR. A为1时出错”。如果设置了SCTLR.A且地址不是4对齐的,则vst1.32将出错,但vst1.8不会出错。
Endianness-如果设置了CPSR.E,则存储的每个元素都将进行字节交换。这意味着对于vst1.8没有字节交换(它是一个字节数组),但对于vst1.32,每个4字节元素都交换了它的字节。
这两个操作都隐藏在the pseudocode for MemU[]中,这就是为什么仅仅看指令的伪代码并不能立即看出这一点。