Last active
August 3, 2021 20:35
-
-
Save jart/fe8d104ef93149b5ba9b72912820282c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
RMS NOTATION TUTORIAL | |
BEHAVIOR | |
=: write-only | |
+: read/writeable | |
&: earlyclobber (impacts register sharing, defensive copying, etc.) | |
%: commutative | |
,: groups alternative constraints | |
?: discourages group of constraints | |
SELECTION | |
Autonomous | |
a: ax/eax/rax | |
b: bx/ebx/rbx | |
c: cx/cbx/cbx | |
d: dx/edx/rdx | |
S: si/esi/rsi | |
D: di/edi/rdi | |
Yz: %xmm0 | |
Yp: integer register when TARGET_PARTIAL_REG_STALL (?) | |
Ya: ??? | |
otherwise use "g" and give it a variable | |
Algorithmic | |
r: pick one of a,b,c,d,D,S,r8-15 registers, referenced as %0,etc. | |
q: pick one of a,b,c,d,r8-r15 for lo-byte access, e.g. %b0,%w0,%k0,etc. | |
Q: pick one of a,b,c,d for hi-byte access, e.g. %h0,etc. | |
U: pick one of a,c,d,D,S,r8-11 (call-clobbered) | |
R: pick one of a,b,c,d,di,si,bp,sp (all models) | |
y: pick mmx register (or plain floating point?) | |
x: pick sse register | |
m: memory | |
o: memory offsetable by an immediate, referenced as %0,2+%0,etc. | |
p: memory, intended for load/push address and segments (movl %@:%p1, %0) | |
g: probably shorthand for "rmi" combo | |
X: allow anything | |
k: pick evex operand mask register i.e. k0-7 (avx512) | |
v: pick sse register w/ evex encoding i.e. %xmm0-%xmm31 (avx512) | |
Yr: pick sse register w/o rex prefix (ignored if -mavx) | |
Yk: pick evex operand mask register usable as predicate i.e. k1-7 (avx512) | |
Yd: pick sse that's evex encodable for -mavx512dq (otherwise any sse4.1) | |
Yv: pick sse that's evex encodable for -mavx512vl (otherwise any sse) | |
Yh: pick sse that's evex encodable with number factor of four | |
Yb: pick register for GOT base (intended for -fno-plt and __tls_get_addr) | |
Combos | |
rm: pick register or memory address (converting immediates) | |
rmi: pick register or memory address (allowing immediates) | |
etc. | |
Immediates | |
i: integer literal or compiler/assembler constexpr or linker embedding | |
n: integer literal or compiler constexpr? | |
s: integer constexpr but not literal (or known at link time?) | |
C: SSE constant zero operand | |
E: const double | |
F: const double or const vector | |
G: 1=+1.0,2=log₂10?,3=log₂𝑒?,4=π?,3=log₁₀2?,4=logₑ2?,5=+0.0? (fld?) | |
e: i∊[-2^31,2^31) for sign-extending immediates | |
Z: i∊[0,2^32) for zero-extending immediates | |
I: i∊[0,31] (5 bits for 32-bit shifts) | |
J: i∊[0,63] (6 bits for 64-bit shifts) | |
K: i∊[-128,127] | |
L: permit uncasted char/short literal as zero-extended operand to andl? | |
M: i∊[0,3] (intended for index scaling, e.g. "mov\t(?,?,1<<%0),?") | |
N: i∊[0,255] (for in & out) | |
O: i∊[0,32] (wut?) | |
M: 2-bit integer constant (shifts for index scaling) | |
I: 5-bit integer constant (for 32-bit shifts) | |
J: 6-bit integer constant (for 64-bit shifts) | |
K: signed 8-bit integer constant | |
G: 80387 constant | |
C: sse constant zero operand | |
Addresses | |
Ts: address w/o segment register | |
Ti: address w/o index or rip (see also mpx) | |
Tb: address w/o base or rip (see also mpx) | |
Tv: evex-sib address operand (avx512) | |
Transcendentals | |
f: any stack slot | |
t: top of stack (%st(0)) and possibly converts xmm to ymm | |
u: second top of stack (%st(1)) | |
Ts: address operand without segment register | |
Specials | |
%[{}|] avx512 syntax escaping (whew) | |
%%REG explicitly-supplied register (used w/ clobbers) | |
%= generates number unique to each instance | |
AUGMENTATION | |
%pN print raw | |
%PN print w/ @plt | |
%aN print address | |
%bN print lo-byte form, e.g. xchgb %b0,%%al (QImode 8-bit) | |
%hN print hi-byte form, e.g. xchgb %h0,%%ah (QImode 8-bit) | |
%wN print lo-word form, e.g. xchgw %w0,%%ax (HImode 16-bit) | |
%kN print dword form, e.g. xchgl %k0,%%eax (SImode 32-bit) | |
%qN print qword form, e.g. xchgq %q0,%%rax (DImode 64-bit) | |
%HN access high 8 bytes of SSE register, or +8 displacement | |
%kN print 32-bit form of operand, e.g. xchgl %k0,%%eax | |
%cN print constant without punctuation, e.g. lea %c0(%1),%2 | |
%lN print label without punctuation, e.g. jumps | |
%nN negated literal, e.g. lea %n0(%1),%2 | |
%zN print only opcode suffix for operand type | |
%VN print register name without %, e.g. call foo%V0 | |
INSTRUCTION NOTATION | |
Bell Laboratories | |
mov $1,r0 | |
mov r0,r2 | |
mov r0,var | |
mov r2,(r3) | |
mov 16(r2,r5),r0 | |
/ fortran | |
NASA | |
mov eax, 1 | |
mov ebx, eax | |
mov offset var, eax | |
mov dword ptr [ecx], ebx | |
add eax, dword ptr [fs:ebx+esi*4+42h] | |
; etc. | |
Gnubell | |
movw $1,%ax | |
movl %eax,%ebx | |
movl %eax,var | |
movl %ebx,(%ecx) | |
addl 0x42(%fs,%ebx,%esi,4),%eax | |
lock addl $0x12331337,%fs:-0x1337(%ebx,%esi,1) | |
/ not guaranteed | |
# not guaranteed | |
NOTES | |
Lettering is arbitrarily defined by a lisp config file dating back | |
to gcc 1.x and each target author is granted freedom to choose his | |
or her own lettering which community reserves ability to change as | |
these aren't standardized in any way so please use w/ some caution | |
and note 4.2.1 holds a certain degree of significance in timelines |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Shouldn’t line 18 be c: cx/ecx/rcx? https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints Seems to say so (“the c register”).