[llvm] r241698 - Expand LangRef.html's documentation on LLVM's inline assembly.

Eric Christopher echristo at gmail.com
Fri Jul 10 21:16:05 PDT 2015


On Fri, Jul 10, 2015 at 9:13 PM Sean Silva <chisophugis at gmail.com> wrote:

> On Fri, Jul 10, 2015 at 9:10 PM, Eric Christopher <echristo at gmail.com>
> wrote:
>
>> Yeah, I said it on the review thread, but once again: Holy crap amazing.
>>
>
> And now when somebody is changing inline asm syntax, I can say "does this
> need a docs update?" :}
>
>
You know, I'd thought that too :)

-eric


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


More information about the llvm-commits mailing list