2010-01-18 166 views
1

我目前尝试使用ARM汇编代码编写iPhone的VFP单元的程序。 VFP可以做浮点计算,但是AFAIK没有整数算术。但是,它可以将float转换为有符号整数(4字节)。另外,根据这个快速参考:http://www.voti.nl/hvu/arm/ARMquickref.pdf 它似乎不支持任何移位操作汇编:将浮点值转换为带符号的字节

我想要做的是转换4个浮点数,我敢肯定,每个大于-127和小于127成4个有符号的字节。我可以将浮点数转换为有符号整数,然后将值向左移动12个字节(分别为接下来的两个值的8个和4个字节),并将所有四个位按比例或运算。

然而,由于转移不可用,我需要找到另一种方式来做到这一点。此外 - 我不能使用整数算术(所以我不能乘以已转换的整数2^n为了转移,但我不得不在浮标上工作)。

任何人都知道我能做到吗?

btw对那些熟悉ARM体系结构的人来说 - 我不想切换到Thumb指令,因为这是在一个对许多元素进行操作的循环中完成的,我不想在这里面的拇指和胳膊指令之间切换。循环(因为那很贵)

谢谢!

编辑:

另一个问题:我怎么能正常化有三个元素的向量?

回答

2

您希望VFP ftosis指令将单精度FP值转换为4字节整数。如果您在S0-S3四个浮点,然后做后:

ftosis s0, s0 
ftosis s1, s1 
ftosis s2, s2 
ftosis s3, s3 

你在S0-S3四个4字节的整数,可连续存储到存储与fstm

在支持NEON的ARM处理器上,可以使用vcvt.s32.f32 q0, q0通过一条指令执行四次转换。


编辑回答您的后续问题,这里有一个简单的例子功能,需要输入一个指针到四个花车在内存中,并返回打包成一个单一的int32_t转换值:

_floatToPackedInt: 
    fldmias r0, {s4-s7} 
    ftosizs s0, s4 
    ftosizs s1, s5 
    ftosizs s2, s6 
    ftosizs s3, s7 
    fmrrs r0, r1, {s0,s1} 
    fmrrs r2, r3, {s2,s3} 
    uxtb  r0, r0 
    uxtb  r1, r1 
    uxtb  r2, r2 
    orr  r0, r0, r1, lsl #8 
    orr  r0, r0, r2, lsl #16 
    orr  r0, r0, r3, lsl #24 
    bx  lr 

我没有真正付出任何努力来调整这一点,因为如果它们对性能至关重要,您不希望以这种方式进行转换;你宁愿要么操作大数值的数组,也要管理这些代码,以便多次转换同时进行,或者将其与其他正在进行有用工作的操作交错。

您也可以在uxtb之前插入ssat s,以使超出范围的值饱和而不是打包。

此外,请注意,此代码在ARMv7内核上的性能较差;你一定想在该平台上使用NEON矢量操作。

+0

是的,我知道这一点 - 但问题是从signed int转换为signed byte!最后,我想没有4个4字节的整数,但是在一个寄存器中有4个1字节的带符号的字节 – genesys 2010-01-18 23:34:36

+0

对不起,一点也不清楚,那就是你想从你的问题中得到的结果(“然后将值移动12个字节到左边”等等)。您可以直接在NEON上执行此操作,但是在仅具有VFP的ARM内核上,您需要将转换后的值移回通用寄存器并将其压缩为字节。 – 2010-01-18 23:45:54

+0

你确定吗?有按位或 - 所以我thoght也许我可以建立一些使用浮点算术。如果我将我的float在-127 <= f <= 127的范围内,我不能乘以#4096(= 2^12),然后使用ftosis将其转换为int?这不会导致与将转换后的int向左移动12位相同吗? - 如果没有,也许你可以回答我的第二个问题? (请参阅上面问题中的编辑) – genesys 2010-01-18 23:59:21