为什么Free Pascal自动将记录数据传递给xmm寄存器?

时间:2017-02-07 04:06:12

标签: assembly sse inline-assembly simd freepascal

我的数据类型名为TVector,如下所示:

type
   TVector = record
       x,y,z,w : single;
   end; 

我有名为v1v2的变量,其中包含以下数据:

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和{{的值1}}按以下顺序

v2

我的问题是为什么Free Pascal会这样做?为什么不按顺序如下?

xmm0 = {1,2,0,0}
xmm1 = {3,4,0,0}
xmm2 = {5,6,0,0}
xmm3 = {7,8,0,0}

或者为什么不让我手动为xmm寄存器赋值?类似的东西:

xmm0 = {1,2,3,4}
xmm1 = {5,6,7,8}

1 个答案:

答案 0 :(得分:1)

Michael Petch在评论和挖掘System V ABI文件后指出。 FreePascal遵循x86-64 ABI调用约定(我的ubuntu是14.04 LTS 64位),它将按照我在我的问题中提到的顺序将浮点参数传递给xmm寄存器。

因此,为了将xmm0xmm1寄存器的低四字组合成xmm0寄存器,我需要使用movlhps指令

 movlhps xmm0, xmm1

同样适用于xmm2xmm3个寄存器。

返回浮点值的函数需要将其结果存储在xmm0寄存器中。如果结果超过64位浮点,则剩余的64位进入xmm1寄存器。所以对我来说,它应该是

 xmm0 = {result.x, result.y, (not used), (not used)}
 xmm1 = {result.z, result.w, (not used), (not used)}