Oracle Solaris Studio 12.4 Man Pages

Exit Print View

Updated: January 2015
 
 

filename.il(4)

Name

inline , filename.il - 汇编语言内联模板文件

Description

汇编语言调用指令会替换为从内联模板 (*.il) 文件获得的相应函数主体的副本。

内联模板文件带有后缀 .il,例如:

% CC foo.il hello.c

内联由编译器的代码生成器完成。

Usage

每个 inlinefile 包含一个或多个有标签的汇编语言模板,其格式为:

 
inline-directive
instructions
...
.end

其中 instructions 构成指定例程的内联扩展。inline-directive 是以下格式的命令:

.inline   identifier, argsize

此命令为由 identifier 指定的例程声明代码块,其中 argsize 作为例程参数的总大小(以字节数表示)。忽略 argsize 的值。

对指定例程的调用会替换为内联模板中的代码。

注意:argsize 的值会被忽略,但会包括该参数以便与旧的编译器版本兼容。

允许使用多个模板;将忽略第一个后面的匹配模板。

编译器可以更改内联模板的主体对其进行优化。模板文件中的指令 .volatile 可禁止此类优化。

编码约定

内联模板应该编码为 C 兼容过程调用的扩展,不同之处在于,无法依靠返回地址在预期位置,因为尚未执行任何调用指令。

内联模板必须遵守标准的 Oracle Solaris Studio 参数传递和寄存器使用约定,如下详述。它们不得调用违反这些约定的例程;例如,setjmp(3c) 等汇编语言例程可能会引起问题。

不得使用或设置除下方提及的寄存器之外的寄存器。

只能将内联模板中的分支指令传输给在内联模板中定义的数字标签(1f2b 等)。不允许其他任何控制传输。

模板不需要返回指令,并且不应包含指令。

只保证由 Oracle Solaris Studio 编译器生成的操作代码和寻址模式起作用。允许对指令进行二进制编码,但结果代码的正确性取决于内联模板其余部分的正确性。二进制编码还会禁止编译器对模板进行任何优化。

SPARC 系统的编码约定

在 SPARC 上,C 函数的参数在传递时就像它们在参数数组中一样。数组元素称为“槽位”(slot)。槽位从零开始计数。对于 32 位代码,数组具有 32 位元素(槽位);对于 64 位代码,数组具有 64 位元素(槽位)。例程的连续参数在参数数组中的连续槽位中传递。

对于 32 位代码,参数数组始于 %fp+68,堆栈和帧指针在 64 位(8 字节)边界上对齐。对于 64 位代码,参数数组始于 %fp+BIAS+128,堆栈和帧指针在 128 位(16 字节)边界上对齐。在寄存器中传递的参数也有对应于其槽位的(未使用的)内存位置。

大于槽位大小的数据类型在多个槽位中传递。对于 32 位代码,double 和 long long 在 2 个槽位中传递,并且它们不对齐,但打包到上一个参数槽位旁边。对于 64 位代码,double 和 long long 只占据一个槽位,但 long double 和 double complex 占据两个槽位,并且这些槽位对齐 (slot # % 2 == 0),在必要时会跳过一个槽位进行对齐。

参数数组的前六个槽位在寄存器中传递。对于 32 位代码,这些槽位始终进入到寄存器 %o0%o5 的较低 32 位中。

对于 64 位代码,这 6 个槽位进入到寄存器 %o0%o5 的完全 64 位中(如果它们是整数类型)。Float、double、long double 类型在 double 寄存器 %d0%d10 中传递,这些寄存器对应于槽位 0 到 5。Float complex、double complex 和 long double complex 类型在传递时就像它们只是其基本类型的两个参数一样。Imaginary 类型传递的方式与普通 float 类型相同。对于 64 位代码,槽位 6-31 中的 float、double 和 long double 在寄存器 %d12%d62 中传递。通过值传递的结构和联合较为复杂,不建议用于内联模板。

返回整数值的函数在 %o0 或者 %o0%o1 中返回值。对于 32 位代码,long long 返回时,上 32 位在 %o0 中,下 32 位在 %o1 中。

返回浮点或复杂值的函数在 %f0%f1%d0%d2%d4%d6 的某个子集中返回值。

寄存器 %o0-%o5%f0-%f31 可能会用作临时寄存器。

整数和单精度浮点参数 32 位对齐。

如果双精度浮点参数的偏移量是 8 的倍数,则保证 64 位对齐。

每个控制传输指令(分支和调用)后面必须紧跟 nop。

调用指令必须包括一个额外(最终)参数,它表示用于将参数传递给所调用例程的寄存器数量。

请注意,对于 SPARC 系统,将删除扩展“调用”后面的指令。

s86/x64 平台说明

-xarch 设置为 ssesse2、sse2asse3 以及更高级别的情况下编译的程序必须仅在提供这些扩展和功能的平台上运行。

此警告还会扩展到采用 .il 内联汇编语言函数或 __asm() 汇编程序代码(使用扩展功能)的程序。

如果在不同的步骤中进行编译和链接,请始终使用编译器和相同的 -xarch 设置进行链接,以确保链接正确的启动例程。

32 位 x86 系统的编码约定

参数在堆栈上传递。由于未发出任何调用指令,因此第一个参数位于 (%esp),第二个参数位于 4 (%esp) 等等。32 位或更小的整数结果在 %eax 中返回,64 位整数结果在 %edx:%eax 中返回。浮点结果在 %st(0) 中返回。

代码可能会使用寄存器 %eax%ecx%edx。其他任何寄存器中的值都必须保留。浮点堆栈在内联扩展模板开头处为空,并且在结尾处也必须为空(返回的浮点值除外)。

x64 平台的编码约定

参数根据其分类传递。分类包括整数、sse 和内存参数。

_Bool、char、short、int、long、long long 和 pointer 类型(带符号和无符号)的参数是整数参数。大小小于或等于 16 字节且包含 _Bool、char、short、int、long、long long 和 pointer 类型对齐成员的聚合类型(结构、联合、数组)的参数也是整数参数。

float 和 double 类型的参数是 sse 参数。大小小于或等于 16 字节且包含 float 和 double 类型对齐成员的聚合类型的参数也是 sse 参数。

long double 类型的参数和大小大于 16 字节或包含未对齐成员的聚合类型的参数是内存参数。

整数参数在整数寄存器中由下一个序列传递:%rdi、%rsi、%rdx、%rcx、%r8 和 %r9。一个聚合类型的整数参数最多可容纳 2 个整数寄存器。如果整数参数的数量大于 6 个,则将第 7 个以及后续整数参数视为内存参数。

Sse 参数在 sse 寄存器中按从 %xmm0 到 %xmm7 的顺序传递。一个聚合类型的 sse 参数最多可容纳 2 个 sse 寄存器,每个 sse 寄存器最多可容纳 8 字节的参数。例如,double complex 类型的参数在 2 个后续 sse 寄存器中传递,float complex 类型的参数在 1 个 sse 寄存器中传递。如果 sse 参数的数量大于 8 个,则将第 9 个以及后续 sse 参数视为内存参数。

整数参数和 sse 参数独立编号。

内存参数在堆栈上按在函数参数列表中从右向左的显示顺序传递。堆栈上的每个参数都根据其大小对齐,如果大小小于或等于 8,则在 8 处对齐;否则,如果在内联扩展模板堆栈开头,则在 16 处对齐。

由于未发出任何调用指令,因此第一个内存参数位于 (%rsp),第二个内存参数位于 8(%rsp) 或位于 16(%rsp),具体取决于第一个内存参数的大小和第二个内存参数的对齐方式等等。

返回值分类的方式与参数相同。

8 字节或更小的整数结果在 %rax 中返回,9 到 16 字节的整数结果在 %rdx:%rax 中返回。

Sse 结果也根据其大小在 %xmm0 或 %xmm1:%xmm0 中返回。

long double 类型的结果在 %st(0) 中返回。

如果返回值的类型是 long double complex,则值的实部在 %st0 中返回,虚部在 %st1 中返回。

对于内存结果,调用方会为返回值提供空间,并在 %rdi 中传递此存储的地址,如同这是函数的第一个参数。实际上,此地址将成为隐藏的首参数。返回时,%rax 将包含调用方已在 %rdi 中传入的地址。

代码无法更改寄存器 %rbp。浮点堆栈在内联扩展模板开头处为空,并且在结尾处也必须为空(返回的浮点值除外)。

除 %rbp 之外,寄存器 %rbx 和 %r12-%r15 中的值必须在内联的代码中保留。

Examples

有关示例,请参见 libm.ilvis.il。您可以在编译器的 lib/ 目录下找到特定于支持的每个体系结构的这些库的一个版本。

See also

由 Darryl Gove 编著的《Solaris Application Programming》,(Prentice-Hall 2008 ISBN:0138134553)

SPARC International Inc. 提供的《The SPARC Architecture Manual Version 9》。http://www.sparc.org/specificationsDocuments.html