Skip to content

Instantly share code, notes, and snippets.

@jart
Last active August 3, 2021 20:35
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jart/fe8d104ef93149b5ba9b72912820282c to your computer and use it in GitHub Desktop.
Save jart/fe8d104ef93149b5ba9b72912820282c to your computer and use it in GitHub Desktop.
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
@swolchok
Copy link

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”).

@jart
Copy link
Author

jart commented Mar 4, 2021

Thanks @swolchok!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment