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位整数常量
L
0xFF
或者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寄存器
q
n- 单个寄存器。如果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)
P
n- 常量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
寄存器。该约束不再被支持。
l
lo
寄存器。使用该寄存器来存放不大于一个字的值。
x
hi
和 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
指令加载的常量)
L
movcc
指令所支持的范围内的常量
M
movrcc
指令所支持的范围内的常量
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指令