为什么 Free Pascal 会自动将记录数据传递给 xmm 寄存器?
Why Free Pascal automatically pass record data to xmm registers?
我的数据类型名为 TVector
,如下所示:
type
TVector = record
x,y,z,w : single;
end;
并且我有名为 v1
和 v2
的变量,其中包含以下数据:
v1.x:=1;
v1.y:=2;
v1.z:=3;
v1.w:=4;
v2.x:=5;
v2.y:=6;
v2.z:=7;
v2.w:=8;
两个变量都按如下方式传递给方法:
function TSSEVectorOperation.add(const vect1: TVector; const vect2: TVector): TVector; assembler;
asm
...
addps xmm1, xmm2
movaps xmm0, xmm1
...
end;
当我使用 Lazarus IDE(在 Ubuntu 中)调试并进入 add()
方法时,我了解到最初 xmm0
- xmm3
寄存器包含v1
和 v2
中的值按以下顺序
xmm0 = {1,2,0,0}
xmm1 = {3,4,0,0}
xmm2 = {5,6,0,0}
xmm3 = {7,8,0,0}
我的问题是为什么 Free Pascal 会这样?为什么不按照下面的顺序呢?
xmm0 = {1,2,3,4}
xmm1 = {5,6,7,8}
或者为什么不让我手动给 xmm 寄存器赋值?类似于:
movaps xmm0, vect1
movaps xmm1, vect2
正如 Michael Petch 在评论中和挖掘 System V ABI 文档后指出的那样。 FreePascal 确实遵循 x86-64 ABI 调用约定(我的 ubuntu 是 14.04 LTS 64 位),它将按照我在问题中提到的顺序将 floating-point 参数传递给 xmm
寄存器。
所以为了将xmm0
和xmm1
寄存器的低四字组合成xmm0
寄存器,我需要使用movlhps
指令
movlhps xmm0, xmm1
xmm2
和 xmm3
寄存器也是如此。
returnsfloating-point值需要将其结果存入xmm0
寄存器的函数。如果结果超过 64 位 floating-point,则剩余的 64 位进入 xmm1
寄存器。所以对于我来说,应该是
xmm0 = {result.x, result.y, (not used), (not used)}
xmm1 = {result.z, result.w, (not used), (not used)}
我的数据类型名为 TVector
,如下所示:
type
TVector = record
x,y,z,w : single;
end;
并且我有名为 v1
和 v2
的变量,其中包含以下数据:
v1.x:=1;
v1.y:=2;
v1.z:=3;
v1.w:=4;
v2.x:=5;
v2.y:=6;
v2.z:=7;
v2.w:=8;
两个变量都按如下方式传递给方法:
function TSSEVectorOperation.add(const vect1: TVector; const vect2: TVector): TVector; assembler;
asm
...
addps xmm1, xmm2
movaps xmm0, xmm1
...
end;
当我使用 Lazarus IDE(在 Ubuntu 中)调试并进入 add()
方法时,我了解到最初 xmm0
- xmm3
寄存器包含v1
和 v2
中的值按以下顺序
xmm0 = {1,2,0,0}
xmm1 = {3,4,0,0}
xmm2 = {5,6,0,0}
xmm3 = {7,8,0,0}
我的问题是为什么 Free Pascal 会这样?为什么不按照下面的顺序呢?
xmm0 = {1,2,3,4}
xmm1 = {5,6,7,8}
或者为什么不让我手动给 xmm 寄存器赋值?类似于:
movaps xmm0, vect1
movaps xmm1, vect2
正如 Michael Petch 在评论中和挖掘 System V ABI 文档后指出的那样。 FreePascal 确实遵循 x86-64 ABI 调用约定(我的 ubuntu 是 14.04 LTS 64 位),它将按照我在问题中提到的顺序将 floating-point 参数传递给 xmm
寄存器。
所以为了将xmm0
和xmm1
寄存器的低四字组合成xmm0
寄存器,我需要使用movlhps
指令
movlhps xmm0, xmm1
xmm2
和 xmm3
寄存器也是如此。
returnsfloating-point值需要将其结果存入xmm0
寄存器的函数。如果结果超过 64 位 floating-point,则剩余的 64 位进入 xmm1
寄存器。所以对于我来说,应该是
xmm0 = {result.x, result.y, (not used), (not used)}
xmm1 = {result.z, result.w, (not used), (not used)}