16.8.5 机器特定的约束
只要可能,就应该在asm参数中使用通用目的的约束字母, 因为它们可以向阅读你的代码的人们传达更加可读的意思。如果无法做到, 则使用在不同体系结构中通常具有非常相似的意思的约束字母。 最通用的约束为‘m’和‘r’(分别用于内存和通用寄存器; 参见Simple Constraints, 以及‘I’,通常用于指示最常见的立即数常量格式。
每个体系结构定义了额外的约束。这些约束被编译器本身使用,用于指令生成, 同时也用于asm语句;因此,一些约束对于asm并不是很有用处。 这里有一个总结,关于在一些特定机器上使用的机器相关的约束; 包括对asm有用处的和没有用处的。 在表中提到的针对每个体系结构的编译器原文件,是该体系结构的约束的定义参考。
- ARM family—config/arm/arm.h
-
f- 浮点寄存器
w- VFP浮点寄存器
F- 浮点常量0.0, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0或者10.0
G- 浮点常量,其负数满足约束‘F’
I- 可以在数据处理指令中作为立即数的整数。即,0到255范围的整数,被2的倍数进行旋转
J- 范围在−4095到4095的整数
K- 当倒置后,满足约束‘I’的整数
L- 当求负后,满足约束‘I’的整数
M- 范围在0到32的整数
Q- 一个内存引用,其确切的地址在单个寄存器中(`‘m’'可以用于
asm语句)
R- 在常量池中的项
S- 在当前文件中text段中的符号
Uv- 适于VFP加载/存储insn(寄存器+常量 偏移量)的内存引用
Uy- 适于iWMMXt加载/存储指令的内存引用
Uq- 适于ARMv4 ldrsb指令的内存引用
- AVR family—config/avr/constraints.md
-
l- 寄存器r0到r15
a- 寄存器r16到r23
d- 寄存器r16到r31
w- 寄存器r24到r31。这些寄存器可以用于‘adiw’命令
e- 指针寄存器(r26–r31)
b- 基指针寄存器(r28–r31)
q- 栈指针寄存器(SPH:SPL)
t- 临时寄存器r0
x- 寄存器对X (r27:r26)
y- 寄存器对Y (r29:r28)
z- 寄存器对Z (r31:r30)
I- 常量,大于−1,小于64
J- 常量,大于−64,小于1
K- 常量整数2
L- 常量整数0
M- 8位的常量
N- 常量整数−1
O- 常量整数8,16或24
P- 常量整数1
G- 浮点常量0.0
R- 整数常量,范围在-6 ... 5
Q- 一个内存地址,基于Y或者Z指针,加上一个位移
- CRX Architecture—config/crx/crx.h
-
b- 寄存器从r0到r14(不含栈指针)
l- 寄存器r16(64位累加器lo寄存器)
h- 寄存器r17(64位累加器hi寄存器)
k- 寄存器对r16-r17(64位累加器lo-hi寄存器对)
I- 3位的常量
J- 4位的常量
K- 5位的常量
L- 常量-1, 4, -4, 7, 8, 12, 16, 20, 32, 48
G- 浮点常量,合法的可以用于存储的立即数。
- Hewlett-Packard PA-RISC—config/pa/pa.h
-
a- 通用寄存器1
f- 浮点寄存器
q- 移位数量寄存器
x- 浮点寄存器(不推荐的)
y- 高位部分浮点寄存器(32位),浮点寄存器(64位)
Z- 任何寄存器
I- 有符号的11位整数常量
J- 有符号的14位整数常量
K- 可以使用指令
zdepi存放的整数常量
L- 有符号的5位整数常量
M- 整数常量0
N- 可以使用
ldil指令加载的整数常量
O- 整数常量,其值加上1便为2的幂
P- 可以用于在
depi和extru指令中and运算的整数常量
S- 整数常量31
U- 整数常量63
G- 浮点常量0.0
A- 一个
lo_sum data-linkage-table内存操作数
Q- 可以用作整数存储指令的目的操作数的内存操作数
R- 缩放或者未缩放的索引内存操作数
T- 浮点加载和存储的内存操作数
W- 寄存器间接内存操作数
- picoChip family—picochip.h
-
k- 栈寄存器
f- 指针寄存器。可以用于访问内存,无需提供偏移量。任何其它寄存器可以用于访问内存,但需要一个常量偏移量。当偏移量为零的时候,使用指针寄存器会更有效,因为这将减少代码大小。
t- 成对寄存器。相邻的两个寄存器,用来创建一个32位寄存器。
a- 任何绝对内存地址(例如,符号常量,符号常量+偏移量)
I- 4位有符号整数
J- 4位无符号整数
K- 8位有符号整数
M- 任何绝对值不大于4位的常量
N- 10位有符号整数
O- 16位有符号整数
- PowerPC and IBM RS6000—config/rs6000/rs6000.h
-
b- 基址寄存器
f- 浮点寄存器
v- 向量寄存器
h- ‘MQ’, ‘CTR’或者‘LINK’寄存器
q- ‘MQ’寄存器
c- ‘CTR’寄存器
l- ‘LINK’寄存器
x- ‘CR’寄存器(条件寄存器)编号0
y- ‘CR’寄存器(条件寄存器)
z- ‘FPMEM’栈内存,用于FPR-GPR传送
I- 有符号16位常量
J- 无符号16位常量,向左移16位(使用‘L’来替代常量)
K- 无符号16位常量
L- 有符号16位常量,向左移16位
M- 大于31的常量
N- 2的幂
O- 零
P- 常量,其负数为有符号的16位常量
G- 浮点常量,可以使用一个字的指令将其加载到寄存器中
H- 整数/浮点常量,可以使用三条指令将其加载到寄存器中
Q- 内存操作数,相对于寄存器的偏移量(‘m’适用于
asm语句)
Z- 内存操作数,来自寄存器的一个索引或者间接访问(‘m’适用于
asm语句)
R- AIX TOC项
a- 地址操作数,来自寄存器的一个索引或者间接访问(‘p’适用于
asm语句)
S- 适于作64位掩码操作数的常量
T- 适于作32位掩码操作数的常量
U- System V Release 4对小数据区域的引用
t- AND掩码,可以通过两条rldic{l, r}指令执行
W- 不需要内存的向量常量
- Intel 386—config/i386/constraints.md
-
R- 遗留的寄存—八个在所有i386处理上都可用的寄存器(
a, b, c, d,
si, di, bp, sp)。
q- 任何可以作为r
l访问的寄存器。在32位机器模式中,为a, b, c和d; 在64位机器模式中,为任何整数寄存器。
Q- 任何可以作为r
h来访问的寄存器:a, b, c和d。
l- 任何在基址+索引的内存访问中,可以作为索引的寄存器:即除了栈指针以外的任何通用寄存器。
a- 寄存器
a
b- 寄存器
b
c- 寄存器
c
d- 寄存器
d
S- 寄存器
si
D- 寄存器
di
A- 寄存器
a和d,作为一对(用于在一个寄存器中返回结果的一半,另一个寄存器中返回另一半的指令)
f- 任何80387浮点(栈)寄存器
t- 80387浮点栈顶(
%st(0))
u- 从80387浮点栈顶起始的第二项(
%st(1))
y- 任何MMX寄存器
x- 任何SSE寄存器
Yz- 第一个SSE寄存器(
%xmm0)
Y2- 任何SSE寄存器,当SSE2被启用
Yi- 任何SSE寄存器,当SSE2和inter-unit move被启用
Ym- 任何MMX寄存器,当inter-unit move被启用
I- 整数常量,范围在0 ... 31,用于32位移位
J- 整数常量,范围在0 ... 63,用于64位移位
K- 有符号8位整数常量
L0xFF或者0xFFFF,用于andsi,作为零扩展move
M- 0, 1, 2, 或者 3 (用于
lea指令的移位)
N- 无符号8位整数常量(用于
in和out指令)
O- 整数常量,范围在0 ... 127,用于64位移位
G- 标准的80387浮点常量
C- 标准的SSE浮点常量
e- 32位有符号整数常量,或者已知适合该范围的符号引用(用于有符号扩展x86-64指令的立即数)
Z- 32位无符号整数常量,或者已知适合该范围的符号引用(用于零扩展x86-64指令的立即数)
- Intel IA-64—config/ia64/ia64.h
-
a- 通用寄存器
r0到r3,用于addl指令
b- 分支寄存器
c- 断言寄存器(‘c’ as in “conditional”)
d- 在M-unit中的应用寄存器
e- 在I-unit中的应用寄存器
f- 浮点寄存器
m- 内存操作数,记住在IA-64上,‘m’允许使用‘%Pn’打印的后增和后减方式。使用‘S’来禁止后增和后减。
G- 浮点常量0.0或者1.0
I- 14位有符号整数常量
J- 22位有符号整数常量
K- 8位有符号整数常量,用于逻辑指令
L- 8位被调整的有符号整数常量,用于比较伪操作
M- 6位无符号整数常量,用于移位计数
N- 9位有符号整数常量,用于后增方式的加载和存储
O- 常量零
P- 0 或者 −1,用于
dep指令
Q- 非volatile内存,用于浮点加载和存储
R- 整数常量范围在1到4,用于
shladd指令
S- 除了后增和后减以外的内存操作数
- FRV—config/frv/frv.h
-
a- 类别
ACC_REGS中的寄存器(acc0 到 acc7).
b- 类别
EVEN_ACC_REGS中的寄存器(acc0 到 acc7).
c- 类别
CC_REGS中的寄存器(fcc0 到 fcc3 以及 icc0 到 icc3).
d- 类别
GPR_REGS中的寄存器(gr0 到 gr63).
e- 类别
EVEN_REGS中的寄存器(gr0 到 gr63)。奇数寄存器不在该类中,但是可以使用大于4个字节的机器模式来使用。
f- 类别
FPR_REGS中的寄存器(fr0 到 fr63).
h- 类别
FEVEN_REGS中的寄存器(fr0 到 fr63)。奇数寄存器不在该类中,但是可以使用大于4个字节的机器模式来使用。
l- 类比
LR_REG中的寄存器(lr寄存器)。
q- 类别
QUAD_REGS中的寄存器(gr2 到 gr63)。无法被4整除的寄存器编号不在该类中,但是可以使用大于8个字节的机器模式来使用。
t- 类别
ICC_REGS中的寄存器(icc0 到 icc3).
u- 类别
FCC_REGS中的寄存器(fcc0 到 fcc3).
v- 类别
ICR_REGS中的寄存器(cc4 到 cc7).
w- 类别
FCR_REGS中的寄存器(cc0 到 cc3).
x- 类别
QUAD_FPR_REGS中的寄存器(fr0 到 fr63)。无法被4整除的寄存器编号不在该类中,但是可以使用大于8个字节的机器模式来使用。
z- 类别
SPR_REGS中的寄存器(lcr 和 lr).
A- 类别
QUAD_ACC_REGS中的寄存器(acc0 到 acc7).
B- 类别
ACCG_REGS中的寄存器(accg0 到 accg7).
C- 类别
CR_REGS中的寄存器(cc0 到 cc7).
G- 浮点常量零
I- 6位有符号整数常量
J- 10位有符号整数常量
L- 16位有符号整数常量
M- 16位无符号整数常量
N- 12位有符号整数常量,且为负—即,范围在−2048 到 −1
O- 常量零
P- 12有符号整数常量,且大于零—即,范围在1到2047
- Blackfin family—config/bfin/constraints.md
-
a- P寄存器
d- D寄存器
z- 被函数调用破坏的P寄存器
qn- 单个寄存器。如果n在范围0到7中,则对应D寄存器。如果为
A,则是寄存器P0。
D- 偶数编号的D寄存器
W- 奇数编号的D寄存器
e- 累加寄存器
A- 偶数编号的累加寄存器
B- 奇数编号的累加寄存器
b- I寄存器
v- B寄存器
f- M寄存器
c- 用于循环缓冲的寄存器,即I, B或者L寄存器。
C- CC寄存器
t- LT0或者LT1.
k- LC0或者LC1.
u- LB0或者LB1.
x- 任何D, P, B, M, I 或者L寄存器。
y- 通常只用于函数序言和尾声的额外寄存器:RETS, RETN, RETI, RETX, RETE, ASTAT, SEQSTAT 和 USP。
w- 除了累加器和CC以外的任何寄存器。
Ksh- 有符号16位整数(范围在-32768到32767)
Kuh- 无符号16位整数(范围在0到65535)
Ks7- 有符号7位整数(范围在-64 到 63)
Ku7- 无符号7位整数(范围在0到127)
Ku5- 无符号5位整数(范围在0到31)
Ks4- 有符号4位整数(范围在-8到7)
Ks3- 有符号3位整数(范围在-3到4)
Ku3- 无符号3位整数(范围在0到7)
Pn- 常量n,为一单个数字的常量,范围在0到4。
PA- 一个整数,等于MACFLAG_XXX常量中的一个,适合用于每个累加器。
PB- 一个整数,等于MACFLAG_XXX常量中的一个,只适合用于累加器A1。
M1- 常量255
M2- 常量65535
J- 整数常量,只有一个位被设置。
L- 整数常量,只有一个位没有被设置。
H
Q- 任何SYMBOL_REF
- MIPS—config/mips/constraints.md
-
d- 地址寄存器。与
r等价,只不过是生成MIPS16代码
f- 浮点寄存器(如果可用)
h- 之前为
hi寄存器。该约束不再被支持。
llo寄存器。使用该寄存器来存放不大于一个字的值。
xhi 和 lo寄存器的结合。使用该寄存器来存放双字的值。
c- 适用于间接跳转的寄存器。对于-mabicalls,其将总是为
$25。
v- 寄存器
$3。不要在新的代码中使用该约束;保留它只是为了与glibc兼容。
y- 等价于
r; 保留它是为了向后兼容。
z- 浮点条件代码寄存器
I- 有符号16位常量(用于算术指令)
J- 整数零
K- 无符号16位常量(用于逻辑指令)
L- 有符号32位常量,其中低16位为零。这样的常量可以使用
lui来加载。
M- 不可以使用
lui, addiu或ori加载的常量。
N- 常量,范围在-65535 到 -1 (含)。
O- 有符号15位常量
P- 常量,范围在1到65535 (含)
G- 浮点零
R- 可以用于非宏的加载和存储中的地址。
- Motorola 680x0—config/m68k/constraints.md
-
a- 地址寄存器
d- 数据寄存器
f- 68881浮点寄存器,如果可用
I- 整数,范围在1到8
J- 16位有符号数字
K- 有符号数字,大于0x80
L- 整数,范围在−8 到 −1
M- 有符号数字,大于0x100
N- 范围在24到31,rotatert:SI 8 到 1,表示为rotate
O- 16 (使用swap的rotate)
P- 范围在8到15,rotatert:HI 8 到 1,表示为rotate
R- mov3q可以处理的数字
G- 浮点常量,且不是68881常量
S- 操作数,当-mpcrel有效时,满足'm'
T- 操作数,当-mpcrel无效时,满足's'
Q- 地址寄存器,简介寻址模式
U- 寄存器偏移寻址
W- const_call_operand
Cs- symbol_ref 或 const
Ci- const_int
C0- const_int 0
Cj- 不适合16位的有符号数的范围不适合16位
Cmvq- 用于mvq的整数
Capsw- 整数,用于moveq后面跟一个swap
Cmvz- 用于mvz的整数
Cmvs- 用于mvs的整数
Ap- push_operand
Ac- 允许在clr中使用的非寄存器操作数
- Motorola 68HC11 & 68HC12 families—config/m68hc11/m68hc11.h
-
a- 寄存器`a'
b- 寄存器`b'
d- 寄存器`d'
q- 8位寄存器
t- 临时软寄存器_.tmp
u- 软寄存器_.d1 到 _.d31
w- 栈指针寄存器
x- 寄存器`x'
y- 寄存器`y'
z- 伪寄存器`z' (在后来被`x' 或 `y'替换)
A- 地址寄存器:x, y 或 z
B- 地址寄存器:x 或 y
D- 寄存器(x:d),形成一个32位的值
L- 常量,范围在−65536 到 65535
M- 常量,低16位为零
N- 常整数1 或 −1
O- 常整数16
P- 常量,范围在−8 到 2
- SPARC—config/sparc/sparc.h
-
f- SPARC-V8体系结构上的浮点寄存器,以及SPARC-V9体系结构上的低浮点寄存器。
e- 浮点寄存器。在SPARC-V8体系结构上等价于‘f’,在SPARC-V9体系结构上包含低位和高位的浮点寄存器。
c- 浮点条件代码寄存器。
d- 低位浮点寄存器。只用于SPARC-V9体系结构上,当虚拟指令集可用的时候。
b- 浮点寄存器。只用于SPARC-V9体系结构上,当虚拟指令集可用的时候。
h- 64位global或out寄存器,用于SPARC-V8+体系结构。
D- 向量常量
I- 有符号13位常量
J- 零
K- 32位常量,低12位被清零(可以使用
sethi指令加载的常量)
Lmovcc指令所支持的范围内的常量
Mmovrcc指令所支持的范围内的常量
N- 与‘K’相同,只不过,其会验证不在低32位范围的位全是零。对于机器模式宽于
SImode的,比需使用其,而不是‘K’
O- 常量4096
G- 浮点零
H- 有符号13位常量,符号扩展到32或64位
Q- 浮点常量,其整数表示可以使用单个sethi指令,被移送到整数寄存器中。
R- 浮点常量,其整数表示可以使用单个mov指令,被移送到整数寄存器中。
S- 浮点常量,其整数表示可以使用一个high/lo_sum指令序列,被移送到整数寄存器中。
T- 内存地址,对齐到8字节的边界
U- 偶数寄存器
W- 内存地址,用于‘e’约束寄存器
Y- 向量零
- SPU—config/spu/spu.h
-
a- 立即数,可以使用il/ila/ilh/ilhu指令加载。const_int被当作64位值。
c- 立即数,用于and/xor/or指令。const_int被当作64位值。
d- 立即数,用于
iohl指令。const_int被当作64位值。
f- 立即数,可以使用
fsmbi指令加载。
A- 立即数,可以使用il/ila/ilh/ilhu指令加载。const_int被当作32位值。
B- 立即数,用于大多算术指令。const_int被当作32位值。
C- 立即数,用于and/xor/or指令。const_int被当作32位值。
D- 立即数,用于
iohl指令。const_int被当作32位值。
I- 常量,范围为[-64, 63],用于shift/rotate指令。
J- 无符号7位常量,用于conversion/nop/channel指令。
K- 有符号10位常量,用于大多算术指令。
M- 有符号16位立即数,用于
stop。
N- 无符号16位常量,用于
iohl和fsmbi。
O- 无符号7位常量,其3个最小有效位是0。
P- 无符号3位常量,用于16字节的rotate和shift。
R- 调用操作数,寄存器,用于间接调用。
S- 调用操作数,符号,用于相关调用。
T- 调用操作数,const_int,用于绝对调用。
U- 立即数,可以使用il/ila/ilh/ilhu指令加载。const_int被扩展为128位。
W- 立即数,用于shift和rotate指令。const_int被当作32位值。
Y- 立即数,用于and/xor/or指令。const_int被有符号扩展为128位。
Z- 立即数,用于
iohl指令。const_int被有符号扩展为128位。
- S/390 and zSeries—config/s390/s390.h
-
a- 地址寄存器(通用目的寄存器,除了r0)
c- 条件代码寄存器
d- 数据寄存器(任意通用寄存器)
f- 浮点寄存器
I- 无符号8位常量(0–255)
J- 无符号12位常量(0–4095)
K- 有符号16位常量(−32768–32767)
L- 适合作偏移量的值
(0..4095)- 短偏移
(-524288..524287)- 长偏移
M- 常量整数,值为0x7fffffff
N- 多个字母约束,跟随4个参数字母
0..9:- 部分的编号,从最大有效到最小有效计数
H,Q:- 部分的机器模式
D,S,H:- 包含的操作数的机器模式
0,F:- 其它部分的值(F—所有位都被设置)
如果常量所指定的部分具有与其它部分不同的值,则约束匹配
Q- 没有索引寄存器,但是有短偏移的内存引用
R- 具有索引寄存器和短偏移的内存引用
S- 没有索引寄存器,但是有长偏移的内存引用
T- 具有索引寄存器和长偏移的内存引用
U- 具有短偏移的指针
W- 具有长偏移的指针
Y- 移位计数操作数
- Score family—config/score/score.h
-
d- 寄存器r0到r32
e- 寄存器r0到r16
t- r8—r11 或 r22—r27 寄存器
h- hi寄存器
l- lo寄存器
x- hi + lo 寄存器
q- cnt寄存器
y- lcb寄存器
z- scb寄存器
a- cnt + lcb + scb寄存器
c- cr0—cr15寄存器
b- cp1寄存器
f- cp2寄存器
i- cp3寄存器
j- cp1 + cp2 + cp3寄存器
I- 高16位常量(32位常量,16位最小有效位为零)
J- 无符号5位整数(范围从0到31)
K- 无符号16位整数(范围从0到65535)
L- 有符号16位整数(范围从−32768到32767)
M- 无符号14位整数(范围从0到16383)
N- 有符号14位整数(范围从−8192到8191)
Z- 任何SYMBOL_REF
- Xstormy16—config/stormy16/stormy16.h
-
a- 寄存器r0
b- 寄存器r1
c- 寄存器r2
d- 寄存器r8
e- 寄存器r0到r7
t- 寄存器r0和r1
y- 进位寄存器
z- 寄存器r8和r9
I- 常量,在0和3之间
J- 常量,只有一位被设置
K- 常量,只有一位被清零
L- 常量,在0和255之间
M- 常量,在−255和0之间
N- 常量,在−3和0之间
O- 常量,在1和4之间
P- 常量,在−4和−1之间
Q- 内存引用,为一个栈压入
R- 内存引用,为一个栈弹出
S- 内存引用,表示一个已知的常量地址
T- 通过Rx指示的寄存器(还没实现)
U- 不在2和15之间的常量
Z- 常量0
- Xtensa—config/xtensa/constraints.md
-
a- 通用32位寄存器
b- 一位布尔寄存器
A- MAC16 40位累加器
I- 有符号12位整数常量,用在MOVI指令中
J- 有符号8位整数常量,用在ADDI指令中
K- 整数常量,用于BccI指令
L- 无符号常量,用于BccUI指令