注册使用和约定
PowerPC® 32 位体系结构具有 32 个 GPRS 和 32 个 FPR。
PowerPC® 32 位体系结构具有 32 个 GPRS 和 32 个 FPR。 每个 GPR 为 32 位宽,每个 FPR 为 64 位宽。 另外,还存在用于分支,异常处理和其他目的的专用寄存器。 "通用注册公约" 表显示了如何使用 GPR。
| 寄存器 | 状态 | 使用 |
|---|---|---|
| GPR0 | volatile | 在函数 prolog 中。 |
| GPR1 | 专用 | 堆栈指针。 |
| GPR2 | 专用 | "目录" (TOC) 指针。 |
| GPR3 | volatile | 函数的自变量列表的第一个词; 标量函数的第一个词返回。 |
| GPR4 | volatile | 函数的自变量列表的第二个词; 标量函数的第二个词返回。 |
| GPR5 | volatile | 函数的自变量列表的第三个词。 |
| GPR6 | volatile | 函数的自变量列表的第四个词。 |
| GPR7 | volatile | 函数的参数列表的第五个字。 |
| GPR8 | volatile | 函数的自变量列表的第六个词。 |
| GPR9 | volatile | 函数的自变量列表的第七个单词。 |
| GPR10 | volatile | 函数的自变量列表的第八个单词。 |
| GPR11 | volatile | 在指针调用中,作为需要它的语言 (例如, PACAL) 的环境指针。 |
| GPR12 | volatile | 对于某些语言和 格连克 代码所需要的特殊异常处理。 |
| GPR13 | 保留的 | 在 64 位环境下保留; 未在系统调用之间复原。 |
| GPR14:GPR31 | 非易失性 | 必须在函数调用中保留这些寄存器。 |
使用 GPR 的首选方法是先使用易失性寄存器。 接下来,从 GPR31开始,按降序使用非易失性寄存器。 GPR1 和 GPR2 必须分别作为堆栈和目录 (TOC) 区域指针来专用。 GPR1 和 GPR2 必须显示为通过调用进行保存,并且在返回时必须具有与进行调用时相同的值。
易失性寄存器 (Volatile register) 是临时寄存器,被认为是在呼叫过程中被破坏的,因此不会被被被呼叫方保存。 易失性寄存器也用于特定用途,如上表中所示。 如果更改了非易失性寄存器和专用寄存器,那么它们需要保存和恢复,从而保证在函数调用中保留它们的值。
"浮点寄存器约定" 表显示了如何使用 FPR。
| 寄存器 | 状态 | 使用 |
|---|---|---|
| FPR0 | volatile | 作为临时寄存器。 |
| FPR1 | volatile | 第一个浮点参数; 浮点标量返回的前 8 个字节。 |
| FPR2 | volatile | 第二个浮点参数; 浮点标量 8 的第二个 8 字节。 |
| FPR3 | volatile | 第三个浮点参数; 浮点标量返回的第三个 8 字节。 |
| FPR4 | volatile | 第四个浮点参数; 浮点标量返回的第四个 8 字节。 |
| FPR5 | volatile | 第五个浮点参数。 |
| FPR6 | volatile | 第六个浮点参数。 |
| FPR7 | volatile | 第七个浮点参数。 |
| FPR8 | volatile | 第八个浮点参数。 |
| FPR9 | volatile | 第九个浮点参数。 |
| FPR10 | volatile | 第十个浮点参数。 |
| FPR11 | volatile | 第十一个浮点参数。 |
| FPR12 | volatile | 第十二个浮点参数。 |
| FPR13 | volatile | 第十三个浮点参数。 |
| FPR14:FPR31 | 非易失性 | 如果已修改,那么必须在整个调用中保留。 |
使用 FPR 的首选方法是首先使用易失性寄存器。 接下来,将按降序使用非易失性寄存器,从 FPR31 开始,向下继续到 FPR14。
在多个寄存器中仅返回黄牛。 所需要的寄存器数取决于标量的大小和类型。 对于浮点值,将出现以下结果:
- 128 位浮点值在 FPR1 中返回高阶 64 位,在 FPR2中返回低阶 64 位。
- 8 个字节或 16 个字节的复杂值将返回 FPR1 中的实部分,并返回 FPR2中的虚部分。
- 32 个字节的复杂值在 FPR1 和 FPR2中以 128 位浮点值形式返回实际部分,在 FPR1 中返回高阶 64 位,在 FPR2中返回低阶 64 位。 32 个字节的复数值的虚部分返回 FPR3 中的高位 64 位和 FPR4中的低位 64 位。
针对复杂类型调用约定的示例
complex double foo(complex double);
单精度复合体 (复杂浮点) 的传递方式与双精度的传递方式相同,并且值加宽为双精度。
在 fp1 和 fp2 中返回双精度和单精度复合体 (复杂双精度和复杂浮点) ,并将单精度值加宽到双精度。
十进制浮点类型的调用约定 (_Decimal128)
_Decimal64 参数在下一个可用 fpr 中传递,结果在 fp1中返回。
_Decimal32 参数在下一个可用 fpr 的下半部分中传递,结果在 fp1的下半部分返回,而不会转换为 _Decimal64。
与浮点型或双精度型不同,对于 DFP ,始终需要函数原型。 因此,不需要将 _Decimal32 拓宽到 _Decinmal64。
#include <float.h>
#define DFP_ROUND_HALF_UP 4
_Decimal32 Add_GST_and_Ontario_PST_d32 (_Decimal32 price)
{
_Decimal32 gst;
_Decimal32 pst;
_Decimal32 total;
long original_rounding_mode = __dfp_get_rounding_mode ( );
__dfp_set_rounding_mode (DFP_ROUND_HALF_UP);
gst = price * 0.06dd;
pst = price * 0.08dd;
total = price + gst + pst;
__dfp_set_rounding_mode (original_rounding_mode);
return (total);
}
| 000000 PDEF Add_GST_and_Ontario_PST_d32
>> 0| PROC price,fp1
0| 000000 stw 93E1FFFC 1 ST4A #stack(gr1,-4)=gr31
0| 000004 stw 93C1FFF8 1 ST4A #stack(gr1,-8)=gr30
0| 000008 stwu 9421FF80 1 ST4U gr1,#stack(gr1,-128)=gr1
0| 00000C lwz 83C20004 1 L4A gr30=.+CONSTANT_AREA(gr2,0)
0| 000010 addi 38A00050 1 LI gr5=80
0| 000014 ori 60A30000 1 LR gr3=gr5
>> 0| 000018 stfiwx 7C211FAE 1 STDFS price(gr1,gr3,0)=fp1
9| 00001C mffs FC00048E 1 LFFSCR fp0=fcr
9| 000020 stfd D8010058 1 STFL #MX_SET1(gr1,88)=fp0
9| 000024 lwz 80010058 1 L4A gr0=#MX_SET1(gr1,88)
9| 000028 rlwinm 5400077E 1 RN4 gr0=gr0,0,0x7
9| 00002C stw 9001004C 1 ST4A original_rounding_mode(gr1,76)=gr0
10| 000030 mtfsfi FF81410C 1 SETDRND fcr=4,fcr
11| 000034 ori 60A30000 1 LR gr3=gr5
11| 000038 lfiwax 7C011EAE 1 LDFS fp0=price(gr1,gr3,0)
11| 00003C dctdp EC000204 1 CVDSDL fp0=fp0,fcr
11| 000040 lfd C83E0000 1 LDFL fp1=+CONSTANT_AREA(gr30,0)
11| 000044 dmul EC000844 1 MDFL fp0=fp0,fp1,fcr
11| 000048 drsp EC000604 1 CVDLDS fp0=fp0,fcr
11| 00004C addi 38600040 1 LI gr3=64
11| 000050 ori 60640000 1 LR gr4=gr3
11| 000054 stfiwx 7C0127AE 1 STDFS gst(gr1,gr4,0)=fp0
12| 000058 ori 60A40000 1 LR gr4=gr5
12| 00005C lfiwax 7C0126AE 1 LDFS fp0=price(gr1,gr4,0)
12| 000060 dctdp EC000204 1 CVDSDL fp0=fp0,fcr
12| 000064 lfd C83E0008 1 LDFL fp1=+CONSTANT_AREA(gr30,8)
12| 000068 dmul EC000844 1 MDFL fp0=fp0,fp1,fcr
12| 00006C drsp EC000604 1 CVDLDS fp0=fp0,fcr
12| 000070 addi 38800044 1 LI gr4=68
12| 000074 ori 60860000 1 LR gr6=gr4
12| 000078 stfiwx 7C0137AE 1 STDFS pst(gr1,gr6,0)=fp0
13| 00007C lfiwax 7C012EAE 1 LDFS fp0=price(gr1,gr5,0)
13| 000080 lfiwax 7C211EAE 1 LDFS fp1=gst(gr1,gr3,0)
13| 000084 dctdp EC000204 1 CVDSDL fp0=fp0,fcr
13| 000088 dctdp EC200A04 1 CVDSDL fp1=fp1,fcr
13| 00008C mffs FC40048E 1 LFFSCR fp2=fcr
13| 000090 stfd D8410058 1 STFL #MX_SET1(gr1,88)=fp2
13| 000094 lwz 80010058 1 L4A gr0=#MX_SET1(gr1,88)
13| 000098 rlwinm 5400077E 1 RN4 gr0=gr0,0,0x7
13| 00009C mtfsfi FF81710C 1 SETDRND fcr=7,fcr
13| 0000A0 dadd EC000804 1 ADFL fp0=fp0,fp1,fcr
13| 0000A4 stw 90010058 1 ST4A #MX_SET1(gr1,88)=gr0
13| 0000A8 lfd C8210058 1 LFL fp1=#MX_SET1(gr1,88)
13| 0000AC mtfsf FC030D8E 1 LFSCR8 fsr,fcr=fp1,1,1
13| 0000B0 addi 38000007 1 LI gr0=7
13| 0000B4 addi 38600000 1 LI gr3=0
13| 0000B8 stw 90610068 1 ST4A #MX_CONVF1_0(gr1,104)=gr3
13| 0000BC stw 9001006C 1 ST4A #MX_CONVF1_0(gr1,108)=gr0
13| 0000C0 lfd C8210068 1 LDFL fp1=#MX_CONVF1_0(gr1,104)
13| 0000C4 drrnd EC010646 1 RRDFL fp0=fp0,fp1,3,fcr
13| 0000C8 drsp EC000604 1 CVDLDS fp0=fp0,fcr
13| 0000CC lfiwax 7C2126AE 1 LDFS fp1=pst(gr1,gr4,0)
13| 0000D0 dctdp EC000204 1 CVDSDL fp0=fp0,fcr
13| 0000D4 dctdp EC200A04 1 CVDSDL fp1=fp1,fcr
13| 0000D8 mffs FC40048E 1 LFFSCR fp2=fcr
13| 0000DC stfd D8410058 1 STFL #MX_SET1(gr1,88)=fp2
13| 0000E0 lwz 80810058 1 L4A gr4=#MX_SET1(gr1,88)
13| 0000E4 rlwinm 5484077E 1 RN4 gr4=gr4,0,0x7
13| 0000E8 mtfsfi FF81710C 1 SETDRND fcr=7,fcr
13| 0000EC dadd EC000804 1 ADFL fp0=fp0,fp1,fcr
13| 0000F0 stw 90810058 1 ST4A #MX_SET1(gr1,88)=gr4
13| 0000F4 lfd C8210058 1 LFL fp1=#MX_SET1(gr1,88)
13| 0000F8 mtfsf FC030D8E 1 LFSCR8 fsr,fcr=fp1,1,1
13| 0000FC stw 90610068 1 ST4A #MX_CONVF1_0(gr1,104)=gr3
13| 000100 stw 9001006C 1 ST4A #MX_CONVF1_0(gr1,108)=gr0
13| 000104 lfd C8210068 1 LDFL fp1=#MX_CONVF1_0(gr1,104)
13| 000108 drrnd EC010646 1 RRDFL fp0=fp0,fp1,3,fcr
13| 00010C drsp EC000604 1 CVDLDS fp0=fp0,fcr
13| 000110 addi 38600048 1 LI gr3=72
13| 000114 ori 60640000 1 LR gr4=gr3
13| 000118 stfiwx 7C0127AE 1 STDFS total(gr1,gr4,0)=fp0
14| 00011C lwz 8001004C 1 L4A gr0=original_rounding_mode(gr1,76)
14| 000120 stw 90010058 1 ST4A #MX_SET1(gr1,88)=gr0
14| 000124 lfd C8010058 1 LFL fp0=#MX_SET1(gr1,88)
14| 000128 mtfsf FC03058E 1 LFSCR8 fsr,fcr=fp0,1,1
>> 15| 00012C lfiwax 7C211EAE 1 LDFS fp1=total(gr1,gr3,0)
16| CL.1:
16| 000130 lwz 83C10078 1 L4A gr30=#stack(gr1,120)
16| 000134 addi 38210080 1 AI gr1=gr1,128
16| 000138 bclr 4E800020 1 BA lr
#include <float.h>
#define DFP_ROUND_HALF_UP 4
_Decimal64 Add_GST_and_Ontario_PST_d64 (_Decimal64 price)
{
_Decimal64 gst;
_Decimal64 pst;
_Decimal64 total;
long original_rounding_mode = __dfp_get_rounding_mode ( );
__dfp_set_rounding_mode (DFP_ROUND_HALF_UP);
gst = price * 0.06dd;
pst = price * 0.08dd;
total = price + gst + pst;
__dfp_set_rounding_mode (original_rounding_mode);
return (total);
}
| 000000 PDEF Add_GST_and_Ontario_PST_d64
>> 0| PROC price,fp1
0| 000000 stw 93E1FFFC 1 ST4A #stack(gr1,-4)=gr31
0| 000004 stw 93C1FFF8 1 ST4A #stack(gr1,-8)=gr30
0| 000008 stwu 9421FF80 1 ST4U gr1,#stack(gr1,-128)=gr1
0| 00000C lwz 83C20004 1 L4A gr30=.+CONSTANT_AREA(gr2,0)
>> 0| 000010 stfd D8210098 1 STDFL price(gr1,152)=fp1
9| 000014 mffs FC00048E 1 LFFSCR fp0=fcr
9| 000018 stfd D8010060 1 STFL #MX_SET1(gr1,96)=fp0
9| 00001C lwz 80010060 1 L4A gr0=#MX_SET1(gr1,96)
9| 000020 rlwinm 5400077E 1 RN4 gr0=gr0,0,0x7
9| 000024 stw 90010058 1 ST4A original_rounding_mode(gr1,88)=gr0
10| 000028 mtfsfi FF81410C 1 SETDRND fcr=4,fcr
11| 00002C lfd C8010098 1 LDFL fp0=price(gr1,152)
11| 000030 lfd C83E0000 1 LDFL fp1=+CONSTANT_AREA(gr30,0)
11| 000034 dmul EC000844 1 MDFL fp0=fp0,fp1,fcr
11| 000038 stfd D8010040 1 STDFL gst(gr1,64)=fp0
12| 00003C lfd C8010098 1 LDFL fp0=price(gr1,152)
12| 000040 lfd C83E0008 1 LDFL fp1=+CONSTANT_AREA(gr30,8)
12| 000044 dmul EC000844 1 MDFL fp0=fp0,fp1,fcr
12| 000048 stfd D8010048 1 STDFL pst(gr1,72)=fp0
13| 00004C lfd C8010098 1 LDFL fp0=price(gr1,152)
13| 000050 lfd C8210040 1 LDFL fp1=gst(gr1,64)
13| 000054 dadd EC000804 1 ADFL fp0=fp0,fp1,fcr
13| 000058 lfd C8210048 1 LDFL fp1=pst(gr1,72)
13| 00005C dadd EC000804 1 ADFL fp0=fp0,fp1,fcr
13| 000060 stfd D8010050 1 STDFL total(gr1,80)=fp0
14| 000064 lwz 80010058 1 L4A gr0=original_rounding_mode(gr1,88)
14| 000068 stw 90010060 1 ST4A #MX_SET1(gr1,96)=gr0
14| 00006C lfd C8010060 1 LFL fp0=#MX_SET1(gr1,96)
14| 000070 mtfsf FC03058E 1 LFSCR8 fsr,fcr=fp0,1,1
>> 15| 000074 lfd C8210050 1 LDFL fp1=total(gr1,80)
16| CL.1:
16| 000078 lwz 83C10078 1 L4A gr30=#stack(gr1,120)
16| 00007C addi 38210080 1 AI gr1=gr1,128
16| 000080 bclr 4E800020 1 BA lr
include <float.h>
#define DFP_ROUND_HALF_UP 4
_Decimal128 Add_GST_and_Ontario_PST_d128 (_Decimal128 price)
{
_Decimal128 gst;
_Decimal128 pst;
_Decimal128 total;
long original_rounding_mode = __dfp_get_rounding_mode ( );
__dfp_set_rounding_mode (DFP_ROUND_HALF_UP);
gst = price * 0.06dd;
pst = price * 0.08dd;
total = price + gst + pst;
__dfp_set_rounding_mode (original_rounding_mode);
return (total);
}
| 000000 PDEF Add_GST_and_Ontario_PST_d128
>> 0| PROC price,fp2,fp3
0| 000000 stw 93E1FFFC 1 ST4A #stack(gr1,-4)=gr31
0| 000004 stw 93C1FFF8 1 ST4A #stack(gr1,-8)=gr30
0| 000008 stwu 9421FF70 1 ST4U gr1,#stack(gr1,-144)=gr1
0| 00000C lwz 83C20004 1 L4A gr30=.+CONSTANT_AREA(gr2,0)
>> 0| 000010 stfd D84100A8 1 STDFL price(gr1,168)=fp2
>> 0| 000014 stfd D86100B0 1 STDFL price(gr1,176)=fp3
9| 000018 mffs FC00048E 1 LFFSCR fp0=fcr
9| 00001C stfd D8010078 1 STFL #MX_SET1(gr1,120)=fp0
9| 000020 lwz 80010078 1 L4A gr0=#MX_SET1(gr1,120)
9| 000024 rlwinm 5400077E 1 RN4 gr0=gr0,0,0x7
9| 000028 stw 90010070 1 ST4A original_rounding_mode(gr1,112)=gr0
10| 00002C mtfsfi FF81410C 1 SETDRND fcr=4,fcr
11| 000030 lfd C80100A8 1 LDFL fp0=price(gr1,168)
11| 000034 lfd C82100B0 1 LDFL fp1=price(gr1,176)
11| 000038 lfd C85E0000 1 LDFL fp2=+CONSTANT_AREA(gr30,0)
11| 00003C lfd C87E0008 1 LDFL fp3=+CONSTANT_AREA(gr30,8)
11| 000040 dmulq FC001044 1 MDFE fp0,fp1=fp0-fp3,fcr
11| 000044 stfdp F4010040 1 STDFE gst(gr1,64)=fp0,fp1
12| 000048 lfd C80100A8 1 LDFL fp0=price(gr1,168)
12| 00004C lfd C82100B0 1 LDFL fp1=price(gr1,176)
12| 000050 lfd C85E0010 1 LDFL fp2=+CONSTANT_AREA(gr30,16)
12| 000054 lfd C87E0018 1 LDFL fp3=+CONSTANT_AREA(gr30,24)
12| 000058 dmulq FC001044 1 MDFE fp0,fp1=fp0-fp3,fcr
12| 00005C stfdp F4010050 1 STDFE pst(gr1,80)=fp0,fp1
13| 000060 lfd C80100A8 1 LDFL fp0=price(gr1,168)
13| 000064 lfd C82100B0 1 LDFL fp1=price(gr1,176)
13| 000068 lfd C8410040 1 LDFL fp2=gst(gr1,64)
13| 00006C lfd C8610048 1 LDFL fp3=gst(gr1,72)
13| 000070 daddq FC001004 1 ADFE fp0,fp1=fp0-fp3,fcr
13| 000074 lfd C8410050 1 LDFL fp2=pst(gr1,80)
13| 000078 lfd C8610058 1 LDFL fp3=pst(gr1,88)
13| 00007C daddq FC001004 1 ADFE fp0,fp1=fp0-fp3,fcr
13| 000080 stfdp F4010060 1 STDFE total(gr1,96)=fp0,fp1
14| 000084 lwz 80010070 1 L4A gr0=original_rounding_mode(gr1,112)
14| 000088 stw 90010078 1 ST4A #MX_SET1(gr1,120)=gr0
14| 00008C lfd C8010078 1 LFL fp0=#MX_SET1(gr1,120)
14| 000090 mtfsf FC03058E 1 LFSCR8 fsr,fcr=fp0,1,1
>> 15| 000094 lfd C8410060 1 LDFL fp2=total(gr1,96)
>> 15| 000098 lfd C8610068 1 LDFL fp3=total(gr1,104)
16| CL.1:
16| 00009C lwz 83C10088 1 L4A gr30=#stack(gr1,136)
16| 0000A0 addi 38210090 1 AI gr1=gr1,144
16| 0000A4 bclr 4E800020 1 BA lr