本手冊適合須要深刻分析GCC工做原理,或須要爲GCC後端適配新的CPU架構的技術人員查閱。html
持續更新,轉載請註明出處:www.cnblogs.com/sci-dev/前端
本翻譯所遵循的術語規範:node
機器描述:Machine Descriptiongit
指令規則:Insn Patternexpress
操做數約束:Operand Constraints編程
匹配約束:Matching Constraints後端
標準操做:Standard Operation數組
窺孔優化:Peephole Optimization架構
並行表達式:Parallel Experssionapp
識別模板: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語言頭文件。
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規則看起來並無被命名,由於它們的名稱被忽略了。
A 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代碼(生成彙編代碼)。
A 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_operand
, match_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)】
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"’ 是一個操做數約束,它的含義將在下文解釋。
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 parallel
, and 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。
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)】。
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")
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 normal. genrecog
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 定義機器相關謂詞(如何編寫機器相關謂詞函數)
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 eq
, ne
, lt
, ltu
, le
, leu
, gt
, gtu
, ge
, geu
.
該謂詞匹配符合mode的任意執行算術比較的表達式,而且表達式代碼可用於整數mode,即表達式代碼爲以下中的一個:eq
, ne
, lt
, ltu
, le
, leu
, gt
, gtu
, ge
, geu。
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。