<div dir="ltr">Yeah, I said it on the review thread, but once again: Holy crap amazing.<div><br></div><div>Thanks!</div><div><br></div><div>-eric</div></div><br><div class="gmail_quote"><div dir="ltr">On Fri, Jul 10, 2015 at 8:46 PM Sean Silva <<a href="mailto:chisophugis@gmail.com">chisophugis@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Nice! Thanks for going to the effort of doing this!</div><div dir="ltr"><div><br></div><div>-- Sean Silva</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jul 8, 2015 at 11:08 AM, James Y Knight <span dir="ltr"><<a href="mailto:jyknight@google.com" target="_blank">jyknight@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: jyknight<br>
Date: Wed Jul  8 13:08:36 2015<br>
New Revision: 241698<br>
<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D241698-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=lv0MDBR_L89Ozm9msg-p5QPExhEnhYqZdq_EqUZKweA&s=dO9t2sFA0lX0jldgHeKs_A7LBANFzYnbxmvF8DMsADk&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=241698&view=rev</a><br>
Log:<br>
Expand LangRef.html's documentation on LLVM's inline assembly.<br>
<br>
While trying to figure out how this was all supposed to work, I<br>
figured I'd start writing down some documentation, since it was<br>
basically completely missing.<br>
<br>
Differential Revision: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D10816&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=lv0MDBR_L89Ozm9msg-p5QPExhEnhYqZdq_EqUZKweA&s=eKi2Q2TZiHoKxf8fj2oY4ryVRrkPdjNaqZYHFXfkubk&e=" rel="noreferrer" target="_blank">http://reviews.llvm.org/D10816</a><br>
<br>
Modified:<br>
    llvm/trunk/docs/LangRef.rst<br>
<br>
Modified: llvm/trunk/docs/LangRef.rst<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_docs_LangRef.rst-3Frev-3D241698-26r1-3D241697-26r2-3D241698-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=lv0MDBR_L89Ozm9msg-p5QPExhEnhYqZdq_EqUZKweA&s=5QmW2LYqDSzF-UD9k5v-SloKksk9UlavCpRyWTo3rwM&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=241698&r1=241697&r2=241698&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/docs/LangRef.rst (original)<br>
+++ llvm/trunk/docs/LangRef.rst Wed Jul  8 13:08:36 2015<br>
@@ -1446,8 +1446,8 @@ The strings can contain any character by<br>
 characters. The escape sequence used is simply "\\xx" where "xx" is the<br>
 two digit hex code for the number.<br>
<br>
-The inline asm code is simply printed to the machine code .s file when<br>
-assembly code is generated.<br>
+Note that the assembly string *must* be parseable by LLVM's integrated assembler<br>
+(unless it is disabled), even when emitting a ``.s`` file.<br>
<br>
 .. _langref_datalayout:<br>
<br>
@@ -2800,13 +2800,36 @@ Inline Assembler Expressions<br>
 ----------------------------<br>
<br>
 LLVM supports inline assembler expressions (as opposed to :ref:`Module-Level<br>
-Inline Assembly <moduleasm>`) through the use of a special value. This<br>
-value represents the inline assembler as a string (containing the<br>
-instructions to emit), a list of operand constraints (stored as a<br>
-string), a flag that indicates whether or not the inline asm expression<br>
-has side effects, and a flag indicating whether the function containing<br>
-the asm needs to align its stack conservatively. An example inline<br>
-assembler expression is:<br>
+Inline Assembly <moduleasm>`) through the use of a special value. This value<br>
+represents the inline assembler as a template string (containing the<br>
+instructions to emit), a list of operand constraints (stored as a string), a<br>
+flag that indicates whether or not the inline asm expression has side effects,<br>
+and a flag indicating whether the function containing the asm needs to align its<br>
+stack conservatively.<br>
+<br>
+The template string supports argument substitution of the operands using "``$``"<br>
+followed by a number, to indicate substitution of the given register/memory<br>
+location, as specified by the constraint string. "``${NUM:MODIFIER}``" may also<br>
+be used, where ``MODIFIER`` is a target-specific annotation for how to print the<br>
+operand (See :ref:`inline-asm-modifiers`).<br>
+<br>
+A literal "``$``" may be included by using "``$$``" in the template. To include<br>
+other special characters into the output, the usual "``\XX``" escapes may be<br>
+used, just as in other strings. Note that after template substitution, the<br>
+resulting assembly string is parsed by LLVM's integrated assembler unless it is<br>
+disabled -- even when emitting a ``.s`` file -- and thus must contain assembly<br>
+syntax known to LLVM.<br>
+<br>
+LLVM's support for inline asm is modeled closely on the requirements of Clang's<br>
+GCC-compatible inline-asm support. Thus, the feature-set and the constraint and<br>
+modifier codes listed here are similar or identical to those in GCC's inline asm<br>
+support. However, to be clear, the syntax of the template and constraint strings<br>
+described here is *not* the same as the syntax accepted by GCC and Clang, and,<br>
+while most constraint letters are passed through as-is by Clang, some get<br>
+translated to other codes when converting from the C source to the LLVM<br>
+assembly.<br>
+<br>
+An example inline assembler expression is:<br>
<br>
 .. code-block:: llvm<br>
<br>
@@ -2852,6 +2875,593 @@ If multiple keywords appear the '``sidee<br>
 first, the '``alignstack``' keyword second and the '``inteldialect``'<br>
 keyword last.<br>
<br>
+Inline Asm Constraint String<br>
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br>
+<br>
+The constraint list is a comma-separated string, each element containing one or<br>
+more constraint codes.<br>
+<br>
+For each element in the constraint list an appropriate register or memory<br>
+operand will be chosen, and it will be made available to assembly template<br>
+string expansion as ``$0`` for the first constraint in the list, ``$1`` for the<br>
+second, etc.<br>
+<br>
+There are three different types of constraints, which are distinguished by a<br>
+prefix symbol in front of the constraint code: Output, Input, and Clobber. The<br>
+constraints must always be given in that order: outputs first, then inputs, then<br>
+clobbers. They cannot be intermingled.<br>
+<br>
+There are also three different categories of constraint codes:<br>
+<br>
+- Register constraint. This is either a register class, or a fixed physical<br>
+  register. This kind of constraint will allocate a register, and if necessary,<br>
+  bitcast the argument or result to the appropriate type.<br>
+- Memory constraint. This kind of constraint is for use with an instruction<br>
+  taking a memory operand. Different constraints allow for different addressing<br>
+  modes used by the target.<br>
+- Immediate value constraint. This kind of constraint is for an integer or other<br>
+  immediate value which can be rendered directly into an instruction. The<br>
+  various target-specific constraints allow the selection of a value in the<br>
+  proper range for the instruction you wish to use it with.<br>
+<br>
+Output constraints<br>
+""""""""""""""""""<br>
+<br>
+Output constraints are specified by an "``=``" prefix (e.g. "``=r``"). This<br>
+indicates that the assembly will write to this operand, and the operand will<br>
+then be made available as a return value of the ``asm`` expression. Output<br>
+constraints do not consume an argument from the call instruction. (Except, see<br>
+below about indirect outputs).<br>
+<br>
+Normally, it is expected that no output locations are written to by the assembly<br>
+expression until *all* of the inputs have been read. As such, LLVM may assign<br>
+the same register to an output and an input. If this is not safe (e.g. if the<br>
+assembly contains two instructions, where the first writes to one output, and<br>
+the second reads an input and writes to a second output), then the "``&``"<br>
+modifier must be used (e.g. "``=&r``") to specify that the output is an<br>
+"early-clobber" output. Marking an ouput as "early-clobber" ensures that LLVM<br>
+will not use the same register for any inputs (other than an input tied to this<br>
+output).<br>
+<br>
+Input constraints<br>
+"""""""""""""""""<br>
+<br>
+Input constraints do not have a prefix -- just the constraint codes. Each input<br>
+constraint will consume one argument from the call instruction. It is not<br>
+permitted for the asm to write to any input register or memory location (unless<br>
+that input is tied to an output). Note also that multiple inputs may all be<br>
+assigned to the same register, if LLVM can determine that they necessarily all<br>
+contain the same value.<br>
+<br>
+Instead of providing a Constraint Code, input constraints may also "tie"<br>
+themselves to an output constraint, by providing an integer as the constraint<br>
+string. Tied inputs still consume an argument from the call instruction, and<br>
+take up a position in the asm template numbering as is usual -- they will simply<br>
+be constrained to always use the same register as the output they've been tied<br>
+to. For example, a constraint string of "``=r,0``" says to assign a register for<br>
+output, and use that register as an input as well (it being the 0'th<br>
+constraint).<br>
+<br>
+It is permitted to tie an input to an "early-clobber" output. In that case, no<br>
+*other* input may share the same register as the input tied to the early-clobber<br>
+(even when the other input has the same value).<br>
+<br>
+You may only tie an input to an output which has a register constraint, not a<br>
+memory constraint. Only a single input may be tied to an output.<br>
+<br>
+There is also an "interesting" feature which deserves a bit of explanation: if a<br>
+register class constraint allocates a register which is too small for the value<br>
+type operand provided as input, the input value will be split into multiple<br>
+registers, and all of them passed to the inline asm.<br>
+<br>
+However, this feature is often not as useful as you might think.<br>
+<br>
+Firstly, the registers are *not* guaranteed to be consecutive. So, on those<br>
+architectures that have instructions which operate on multiple consecutive<br>
+instructions, this is not an appropriate way to support them. (e.g. the 32-bit<br>
+SparcV8 has a 64-bit load, which instruction takes a single 32-bit register. The<br>
+hardware then loads into both the named register, and the next register. This<br>
+feature of inline asm would not be useful to support that.)<br>
+<br>
+A few of the targets provide a template string modifier allowing explicit access<br>
+to the second register of a two-register operand (e.g. MIPS ``L``, ``M``, and<br>
+``D``). On such an architecture, you can actually access the second allocated<br>
+register (yet, still, not any subsequent ones). But, in that case, you're still<br>
+probably better off simply splitting the value into two separate operands, for<br>
+clarity. (e.g. see the description of the ``A`` constraint on X86, which,<br>
+despite existing only for use with this feature, is not really a good idea to<br>
+use)<br>
+<br>
+Indirect inputs and outputs<br>
+"""""""""""""""""""""""""""<br>
+<br>
+Indirect output or input constraints can be specified by the "``*``" modifier<br>
+(which goes after the "``=``" in case of an output). This indicates that the asm<br>
+will write to or read from the contents of an *address* provided as an input<br>
+argument. (Note that in this way, indirect outputs act more like an *input* than<br>
+an output: just like an input, they consume an argument of the call expression,<br>
+rather than producing a return value. An indirect output constraint is an<br>
+"output" only in that the asm is expected to write to the contents of the input<br>
+memory location, instead of just read from it).<br>
+<br>
+This is most typically used for memory constraint, e.g. "``=*m``", to pass the<br>
+address of a variable as a value.<br>
+<br>
+It is also possible to use an indirect *register* constraint, but only on output<br>
+(e.g. "``=*r``"). This will cause LLVM to allocate a register for an output<br>
+value normally, and then, separately emit a store to the address provided as<br>
+input, after the provided inline asm. (It's not clear what value this<br>
+functionality provides, compared to writing the store explicitly after the asm<br>
+statement, and it can only produce worse code, since it bypasses many<br>
+optimization passes. I would recommend not using it.)<br>
+<br>
+<br>
+Clobber constraints<br>
+"""""""""""""""""""<br>
+<br>
+A clobber constraint is indicated by a "``~``" prefix. A clobber does not<br>
+consume an input operand, nor generate an output. Clobbers cannot use any of the<br>
+general constraint code letters -- they may use only explicit register<br>
+constraints, e.g. "``~{eax}``". The one exception is that a clobber string of<br>
+"``~{memory}``" indicates that the assembly writes to arbitrary undeclared<br>
+memory locations -- not only the memory pointed to by a declared indirect<br>
+output.<br>
+<br>
+<br>
+Constraint Codes<br>
+""""""""""""""""<br>
+After a potential prefix comes constraint code, or codes.<br>
+<br>
+A Constraint Code is either a single letter (e.g. "``r``"), a "``^``" character<br>
+followed by two letters (e.g. "``^wc``"), or "``{``" register-name "``}``"<br>
+(e.g. "``{eax}``").<br>
+<br>
+The one and two letter constraint codes are typically chosen to be the same as<br>
+GCC's constraint codes.<br>
+<br>
+A single constraint may include one or more than constraint code in it, leaving<br>
+it up to LLVM to choose which one to use. This is included mainly for<br>
+compatibility with the translation of GCC inline asm coming from clang.<br>
+<br>
+There are two ways to specify alternatives, and either or both may be used in an<br>
+inline asm constraint list:<br>
+<br>
+1) Append the codes to each other, making a constraint code set. E.g. "``im``"<br>
+   or "``{eax}m``". This means "choose any of the options in the set". The<br>
+   choice of constraint is made independently for each constraint in the<br>
+   constraint list.<br>
+<br>
+2) Use "``|``" between constraint code sets, creating alternatives. Every<br>
+   constraint in the constraint list must have the same number of alternative<br>
+   sets. With this syntax, the same alternative in *all* of the items in the<br>
+   constraint list will be chosen together.<br>
+<br>
+Putting those together, you might have a two operand constraint string like<br>
+``"rm|r,ri|rm"``. This indicates that if operand 0 is ``r`` or ``m``, then<br>
+operand 1 may be one of ``r`` or ``i``. If operand 0 is ``r``, then operand 1<br>
+may be one of ``r`` or ``m``. But, operand 0 and 1 cannot both be of type m.<br>
+<br>
+However, the use of either of the alternatives features is *NOT* recommended, as<br>
+LLVM is not able to make an intelligent choice about which one to use. (At the<br>
+point it currently needs to choose, not enough information is available to do so<br>
+in a smart way.) Thus, it simply tries to make a choice that's most likely to<br>
+compile, not one that will be optimal performance. (e.g., given "``rm``", it'll<br>
+always choose to use memory, not registers). And, if given multiple registers,<br>
+or multiple register classes, it will simply choose the first one. (In fact, it<br>
+doesn't currently even ensure explicitly specified physical registers are<br>
+unique, so specifying multiple physical registers as alternatives, like<br>
+``{r11}{r12},{r11}{r12}``, will assign r11 to both operands, not at all what was<br>
+intended.)<br>
+<br>
+Supported Constraint Code List<br>
+""""""""""""""""""""""""""""""<br>
+<br>
+The constraint codes are, in general, expected to behave the same way they do in<br>
+GCC. LLVM's support is often implemented on an 'as-needed' basis, to support C<br>
+inline asm code which was supported by GCC. A mismatch in behavior between LLVM<br>
+and GCC likely indicates a bug in LLVM.<br>
+<br>
+Some constraint codes are typically supported by all targets:<br>
+<br>
+- ``r``: A register in the target's general purpose register class.<br>
+- ``m``: A memory address operand. It is target-specific what addressing modes<br>
+  are supported, typical examples are register, or register + register offset,<br>
+  or register + immediate offset (of some target-specific size).<br>
+- ``i``: An integer constant (of target-specific width). Allows either a simple<br>
+  immediate, or a relocatable value.<br>
+- ``n``: An integer constant -- *not* including relocatable values.<br>
+- ``s``: An integer constant, but allowing *only* relocatable values.<br>
+- ``X``: Allows an operand of any kind, no constraint whatsoever. Typically<br>
+  useful to pass a label for an asm branch or call.<br>
+<br>
+  .. FIXME: but that surely isn't actually okay to jump out of an asm<br>
+     block without telling llvm about the control transfer???)<br>
+<br>
+- ``{register-name}``: Requires exactly the named physical register.<br>
+<br>
+Other constraints are target-specific:<br>
+<br>
+AArch64:<br>
+<br>
+- ``z``: An immediate integer 0. Outputs ``WZR`` or ``XZR``, as appropriate.<br>
+- ``I``: An immediate integer valid for an ``ADD`` or ``SUB`` instruction,<br>
+  i.e. 0 to 4095 with optional shift by 12.<br>
+- ``J``: An immediate integer that, when negated, is valid for an ``ADD`` or<br>
+  ``SUB`` instruction, i.e. -1 to -4095 with optional left shift by 12.<br>
+- ``K``: An immediate integer that is valid for the 'bitmask immediate 32' of a<br>
+  logical instruction like ``AND``, ``EOR``, or ``ORR`` with a 32-bit register.<br>
+- ``L``: An immediate integer that is valid for the 'bitmask immediate 64' of a<br>
+  logical instruction like ``AND``, ``EOR``, or ``ORR`` with a 64-bit register.<br>
+- ``M``: An immediate integer for use with the ``MOV`` assembly alias on a<br>
+  32-bit register. This is a superset of ``K``: in addition to the bitmask<br>
+  immediate, also allows immediate integers which can be loaded with a single<br>
+  ``MOVZ`` or ``MOVL`` instruction.<br>
+- ``N``: An immediate integer for use with the ``MOV`` assembly alias on a<br>
+  64-bit register. This is a superset of ``L``.<br>
+- ``Q``: Memory address operand must be in a single register (no<br>
+  offsets). (However, LLVM currently does this for the ``m`` constraint as<br>
+  well.)<br>
+- ``r``: A 32 or 64-bit integer register (W* or X*).<br>
+- ``w``: A 32, 64, or 128-bit floating-point/SIMD register.<br>
+- ``x``: A lower 128-bit floating-point/SIMD register (``V0`` to ``V15``).<br>
+<br>
+AMDGPU:<br>
+<br>
+- ``r``: A 32 or 64-bit integer register.<br>
+- ``[0-9]v``: The 32-bit VGPR register, number 0-9.<br>
+- ``[0-9]s``: The 32-bit SGPR register, number 0-9.<br>
+<br>
+<br>
+All ARM modes:<br>
+<br>
+- ``Q``, ``Um``, ``Un``, ``Uq``, ``Us``, ``Ut``, ``Uv``, ``Uy``: Memory address<br>
+  operand. Treated the same as operand ``m``, at the moment.<br>
+<br>
+ARM and ARM's Thumb2 mode:<br>
+<br>
+- ``j``: An immediate integer between 0 and 65535 (valid for ``MOVW``)<br>
+- ``I``: An immediate integer valid for a data-processing instruction.<br>
+- ``J``: An immediate integer between -4095 and 4095.<br>
+- ``K``: An immediate integer whose bitwise inverse is valid for a<br>
+  data-processing instruction. (Can be used with template modifier "``B``" to<br>
+  print the inverted value).<br>
+- ``L``: An immediate integer whose negation is valid for a data-processing<br>
+  instruction. (Can be used with template modifier "``n``" to print the negated<br>
+  value).<br>
+- ``M``: A power of two or a integer between 0 and 32.<br>
+- ``N``: Invalid immediate constraint.<br>
+- ``O``: Invalid immediate constraint.<br>
+- ``r``: A general-purpose 32-bit integer register (``r0-r15``).<br>
+- ``l``: In Thumb2 mode, low 32-bit GPR registers (``r0-r7``). In ARM mode, same<br>
+  as ``r``.<br>
+- ``h``: In Thumb2 mode, a high 32-bit GPR register (``r8-r15``). In ARM mode,<br>
+  invalid.<br>
+- ``w``: A 32, 64, or 128-bit floating-point/SIMD register: ``s0-s31``,<br>
+  ``d0-d31``, or ``q0-q15``.<br>
+- ``x``: A 32, 64, or 128-bit floating-point/SIMD register: ``s0-s15``,<br>
+  ``d0-d7``, or ``q0-q3``.<br>
+- ``t``: A floating-point/SIMD register, only supports 32-bit values:<br>
+  ``s0-s31``.<br>
+<br>
+ARM's Thumb1 mode:<br>
+<br>
+- ``I``: An immediate integer between 0 and 255.<br>
+- ``J``: An immediate integer between -255 and -1.<br>
+- ``K``: An immediate integer between 0 and 255, with optional left-shift by<br>
+  some amount.<br>
+- ``L``: An immediate integer between -7 and 7.<br>
+- ``M``: An immediate integer which is a multiple of 4 between 0 and 1020.<br>
+- ``N``: An immediate integer between 0 and 31.<br>
+- ``O``: An immediate integer which is a multiple of 4 between -508 and 508.<br>
+- ``r``: A low 32-bit GPR register (``r0-r7``).<br>
+- ``l``: A low 32-bit GPR register (``r0-r7``).<br>
+- ``h``: A high GPR register (``r0-r7``).<br>
+- ``w``: A 32, 64, or 128-bit floating-point/SIMD register: ``s0-s31``,<br>
+  ``d0-d31``, or ``q0-q15``.<br>
+- ``x``: A 32, 64, or 128-bit floating-point/SIMD register: ``s0-s15``,<br>
+  ``d0-d7``, or ``q0-q3``.<br>
+- ``t``: A floating-point/SIMD register, only supports 32-bit values:<br>
+  ``s0-s31``.<br>
+<br>
+<br>
+Hexagon:<br>
+<br>
+- ``o``, ``v``: A memory address operand, treated the same as constraint ``m``,<br>
+  at the moment.<br>
+- ``r``: A 32 or 64-bit register.<br>
+<br>
+MSP430:<br>
+<br>
+- ``r``: An 8 or 16-bit register.<br>
+<br>
+MIPS:<br>
+<br>
+- ``I``: An immediate signed 16-bit integer.<br>
+- ``J``: An immediate integer zero.<br>
+- ``K``: An immediate unsigned 16-bit integer.<br>
+- ``L``: An immediate 32-bit integer, where the lower 16 bits are 0.<br>
+- ``N``: An immediate integer between -65535 and -1.<br>
+- ``O``: An immediate signed 15-bit integer.<br>
+- ``P``: An immediate integer between 1 and 65535.<br>
+- ``m``: A memory address operand. In MIPS-SE mode, allows a base address<br>
+  register plus 16-bit immediate offset. In MIPS mode, just a base register.<br>
+- ``R``: A memory address operand. In MIPS-SE mode, allows a base address<br>
+  register plus a 9-bit signed offset. In MIPS mode, the same as constraint<br>
+  ``m``.<br>
+- ``ZC``: A memory address operand, suitable for use in a ``pref``, ``ll``, or<br>
+  ``sc`` instruction on the given subtarget (details vary).<br>
+- ``r``, ``d``,  ``y``: A 32 or 64-bit GPR register.<br>
+- ``f``: A 32 or 64-bit FPU register (``F0-F31``), or a 128-bit MSA register<br>
+  (``W0-W31``).<br>
+- ``c``: A 32-bit or 64-bit GPR register suitable for indirect jump (always<br>
+  ``25``).<br>
+- ``l``: The ``lo`` register, 32 or 64-bit.<br>
+- ``x``: Invalid.<br>
+<br>
+NVPTX:<br>
+<br>
+- ``b``: A 1-bit integer register.<br>
+- ``c`` or ``h``: A 16-bit integer register.<br>
+- ``r``: A 32-bit integer register.<br>
+- ``l`` or ``N``: A 64-bit integer register.<br>
+- ``f``: A 32-bit float register.<br>
+- ``d``: A 64-bit float register.<br>
+<br>
+<br>
+PowerPC:<br>
+<br>
+- ``I``: An immediate signed 16-bit integer.<br>
+- ``J``: An immediate unsigned 16-bit integer, shifted left 16 bits.<br>
+- ``K``: An immediate unsigned 16-bit integer.<br>
+- ``L``: An immediate signed 16-bit integer, shifted left 16 bits.<br>
+- ``M``: An immediate integer greater than 31.<br>
+- ``N``: An immediate integer that is an exact power of 2.<br>
+- ``O``: The immediate integer constant 0.<br>
+- ``P``: An immediate integer constant whose negation is a signed 16-bit<br>
+  constant.<br>
+- ``es``, ``o``, ``Q``, ``Z``, ``Zy``: A memory address operand, currently<br>
+  treated the same as ``m``.<br>
+- ``r``: A 32 or 64-bit integer register.<br>
+- ``b``: A 32 or 64-bit integer register, excluding ``R0`` (that is:<br>
+  ``R1-R31``).<br>
+- ``f``: A 32 or 64-bit float register (``F0-F31``), or when QPX is enabled, a<br>
+  128 or 256-bit QPX register (``Q0-Q31``; aliases the ``F`` registers).<br>
+- ``v``: For ``4 x f32`` or ``4 x f64`` types, when QPX is enabled, a<br>
+  128 or 256-bit QPX register (``Q0-Q31``), otherwise a 128-bit<br>
+  altivec vector register (``V0-V31``).<br>
+<br>
+  .. FIXME: is this a bug that v accepts QPX registers? I think this<br>
+     is supposed to only use the altivec vector registers?<br>
+<br>
+- ``y``: Condition register (``CR0-CR7``).<br>
+- ``wc``: An individual CR bit in a CR register.<br>
+- ``wa``, ``wd``, ``wf``: Any 128-bit VSX vector register, from the full VSX<br>
+  register set (overlapping both the floating-point and vector register files).<br>
+- ``ws``: A 32 or 64-bit floating point register, from the full VSX register<br>
+  set.<br>
+<br>
+Sparc:<br>
+<br>
+- ``I``: An immediate 13-bit signed integer.<br>
+- ``r``: A 32-bit integer register.<br>
+<br>
+SystemZ:<br>
+<br>
+- ``I``: An immediate unsigned 8-bit integer.<br>
+- ``J``: An immediate unsigned 12-bit integer.<br>
+- ``K``: An immediate signed 16-bit integer.<br>
+- ``L``: An immediate signed 20-bit integer.<br>
+- ``M``: An immediate integer 0x7fffffff.<br>
+- ``Q``, ``R``, ``S``, ``T``: A memory address operand, treated the same as<br>
+  ``m``, at the moment.<br>
+- ``r`` or ``d``: A 32, 64, or 128-bit integer register.<br>
+- ``a``: A 32, 64, or 128-bit integer address register (excludes R0, which in an<br>
+  address context evaluates as zero).<br>
+- ``h``: A 32-bit value in the high part of a 64bit data register<br>
+  (LLVM-specific)<br>
+- ``f``: A 32, 64, or 128-bit floating point register.<br>
+<br>
+X86:<br>
+<br>
+- ``I``: An immediate integer between 0 and 31.<br>
+- ``J``: An immediate integer between 0 and 64.<br>
+- ``K``: An immediate signed 8-bit integer.<br>
+- ``L``: An immediate integer, 0xff or 0xffff or (in 64-bit mode only)<br>
+  0xffffffff.<br>
+- ``M``: An immediate integer between 0 and 3.<br>
+- ``N``: An immediate unsigned 8-bit integer.<br>
+- ``O``: An immediate integer between 0 and 127.<br>
+- ``e``: An immediate 32-bit signed integer.<br>
+- ``Z``: An immediate 32-bit unsigned integer.<br>
+- ``o``, ``v``: Treated the same as ``m``, at the moment.<br>
+- ``q``: An 8, 16, 32, or 64-bit register which can be accessed as an 8-bit<br>
+  ``l`` integer register. On X86-32, this is the ``a``, ``b``, ``c``, and ``d``<br>
+  registers, and on X86-64, it is all of the integer registers.<br>
+- ``Q``: An 8, 16, 32, or 64-bit register which can be accessed as an 8-bit<br>
+  ``h`` integer register. This is the ``a``, ``b``, ``c``, and ``d`` registers.<br>
+- ``r`` or ``l``: An 8, 16, 32, or 64-bit integer register.<br>
+- ``R``: An 8, 16, 32, or 64-bit "legacy" integer register -- one which has<br>
+  existed since i386, and can be accessed without the REX prefix.<br>
+- ``f``: A 32, 64, or 80-bit '387 FPU stack pseudo-register.<br>
+- ``y``: A 64-bit MMX register, if MMX is enabled.<br>
+- ``x``: If SSE is enabled: a 32 or 64-bit scalar operand, or 128-bit vector<br>
+  operand in a SSE register. If AVX is also enabled, can also be a 256-bit<br>
+  vector operand in an AVX register. If AVX-512 is also enabled, can also be a<br>
+  512-bit vector operand in an AVX512 register, Otherwise, an error.<br>
+- ``Y``: The same as ``x``, if *SSE2* is enabled, otherwise an error.<br>
+- ``A``: Special case: allocates EAX first, then EDX, for a single operand (in<br>
+  32-bit mode, a 64-bit integer operand will get split into two registers). It<br>
+  is not recommended to use this constraint, as in 64-bit mode, the 64-bit<br>
+  operand will get allocated only to RAX -- if two 32-bit operands are needed,<br>
+  you're better off splitting it yourself, before passing it to the asm<br>
+  statement.<br>
+<br>
+XCore:<br>
+<br>
+- ``r``: A 32-bit integer register.<br>
+<br>
+<br>
+.. _inline-asm-modifiers:<br>
+<br>
+Asm template argument modifiers<br>
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br>
+<br>
+In the asm template string, modifiers can be used on the operand reference, like<br>
+"``${0:n}``".<br>
+<br>
+The modifiers are, in general, expected to behave the same way they do in<br>
+GCC. LLVM's support is often implemented on an 'as-needed' basis, to support C<br>
+inline asm code which was supported by GCC. A mismatch in behavior between LLVM<br>
+and GCC likely indicates a bug in LLVM.<br>
+<br>
+Target-independent:<br>
+<br>
+- ``c``: Print an immediate integer constant  unadorned, without<br>
+  the target-specific immediate punctuation (e.g. no ``$`` prefix).<br>
+- ``n``: Negate and print immediate integer constant unadorned, without the<br>
+  target-specific immediate punctuation (e.g. no ``$`` prefix).<br>
+- ``l``: Print as an unadorned label, without the target-specific label<br>
+  punctuation (e.g. no ``$`` prefix).<br>
+<br>
+AArch64:<br>
+<br>
+- ``w``: Print a GPR register with a ``w*`` name instead of ``x*`` name. E.g.,<br>
+  instead of ``x30``, print ``w30``.<br>
+- ``x``: Print a GPR register with a ``x*`` name. (this is the default, anyhow).<br>
+- ``b``, ``h``, ``s``, ``d``, ``q``: Print a floating-point/SIMD register with a<br>
+  ``b*``, ``h*``, ``s*``, ``d*``, or ``q*`` name, rather than the default of<br>
+  ``v*``.<br>
+<br>
+AMDGPU:<br>
+<br>
+- ``r``: No effect.<br>
+<br>
+ARM:<br>
+<br>
+- ``a``: Print an operand as an address (with ``[`` and ``]`` surrounding a<br>
+  register).<br>
+- ``P``: No effect.<br>
+- ``q``: No effect.<br>
+- ``y``: Print a VFP single-precision register as an indexed double (e.g. print<br>
+  as ``d4[1]`` instead of ``s9``)<br>
+- ``B``: Bitwise invert and print an immediate integer constant without ``#``<br>
+  prefix.<br>
+- ``L``: Print the low 16-bits of an immediate integer constant.<br>
+- ``M``: Print as a register set suitable for ldm/stm. Also prints *all*<br>
+  register operands subsequent to the specified one (!), so use carefully.<br>
+- ``Q``: Print the low-order register of a register-pair, or the low-order<br>
+  register of a two-register operand.<br>
+- ``R``: Print the high-order register of a register-pair, or the high-order<br>
+  register of a two-register operand.<br>
+- ``H``: Print the second register of a register-pair. (On a big-endian system,<br>
+  ``H`` is equivalent to ``Q``, and on little-endian system, ``H`` is equivalent<br>
+  to ``R``.)<br>
+<br>
+  .. FIXME: H doesn't currently support printing the second register<br>
+     of a two-register operand.<br>
+<br>
+- ``e``: Print the low doubleword register of a NEON quad register.<br>
+- ``f``: Print the high doubleword register of a NEON quad register.<br>
+- ``m``: Print the base register of a memory operand without the ``[`` and ``]``<br>
+  adornment.<br>
+<br>
+Hexagon:<br>
+<br>
+- ``L``: Print the second register of a two-register operand. Requires that it<br>
+  has been allocated consecutively to the first.<br>
+<br>
+  .. FIXME: why is it restricted to consecutive ones? And there's<br>
+     nothing that ensures that happens, is there?<br>
+<br>
+- ``I``: Print the letter 'i' if the operand is an integer constant, otherwise<br>
+  nothing. Used to print 'addi' vs 'add' instructions.<br>
+<br>
+MSP430:<br>
+<br>
+No additional modifiers.<br>
+<br>
+MIPS:<br>
+<br>
+- ``X``: Print an immediate integer as hexadecimal<br>
+- ``x``: Print the low 16 bits of an immediate integer as hexadecimal.<br>
+- ``d``: Print an immediate integer as decimal.<br>
+- ``m``: Subtract one and print an immediate integer as decimal.<br>
+- ``z``: Print $0 if an immediate zero, otherwise print normally.<br>
+- ``L``: Print the low-order register of a two-register operand, or prints the<br>
+  address of the low-order word of a double-word memory operand.<br>
+<br>
+  .. FIXME: L seems to be missing memory operand support.<br>
+<br>
+- ``M``: Print the high-order register of a two-register operand, or prints the<br>
+  address of the high-order word of a double-word memory operand.<br>
+<br>
+  .. FIXME: M seems to be missing memory operand support.<br>
+<br>
+- ``D``: Print the second register of a two-register operand, or prints the<br>
+  second word of a double-word memory operand. (On a big-endian system, ``D`` is<br>
+  equivalent to ``L``, and on little-endian system, ``D`` is equivalent to<br>
+  ``M``.)<br>
+- ``w``: No effect.<br>
+<br>
+NVPTX:<br>
+<br>
+- ``r``: No effect.<br>
+<br>
+PowerPC:<br>
+<br>
+- ``L``: Print the second register of a two-register operand. Requires that it<br>
+  has been allocated consecutively to the first.<br>
+<br>
+  .. FIXME: why is it restricted to consecutive ones? And there's<br>
+     nothing that ensures that happens, is there?<br>
+<br>
+- ``I``: Print the letter 'i' if the operand is an integer constant, otherwise<br>
+  nothing. Used to print 'addi' vs 'add' instructions.<br>
+- ``y``: For a memory operand, prints formatter for a two-register X-form<br>
+  instruction. (Currently always prints ``r0,OPERAND``).<br>
+- ``U``: Prints 'u' if the memory operand is an update form, and nothing<br>
+  otherwise. (NOTE: LLVM does not support update form, so this will currently<br>
+  always print nothing)<br>
+- ``X``: Prints 'x' if the memory operand is an indexed form. (NOTE: LLVM does<br>
+  not support indexed form, so this will currently always print nothing)<br>
+<br>
+Sparc:<br>
+<br>
+- ``r``: No effect.<br>
+<br>
+SystemZ:<br>
+<br>
+SystemZ implements only ``n``, and does *not* support any of the other<br>
+target-independent modifiers.<br>
+<br>
+X86:<br>
+<br>
+- ``c``: Print an unadorned integer or symbol name. (The latter is<br>
+  target-specific behavior for this typically target-independent modifier).<br>
+- ``A``: Print a register name with a '``*``' before it.<br>
+- ``b``: Print an 8-bit register name (e.g. ``al``); do nothing on a memory<br>
+  operand.<br>
+- ``h``: Print the upper 8-bit register name (e.g. ``ah``); do nothing on a<br>
+  memory operand.<br>
+- ``w``: Print the 16-bit register name (e.g. ``ax``); do nothing on a memory<br>
+  operand.<br>
+- ``k``: Print the 32-bit register name (e.g. ``eax``); do nothing on a memory<br>
+  operand.<br>
+- ``q``: Print the 64-bit register name (e.g. ``rax``), if 64-bit registers are<br>
+  available, otherwise the 32-bit register name; do nothing on a memory operand.<br>
+- ``n``: Negate and print an unadorned integer, or, for operands other than an<br>
+  immediate integer (e.g. a relocatable symbol expression), print a '-' before<br>
+  the operand. (The behavior for relocatable symbol expressions is a<br>
+  target-specific behavior for this typically target-independent modifier)<br>
+- ``H``: Print a memory reference with additional offset +8.<br>
+- ``P``: Print a memory reference or operand for use as the argument of a call<br>
+  instruction. (E.g. omit ``(rip)``, even though it's PC-relative.)<br>
+<br>
+XCore:<br>
+<br>
+No additional modifiers.<br>
+<br>
+<br>
 Inline Asm Metadata<br>
 ^^^^^^^^^^^^^^^^^^^<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>