SPARC体系下硬浮点编译故障分析

news2024/11/18 9:45:01

问题说明

之前extension版的app工程都是用的软浮点编译的,在增加姿控算法库后,统一改用硬浮点运行,发现之前一个浮点数解析不对了,排查发现和工程编译选项有关,为软浮点时正常,硬浮点时异常。该问题脱离业务程序环境直接用test工程测试可复现。

在这里插入图片描述

软浮点编译运行
在这里插入图片描述

硬浮点编译运行
在这里插入图片描述
命令行输入字符串“40.0”程序解析出0.0。显然出错了,单系统并未奔溃。

初步分析

之前在该硬件平台(sparc V8体系结构)下专门测试过软硬浮点速度差异,计算结果都是正常的,硬浮点速度也显著提升。说明硬浮点本身运算没问题,怀疑是浮点二进制接口上出现了不匹配。

ABI汇编分析

脱离C库的浮点相关接口,只研究浮点二进制接口特性。
测试条件:
1.sparc V8体系结构,处理器无MMU
2. lite版Sylixos,app可独立开发,加载,运行但本质是静态链接的。
3. base和bsp都是软浮点编译,静态库硬浮点编译,app软浮点和硬浮点编译。
4. 都采用-O0编译,避免编译器优化,便于汇编分析

静态库函数源码如下:

float  testfloat(float a, float b)
{
    return  (a + b);
}

软浮点编译,反汇编如下:

401b917c <testfloat>:
401b917c:	9d e3 bf a0 	save  %sp, -96, %sp
401b9180:	f0 27 a0 44 	st  %i0, [ %fp + 0x44 ]
401b9184:	f2 27 a0 48 	st  %i1, [ %fp + 0x48 ]
401b9188:	d0 07 a0 44 	ld  [ %fp + 0x44 ], %o0
401b918c:	d2 07 a0 48 	ld  [ %fp + 0x48 ], %o1
401b9190:	7f fe c6 a4 	call  4016ac20 <__addsf3>
401b9194:	01 00 00 00 	nop 
401b9198:	82 10 00 08 	mov  %o0, %g1
401b919c:	b0 10 00 01 	mov  %g1, %i0
401b91a0:	81 e8 00 00 	restore 
401b91a4:	81 c3 e0 08 	retl 
401b91a8:	01 00 00 00 	nop 

硬浮点编译,反汇编如下:

401b8e48 <testfloat>:
401b8e48:	9c 03 bf b0 	add  %sp, -80, %sp
401b8e4c:	d0 23 a0 4c 	st  %o0, [ %sp + 0x4c ]
401b8e50:	d1 03 a0 4c 	ld  [ %sp + 0x4c ], %f8
401b8e54:	d2 23 a0 4c 	st  %o1, [ %sp + 0x4c ]
401b8e58:	d3 03 a0 4c 	ld  [ %sp + 0x4c ], %f9
401b8e5c:	9c 03 a0 50 	add  %sp, 0x50, %sp
401b8e60:	81 c3 e0 08 	retl 
401b8e64:	81 a2 08 29 	fadds  %f8, %f9, %f0

app调用静态库函数源码:

extern  float  testfloat(float a, float b);
float floattest (float  a, float  b)
{
    return  (testfloat(a,b));
}

软浮点编译,反汇编如下:

401b5c20 <floattest>:
401b5c20:	9d e3 bf a0 	save  %sp, -96, %sp
401b5c24:	f0 27 a0 44 	st  %i0, [ %fp + 0x44 ]
401b5c28:	f2 27 a0 48 	st  %i1, [ %fp + 0x48 ]
401b5c2c:	d0 07 a0 44 	ld  [ %fp + 0x44 ], %o0
401b5c30:	d2 07 a0 48 	ld  [ %fp + 0x48 ], %o1
401b5c34:	40 00 0c 85 	call  401b8e48 <testfloat>
401b5c38:	01 00 00 00 	nop 
401b5c3c:	82 10 00 08 	mov  %o0, %g1
401b5c40:	b0 10 00 01 	mov  %g1, %i0
401b5c44:	81 e8 00 00 	restore 
401b5c48:	81 c3 e0 08 	retl 
401b5c4c:	01 00 00 00 	nop 

硬浮点编译,反汇编如下:

401b2f18 <floattest>:
401b2f18:	9d e3 bf a0 	save  %sp, -96, %sp
401b2f1c:	f0 27 a0 44 	st  %i0, [ %fp + 0x44 ]
401b2f20:	f2 27 a0 48 	st  %i1, [ %fp + 0x48 ]
401b2f24:	d0 07 a0 44 	ld  [ %fp + 0x44 ], %o0
401b2f28:	d2 07 a0 48 	ld  [ %fp + 0x48 ], %o1
401b2f2c:	40 00 0c 85 	call  401b6140 <testfloat>
401b2f30:	01 00 00 00 	nop 
401b2f34:	91 a0 00 20 	fmovs  %f0, %f8
401b2f38:	81 a0 00 28 	fmovs  %f8, %f0
401b2f3c:	81 e8 00 00 	restore 
401b2f40:	81 c3 e0 08 	retl 
401b2f44:	01 00 00 00 	nop 

显然,
软浮点编译时,输入参数是通过定点寄存器 %i0, %i1传递,输出用定点寄存器%o0传递;
硬浮点编译时,输入参数是通过定点寄存器 %i0, %i1传递,输出用浮点寄存器%f0传递;
函数调用方和被调研方,如果使用相同的浮点编译方法(同为软浮点编译或同为硬浮点编译)则都可以得到正确结果。

而上述bug出错就源于,一个硬浮点编译的函数调用了一个软浮点编译的函数,被调用函数把结果放到了%o0寄存器中,而调用方却去%f0寄存器中获取结果,自然就出错了。

解决思路

现在的问题是,base,bsp必须用软浮点编译,app可以是软浮点也可以是硬浮点编译,app用到的一个静态库里面有大量浮点计算要求必须硬浮点编译。这时app用软浮点编译和静态库有冲突,用硬浮点编译和base 库有冲突。

首先想到的是用-mfloat-abi=softfp编译选项来编译静态库,让静态库即能用到硬浮点的提速又能在接口上和其他程序兼容。

  • -mfloat-abi=soft 调用软浮点库(softfloat lib 定点运算)来实现浮点运算,浮点参数通过定点寄存器传递.
  • -mfloat-abi=hard 调用FPU硬浮点指令实现浮点运算, 浮点参数一般通过浮点寄存器传递.。
  • -mfloat-abi=softfp 调用FPU硬浮点指令实现浮点运算,但浮点参数通过定点寄存器传递.

操作系统内核, 驱动程序, BSP, 内核模块一般采用 -mfloat-abi=soft 编译.如果存在 VFP 应用程序可使用 -mfloat-abi=softfp 来编译。

但可惜sparc-sylixos-elf-gcc没有此选项。arm-sylixos-eabi-gcc及其他体系结构是有该选项的。

$ sparc-sylixos-elf-gcc.exe --target-help
The following options are target specific:
  -m32                        Use 32-bit ABI
  -m64                        Use 64-bit ABI
  -mapp-regs                  Use ABI reserved registers
  -mcbcond                    Use UltraSPARC Compare-and-Branch extensions
  -mcmodel=                   Use given SPARC-V9 code model
  -mcpu=                      Use features of and schedule code for given CPU
  -mdebug=                    Enable debug output
  -mfaster-structs            Use structs on stronger alignment for double-word
                              copies
  -mfix-at697f                Enable workaround for single erratum of AT697F
                              processor (corresponding to erratum #13 of AT697E
                              processor)
  -mfix-ut699                 Enable workarounds for the errata of the UT699
                              processor
  -mflat                      Use flat register window model
  -mfmaf                      Use UltraSPARC Fused Multiply-Add extensions
  -mfpu                       Use hardware FP
  -mhard-float                Use hardware FP
  -mhard-quad-float           Use hardware quad FP instructions
  -mmemory-model=             Specify the memory model in effect for the
                              program.
  -mpopc                      Use UltraSPARC Population-Count instruction
  -mptr32                     Pointers are 32-bit
  -mptr64                     Pointers are 64-bit
  -mrelax                     Optimize tail call instructions in assembler and
                              linker
  -msoft-float                Do not use hardware FP
  -msoft-quad-float           Do not use hardware quad fp instructions
  -mstack-bias                Use stack bias
  -mstd-struct-return         Enable strict 32-bit psABI struct return checking.
  -mtune=                     Schedule code for given CPU
  -munaligned-doubles         Assume possible double misalignment
  -muser-mode                 Do not generate code that can only run in
                              supervisor mode
  -mv8plus                    Compile for V8+ ABI
  -mvis                       Use UltraSPARC Visual Instruction Set version 1.0
                              extensions
  -mvis2                      Use UltraSPARC Visual Instruction Set version 2.0
                              extensions
  -mvis3                      Use UltraSPARC Visual Instruction Set version 3.0
                              extensions

$ arm-sylixos-eabi-gcc.exe --target-help
The following options are target specific:
  -mabi=                      Specify an ABI
  -mabort-on-noreturn         Generate a call to abort if a noreturn function
                              returns
  -mapcs-float                Pass FP arguments in FP registers
  -mapcs-frame                Generate APCS conformant stack frames
  -mapcs-reentrant            Generate re-entrant, PIC code
  -march=                     Specify the name of the target architecture
  -marm                       Generate code in 32 bit ARM state.
  -mbig-endian                Assume target CPU is configured as big endian
  -mcallee-super-interworking Thumb: Assume non-static functions may be called
                              from ARM code
  -mcaller-super-interworking Thumb: Assume function pointers may go to non-
                              Thumb aware code
  -mcpu=                      Specify the name of the target CPU
  -mfix-cortex-m3-ldrd        Avoid overlapping destination and address
                              registers on LDRD instructions that may trigger
                              Cortex-M3 errata.
  -mfloat-abi=                Specify if floating point hardware should be used
  -mfp16-format=              Specify the __fp16 floating-point format
  -mfpu=                      Specify the name of the target floating point
                              hardware/format
  -mlittle-endian             Assume target CPU is configured as little endian
  -mlong-calls                Generate call insns as indirect calls, if
                              necessary
  -mlra                       Use LRA instead of reload (transitional)
  -mneon-for-64bits           Use Neon to perform 64-bits operations rather
                              than core registers.
  -mnew-generic-costs         Use the new generic RTX cost tables if new core-
                              specific cost table not available (transitional).
  -mold-rtx-costs             Use the old RTX costing tables (transitional).
  -mpic-data-is-text-relative Assume data segments are relative to text segment.
  -mpic-register=             Specify the register to be used for PIC addressing
  -mpoke-function-name        Store function names in object code
  -mrestrict-it               Generate IT blocks appropriate for ARMv8.
  -msched-prolog              Permit scheduling of a function's prologue
                              sequence
  -msingle-pic-base           Do not load the PIC register in function prologues
  -mslow-flash-data           Assume loading data from flash is slower than
                              fetching instructions.
  -mstructure-size-boundary=  Specify the minimum bit alignment of structures
  -mthumb                     Generate code for Thumb state
  -mthumb-interwork           Support calls between Thumb and ARM instruction
                              sets
  -mtls-dialect=              Specify thread local storage scheme
  -mtp=                       Specify how to access the thread pointer
  -mtpcs-frame                Thumb: Generate (non-leaf) stack frames even if
                              not needed
  -mtpcs-leaf-frame           Thumb: Generate (leaf) stack frames even if not
                              needed
  -mtune=                     Tune code for the given processor
  -munaligned-access          Enable unaligned word and halfword accesses to
                              packed data.
  -mvectorize-with-neon-double Use Neon double-word (rather than quad-word)
                              registers for vectorization
  -mvectorize-with-neon-quad  Use Neon quad-word (rather than double-word)
                              registers for vectorization
  -mword-relocations          Only generate absolute relocations on word sized
                              values.
  -mwords-little-endian       Assume big endian bytes, little endian words.
                              This option is deprecated.

另一个方法是这样的,APP和算法库都使用硬浮点编译,这时,app调用的base库里的会返回浮点数的函数接口就会出错,那把这些函数单独用硬浮点编译一个libcfoat静态库,app同时连接base和libcfoat两个库,其中返回浮点的用libcfoat静态库中的,其他用base静态库中的。这这方式实现会比较繁琐,但也能解决浮点接口冲突问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/370487.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【华为OD机试模拟题】用 C++ 实现 - VLAN 资源池(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

Stream操作流 练习

基础数据&#xff1a;Data AllArgsConstructor NoArgsConstructor public class User {private String name;private int age;private String sex;private String city;private Integer money; static List<User> users new ArrayList<>();public static void m…

【计算机三级网络技术】 第一篇 网络系统结构与系统设计的基本原则

网络系统结构与系统设计的基本原则 文章目录网络系统结构与系统设计的基本原则一、计算机网络的基本结构二、计算机网络分类及其互联方式1.局域网2.城域网3.广域网4.计算机网络的互联方式三、局域网技术四、城域网技术1.城域网的概念2.宽带城域网建设产生的影响3.推动城域网快速…

HTML - 扫盲

文章目录1. 前言2. HTML2.1 下载 vscode3 HTML 常见标签3.1 注释标签3.2 标题标签3.3 段落标签3.4 换行标签3.5 格式化标签1. 加粗2. 倾斜3. 下划线3.6 图片标签3.7 超链接标签3.8 表格标签3.9 列表标签4. 表单标签4.1 from 标签4.2 input 标签4.3 select 标签4.4 textarea标签…

webgl渲染优化——深度缓冲区、多边形缓冲机制

文章目录前言深度缓冲区多边形缓冲机制总结前言 webgl在渲染三维场景时&#xff0c;按照Z坐标的值决定前后关系&#xff0c;但是在默认状态下它并未开启深度检测&#xff0c;而是将后绘制的物体放在前面&#xff1b;当两个物体Z坐标相差无几时&#xff0c;会产生深度冲突&…

【Redis】线程模型:Redis是单线程还是多线程?

【Redis】线程模型&#xff1a;Redis是单线程还是多线程&#xff1f; 文章目录【Redis】线程模型&#xff1a;Redis是单线程还是多线程&#xff1f;Redis 是单线程吗&#xff1f;Redis 单线程模式是怎样的&#xff1f;Redis 采用单线程为什么还这么快&#xff1f;Redis 6.0 之前…

高端装备的AC主轴头结构

加工机器人的AC主轴头和位置相关动力学特性1. 位置依赖动态特性及其复杂性2. AC主轴头2.1 常见主轴头摆角结构2.2 摆动机构3. 加装AC主轴头的作用和局限性4. 切削机器人的减速器类型5. 其他并联结构形式参考文献资料1. 位置依赖动态特性及其复杂性 However, FRF measurements …

JS学习第3天——Web APIs之DOM(什么是DOM,相关API)

目录一、Web APIs介绍1、API2、Web API二、DOM1、DOM树2、获取元素3、事件基础4、操作元素属性5、节点&#xff08;node&#xff09;操作三、以上内容总结四、小案例一、Web APIs介绍 JS的组成&#xff1a;ECMAScript&#xff08;基础语法&#xff09;、DOM&#xff08;页面文…

CTFer成长之路之反序列化漏洞

反序列化漏洞CTF 1.访问url&#xff1a; http://91a5ef16-ff14-4e0d-a687-32bdb4f61ecf.node3.buuoj.cn/ 点击下载源码 本地搭建环境并访问url&#xff1a; http://127.0.0.1/www/public/ 构造payload&#xff1a; ?sindex/index/hello&ethanwhoamiPOST的参数&#…

【渗透测试学习】—记录一次自测试渗透实战

写在前面 本文是作者入门web安全后的第一次完整的授权渗透测试实战&#xff0c;因为最近在总结自己学习与挖掘到的漏&#xff0c;无意中翻到了这篇渗透测试报告&#xff0c;想当初我的这篇渗透测试报告是被评为优秀渗透测试报告的&#xff0c;故在此重新整了一下&#xff0c;分…

创客匠人直播:构建公域到私域的用户增长模型

进入知识付费直播带货时代&#xff0c;很多拥有知识技能经验的老师和培训机构吃到了流量红利。通过知识付费直播&#xff0c;老师们可以轻松实现引流、变现&#xff0c;还可以突破时间、地域的限制&#xff0c;为全国各地的学员带来优质的教学服务&#xff0c;因此越来越受到教…

【Linux】-- 多线程安全

目录 进程互斥 计算 -> 时序问题 加锁保护 pthread_mutex_lock pthread_mutex_unlock 使用init与destory pthread_mutex_init phtread_mutex_destory 锁的实现原理 图 可重入VS线程安全 死锁 Linux线程同步 条件变量 系统调用 进程互斥 进程线程间的互斥相关…

【C语言经典例题】打印菱形

目录 一、题目要求 二、解题思路 上半部分三角形 打印空格 打印星号* 下半部分三角形 打印空格 打印星号* 三、完整代码 代码 运行截图&#xff1a; 一、题目要求 输入一个整数n&#xff08;n为奇数&#xff09;&#xff0c;n为菱形的高&#xff0c;打印出该菱形 例&a…

【模拟集成电路】鉴频鉴相器设计(Phase Frequency Detector,PFD)

鉴频鉴相器设计&#xff08;Phase Frequency Detector&#xff0c;PFD&#xff09;前言一、 PFD的工作原理二、 PFD电路设计&#xff08;1&#xff09;PFD电路图&#xff08;2&#xff09;D触发器电路图&#xff08;3&#xff09;与非门&#xff08;NAND&#xff09;电路图&…

【死磕数据库专栏】MySQL对数据库增删改查的基本操作

前言 本文是专栏【死磕数据库专栏】的第二篇文章&#xff0c;主要讲解MySQL语句最常用的增删改查操作。我一直觉得这个世界就是个程序&#xff0c;每天都在执行增删改查。 MySQL 中我们最常用的增删改查&#xff0c;对应SQL语句就是 insert 、delete、update、select&#xf…

亚马逊侵权了怎么办?不要恐慌,这套申诉方法教你解决

侵权&#xff0c;在亚马逊可是大忌&#xff01;在亚马逊平台上&#xff0c;卖家侵权行为被认为是极为严重的违规行为。亚马逊采取的对待侵权的措施通常相当严厉&#xff0c;从轻者的产品下架到重者直接被禁售。所以如果你的产品涉嫌侵犯知识产权&#xff0c;那么想要在亚马逊上…

软件质量保证与测试(测试部分)

第九章、软件测试过程 9.1 计算机软件的可靠性要素 9.2 软件测试的目的和原则 9.3 软件测试过程 9.4 软件测试与软件开发的关系 9.7 测试工具选择 9.7.1 白盒测试工具 9.7.2 黑盒测试工具 第十章、黑盒测试 10.1 黑盒测试的基本概念 10.2 等价类划分 10.2.2 划分等价类的方法…

MinGW编译log4cpp

log4cpp的官网和下载地址 https://log4cpp.sourceforge.net/ https://sourceforge.net/projects/log4cpp/files/ 使用MinGW编译log4cpp 进入到log4cpp的源码目录 cd F:\3rdParty\Log\log4cpp\log4cpp-1.1.3\log4cpp 创建文件夹 mkdir build && mkdir outcd build …

死磕Spring,什么是SPI机制,对SpringBoot自动装配有什么帮助

文章目录如果没时间看的话&#xff0c;在这里直接看总结一、Java SPI的概念和术语二、看看Java SPI是如何诞生的三、Java SPI应该如何应用四、从0开始&#xff0c;手撸一个SPI的应用实例五、SpringBoot自动装配六、Spring SPI机制与Spring Factories机制做对比七、这里是给我自…

软件测试5年,历经3轮面试成功拿下华为Offer,24K/16薪不过分吧

前言 转眼过去&#xff0c;距离读书的时候已经这么久了吗&#xff1f;&#xff0c;从18年5月本科毕业入职了一家小公司&#xff0c;到现在快5年了&#xff0c;前段时间社招想着找一个新的工作&#xff0c;前前后后花了一个多月的时间复习以及面试&#xff0c;前几天拿到了华为的…