zoukankan      html  css  js  c++  java
  • GCC后端移植 机器描述文档(中文版)

    本手册适合需要深入分析GCC工作原理,或需要为GCC后端适配新的CPU架构的技术人员查阅。

    持续更新,转载请注明出处:www.cnblogs.com/cassuto/


    Generated from gcc-5.4.0/gcc/doc/md.texi

    本翻译所遵循的术语规范:

    机器描述:Machine Description

    指令规则:Insn Pattern

    操作数约束:Operand Constraints

    匹配约束:Matching Constraints

    标准操作:Standard Operation

    窥孔优化:Peephole Optimization

    并行表达式:Parallel Experssion

    识别模板:Recognition Template

    机器模式:Machine Mode

    构造:Construct

    匹配:Match

    特征相同:identical-looking

    指令发射:Emit

    上次更新时间2019/9/22。翻译过程中多有疏漏之处,欢迎批评指正。

    目录


    1.1 Overview of How the Machine Description is Used How the machine description is used.

    1.1 机器描述的使用概述(如何使用机器描述)

    1.2 Everything about Instruction Patterns How to write instruction patterns.

    1.2 指令规则详解(如何编写指令规则)

    1.3 Example of define_insn An explained example of a define_insn pattern.

    1.3 define_insn实例(如何使用define_insn

    1.4 RTL Template The RTL template defines what insns match a pattern.

    1.4 RTL模板(RTL模板:定义何种指令匹配何种规则)

    1.5 Output Templates and Operand Substitution The output template says how to make assembler code from such an insn.

    1.5 输出模板、操作数替换(输出模板:定义如何从指令生成汇编代码)
    1.6 C Statements for Assembler Output For more generality, write C code to output the assembler code.

    1.6 用于汇编程序输出的C代码(为了使GCC更加通用,请编写这部分的代码)
    1.7 Predicates Controlling what kinds of operands can be used for an insn.

    1.7 谓词控制(判断何种操作数可以被使用)

    1.8 Operand Constraints Fine-tuning operand selection.

    1.8 操作数约束(微调操作数的选择)

    1.9 Standard Pattern Names For Generation Names mark patterns to use for code generation.

    1.9 规则标准名(标识用于生成的规则)
    1.10 When the Order of Patterns Matters When the order of patterns makes a difference.

    1.10 注意规则的顺序(当规则的顺序不同时)
    1.11 Interdependence of Patterns Having one pattern may make you need another.

    1.11 规则的互相依赖(一个规则可能依赖于另一个规则)
    1.12 Defining Jump Instruction Patterns Special considerations for patterns for jump insns.

    1.12 定义跳转指令的规则(跳转类指令需要特殊考虑)
    1.13 Defining Looping Instruction Patterns How to define patterns for special looping insns.

    1.13 定义循环指令的规则(循环类指令需要特殊考虑)
    1.14 Canonicalization of Instructions

    1.14 指令规范化
    1.15 Defining RTL Sequences for Code Generation Generating a sequence of several RTL insns for a standard operation.

    1.15 定义用于代码生成的RTL序列(为标准操作生成一系列RTL指令)

    1.16 Defining How to Split Instructions Splitting Instructions into Multiple Instructions.

    1.16 定义指令分割规则(将指令分割为多重指令)
    1.17 Including Patterns in Machine Descriptions.

    1.17 在机器描述中include规则
    1.18 Machine-Specific Peephole Optimizers Defining machine-specific peephole optimizations.

    1.18 定义机器相关的窥孔优化器
    1.19 Instruction Attributes Specifying the value of attributes for generated insns.

    1.19 指令属性(为生成的指令设置属性值)
    1.20 Conditional Execution Generating define_insn patterns for predication.

    1.20 条件执行(生成用于预测的define_insn规则)
    1.21 RTL Templates Transformations Generating define_insn and define_expand patterns from other patterns.

    1.21 RTL模板(生成define_insn和define_expand规则)
    1.22 Constant Definitions Defining symbolic constants that can be used in the md file.

    1.22 常量定义(定义符号常量)
    1.23 Iterators Using iterators to generate patterns from a template.

    1.23 迭代器(使用迭代器从一个模板生成规则)

    前言


    A machine description has two parts: a file of instruction patterns (‘.md’ file) and a C header file of macro definitions.

    一个完整的机器描述应当包括两部分:描述指令规则的文件('.md'文件)、包含相关宏定义的C语言头文件。

    The ‘.md’ file for a target machine contains a pattern for each instruction that the target machine supports (or at least each instruction that is worth telling the compiler about).

    '.md'文件包含目标机器所支持的所有指令的规则(或者应至少包含编译器用到的指令)。

     It may also contain comments. A semicolon causes the rest of the line to be a comment, unless the semicolon is inside a quoted string.

    机器描述文件还可以包括注释:由一个‘;’分号引导单行注释,如果分号在由 " 包围的字符串中则不视为注释。

    See the next chapter for information on the C header file.

    下一章节将介绍C语言头文件。

    1.1 机器描述的使用概述(Overview of How the Machine Description is Used)


    There are three main conversions that happen in the compiler:

    在整个编译过程中,编译器内部发生了如下转换:

      1. The front end reads the source code and builds a parse tree.

    1. 前端读取源代码,构建语法树。

      2. The parse tree is used to generate an RTL insn list based on named instruction patterns.

    2. 根据命名指令规则,从语法树生成RTL指令。

      3. The insn list is matched against the RTL templates to produce assembler code.

    3. 从(RTL)指令列表匹配RTL模板,生成汇编代码。

    For the generate pass, only the names of the insns matter, from either a named define_insn or a define_expand. The compiler will choose the pattern with the right name and apply the operands according to the documentation later in this chapter, without regard for the RTL template or operand constraints. Note that the names the compiler looks for are hard-coded in the compiler—it will ignore unnamed patterns and patterns with names it doesn’t know about, but if you don’t provide a named pattern it needs, it will abort.

      对于生成过程来说,不论是命名的define_insn指令还是define_expand指令,指令的名称都非常重要。编译器会根据名称选择对应规则,在不考虑RTL模板和操作数约束的情况下(根据后文所述),将操作数应用到规则。注意规则名称是硬性编码的——编译器忽略未命名的规则、名称未知的规则;如果缺失必要的命名规则,编译器将会异常终止。

    If a define_insn is used, the template given is inserted into the insn list. If a define_expand is used, one of three things happens, based on the condition logic. The condition logic may manually create new insns for the insn list, say via emit_insn(), and invoke DONE. For certain named patterns, it may invoke FAIL to tell the compiler to use an alternate way of performing that task. If it invokes neither DONE nor FAIL, the template given in the pattern is inserted, as if the define_expand were a define_insn.

      如果使用define_insn,指定的模板将被插入到指令列表;

      如果使用define_expand,根据条件逻辑可能出现3种情况:

        1. 条件逻辑有可能手动地在指令列表中创建新指令(通过emit_insn()完成),然后调用DONE结束。

        2. 对于特定的命名规则而言,条件逻辑可能调用FAIL通知编译器使用另一种方法来执行该任务。

        3. 如果条件逻辑既不调用DONE也不调用FAIL,则将规则中指定的模板插入到指令列表,这种情况下define_expand 等效于define_insn。

    Once the insn list is generated, various optimization passes convert, replace, and rearrange the insns in the insn list. This is where the define_split and define_peephole patterns get used, for example.

      一旦指令列表被生成,就进行各种优化,包括转换、替换和重新排列指令列表中的指令。这时就用到了诸如define_split和define_peephole之类的规则。

    Finally, the insn list’s RTL is matched up with the RTL templates in the define_insn patterns, and those patterns are used to emit the final assembly code. For this purpose, each named define_insn acts like it’s unnamed, since the names are ignored.

      最终,指令列表中的RTL与RTL模板中define_insn定义的规则相匹配,根据这些规则生成最终的汇编代码。为此,每一个命名的define_insn规则看起来并没有被命名,因为它们的名称被忽略了。

    1.2 指令规则详解(Everything about Instruction Patterns)


    define_insn expression is used to define instruction patterns to which insns may be matched. A define_insn expression contains an incomplete RTL expression, with pieces to be filled in later, operand constraints that restrict how the pieces can be filled in, and an output template or C code to generate the assembler output.

    define_insn表达式用于定义指令规则,指定关联何种指令。define_insn表达式包括:不完整RTL表达式(部分字段在之后才会填充)、操作数约束(限制如何填充这些字段)、输出模板或者相关C代码(生成汇编代码)。

    define_insn is an RTL expression containing four or five operands:

    define_insn是一种RTL表达式,包括4或5个操作数:

      1. An optional name. The presence of a name indicate that this instruction pattern can perform a certain standard job for the RTL-generation pass of the compiler. This pass knows certain names and will use the instruction patterns with those names, if the names are defined in the machine description.

      1. 可选的名称。如果给出名称,则说明该规则支持对应的标准操作。如果某些名称是在机器描述中定义的,则此过程知道这些名称,并将使用它们对应的指令规则。

        The absence of a name is indicated by writing an empty string where the name should go. Nameless instruction patterns are never used for generating RTL code, but they may permit several simpler insns to be combined later on.

        如果名称未给出(在名称字段书写一个空串),则该规则为无名规则。无名规则永不用于生成RTL代码,但是他们允许在以后合并一些更简单的指令。

        Names that are not thus known and used in RTL-generation have no effect; they are equivalent to no name at all.

        因此,在RTL生成中的未知名称没有任何效果;它们相当于完全没有名称。

        For the purpose of debugging the compiler, you may also specify a name beginning with the ‘*’ character. Such a name is used only for identifying the instruction in RTL dumps; it is equivalent to having a nameless pattern for all other purposes. Names beginning with the ‘*’ character are not required to be unique.

        为了调试编译器,可能要指定以`*`字符开始的名称。这类名称只标识RTL转储中的指令;它等价于有一个使用其它所有目的的无名规则。以`*`字符开始的名称不一定唯一。

      2. The RTL template: This is a vector of incomplete RTL expressions which describe the semantics of the instruction (see section RTL Template). It is incomplete because it may contain match_operandmatch_operator, and match_dup expressions that stand for operands of the instruction.If the vector has multiple elements, the RTL template is treated as a parallel expression.

      2. RTL模板。一个向量,包含不完整RTL表达式。该参数描述了指令的语义【参见: RTL模板(RTL Template)】。该表达式是不完整的,因为它可能包含match_operand、match_operator和 match_dup表达式,表示指令的操作数。如果该向量有多个元素,RTL模板将被视为并行表达式

      3. The condition: This is a string which contains a C expression. When the compiler attempts to match RTL against a pattern, the condition is evaluated. If the condition evaluates to true, the match is permitted. The condition may be an empty string, which is treated as always true.

      3. 条件。包含C表达式的字符串。当编译器尝试通过规则匹配RTL前,会先判断条件的值。如果取值为true,才允许匹配。条件参数可为空串,此时视其为永真值(true)。

        For a named pattern, the condition may not depend on the data in the insn being matched, but only the target-machine-type flags. The compiler needs to test these conditions during initialization in order to learn exactly which named instructions are available in a particular run.

        对于命名规则而言,除target-machine-type标志外,条件可不依赖于待匹配指令中的数据。编译器在初始化时需要测试这些条件,以确定当前有哪些指令可用。

        For nameless patterns, the condition is applied only when matching an individual insn, and only after the insn has matched the pattern’s recognition template. The insn’s operands may be found in the vector operands.

        对于无名规则而言,仅当匹配单个指令时,条件才发挥作用,而且仅当指令成功匹配到规则的识别模板之后,条件才有用。指令的操作数可在向量operands中找到。

        For an insn where the condition has once matched, it cannot later be used to control register allocation by excluding certain register or value combinations.

        已经成功进行条件匹配的指令,不能在之后通过排除某些寄存器或值组合来控制寄存器分配。

    4.The output template or output statement: This is either a string, or a fragment of C code which returns a string.

      4. 输出模板(或输出代码)。一个字符串,或者一个C代码片段(返回字符串)。

        When simple substitution isn’t general enough, you can specify a piece of C code to compute the output. See section C Statements for Assembler Output.

        当简单地替换不再满足需求时,你需要指定一个C代码片段来完成输出。【参考:用于汇编程序输出的C代码(C Statements for Assembler Output)】

    5. The insn attributes: This is an optional vector containing the values of attributes for insns matching this pattern (see section Instruction Attributes).

      5. 指令属性。一个可选的向量,包含匹配该规则的目标指令的属性值。【参考:指令属性(Instruction Attributes)】

    1.3 define_insn实例(Example of define_insn)


    Here is an example of an instruction pattern, taken from the machine description for the 68000/68020.

    这是一个指令规则的实例:(出自68000/68020架构的机器描述)

    	
    (define_insn "tstsi"
      [(set (cc0)
            (match_operand:SI 0 "general_operand" "rm"))]
      ""
      "*
    {
      if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
        return "tstl %0";
      return "cmpl #0,%0";
    }")

    This can also be written using braced strings:

    也可以写成花括号字符串的形式:

    (define_insn "tstsi"
      [(set (cc0)
            (match_operand:SI 0 "general_operand" "rm"))]
      ""
    {
      if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
        return "tstl %0";
      return "cmpl #0,%0";
    })

    (译者注:即直接将C代码片段书写在花括号{}中,而不必放到"包围的字符串里)

    This describes an instruction which sets the condition codes based on the value of a general operand. It has no condition, so any insn with an RTL description of the form shown may be matched to this pattern. The name ‘tstsi’ means “test a SImode value” and tells the RTL generation pass that, when it is necessary to test such a value, an insn to do so can be constructed using this pattern.

    上述代码描述了一条根据通用寄存器的值设置条件码的指令。我们没有为该规则指定条件,故任何具有上述RTL描述形式的指令都可能被匹配到该条规则。"tstsi"即“测试一个SImode值”。当有必要测试这个值时,RTL生成器将处理该规则,使用该规则构造对应的指令。

    The output control string is a piece of C code which chooses which output template to return based on the kind of operand and the specific type of CPU for which code is being generated.

    "rm"’ is an operand constraint. Its meaning is explained below.

    其中,输出控制字符串是一个C代码片段,用于根据操作数的种类以及指定的目标CPU来选择输出模板。

    "rm"’ 是一个操作数约束,它的含义将在下文解释。

    1.4 RTL模板(RTL Template)


    The RTL template is used to define which insns match the particular pattern and how to find their operands. For named patterns, the RTL template also says how to construct an insn from specified operands.

    RTL模板定义何种指令匹配何种特定的规则,以及如何寻找他们的操作数。对于命名规则而言,RTL模板也告诉我们如何从指定的操作数构造一条指令。

    Construction involves substituting specified operands into a copy of the template. Matching involves determining the values that serve as the operands in the insn being matched. Both of these activities are controlled by special expression types that direct matching and substitution of the operands.

    “构造”包括将指定操作数替换为模板的副本。“匹配”包括确定要匹配的指令中用作操作数的值。这些活动都受到特殊的表达式类型控制,这些表达式类型直接匹配和替换操作数。

    (match_operand:m n predicate constraint)

      This expression is a placeholder for operand number n of the insn. When constructing an insn, operand number n will be substituted at this point. When matching an insn, whatever appears at this position in the insn will be taken as operand number n; but it must satisfy predicate or this instruction pattern will not match at all.

      该表达式是一个占位符,表示指令的第n操作数。当构造一条指令时,将替换操作数n;当匹配一条指令时,指令中任何在此位置出现的内容都将被视为操作数n。但它必须满足predicate,否则不会匹配。

      Operand numbers must be chosen consecutively counting from zero in each instruction pattern. There may be only one match_operand expression in the pattern for each operand number. Usually operands are numbered in the order of appearance in match_operand expressions. In the case of a define_expand, any operand numbers used only in match_dup expressions have higher values than all other operand numbers.

      在每个指令规则中,操作数必须从零开始连续计数。对于每个操作数,规则中只能有一个match_operand 表达式。通常来说,在match_operand表达式中,操作数按出现顺序编号。在使用define_expand的情况下,任何仅用在match_dup表达式中的操作数必须比其他所有操作数具有更大的值。

      predicate is a string that is the name of a function that accepts two arguments, an expression and a machine mode. See section Predicates. During matching, the function will be called with the putative operand as the expression and m as the mode argument (if m is not specified, VOIDmode will be used, which normally causes predicate to accept any mode). If it returns zero, this instruction pattern fails to match. predicate may be an empty string; then it means no test is to be done on the operand, so anything which occurs in this position is valid.

      predicate是一个字符串,代表函数名称。该函数接受两个参数(expression和机器mode【参考:谓词(Predicates)】。在匹配过程中,该函数将被调用:推导出的操作数作为expression参数,m作为mode参数。(如果m未指定,将使用VOIDmode,使predicate接受任何模式)。如果该函数返回0,本次指令匹配将失败。predicate可以是一个空串,意味着不需要对操作数进行测试,任何可能的匹配都是有效的。

      Most of the time, predicate will reject modes other than m—but not always. For example, the predicate address_operand uses m as the mode of memory ref that the address should be valid for. Many predicates accept const_int nodes even though their mode is VOIDmode.

      大多数情况下,predicate将拒绝不是m的其它模式(但不绝对)。例如,谓词address_operand将m视作内存引用的模式,其中内存引用的地址必须有效。许多谓词接受const_int节点,尽管他们的模式是VOIDmode。

      constraint controls reloading and the choice of the best register class to use for a value, as explained later (see section Operand Constraints). If the constraint would be an empty string, it can be omitted.

      constraint控制Reload,并选择最适合当前值的寄存器类型【参考:操作数约束(Operand Constraints)】。约束可以是空串,可省略。

      People are often unclear on the difference between the constraint and the predicate. The predicate helps decide whether a given insn matches the pattern. The constraint plays no role in this decision; instead, it controls various decisions in the case of an insn which does match.

      人们常常不清楚约束(constraint)和谓词(predicate)之间的区别。谓词帮助决定给定的指令是否与规则匹配。约束在这个决策中不起作用;相反地,它在指令不匹配的情况下控制各种决策。

    (match_scratch:m n constraint)

      This expression is also a placeholder for operand number n and indicates that operand must be a scratch or reg expression.

      该表达式是一个占位符,表示指令的第n操作数。同时指出操作数必须是一个scratch或者reg类型的表达式。

      When matching patterns, this is equivalent to

      当进行规则的匹配时,该表达式等价于:  

      (match_operand:m n "scratch_operand" constraint)

      but, when generating RTL, it produces a (scratch:m) expression.

      当生成RTL时,该表达式产生一个(scratch:m)表达式。

      (scratch:m)

      If the last few expressions in a parallel are clobber expressions whose operands are either a hard register or match_scratch, the combiner can add or delete them when necessary. @xref{Side Effects}.

      如果parallel中最后几个表达式是clobber表达式,其操作数要么是硬件寄存器,要么是match_scratch指定的寄存器。“组合器”可以在必要时添加或删除它们。【注意:Side Effects】

    (match_dup n)

      This expression is also a placeholder for operand number n. It is used when the operand needs to appear more than once in the insn.

      该表达式也是一个占位符,表示指令的第n操作数。当操作数需要在指令中出现多次时使用。

      In construction, match_dup acts just like match_operand: the operand is substituted into the insn being constructed. But in matching, match_dup behaves differently. It assumes that operand number n has already been determined by a match_operand appearing earlier in the recognition template, and it matches only an identical-looking expression.

      在“构造”过程中,match_dup的行为与match_operand基本相同:操作数n被替换为正在构造的指令的操作数。但是在“匹配”过程中,match_dup的行为发生了改变。它假设操作数n已经由前面出现在识别模板中的match_operand确定,并且它只匹配特征相同的表达式。

      Note that match_dup should not be used to tell the compiler that a particular register is being used for two operands (example: add that adds one register to another; the second register is both an input operand and the output operand). Use a matching constraint (see section Simple Constraints) for those. match_dup is for the cases where one operand is used in two places in the template, such as an instruction that computes both a quotient and a remainder, where the opcode takes two input operands but the RTL template has to refer to each of those twice; once for the quotient pattern and once for the remainder pattern.

      注意,当两个操作数同时应用于某个特定寄存器时,不能使用match-dup来指明。(例如:add指令将一个寄存器的值加到另一个寄存器;其中第二个寄存器既是输入,又是输出),而应该使用匹配约束【参见:简单约束(Simple Constraints)】match_dup的真正目的是指明模板中的两个位置使用一个操作数的情况,例如一条同时计算商和余数的指令,其操作码接受两个输入,但是RTL模板不得不引用这两个操作数,一个用于求商规则,另一个用于求余规则。

    (match_operator:m n predicate [operands…])

      This pattern is a kind of placeholder for a variable RTL expression code.

      此规则是变量类型RTL表达式代码的占位符。

      When constructing an insn, it stands for an RTL expression whose expression code is taken from that of operand n, and whose operands are constructed from the patterns operands.

      当构造指令时,它代表一个RTL表达式,其表达式代码是从操作数n取出,并且操作数是根据operands构造的。

      When matching an expression, it matches an expression if the function predicate returns nonzero on that expression and the patterns operands match the operands of the expression.

      匹配表达式时,如果函数predicate返回非0,并且规则的操作数与表达式的操作数匹配,则源表达式匹配成功。

      Suppose that the function commutative_operator is defined as follows, to match any expression whose operator is one of the commutative arithmetic operators of RTL and whose mode is mode:

      假设函数commutative_operator定义如下,目标是匹配这样一个表达式:其算子为RTL规定的commutative运算符之一,并且其模式为mode

     1     
     2 int
     3 commutative_integer_operator (x, mode)
     4      rtx x;
     5      machine_mode mode;
     6 {
     7   enum rtx_code code = GET_CODE (x);
     8   if (GET_MODE (x) != mode)
     9     return 0;
    10   return (GET_RTX_CLASS (code) == RTX_COMM_ARITH
    11           || code == EQ || code == NE);
    12 }

      Then the following pattern will match any RTL expression consisting of a commutative operator applied to two general operands:

      然后,以下规则将匹配这样一个RTL表达式:由commutative运算符组成,并且应用于两个通用操作数。

    	
    (match_operator:SI 3 "commutative_operator"
      [(match_operand:SI 1 "general_operand" "g")
       (match_operand:SI 2 "general_operand" "g")])

      Here the vector [operands…] contains two patterns because the expressions to be matched all contain two operands.

      这里向量 [operands…] 包含了两个规则,因为待匹配的所有表达式都包含两个操作数。

      When this pattern does match, the two operands of the commutative operator are recorded as operands 1 and 2 of the insn. (This is done by the two instances of match_operand.) Operand 3 of the insn will be the entire commutative expression: use GET_CODE (operands[3]) to see which commutative operator was used.

      当该规则匹配时,commutative运算符的两个操作数分别被记为指令的操作数1和2。(这是由match_operand的两个实例完成的)。指令的操作数3就是个commutative表达式:使用GET_CODE (operands[3])来查询该表达式是哪一commutative运算符。

      The machine mode m of match_operator works like that of match_operand: it is passed as the second argument to the predicate function, and that function is solely responsible for deciding whether the expression to be matched “has” that mode.

      match_operator中指定的机器模式m与match_operand中指定的类似。它作为第二个参数传递给predicate函数,该函数只决定要匹配的表达式是否“具有”该模式。

      When constructing an insn, argument 3 of the gen-function will specify the operation (i.e. the expression code) for the expression to be made. It should be an RTL expression, whose expression code is copied into a new expression whose operands are arguments 1 and 2 of the gen-function. The subexpressions of argument 3 are not used; only its expression code matters.

      当构造指令时,生成函数(gen-function)的参数3指定要产生的表达式的操作(即表达式编码)。它应该是一个RTL表达式,其表达式代码被复制到一个新表达式中,该表达式的操作数是gen函数的参数1和2。不使用参数3的子表达式,而是只关心其表达式编码。

      When match_operator is used in a pattern for matching an insn, it usually best if the operand number of the match_operator is higher than that of the actual operands of the insn. This improves register allocation because the register allocator often looks at operands 1 and 2 of insns to see if it can do register tying.

      通常,在规则中使用match_operator匹配指令时,match_operator的操作数应大于指令的实际操作数。这有助于改进寄存器分配,因为寄存器分配器经常检查指令的操作数1和2,以判断是否可以进行寄存器tying。

      There is no way to specify constraints in match_operator. The operand of the insn which corresponds to the match_operator never has any constraints because it is never reloaded as a whole. However, if parts of its operands are matched by match_operand patterns, those parts may have constraints of their own.

      不能在match_operator中指定约束。match_operator对应的指令的操作数根本没有约束,因为它不可能作为一个整体Reload。但是,如果部分操作数与match_operand规则相匹配,则这些部分可能有自己的约束。

    (match_op_dup:m n[operands…])

      Like match_dup, except that it applies to operators instead of operands. When constructing an insn, operand number n will be substituted at this point. But in matching, match_op_dup behaves differently. It assumes that operand number n has already been determined by a match_operator appearing earlier in the recognition template, and it matches only an identical-looking expression.

      与match_dup类似,只是它应用于运算符而不是操作数。在构造指令时,操作数n将在相应位置被替换;但在匹配中,match_op_dup的行为不同。它假设操作数n已经被前面出现在识别模板中的match_operator确定,并且它只匹配特征相同的表达式。

    (match_parallel n predicate [subpat…])

      This pattern is a placeholder for an insn that consists of a parallel expression with a variable number of elements. This expression should only appear at the top level of an insn pattern.

      该规则为一条指令的占位符,该指令由一个具有可变元素数的并行表达式组成。这个表达式应该只出现在指令规则的顶层。

      When constructing an insn, operand number n will be substituted at this point. When matching an insn, it matches if the body of the insn is a parallel expression with at least as many elements as the vector of subpat expressions in the match_parallel, if each subpat matches the corresponding element of the paralleland the function predicate returns nonzero on the parallel that is the body of the insn. It is the responsibility of the predicate to validate elements of the parallel beyond those listed in the match_parallel.

      当构造指令时,操作数n在相应位置被替换;当匹配指令时,若满足如下条件中的一个,则匹配成功:1. 指令的主体是一个并行表达式,并且其元素数量至少应与match_parallel中的subpat表达式向量数量相同;2. 每个subpat与并行表达式对应的元素匹配,并且函数predicate返回非0。predicate的任务是验证并行表达式的元素(除在match_parallel中列出的元素外)。

      A typical use of match_parallel is to match load and store multiple expressions, which can contain a variable number of elements in a parallel. For example,

      match_parallel的典型用途是匹配load和store复合表达式,在并行表达式中包含可变数量的元素。例如:

    	
    (define_insn ""
      [(match_parallel 0 "load_multiple_operation"
         [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
               (match_operand:SI 2 "memory_operand" "m"))
          (use (reg:SI 179))
          (clobber (reg:SI 179))])]
      ""
      "loadm 0,0,%1,%2")

      This example comes from ‘a29k.md’. The function load_multiple_operation is defined in ‘a29k.c’ and checks that subsequent elements in the parallel are the same as the set in the pattern, except that they are referencing subsequent registers and memory locations.

      该实例出自'a29k.md'文件。函数load_multiple_operation定义在'a29k.c'中。该函数检查并行表达式中的后续元素是否与规则中的set相同,除非它们引用的是后续寄存器和内存位置。

      An insn that matches this pattern might look like:

      一个匹配该规则的指令类似这样:

    	
    (parallel
     [(set (reg:SI 20) (mem:SI (reg:SI 100)))
      (use (reg:SI 179))
      (clobber (reg:SI 179))
      (set (reg:SI 21)
           (mem:SI (plus:SI (reg:SI 100)
                            (const_int 4))))
      (set (reg:SI 22)
           (mem:SI (plus:SI (reg:SI 100)
                            (const_int 8))))])

    (match_par_dup n [subpat…])

      Like match_op_dup, but for match_parallel instead of match_operator.

      类似于match_op_dup,但是该规则适用于match_parallel,而不是match_operator。

    1.5 输出模板、操作数替换(Output Templates and Operand Substitution)


    The output template is a string which specifies how to output the assembler code for an instruction pattern. Most of the template is a fixed string which is output literally. The character ‘%’ is used to specify where to substitute an operand; it can also be used to identify places where different variants of the assembler require different syntax.

    输出模板是一个字符串,指定如何为指令规则输出汇编代码。大多数模板是一个字符串常量,按照字面量输出。字符'%'被用来指定操作数替换的位置。当存在编译器变体时,它也用于识别这些不同编译器的语法。

    In the simplest case, a ‘%’ followed by a digit n says to output operand n at that point in the string.

    在最简情况下,'%'后面紧跟着一个数n,指定在该位置输出操作数n。

    %’ followed by a letter and a digit says to output an operand in an alternate fashion. Four letters have standard, built-in meanings described below. The machine description macro PRINT_OPERAND can define additional letters with nonstandard meanings.

    '%'后面紧跟一个字母和数字,指定以另一种方式输出操作数。4个字母具有以下所述的标准内置含义。机器描述宏PRINT_OPERAND可以定义具有非标准含义的附加字母。

    %cdigit’ can be used to substitute an operand that is a constant value without the syntax that normally indicates an immediate operand.

    %cdigit’ 可以用来替换一个常量值操作数,而不需要用来指定立即数的语法。

    %ndigit’ is like ‘%cdigit’ except that the value of the constant is negated before printing.

    %ndigit’ 类以于‘%cdigit’ ,只是在打印之前常量的值被取反。

    %adigit’ can be used to substitute an operand as if it were a memory reference, with the actual operand treated as the address. This may be useful when outputting a “load address” instruction, because often the assembler syntax for such an instruction requires you to write the operand as if it were a memory reference.

    %adigit’ 用于将操作数当作内存引用替换为实际的地址操作数。这在输出“Load address”指令时很有用,因为此类指令的汇编语法通常要求将操作数当作内存引用来编写。

    %ldigit’ is used to substitute a label_ref into a jump instruction.

    %ldigit’ 用于替换label_ref为跳转指令。

    %=’ outputs a number which is unique to each instruction in the entire compilation. This is useful for making local labels to be referred to more than once in a single template that generates multiple assembler instructions.

    输出一个数字,该数字对整个编译过程中的每条指令都是唯一的。倘若单个模板中要生成多个汇编程序指令,并且要重复引用局部标签,则该格式非常有用。

    %’ followed by a punctuation character specifies a substitution that does not use an operand. Only one case is standard: ‘%%’ outputs a ‘%’ into the assembler code. Other nonstandard cases can be defined in the PRINT_OPERAND macro. You must also define which punctuation characters are valid with the PRINT_OPERAND_PUNCT_VALID_P macro.

    %’ 紧跟一个标点字符,指定不进行操作数替换(译者注:转义)。标准只规定一种情况:“%”将在汇编代码中输出“%”。其他非标准情况可以在PRINT_OPERAND宏中定义。同时必须定义哪些标点字符对PRINT_OPERAND_PUNCT_VALID_P宏有效。

    The template may generate multiple assembler instructions. Write the text for the instructions, with ‘;’ between them.

    模板可以生成多个汇编指令。编写指令文本时,在指令之间添加“;”。

    When the RTL contains two operands which are required by constraint to match each other, the output template must refer only to the lower-numbered operand. Matching operands are not always identical, and the rest of the compiler arranges to put the proper RTL expression for printing into the lower-numbered operand.

    当RTL包含两个操作数,且约束指明这两个操作数相互匹配时,输出模板只能引用编号较低的操作数。匹配的操作数并不总是相同,因此编译器的其余部分会安排将正确的RTL表达式打印到这个编号较低的操作数中。

    One use of nonstandard letters or punctuation following ‘%’ is to distinguish between different assembler languages for the same machine; for example, Motorola syntax versus MIT syntax for the 68000. Motorola syntax requires periods in most opcode names, while MIT syntax does not. For example, the opcode ‘movel’ in MIT syntax is ‘move.l’ in Motorola syntax. The same file of patterns is used for both kinds of output syntax, but the character sequence ‘%.’ is used in each place where Motorola syntax wants a period. The PRINT_OPERAND macro for Motorola syntax defines the sequence to output a period; the macro for MIT syntax defines it to do nothing.

    “%”紧跟非标准字母或标点字符格式的一种用法是区分同一机器的不同汇编语言;例如,Motorola语法与MIT 68000语法。在大多数操作码名称中,Motorola语法需要句点,而MIT语法则不需要句点。例如:操作码‘movel’在MIT语法中写作‘movel’,在Motorola语法中写作‘move.l’。两种语法都使用相同的规则文件,但在Motorola语法中,每个句点的地方都换成 ‘%.’ 。Motorola语法定义PRINT_OPERAND宏,使序列输出句点;而MIT语法的宏定义则指明‘%.’不执行任何操作。

    As a special case, a template consisting of the single character # instructs the compiler to first split the insn, and then output the resulting instructions separately. This helps eliminate redundancy in the output templates. If you have a define_insn that needs to emit multiple assembler instructions, and there is a matching define_split already defined, then you can simply use # as the output template instead of writing an output template that emits the multiple assembler instructions.

    特殊情况下,当模板由单个字符`#`组成时,编译器将首先对指令拆分,然后分别输出生成的指令。这将有助于减少输出模板中的冗余。如果define_insn需要发射多条汇编指令,并且匹配的define_split已经定义,则你可以简单地使用#作为输出模板,而不是编写发射多条汇编指令的输出模板。

    If the macro ASSEMBLER_DIALECT is defined, you can use construct of the form ‘{option0|option1|option2}’ in the templates. These describe multiple variants of assembler language syntax. @xref{Instruction Output}.

     如果已经定义了宏ASSEMBLER_DIALECT,则你可以在模板中使用 ‘{option0|option1|option2}’ 形式的指令构造。它们描述了汇编语法的多种变体【参考:指令输出(Instruction Output)】

    1.6 (用于汇编程序输出的C代码)C Statements for Assembler Output


    Often a single fixed template string cannot produce correct and efficient assembler code for all the cases that are recognized by a single instruction pattern. For example, the opcodes may depend on the kinds of operands; or some unfortunate combinations of operands may require extra machine instructions.

    通常,在被单个指令规则识别的所有情况中,一个固定的模板字符串不能生成正确有效的汇编代码。例如,操作码可能取决于操作数的种类;或者某些糟糕的操作数组合可能需要额外的机器指令。

    If the output control string starts with a ‘@’, then it is actually a series of templates, each on a separate line. (Blank lines and leading spaces and tabs are ignored.) The templates correspond to the pattern’s constraint alternatives (see section Multiple Alternative Constraints). For example, if a target machine has a two-address add instruction ‘addr’ to add into a register and another ‘addm’ to add a register to memory, you might write this pattern:

    如果输出控制字符串以‘@’开始,则它实际上是一系列的模板。且每行一个模板(忽略空行和前导空格/制表符)。每个模板对应该规则的备选约束【参考:多重备选约束(Multiple Alternative Constraints)】。例如,如果目标架构有两个地址加法指令:“addr”将结果放到寄存器中;“addm”将寄存器得出的结果放到内存中,则可以按下面的例子编写输出控制字符串。

    (define_insn "addsi3"
      [(set (match_operand:SI 0 "general_operand" "=r,m")
            (plus:SI (match_operand:SI 1 "general_operand" "0,0")
                     (match_operand:SI 2 "general_operand" "g,r")))]
      ""
      "@
       addr %2,%0
       addm %2,%0")

    If the output control string starts with a ‘*’, then it is not an output template but rather a piece of C program that should compute a template. It should execute a return statement to return the template-string you want. Most such templates use C string literals, which require doublequote characters to delimit them. To include these doublequote characters in the string, prefix each one with ‘’.

    如果输出控制字符串以‘*’开始,则它不是输出模板,而是一个计算出模板的C程序。C程序将执行return语句返回需要的模板字符串。大多数模板会用到C字符串语法,即使用双引号"来分割字符串。要在模板字符串中包含这些双引号字符,请在每个字符前面加上‘’。

    If the output control string is written as a brace block instead of a double-quoted string, it is automatically assumed to be C code. In that case, it is not necessary to put in a leading asterisk, or to escape the doublequotes surrounding C string literals.

    如果输出控制字符串是被大括号块{}包围,而不是被双引号""包围,则默认输出控制字符串是C代码。在这种情况下,C代码不必放在前导‘*’中,也不必转义C字符串前后的双引号。

    The operands may be found in the array operands, whose C data type is rtx [].

    操作数可以在数组operands中找到,其C数据类型为rtx []。

    It is very common to select different ways of generating assembler code based on whether an immediate operand is within a certain range. Be careful when doing this, because the result of INTVAL is an integer on the host machine. If the host machine has more bits in an int than the target machine has in the mode in which the constant will be used, then some of the bits you get from INTVAL will be superfluous. For proper results, you must carefully disregard the values of those bits.

    经常出现这种情况:需要根据立即数是否在某个范围内,选择不同的方法生成汇编代码。这时需要特别留意,因为INTVAL的结果是宿主机的整数范围。如果宿主机的int的位数比目标机器相同模式下常量int的位数多,那么从INTVAL获得的一些位是多余的。为了得到正确的结果,必须小心地忽略这些位的值。

    It is possible to output an assembler instruction and then go on to output or compute more of them, using the subroutine output_asm_insn. This receives two arguments: a template-string and a vector of operands. The vector may be operands, or it may be another array of rtx that you declare locally and initialize yourself.

    调用子程序output_asm_insn可以输出一条汇编指令,然后继续输出或计算更多的汇编指令。该子程序接收两个参数:一个模板字符串、一个操作数向量。向量可以是operands,也可以是另一个在本地声明并初始化的rtx数组。

    When an insn pattern has multiple alternatives in its constraints, often the appearance of the assembler code is determined mostly by which alternative was matched. When this is so, the C code can test the variable which_alternative, which is the ordinal number of the alternative that was actually satisfied (0 for the first, 1 for the second alternative, etc.).

    当指令规则有多重备选约束时,汇编代码的结果通常取决于匹配到哪个备选约束。如此,C代码可以通过测试变量which_alternative得出匹配到的约束的序号(0为第一个,1为第二个,以此类推)。

    For example, suppose there are two opcodes for storing zero, ‘clrreg’ for registers and ‘clrmem’ for memory locations. Here is how a pattern could use which_alternative to choose between them:

    例如:假设有两个用来存储0的操作数: ‘clrreg’存储到寄存器, ‘clrmem’ 存储到内存位置。接下来演示指令规则如何通过which_alternative来从中二选一。

    1     
    2 (define_insn ""
    3   [(set (match_operand:SI 0 "general_operand" "=r,m")
    4         (const_int 0))]
    5   ""
    6   {
    7   return (which_alternative == 0
    8           ? "clrreg %0" : "clrmem %0");
    9   })

    The example above, where the assembler code to generate was solely determined by the alternative, could also have been specified as follows, having the output control string start with a ‘@’:

    上述实例中生成的汇编代码是由备选约束单独决定的。也可以用下面的方法,输出控制字符串以‘@’开头:

    1 (define_insn ""
    2   [(set (match_operand:SI 0 "general_operand" "=r,m")
    3         (const_int 0))]
    4   ""
    5   "@
    6    clrreg %0
    7    clrmem %0")

    If you just need a little bit of C code in one (or a few) alternatives, you can use ‘*’ inside of a ‘@’ multi-alternative template:

    如果在一个(或多个)备选约束中只需要很少的C代码,可以在一个‘@’多备选模板中使用‘*’:

    (define_insn ""
      [(set (match_operand:SI 0 "general_operand" "=r,<,m")
            (const_int 0))]
      ""
      "@
       clrreg %0
       * return stack_mem_p (operands[0]) ? "push 0" : "clrmem %0";
       clrmem %0")

    1.7 谓词(Predicates)


    A predicate determines whether a match_operand or match_operator expression matches, and therefore whether the surrounding instruction pattern will be used for that combination of operands. GCC has a number of machine-independent predicates, and you can define machine-specific predicates as needed. By convention, predicates used with match_operand have names that end in ‘_operand’, and those used with match_operator have names that end in ‘_operator’.

    谓词决定是否匹配match_operand或者match_operator表达式,并因此决定附近的指令规则能否用于操作数的合并。GCC有很多机器无关的谓词,你也可以定义机器相关的谓词。方便起见,规定与match_operand一起使用的谓词,其名称应以 ‘_operand’结尾;与match_operator一起使用的谓词,其名称以 ‘_operator’结尾。

    All predicates are Boolean functions (in the mathematical sense) of two arguments: the RTL expression that is being considered at that position in the instruction pattern, and the machine mode that the match_operand or match_operator specifies. In this section, the first argument is called op and the second argument mode. Predicates can be called from C as ordinary two-argument functions; this can be useful in output templates or other machine-specific code.

    所有谓词都是Boolean类型的函数,有2个参数:op:指令规则正在考虑的RTL表达式;mode:match_operand或者match_operator指定的机器模式。(参数名称仅限于本节)。

    可从C代码调用谓词(其实就是一个普通的两参数函数);这种特性在输出模板或其他机器特定代码中是有用的。吐槽

    Operand predicates can allow operands that are not actually acceptable to the hardware, as long as the constraints give reload the ability to fix them up (see section Operand Constraints). However, GCC will usually generate better code if the predicates specify the requirements of the machine instructions as closely as possible. Reload cannot fix up operands that must be constants (“immediate operands”); you must use a predicate that allows only constants, or else enforce the requirement in the extra condition.

    操作数谓词允许实际不在硬件中的操作数(只要约束赋予Reload修复它们的能力【参考:操作数约束(Operand Constraints)】)。然而,如果谓词尽可能详细地指定机器指令的要求,GCC一般能生成更好的代码。Reload不能修复必须是常量的操作数(立即数);这种情况下必须使用只允许常量的谓词,否则在附加条件中会强制执行该要求。

    Most predicates handle their mode argument in a uniform manner. If mode is VOIDmode (unspecified), then op can have any mode. If mode is anything else, then op must have the same mode, unless op is a CONST_INT or integer CONST_DOUBLE. These RTL expressions always have VOIDmode, so it would be counterproductive to check that their mode matches. Instead, predicates that accept CONST_INT and/or integer CONST_DOUBLE check that the value stored in the constant will fit in the requested mode.

    大多数谓词以统一的方法处理mode参数。如果mode为VOIDmode(未指定),则op可以是任意模式。如果mode是其它模式,则op必须是与之相同模式,除非op是CONST_INT或者integer CONST_DOUBLE。因为这些被排除的RTL表达式总为VOIDmode模式,所以检查他们的模式是否匹配会适得其反。相反地,接受CONST_INT 和/或者 integer CONST_DOUBLE的谓词需要检查存储在常量中的值是否符合给出的模式。

    Predicates with this behavior are called normalgenrecog can optimize the instruction recognizer based on knowledge of how normal predicates treat modes. It can also diagnose certain kinds of common errors in the use of normal predicates; for instance, it is almost always an error to use a normal predicate without specifying a mode.

    具有这些行为的谓词被称为normal谓词。genrecog可以根据normal谓词如何处理模式的知识来优化指令识别器。它还可以诊断normal谓词使用中的某些常见错误。例如:在不指定模式的情况下使用normal谓词基本上是错误的。

    Predicates that do something different with their mode argument are called special. The generic predicates address_operand and pmode_register_operand are special predicates. genrecog does not do any optimizations or diagnosis when special predicates are used.

    具体行为与mode参数不同的谓词称为special谓词。通用谓词address_operand和pmode_register_operand是special谓词。genrecog不对special谓词做任何优化或诊断。

    子目录


    1.7.1 Machine-Independent Predicates Predicates available to all back ends.

    1.7.1 机器无关谓词(对所有后端可用)
    1.7.2 Defining Machine-Specific Predicates How to write machine-specific predicate functions.

    1.7.2 定义机器相关谓词(如何编写机器相关谓词函数)

    1.7.1 机器无关谓词(Machine-Independent Predicates)


    These are the generic predicates available to all back ends. They are defined in ‘recog.c’. The first category of predicates allow only constant, or immediate, operands.

    对于所有后端都通用的谓词如下。定义在‘recog.c’文件中。

    (译者注:在下文中,“允许”即判断之意,即断定该对象是否被允许。) 

    第一类谓词允许常量(constant)、立即数(immediate)和操作数(operands):

    Function: immediate_operand

      This predicate allows any sort of constant that fits in mode. It is an appropriate choice for instructions that take operands that must be constant.

      该谓词允许符合mode的所有常量。适合于操作数为常量的指令。

    Function: const_int_operand

      This predicate allows any CONST_INT expression that fits in mode. It is an appropriate choice for an immediate operand that does not allow a symbol or label.

      该谓词允许符合mode的所有CONST_INT表达式。适合于不是符号或者标签的立即数。

    Function: const_double_operand

      This predicate accepts any CONST_DOUBLE expression that has exactly mode. If mode is VOIDmode, it will also accept CONST_INT. It is intended for immediate floating point constants.

      该谓词接受准确符合mode的任意CONST_DOUBLE表达式。如果mode为VOIDmode,它将接受CONST_INT。适合于浮点立即数。

    The second category of predicates allow only some kind of machine register.

    第二类谓词允许机器寄存器:

    Function: register_operand

      This predicate allows any REG or SUBREG expression that is valid for mode. It is often suitable for arithmetic instruction operands on a RISC machine.

      该谓词只允许符合mode的REG或者SUBREG表达式。基本适合于RISC机器的算术指令操作数。

    Function: pmode_register_operand

      This is a slight variant on register_operand which works around a limitation in the machine-description reader.

      register_operand的变种。用于在机器描述Reader中绕过限制。

        (match_operand n "pmode_register_operand" constraint)

      如果Reader能接受‘:P’模式后缀的话,上面这句话等价于:

        (match_operand:P n "register_operand" constraint)

      不幸的是,现实并非如此,因为pmode是某些其他模式的别名,并且可能因机器相关选项而异。

      would mean, if the machine-description reader accepted ‘:P’ mode suffixes. Unfortunately, it cannot, because Pmode is an alias for some other mode, and might vary with machine-specific options. @xref{Misc}.

    Function: scratch_operand

      This predicate allows hard registers and SCRATCH expressions, but not pseudo-registers. It is used internally by match_scratch; it should not be used directly.

      该谓词允许硬件寄存器、SCRATCH表达式,但是不允许伪寄存器。该谓词应由match_scratch内部调用,不能被直接使用。

    The third category of predicates allow only some kind of memory reference.

    第三类谓词允许内存引用:

    Function: memory_operand

      This predicate allows any valid reference to a quantity of mode mode in memory, as determined by the weak form of GO_IF_LEGITIMATE_ADDRESS (@pxref{Addressing Modes}).

      该谓词允许符合一些mode的、有效的引用,由GO_IF_LEGITIMATE_ADDRESS的week形式指定。

    Function: address_operand

      This predicate is a little unusual; it allows any operand that is a valid expression for the address of a quantity of mode mode, again determined by the weak form of GO_IF_LEGITIMATE_ADDRESS. To first order, if ‘(mem:mode (exp))’ is acceptable to memory_operand, then exp is acceptable to address_operand. Note that exp does not necessarily have the mode mode.

      该谓词不常见。允许有效的地址表达式,其值为符合一些mode的地址。由GO_IF_LEGITIMATE_ADDRESS的week形式指定。对于一阶而言,如果 ‘(mem:mode (exp))’接受memory_operand,则exp接受address_operand。注意exp不一定符合mode

      (译者注:FIXME)

    Function: indirect_operand

      This is a stricter form of memory_operand which allows only memory references with a general_operand as the address expression. New uses of this predicate are discouraged, because general_operand is very permissive, so it’s hard to tell what an indirect_operand does or does not allow. If a target has different requirements for memory operands for different instructions, it is better to define target-specific predicates which enforce the hardware’s requirements explicitly.

       这是一个形式上比memory_operand更严格的谓词。它只允许使用general_operand的内存引用作为地址表达式。不鼓励使用这个谓词,因为general_operand非常任性,很难指出一个indirect_operand是允许的还是不允许的。如果目标对不同指令的内存操作数有不同的要求,最好定义特定于目标的谓词,这些谓词显式地强制硬件需求。

    Function: push_operand

      This predicate allows a memory reference suitable for pushing a value onto the stack. This will be a MEM which refers to stack_pointer_rtx, with a side-effect in its address expression (@pxref{Incdec}); which one is determined by the STACK_PUSH_CODE macro (@pxref{Frame Layout}).

      该谓词允许一个适用于压栈操作的内存引用,即引用stack_pointer_rtx的MEM,其地址表达式会有副作用。

    Function: pop_operand

      This predicate allows a memory reference suitable for popping a value off the stack. Again, this will be a MEM referring to stack_pointer_rtx, with a side-effect in its address expression. However, this time STACK_POP_CODE is expected.

      该谓词允许一个适用于弹栈的内存引用,这同样是一个引用stack_pointer_rtx的MEM,其地址表达式会有副作用。然而,此时必须有STACK_POP_CODE。

    The fourth category of predicates allow some combination of the above operands.

    第四类谓词允许上述操作数的组合:

    Function: nonmemory_operand

      This predicate allows any immediate or register operand valid for mode.

      该谓词允许符合mode的任意立即数或者寄存器操作数。

    Function: nonimmediate_operand

      This predicate allows any register or memory operand valid for mode.

      该谓词允许符合mode的任意寄存器或者内存操作数。

    Function: general_operand

      This predicate allows any immediate, register, or memory operand valid for mode.

      该谓词允许符合mode的任意立即数、寄存器、内存操作数。

    Finally, there are two generic operator predicates.

    最后,共有2种通用的运算符谓词。

    Function: comparison_operator

      This predicate matches any expression which performs an arithmetic comparison in mode; that is, COMPARISON_P is true for the expression code.

      该谓词匹配符合mode的任意执行算术比较的表达式,即对于表达式代码COMPARISON_P为true。

    Function: ordered_comparison_operator

      This predicate matches any expression which performs an arithmetic comparison in mode and whose expression code is valid for integer modes; that is, the expression code will be one of eqneltltuleleugtgtugegeu.

      该谓词匹配符合mode的任意执行算术比较的表达式,并且表达式代码可用于整数mode,即表达式代码为如下中的一个:eqneltltuleleugtgtugegeu。

    1.7.2 定义机器相关谓词(Defining Machine-Specific Predicates)


    Many machines have requirements for their operands that cannot be expressed precisely using the generic predicates. You can define additional predicates using define_predicate and define_special_predicate expressions. These expressions have three operands:

    很多时候不能用泛型谓词精确表示机器对操作数的需求。你可以使用define_predicate和define_special_predicate表达式定义额外的谓词,这些谓词包含3个操作数:

      · The name of the predicate, as it will be referred to in match_operand or match_operator expressions.

      · 谓词的名称,它将在match_operand或者match_operator表达式中被引用。

      · An RTL expression which evaluates to true if the predicate allows the operand op, false if it does not. This expression can only use the following RTL codes:

      · 一个布尔值的RTL表达式,如果谓词允许操作数op,则值为true;否则值为false。该表达式只能使用如下的RTL代码:

        MATCH_OPERAND

          When written inside a predicate expression, a MATCH_OPERAND expression evaluates to true if the predicate it names would allow op. The operand number and constraint are ignored. Due to limitations in genrecog, you can only refer to generic predicates and predicates that have already been defined.

          如果MATCH_OPERAND表达式被写在一个谓词表达式的内部,并且MATCH_OPERAND命名的谓词允许操作数op,则MATCH_OPERAND值为true,操作数编号和约束将被忽略。由于genrecog的相关限制,你只能引用已经定义的泛型谓词和谓词。

        MATCH_CODE

          This expression evaluates to true if op or a specified subexpression of op has one of a given list of RTX codes.

          如果操作数op或者指定的子表达式op具有给定的RTX代码列表之一时,该表达式值为true。

  • 相关阅读:
    关于HashMap的线程安全问题
    Java利器之UML类图详解
    mongoDB4.0数据库
    requests-html库render的使用
    爬虫最新的库requests-html库总结
    爬虫多次爬取时候cookie的存储用于登入
    requests模块响应体属性和方法重新整理
    Visual Studio 代码补全功能有时候会失效的原因
    C++Primer笔记——文本查询程序(原创,未使用类)
    Clion 常用快捷键
  • 原文地址:https://www.cnblogs.com/cassuto/p/11564031.html
Copyright © 2011-2022 走看看