Next: , Previous: Disable Insn Alternatives, Up: Constraints


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
可以用于在depiextru指令中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
任何可以作为rl访问的寄存器。在32位机器模式中,为a, b, cd; 在64位机器模式中,为任何整数寄存器。
Q
任何可以作为rh来访问的寄存器:a, b, cd
l
任何在基址+索引的内存访问中,可以作为索引的寄存器:即除了栈指针以外的任何通用寄存器。
a
寄存器a
b
寄存器b
c
寄存器c
d
寄存器d
S
寄存器si
D
寄存器di
A
寄存器ad,作为一对(用于在一个寄存器中返回结果的一半,另一个寄存器中返回另一半的指令)
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位整数常量(用于inout指令)
O
整数常量,范围在0 ... 127,用于64位移位
G
标准的80387浮点常量
C
标准的SSE浮点常量
e
32位有符号整数常量,或者已知适合该范围的符号引用(用于有符号扩展x86-64指令的立即数)
Z
32位无符号整数常量,或者已知适合该范围的符号引用(用于零扩展x86-64指令的立即数)

Intel IA-64—config/ia64/ia64.h
a
通用寄存器r0r3,用于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中的寄存器(acc0acc7).
b
类别EVEN_ACC_REGS中的寄存器(acc0acc7).
c
类别CC_REGS中的寄存器(fcc0fcc3 以及 icc0icc3).
d
类别GPR_REGS中的寄存器(gr0gr63).
e
类别EVEN_REGS中的寄存器(gr0gr63)。奇数寄存器不在该类中,但是可以使用大于4个字节的机器模式来使用。
f
类别FPR_REGS中的寄存器(fr0fr63).
h
类别FEVEN_REGS中的寄存器(fr0fr63)。奇数寄存器不在该类中,但是可以使用大于4个字节的机器模式来使用。
l
类比LR_REG中的寄存器(lr寄存器)。
q
类别QUAD_REGS中的寄存器(gr2gr63)。无法被4整除的寄存器编号不在该类中,但是可以使用大于8个字节的机器模式来使用。
t
类别ICC_REGS中的寄存器(icc0icc3).
u
类别FCC_REGS中的寄存器(fcc0fcc3).
v
类别ICR_REGS中的寄存器(cc4cc7).
w
类别FCR_REGS中的寄存器(cc0cc3).
x
类别QUAD_FPR_REGS中的寄存器(fr0fr63)。无法被4整除的寄存器编号不在该类中,但是可以使用大于8个字节的机器模式来使用。
z
类别SPR_REGS中的寄存器(lcrlr).
A
类别QUAD_ACC_REGS中的寄存器(acc0acc7).
B
类别ACCG_REGS中的寄存器(accg0accg7).
C
类别CR_REGS中的寄存器(cc0cc7).
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寄存器。该约束不再被支持。
l
lo寄存器。使用该寄存器来存放不大于一个字的值。
x
hilo寄存器的结合。使用该寄存器来存放双字的值。
c
适用于间接跳转的寄存器。对于-mabicalls,其将总是为$25
v
寄存器$3。不要在新的代码中使用该约束;保留它只是为了与glibc兼容。
y
等价于r; 保留它是为了向后兼容。
z
浮点条件代码寄存器
I
有符号16位常量(用于算术指令)
J
整数零
K
无符号16位常量(用于逻辑指令)
L
有符号32位常量,其中低16位为零。这样的常量可以使用lui来加载。
M
不可以使用lui, addiuori加载的常量。
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位常量,用于iohlfsmbi
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指令