所以,我使用A64指令集在汇编形式的ARM中编程。我使用指令fmov d1,#31.0将值移动到dx寄存器。但是,当我使用0.0或任何高于31.0的值时,它显示错误:
"Error: invalid floating-point constant at operand 2 -- `fmov d1,#32.0'"
那么,如何在A64上定义浮点常量?为什么不能使用大于31的值或0?如何用十六进制表示这些值?
另一个问题是:根据arm's website,它支持使用浮点寄存器作为Bx,Hx,Sx,Dx和Qx(分别为8,16,34,64和128位),但我只是不能使用Bx,Hx和Qx寄存器,它显示:
"错误:操作数不匹配--'fmov b1,#1.0'"
"错误:所选处理器不支持'fmov h1,#2.0"
"错误:操作数不匹配--'fmov q1,#2.0'"
如何正确设置第二个操作数?
2条答案
按热度按时间rvpgvaaj1#
只有一小部分浮点常量可以和
fmov
一起使用,因为常量在指令中被编码为8位立即数。具体来说,它必须可以表示为±n/16×2r,其中 n 是一个整数,范围是16 ≤ n ≤ 31,r 是一个整数,范围是-3 ≤ n ≤ 4。fmov
仅适用于16、32和64位数据大小,因为ARMv 8未指定8位或128位浮点格式。对于不支持FEAT_FP16
的ARMv 8内核,也不支持16 bit的数据大小,ARMv 8在很多地方都缺乏正交性;并非所有指令都可用于所有操作数大小。另一个简单的解决方案是,使用
ldr
和文本池中的常量(需要手动转换为整数)。例如,要加载32.0
,请将32.0
转换为IEEE 754表示形式,得到0x4040000000000000
。然后可以按如下方式加载此常量:使用SIMD和FP寄存器且值位于文字池中的
ldr
指令提供32位、64位和128位的操作数大小。较小的操作数大小不适用于文字池寻址模式。如果要加载8位或16位寄存器,请加载相应的32位寄存器。一个稍微快一点的解决方案是首先将所需的数字加载到通用寄存器(支持更灵活的立即数生成),然后将其移动到SIMD和FP寄存器:
要加载
0.0
或掩码,请使用movi
指令。此指令的法律的立即数集取决于操作数大小。但对于您的情况,这只是这会清除
d1
寄存器(从而也会清除b1
、h1
、s1
和q1
寄存器)。hfyxw5xn2#
我已经迟到了,但是我(一个业余爱好者)找到了如何使用. data将浮点数加载到寄存器中。下面是我打印PI的示例代码。我希望它能帮助其他人,因为我自己花了大约两个小时试图找到它。-- Jds