【发布时间】:2017-09-06 20:17:31
【问题描述】:
我已经下载了 Sourcery IA16 compiler,它是一个用于 16 位目标的 GNU C++ 编译器,它可以工作(尽管它不支持远指针,并且内联 asm 寄存器分配存在一些故障,无论如何)。
但是当我在 C 中声明一个 float 变量时,编译器会说:
/tmp/ccBB3kEN.o: In function `foo()':
(.text+0x38): undefined reference to `__floatsisf'
/tmp/ccBB3kEN.o: In function `foo()':
(.text+0x44): undefined reference to `__mulsf3'
/tmp/ccBB3kEN.o: In function `foo()':
(.text+0x4c): undefined reference to `__fixsfsi'
如图所示,默认情况下,它要使用soft-fpu,所以我认为,我应该添加一些编译器选项来生成原生FPU代码。但我失败了。
现在我正在使用编译器选项-march=i80186,并且帮助说我应该为其添加一些后缀:
-march=CPU[,+EXTENSION...]
Igenerate code for CPU and EXTENSION, CPU is one of:
generic32, generic64, i386, i486, i586, i686,
pentium, pentiumpro, pentiumii, pentiumiii, pentium4,
prescott, nocona, core, core2, corei7, l1om, k1om,
iamcu, k6, k6_2, athlon, opteron, k8, amdfam10,
bdver1, bdver2, bdver3, bdver4, znver1, btver1,
btver2
EXTENSION is combination of:
8087, 287, 387, no87, mmx, nommx, sse, sse2, sse3,
(etc.)
看起来帮助文本不适用于 IA16,因为它不包含 16 位 CPU(但包含 32/64 位 CPU),并且扩展也不起作用,我已尝试使用 -march=i8086,8087:
ia16-elf-g++: error: unrecognized command line option '-march=i8086,8087
其他选项,如 -mhard-float 也不起作用。
ia16-elf-g++: error: unrecognized command line option '-mhard-float'
我的问题是:如何为这个编译器设置 8086 + 8087 目标?如果不支持,是否有任何其他 C/C++ 编译器可以生成带有 FPU 代码的 MS-DOS .com 输出(在 Linux 或 MacOS 平台上)?
【问题讨论】:
-
我对 DOS 时代 FPU 仿真的回忆是,当软件例程被调用时,它会检查是否安装了 8087 协处理器,如果安装了,它会将调用站点修补为原生 8087 操作码.然后它会返回到修补过的操作码来完成工作(当然,该代码的任何后续执行甚至都不会调用软件例程)。我不知道 GCC FPU 仿真库是否做同样的事情,但它可能值得检查。
-
顺便说一句,我已经看到 OpenWacom 被用于在各种项目中编译 MS-DOS 可执行文件;它可能不像 gcc 那样更新和符合标准,但 Wacom 一直是 DOS 的生产强度编译器,而我认为 gcc 从来都不是。
-
@MichaelBurr:IIRC 所有的 x87 操作码都是用一个特殊的错位第一个字节发出的,它会捕获;然后,中断例程将检查协处理器是否可用,如果可用,它将修补操作码并恢复,否则它将在软件中进行计算。但是从这种链接器错误(直接在相关函数中而不是在某些支持库中),我认为 gcc 只是试图在软件中执行所有计算。
-
“8087”有多个版本,甚至不是完全的 IEEE 754。80{1,2,3}87 更加标准化。不幸的是,ia16-elf 工具链似乎只支持 387,它是 287 的严格超集(添加
FP{,A}TAN更宽的边界,SIN和COS)。
标签: c gcc cross-compiling x86-16 fpu