春晖寸草 / 语言 / GNU C语言指导(下)

分享

   

GNU C语言指导(下)

2011-01-03  春晖寸草

汇编指令和C表达式操作数

In an assembler instruction using asm , you can specify the operands of the instruction using C expressions.在汇编指令使用asm ,您可以指定使用C表达式操作数的指令。 This means you need not guess which registers or memory locations will contain the data you want to use.这意味着你不必猜测哪些寄存器或存储单元将包含您要使用的数据。

You must specify an assembler instruction template much like what appears in a machine description, plus an operand constraint string for each operand.您必须指定一个汇编指令的模板非常喜欢描述出现在一台机器,外加每个操作数操作数约束字符串。

For example, here is how to use the 68881's fsinx instruction:例如,下面是如何使用68881fsinx指令:

      asm ("fsinx %1,%0" : "=f" (result) : "f" (angle));汇编(“fsinx1,%0”“= f”的(结果):“F”类(角度));
     

Here angle is the C expression for the input operand while result is that of the output operand.这里angle是输入操作数为C的表达,而result是,运算输出。 Each has "f" as its operand constraint, saying that a floating point register is required. The = in =f indicates that the operand is an output; all output operands' constraints must use = .每个人都有"f"作为其操作数的约束,说一个浮点寄存器所需的。 ==f表示操作数是一个输出,所有输出操作数的限制,必须使用= The constraints use the same language used in the machine description (see Constraints ).的限制使用相同的语言看到用于在机器的描述( 约束 )。

Each operand is described by an operand-constraint string followed by the C expression in parentheses.每个操作数的描述是括号中的C表达式字符串之后由一个操作数约束。 A colon separates the assembler template from the first output operand and another separates the last output operand from the first input, if any.冒号分隔汇编模板输出操作数从第一次和另一个分离的第一个输入输出操作数从最后,如果有的话。 Commas separate the operands within each group.逗号分隔每个组的操作数内。 The total number of operands is currently limited to 30; this limitation may be lifted in some future version of GCC.操作数的总数目前仅限于30,这是海湾合作委员会取消限制可能在将来的版本。

If there are no output operands but there are input operands, you must place two consecutive colons surrounding the place where the output operands would go.如果没有输出操作数,但也有输入操作数,你必须将两个连续的冒号会去的地方,周围的输出操作数。

As of GCC version 3.1, it is also possible to specify input and output operands using symbolic names which can be referenced within the assembler code.由于GCC版本3.1,它也可以指定输入和输出操作数的符号名称使用汇编代码可以被引用该范围内。 These names are specified inside square brackets preceding the constraint string, and can be referenced inside the assembler code using %[ name ] instead of a percentage sign followed by the operand number.这些名称是指定字符串方括号内的限制前,可以使用汇编代码里面引用%[ 名称 ] ,而不是一个百分比符号数其次是操作数。 Using named operands the above example could look like:使用命名操作数的上面的例子可以是这样的:

      asm ("fsinx %[angle],%[output]"汇编(“fsinx[][输出]”
          : [output] "=f" (result) [输出]“= f”的(结果)
          : [angle] "f" (angle)); []“F”(角));
     

Note that the symbolic operand names have no relation whatsoever to other C identifiers.请注意,符号操作数名没有任何关系到其他C标识符。 You may use any name you like, even those of existing C symbols, but you must ensure that no two operands within the same assembler construct use the same symbolic name.你可以使用任何你喜欢的名字,甚至符号的现有C,但你必须确保没有两个相同的汇编操作数使用相同的内部构造的符号名称。

Output operand expressions must be lvalues; the compiler can check this. The input operands need not be lvalues.输出操作数表达式必须是左值,编译器可以检查此左值。输入操作数不需要。 The compiler cannot check whether the operands have data types that are reasonable for the instruction being executed.编译器不能检查是否有数据类型的操作数所执行的指令是合理的。 It does not parse the assembler instruction template and does not know what it means or even whether it is valid assembler input.它不分析汇编指令模板,不知道这意味着什么,甚至它是否是有效的汇编器输入。 The extended asm feature is most often used for machine instructions the compiler itself does not know exist.扩展asm的特点是通常用于机器指令的编译器本身并不知道存在。 If the output expression cannot be directly addressed (for example, it is a bit-field), your constraint must allow a register.如果输出表达式不能直接处理(例如,它是一个位域),您的约束必须允许登记。 In that case, GCC will use the register as the output of the asm , and then store that register into the output.在这种情况下,GCC将使用寄存器的输出作为asm ,然后存储到输出寄存器。

The ordinary output operands must be write-only; GCC will assume that the values in these operands before the instruction are dead and need not be generated.普通输出操作数必须是只写的; GCC将承担该指令的操作数,然后在这些值是死的,不必产生。 Extended asm supports input-output or read-write operands.扩展ASM支持输入输出或读写操作数。 Use the constraint character + to indicate such an operand and list it with the output operands.使用限制字符+表示这样的操作,并列出它的输出操作数。

When the constraints for the read-write operand (or the operand in which only some of the bits are to be changed) allows a register, you may, as an alternative, logically split its function into two separate operands, one input operand and one write-only output operand.当改变)约束的读写操作数(或操作数,其中只有部分的位将被允许注册,您可以作为一种替代方法,逻辑上的功能分裂,一分为两个独立的操作数,一个输入操作数只写输出操作数。 The connection between them is expressed by constraints which say they need to be in the same location when the instruction executes.在他们之间的连接是表示限制因素说,他们需要在同一位置时,指令执行。 You can use the same C expression for both operands, or different expressions.您可以使用两个相同的C表达式操作数,或不同的表述。 For example, here we write the (fictitious) combine instruction with bar as its read-only source operand and foo as its read-write destination:例如,在这里我们写的(虚构的) combine的指令bar为只读源操作数和foo作为其读写目的地:

      asm ("combine %2,%0" : "=r" (foo) : "0" (foo), "g" (bar));汇编(合并%20”“= R”的(富):0”(富),(巴));
     

The constraint "0" for operand 1 says that it must occupy the same location as operand 0.约束"0"操作数一说,它必须占据相同的位置,操作数0A number in constraint is allowed only in an input operand and it must refer to an output operand.一个约束数只允许在输入操作数,它必须引用一个输出操作数。

Only a number in the constraint can guarantee that one operand will be in the same place as another.只有限制人数,可以保证一个操作数将在另一个相同的地方。 The mere fact that foo is the value of both operands is not enough to guarantee that they will be in the same place in the generated assembler code.这一事实foo是操作数的值都不足以保证他们将在同一地点汇编代码中生成的。 The following would not work reliably:以下将不能可靠地工作:

      asm ("combine %2,%0" : "=r" (foo) : "r" (foo), "g" (bar));汇编(合并%20”“= R”的(富):住宅(富),(巴));
     

Various optimizations or reloading could cause operands 0 and 1 to be in different registers; GCC knows no reason not to do so.各种优化或重新载入可能导致操作数01在不同的登记册;海合会知道没有理由不这样做。 For example, the compiler might find a copy of the value of foo in one register and use it for operand 1, but generate the output operand 0 in a different register (copying it afterward to foo 's own address).例如,编译器可能会找到一个拷贝价值的foo在一个注册和使用1,操作数,但生成输出操作数寄存器0在一个不同的(后来将其复制到foo自己的地址)。 Of course, since the register for operand 1 is not even mentioned in the assembler code, the result will not work, but GCC can't tell that.当然,由于1寄存器操作数甚至没有提到的汇编代码,结果将不能正常工作,但GCC不能告诉。

As of GCC version 3.1, one may write [ name ] instead of the operand number for a matching constraint.由于GCC版本3.1,一个可写[ 名称 ]匹配的约束,而不是一个操作数。 For example:例如:

      asm ("cmoveq %1,%2,%[result]"汇编(“cmoveq1,%2,%[结果]”
          : [result] "=r"(result) [结果]“= R”的(结果)
          : "r" (test), "r"(new), "[result]"(old)); 住宅(测试),住宅(新),“[结果]”(旧));
     

Some instructions clobber specific hard registers.有些指令撞特定硬寄存器。 To describe this, write a third colon after the input operands, followed by the names of the clobbered hard registers (given as strings).为了描述这一点,写一个输入操作数第三个冒号后,),其次饱受重创的寄存器的名称为(给定的字符串。 Here is a realistic example for the VAX:这里是一个现实的例子在VAX为:

      asm volatile ("movc3 %0,%1,%2"汇编挥发性(“movc3012”
                   : /* no outputs */ / *没有输出* /
                   : "g" (from), "g" (to), "g" (count) (从),(对),(计数)
                   : "r0", "r1", "r2", "r3", "r4", "r5"); “r0“R1”时,版“R2”“R3“R4“R5;
     

You may not write a clobber description in a way that overlaps with an input or output operand.你可以不写一撞地描述在一个操作数重叠的输入或输出。 For example, you may not have an operand describing a register class with one member if you mention that register in the clobber list.例如,您可能没有一个操作数描述的是一类具有会员注册,如果你提到名单登记在撞。 Variables declared to live in specific registers (see Explicit Reg Vars ), and used as asm input or output operands must have no part mentioned in the clobber description. There is no way for you to specify that an input operand is modified without also specifying it as an output operand.住在声明的变量特定的寄存器(见显条瓦尔斯 ),汇编和操作数作为输入或输出必须有撞描述中提到的没有参与。没有方法可以让你指定一个输入操作数是修改而不同时指定作为一个输出操作数。 Note that if all the output operands you specify are for this purpose (and hence unused), you will then also need to specify volatile for the asm construct, as described below, to prevent GCC from deleting the asm statement as unused.请注意,如果所有输出操作数指定的目的是为这个(因此未使用),你就还需要指定volatileasm构造,如下所述,防止海湾合作委员会由删去asm语句,未使用的。

If you refer to a particular hardware register from the assembler code, you will probably have to list the register after the third colon to tell the compiler the register's value is modified.如果你是指一个特定的硬件汇编代码寄存器,你可能要排名第三冒号后的登记册告诉编译器的修改寄存器的值。 In some assemblers, the register names begin with % ; to produce one % in the assembler code, you must write %% in the input.在一些汇编,寄存器名称开头% ;生产一%的汇编代码,你必须写%%的投入。

If your assembler instruction can alter the condition code register, add cc to the list of clobbered registers.如果您的汇编指令可以改变条件码寄存器,添加cc到寄存器列表篡改。 GCC on some machines represents the condition codes as a specific hardware register; cc serves to name this register.一些代表海合会机器的具体硬件条件代码登记作为; cc提供该寄存器的名字。 On other machines, the condition code is handled differently, and specifying cc has no effect.在其他机器上,代码是不同的处理条件,并指定cc没有任何效果。 But it is valid no matter what the machine.但它是有效的机器没有什么问题。

If your assembler instruction modifies memory in an unpredictable fashion, add memory to the list of clobbered registers.如果你的汇编指令修改内存中一个不可预知的方式,增加memory的寄存器列表篡改。 This will cause GCC to not keep memory values cached in registers across the assembler instruction.这将导致海湾汇编指令不保存在内存缓存在寄存器中的值。 You will also want to add the volatile keyword if the memory affected is not listed in the inputs or outputs of the asm , as the memory clobber does not count as a side-effect of the asm .你也将要加入volatile关键字如果内存中未列出受影响的输入或输出的asm ,作为memory撞不能算作一个副作用的效果asm

You can put multiple assembler instructions together in a single asm template, separated by the characters normally used in assembly code for the system.您可以将多个汇编指令在同一个asm模板的系统中,代码分离通常由使用的字符集。 A combination that works in most places is a newline to break the line, plus a tab character to move to the instruction field (written as \n\t ).这种组合在多数地方是一个换行符,断行,加上一个制表符移动到指令字段(写为\n\t )。 Sometimes semicolons can be used, if the assembler allows semicolons as a line-breaking character.有时,可以使用分号,如果编译器允许字符分号作为断行。 Note that some assembler dialects use semicolons to start a comment. The input operands are guaranteed not to use any of the clobbered registers, and neither will the output operands' addresses, so you can read and write the clobbered registers as many times as you like.请注意,一些汇编语言中的运用分号来开始一个注释。输入操作数寄存器保证不使用任何的篡改,也不会和输出操作数的地址,所以你可以读取和写入多次篡改为寄存器,你喜欢。 Here is an example of multiple instructions in a template; it assumes the subroutine _foo accepts arguments in registers 9 and 10:下面是一个模板,例如在多指令,它假定子程序_foo接受10个参数在寄存器9

      asm ("movl %0,r9\n\tmovl %1,r10\n\tcall _foo"汇编(“movl0,九号\ ñ \ tmovl1R10\ ñ \ tcall _Foo
          : /* no outputs */ / *没有输出* /
          : "g" (from), "g" (to) (从),(至)
          : "r9", "r10"); 九号“R10;
     

Unless an output operand has the & constraint modifier, GCC may allocate it in the same register as an unrelated input operand, on the assumption the inputs are consumed before the outputs are produced. This assumption may be false if the assembler code actually consists of more than one instruction.除非有一个输出操作数&约束修饰符,GCC可能分配在同一注册它作为一个无关的输入操作数,假设的投入产出前食用产生。这种假设可能是错误的,如果汇编代码实际上包含更多多个指令。 In such a case, use & for each output operand that may not overlap an input.在这种情况下,使用&每个输出操作数可能不重叠的投入。 See Modifiers .修饰符

If you want to test the condition code produced by an assembler instruction, you must include a branch and a label in the asm construct, as follows:如果你想测试的条件代码由汇编指令产生的,你必须包含一个分支和标签在asm兴建,具体如下:

      asm ("clr %0\n\tfrob %1\n\tbeq 0f\n\tmov #1,%0\n0:"汇编(“CLR的%0 \ ñ \ tfrob1 \ ñ \ tbeq女生\ ñ \ tmov1,%0 \ N0的:
          : "g" (result) (结果)
          : "g" (input)); (输入));
     

This assumes your assembler supports local labels, as the GNU assembler and most Unix assemblers do.这是假设你的汇编程序支持局部标签,以GNU汇编器和大多数UNIX汇编程序。

Speaking of labels, jumps from one asm to another are not supported.说到标签,跳跃从一个asm到另一个不支持。 The compiler's optimizers do not know about these jumps, and therefore they cannot take account of them when deciding how to optimize.编译器的优化者不知道这些跳跃,因此他们不能决定时,他们考虑如何优化。

Usually the most convenient way to use these asm instructions is to encapsulate them in macros that look like functions.通常是最方便的方式使用这些asm指令的功能是封装在宏他们看起来像他一样。 For example,例如,

      #define sin(x)       \ #定义的sinx\
     ({ double __value, __arg = (x);   \ ((双__value__arg =x)的; \
        asm ("fsinx %1,%0": "=f" (__value): "f" (__arg));  \汇编(“fsinx1,%0”“= F”类(__value):“F”类(__arg)); \
        __value; }) __value;))
     

Here the variable __arg is used to make sure that the instruction operates on a proper double value, and to accept only those arguments x which can convert automatically to a double .这里的变量__arg是用来确保教学运行在一个适当的double价值,并只接受这些参数x ,可以自动转换成一个double

Another way to make sure the instruction operates on the correct data type is to use a cast in the asm .另一种方法,以确保使用的指令操作上投下正确的数据类型是asm This is different from using a variable __arg in that it converts more different types.这是变量的不同从使用__arg ,它更多不同类型的转换。 For example, if the desired type were int , casting the argument to int would accept a pointer with no complaint, while assigning the argument to an int variable named __arg would warn about using a pointer unless the caller explicitly casts it.例如,如果需要的类型是int ,铸造参数int将接受投诉,没有指针,而分配参数一int变量名为__arg会发出警告,除非使用指针调用者明确地把它。

If an asm has output operands, GCC assumes for optimization purposes the instruction has no side effects except to change the output operands.如果asm具有输出操作数,海湾合作委员会承担输出操作数指令进行优化的目的没有任何副作用,除了改变。 This does not mean instructions with a side effect cannot be used, but you must be careful, because the compiler may eliminate them if the output operands aren't used, or move them out of loops, or replace two with one if they constitute a common subexpression.这并不意味着对一个侧面说明,不能使用,但你必须要小心,因为编译器可以消除他们,如果输出操作数都没有使用,或移动循环出来,或更换一两个,如果它们构成了公共子表达式。 Also, if your instruction does have a side effect on a variable that otherwise appears not to change, the old value of the variable may be reused later if it happens to be found in a register.此外,如果您的指示确实有副作用,改变一个变量,否则会出现没有,旧的变量值,可重复使用后,如果它正好是在注册登记。

You can prevent an asm instruction from being deleted, moved significantly, or combined, by writing the keyword volatile after the asm .您可以防止一个asm指令被删除,移动显着,或合并,通过写关键字volatile后的asm For example:例如:

      #define get_and_set_priority(new)              \ #定义get_and_set_priority(新)\
     ({ int __old;                                  \ ((诠释__old; \
        asm volatile ("get_and_set_priority %0, %1" \汇编挥发性(“get_and_set_priority01”\
                      : "=g" (__old) : "g" (new));  \ “=__old):(新)); \
        __old; }) __old;))
     

If you write an asm instruction with no outputs, GCC will know the instruction has side-effects and will not delete the instruction or move it outside of loops.如果你写的asm指令没有输出,GCC会知道指令的副作用,不会删除或移动它循环指令之外。

The volatile keyword indicates that the instruction has important side-effects.volatile关键字表示该指令,具有重要的副作用。 GCC will not delete a volatile asm if it is reachable. GCC将不会删除动荡asm如果到达。 (The instruction can still be deleted if GCC can prove that control-flow will never reach the location of the instruction.) In addition, GCC will not reschedule instructions across a volatile asm instruction. (指令仍然可以删除如果GCC可以证明,控制流将永远不会达到指示的位置。)此外,海合会将不会重新安排在一个动荡的指示asm指令。 For example:例如:

      *(volatile int *)addr = foo; *(挥发性诠释*= foo的地址;
     asm volatile ("eieio" : : );汇编挥发性(“EIEIO组成的::);
     

Assume addr contains the address of a memory mapped device register.假设addr中包含的内存地址映射的设备寄存器。 The PowerPC eieio instruction (Enforce In-order Execution of I/O) tells the CPU to make sure that the store to that device register happens before it issues any other I/O.PowerPC eieio指令(强制执行序执行的I / O),告诉CPU,以确保登记册存放于该设备发生问题之前,任何其他I / O

Note that even a volatile asm instruction can be moved in ways that appear insignificant to the compiler, such as across jump instructions.请注意,即使一个动荡asm指令可移动的方式,说明出现微不足道跳编译器,如跨越。 You can't expect a sequence of volatile asm instructions to remain perfectly consecutive.你不能指望一个动荡序列asm指令保持完全连续的。 If you want consecutive output, use a single asm .如果你想连续输出,使用单一的asm Also, GCC will perform some optimizations across a volatile asm instruction; GCC does not "forget everything" when it encounters a volatile asm instruction the way some other compilers do.此外,海湾合作委员会将进行一些优化跨挥发asm指令;海湾合作委员会并没有忘记过去的一切,当它遇到一个动荡asm指令的方式做一些其他的编译器。

An asm instruction without any operands or clobbers (an "old style" asm ) will be treated identically to a volatile asm instruction.一个asm指令没有任何操作数或破坏(老风格asm )将被视为同一个volatile asm指令。

It is a natural idea to look for a way to give access to the condition code left by the assembler instruction.这是一个自然的想法,寻找一种方法来提供访问条件码的指令留下的汇编。 However, when we attempted to implement this, we found no way to make it work reliably.然而,当我们试图实现这一点,我们没有发现任何办法让它可靠地工作。 The problem is that output operands might need reloading, which would result in additional following "store" instructions.问题是输出操作数可能需要重新载入,这将导致额外下面的商店的指示。 On most machines, these instructions would alter the condition code before there was time to test it.在大多数机器上,这些指令会改变条件代码之前有时间来检验。 This problem doesn't arise for ordinary "test" and "compare" instructions because they don't have any output operands.这个问题一般不会出现“Test”比较的指示,因为他们没有任何输出操作数。

For reasons similar to those described above, it is not possible to give an assembler instruction access to the condition code left by previous instructions.对于上述这些原因,类似的描述,它不可能提供一个汇编指令访问的条件以前遗留下来的代码的说明。

If you are writing a header file that should be includable in ISO C programs, write __asm__ instead of asm .如果你正在写一个头文件,应纳入项目在ISO C程序,写__asm__ ,而不是asm See Alternate Keywords .替代关键字

i386 floating point asm operands i386硬件浮点运算汇编

There are several rules on the usage of stack-like regs in asm_operands insns.asm_operands指令的一些规则在对堆栈的使用情况一样暂存器。 These rules apply only to the operands that are stack-like regs:这些规则只适用于那些操作数堆栈式暂存器:

  1. Given a set of input regs that die in an asm_operands, it is necessary to know which are implicitly popped by the asm, and which must be explicitly popped by gcc.给定一组输入暂存器asm_operands一个死去的,但要知道这是含蓄地弹出了汇编,并必须明确由海合会弹出。

An input reg that is implicitly popped by the asm must be explicitly clobbered, unless it is constrained to match an output operand.这是一个输入章汇编弹出的含蓄必须明确篡改,除非它被限制匹配输出操作数。

  1. For any input reg that is implicitly popped by an asm, it is necessary to know how to adjust the stack to compensate for the pop. If any non-popped input is closer to the top of the reg-stack than the implicitly popped reg, it would not be possible to know what the stack looked like--it's not clear how the rest of the stack "slides up".对于任何输入章是由隐汇编弹出,这是要知道如何调整,以弥补堆栈弹出。如果有非弹出输入接近顶部的章叠比隐式弹出章,它不可能知道堆栈模样-现在还不清楚如何剩下的栈幻灯片了。

All implicitly popped input regs must be closer to the top of the reg-stack than any input that is not implicitly popped.所有隐含弹出的输入寄存器必须接近顶部的章叠比任何弹出输入不含蓄。

It is possible that if an input dies in an insn, reload might use the input reg for an output reload.这是可能的,如果一个输入一条指令死于一,重载可能使用重载章第一个输入输出。 Consider this example:考虑这个例子:

           asm ("foo" : "=t" (a) : "f" (b));汇编(“= T”型(一):“F”类(二));
          

This asm says that input B is not popped by the asm, and that the asm pushes a result onto the reg-stack, ie, the stack is one deeper after the asm than it was before.ASM说,没有弹出输入B是由汇编,而汇编推,即一个结果到章堆栈,堆栈是一个ASM更深后,比以前。 But, it is possible that reload will think that it can use the same reg for both the input and the output, if input B dies in this insn.但是,它有可能重新加载会认为它可以使用和输出的同时为同一章输入,如果输入B一条指令死于此。

If any input operand uses the f constraint, all output reg constraints must use the & earlyclobber.如果任何输入操作数使用了f约束,所有输出章约束必须使用& earlyclobber

The asm above would be written as上述将写作汇编

           asm ("foo" : "=&t" (a) : "f" (b));汇编(“=T”型(一):“F”类(二));
          
  1. Some operands need to be in particular places on the stack.有些需要在操作数堆栈上的某些地方。 All output operands fall in this category--there is no other way to know which regs the outputs appear in unless the user indicates this in the constraints.所有输出操作数属于这一类-有没有其他办法可以知道哪些暂存器输出的限制,除非出现在用户的指示此操作。

Output operands must specifically indicate which reg an output appears in after an asm. =f is not allowed: the operand constraints must select a class with a single reg.输出操作数必须具体说明哪些章输出后出现一个ASM=f是不允许的:操作数的限制,必须选择一章一类具有单个。

  1. Output operands may not be "inserted" between existing stack regs. Since no 387 opcode uses a read/write operand, all output operands are dead before the asm_operands, and are pushed by the asm_operands. It makes no sense to push anywhere but the top of the reg-stack.输出操作数可能不是插入之间现有的堆栈暂存器。由于没有使用387操作码的读/写操作,所有输出操作数是死的前asm_operands,并推由asm_operands。它是没有意义的任何地方,但推顶该章叠。

Output operands must start at the top of the reg-stack: output operands may not "skip" a reg.输出操作数必须从栈顶的寄存器中:输出操作数可能不会跳过一章。

  1. Some asm statements may need extra stack space for internal calculations.一些汇编语句可能需要额外的内部空间堆栈计算。 This can be guaranteed by clobbering stack registers unrelated to the inputs and outputs.这可以保证clobbering堆栈寄存器无关的输入和输出。

Here are a couple of reasonable asms to want to write.这里有一个合理的asms夫妇想写作。 This asm takes one input, which is internally popped, and produces two outputs.ASM需要一个输入,这是内部弹出,并产生两个输出。

      asm ("fsincos" : "=t" (cos), "=u" (sin) : "0" (inp));汇编(“fsincos”“= T”的等级(CoS),“= U”型(罪):0”(磷化铟));
     

This asm takes two inputs, which are popped by the fyl2xp1 opcode, and replaces them with one output.ASM需要两个输入,这是弹出的fyl2xp1操作码,并取代他们与一输出。 The user must code the st(1) clobber for reg-stack.c to know that fyl2xp1 pops both inputs.用户必须代码st(1)对撞章- stack.c知道fyl2xp1弹出两个输入端。

      asm ("fyl2xp1" : "=t" (result) : "0" (x), "u" (y) : "st(1)");汇编(“fyl2xp1”“=(结果):0”(十),“U”型(年):圣(1;
     

约束asm操作数

Here are specific details on what constraint letters you can use with asm operands. Constraints can say whether an operand may be in a register, and which kinds of register; whether the operand can be a memory reference, and which kinds of address; whether the operand may be an immediate constant, and which possible values it may have.这里有什么具体的细节约束信你可以使用asm操作数;。约束可以说是否可以在一个操作数寄存器,寄存器和种类的操作数是否可以是内存引用,并解决种;是否操作数可以是立即数,并可能值也可能有。 Constraints can also require two operands to match.约束也可以要求两个操作数相匹配。

在汇编代码中使用的名称控制

You can specify the name to be used in the assembler code for a C function or variable by writing the asm (or __asm__ ) keyword after the declarator as follows:您可以指定要使用书面的或可变的汇编代码的C函数的名称asm (或__asm__ )关键字后作为宣告如下:

      int foo asm ("myfoo") = 2;诠释富汇编(“myfoo”= 2;
     

This specifies that the name to be used for the variable foo in the assembler code should be myfoo rather than the usual _foo .这指定的名称是可变用于foo在汇编代码应myfoo而不是通常的_foo

On systems where an underscore is normally prepended to the name of a C function or variable, this feature allows you to define names for the linker that do not start with an underscore.在系统中通常是一个下划线变量名前面加上一个C函数或,此功能允许您定义强调的名称为连接器不启动带有。

It does not make sense to use this feature with a non-static local variable since such variables do not have assembler names.这是没有意义的局部变量使用此功能与一个非静态的,因为这些变量没有汇编程序的名称。 If you are trying to put the variable in a particular register, see Explicit Reg Vars .如果你是试图把特定寄存器中的变量,见显条瓦尔斯 GCC presently accepts such code with a warning, but will probably be changed to issue an error, rather than a warning, in the future.海湾合作委员会目前接受这样的代码与一个警告,但可能会被更改为一个错误,而不是警告的未来,在。

You cannot use asm in this way in a function definition ; but you can get the same effect by writing a declaration for the function before its definition and putting asm there, like this:您不能使用asm定义一个函数的方式,但你可以把相同的定义和函数声明的作用下其前书面asm那儿去,如:

      extern func () asm ("FUNC");外部函数()汇编(函数;
     
     func (x, y)函数(的xy
          int x, y;诠释的xy;
     /* ... / * ... */ * /
     

It is up to you to make sure that the assembler names you choose do not conflict with any other assembler symbols.它是由你来确保你选择汇编名称不与任何其他符号冲突汇编。 Also, you must not use a register name; that would produce completely invalid assembler code.此外,您不得使用登记的名称,这将产生完全无效的汇编代码。 GCC does not as yet have the ability to store static variables in registers. Perhaps that will be added.海湾合作委员会目前尚未有能力存储在寄存器中的静态变量。或许这将增加。

在指定的寄存器变量

GNU C allows you to put a few global variables into specified hardware registers. GNU C语言允许你指定的硬件投入注册了几个全局变量。 You can also specify the register in which an ordinary register variable should be allocated.您还可以指定所分配的寄存器中,一个普通的寄存器变量应。

  • Global register variables reserve registers throughout the program. This may be useful in programs such as programming language interpreters which have a couple of global variables that are accessed very often.全局寄存器变量的方案储备金寄存器各地。方案,这可能是有用的,例如编程语言翻译有一对夫妇的全局变量是访问非常频繁。
  • Local register variables in specific registers do not reserve the registers.在特定的寄存器局部寄存器变量不保留寄存器。 The compiler's data flow analysis is capable of determining where the specified registers contain live values, and where they are available for other uses.编译器的数据流分析是采用能够确定其中指定的寄存器包含生活价值观,并在他们的其他可供。 Stores into local register variables may be deleted when they appear to be dead according to dataflow analysis.变量存储到本地注册可能会被删除时,他们似乎是死了根据数据流分析。 References to local register variables may be deleted or moved or simplified.变量的引用当地注册可能会被删除或移动或简化。

These local variables are sometimes convenient for use with the extended asm feature (see Extended Asm ), if you want to write one output of the assembler instruction directly into a particular register. (This will work provided the register you specify fits the constraints specified for that operand in the asm .)这些本地变量有时延长为方便使用asm功能(见扩展汇编 ),如果你想要写指令寄存器直接输出到特定的一本汇编。(这将提供适合您所指定的登记册指定的限制该操作数在asm 。)

替代关键字

-ansi and the various -std options disable certain keywords. -ansi和各种-std选项禁用某些关键字。 This causes trouble when you want to use GNU C extensions, or a general-purpose header file that should be usable by all programs, including ISO C programs.这将导致麻烦时,你要使用GNU C扩展,或通用头文件应该使用的所有计划方案,包括ISO çThe keywords asm , typeof and inline are not available in programs compiled with -ansi or -std (although inline can be used in a program compiled with -std=c99 ).这些关键字asm typeofinline是编译的程序中不提供与-ansi-std (尽管inline可用于在程序编制与-std=c99 )。 The ISO C99 keyword restrict is only available when -std=gnu99 (which will eventually be the default) or -std=c99 (or the equivalent -std=iso9899:1999 ) is used.ISO C99的关键字restrict仅当-std=gnu99 (这将最终成为默认)或-std=c99 (或等效的-std=iso9899:1999 )被使用。

The way to solve these problems is to put __ at the beginning and end of each problematical keyword.的方式来解决这些问题的方法是把__在开始和结束每一个有问题的关键字。 For example, use __asm__ instead of asm , and __inline__ instead of inline .例如,使用__asm__代替asm ,并__inline__而不是inline

Other C compilers won't accept these alternative keywords; if you want to compile with another compiler, you can define the alternate keywords as macros to replace them with the customary keywords.其他C编译器将不接受这些替代关键字,如果你想编译与另一个编译器,你可以定义关键字,宏替代关键字,以取代他们的习惯。 It looks like this:它看起来像这样:

      #ifndef __GNUC__ IFNDEF__GNUC__
     #define __asm__ asm #定义__asm__汇编
     #endif endif
     

-pedantic and other options cause warnings for many GNU C extensions. You can prevent such warnings within one expression by writing __extension__ before the expression. __extension__ has no effect aside from this. -pedantic和其他选项的原因书面警告的许多GNU C扩展。您可以在一个表达的警告防止这种__extension__前的表现。 __extension__已除了这个没有影响。

不完整的enum类型

You can define an enum tag without specifying its possible values. This results in an incomplete type, much like what you get if you write struct foo without describing the elements.您可以定义一个enum值的标签没有指定其可能的。这种类型的结果在一个不完整的,就像你会得到什么,如果你写struct foo没有描述的元素。 A later declaration which does specify the possible values completes the type.后来一位声明,并完成指定的可能值的类型。

You can't allocate variables or storage using the type while it is incomplete.您不能分配的变量或存储使用类型而这是不完整的。 However, you can work with pointers to that type.但是,您可以使用该类型的指针。

This extension may not be very useful, but it makes the handling of enum more consistent with the way struct and union are handled.这个扩展可能不是非常有用,但它使处理enum更多的方式一致的structunion的处理方式。

This extension is not supported by GNU C++.这个扩展是不支持的GNU C + +

作为字符串函数名

GCC predefines two magic identifiers to hold the name of the current function.海湾合作委员会的两大法宝,识别预定义的函数名持有的电流。 The identifier __FUNCTION__ holds the name of the function as it appears in the source.标识符__FUNCTION__保存函数名称,因为它出现在源。 The identifier __PRETTY_FUNCTION__ holds the name of the function pretty printed in a language specific fashion.标识符__PRETTY_FUNCTION__时尚的名义持有特定语言的一个漂亮的打印功能研究。

These names are always the same in a C function, but in a C++ function they may be different.这些名字总是在一个C函数相同,但在C + +函数,他们可能会有所不同。 For example, this program:例如,这个程序:

      extern "C" {extern“C”
     extern int printf (char *, ...); printf的外部诠释(字符*...);
     } 
     
     class a { A类(
      public:公开:
       sub (int i)分(int i)已
         { 
           printf ("__FUNCTION__ = %s\n", __FUNCTION__); printf__FUNCTION__ =s\ N”的,__FUNCTION__;
           printf ("__PRETTY_FUNCTION__ = %s\n", __PRETTY_FUNCTION__); printf__PRETTY_FUNCTION__为%s \ N”的,__PRETTY_FUNCTION__;
         } 
     }; ;
     
     int诠释
     main (void)主要(无效)
     { 
       a ax;一斧头;
       ax.sub (0); ax.sub0;
       return 0;返回0;
     } 
     

gives this output:让这样的输出:

      __FUNCTION__ = sub __FUNCTION__ =
     __PRETTY_FUNCTION__ = int  a::sub (int) __PRETTY_FUNCTION__ =诠释一::子(智力)
     

The compiler automagically replaces the identifiers with a string literal containing the appropriate name.编译器会自动替换适当的名称标识符与一个包含字符串。 Thus, they are neither preprocessor macros, like __FILE__ and __LINE__ , nor variables.因此,他们既不是预处理宏,像__FILE____LINE__ ,也不是变量。 This means that they catenate with other string literals, and that they can be used to initialize char arrays.这意味着,他们catenate将与其他字符串,它们可以被用来初始化字符数组。 For example例如

      char here[] = "Function " __FUNCTION__ " in " __FILE__;焦这里[] =“功能”__FUNCTION__“中的译注:;
     

On the other hand, #ifdef __FUNCTION__ does not have any special meaning inside a function, since the preprocessor does not do anything special with the identifier __FUNCTION__ .另一方面, #ifdef __FUNCTION__没有任何特殊含义的函数里面,因为预处理器没有做任何特殊的标识符和__FUNCTION__

Note that these semantics are deprecated, and that GCC 3.2 will handle __FUNCTION__ and __PRETTY_FUNCTION__ the same way as __func__ . __func__ is defined by the ISO standard C99:请注意,这些语义是过时了,并且是GCC 3.2将处理__FUNCTION____PRETTY_FUNCTION__的方式相同__func__ __func__C99ISO标准定义的:

      The identifier __func__ is implicitly declared by the translator标识符__func__是隐式声明的翻译
     as if, immediately following the opening brace of each function好象,紧跟在开始括号每个功能
     definition, the declaration定义,声明
     
           static const char __func__[] = "function-name";静态常量字符__func__ [] =“函数名称”;
          
 
     
     appeared, where function-name is the name of the lexically-enclosing看来,在函数名是名称的词汇,封闭
     function.功能。 This name is the unadorned name of the function.此名称是函数朴实的名称。
     

By this definition, __func__ is a variable, not a string literal. In particular, __func__ does not catenate with other string literals.根据这个定义, __func__是一个变量,而不是一个字符串。特别是, __func__catenate将与其他字符串。

In C++ , __FUNCTION__ and __PRETTY_FUNCTION__ are variables, declared in the same way as __func__ .C++ __FUNCTION____PRETTY_FUNCTION__是变量,因为同样的方式声明__func__

获取函数的返回地址或框架

These functions may be used to get information about the callers of a function.这些功能可以被用来获取有关信息的功能调用方。

void * __builtin_return_address无效* __builtin_return_address ( unsigned int level (无符号整数 水平 )

Built-in Function内置函数

 

This function returns the return address of the current function, or of one of its callers.这个函数返回当前函数的返回地址,或来电者之一的。 The level argument is number of frames to scan up the call stack.堆栈的水平参数是多少帧扫描了电话。 A value of 0 yields the return address of the current function, a value of 1 yields the return address of the caller of the current function, and so forth.一个价值0产生的值返回地址当前函数的一, 1产生当前函数返回地址的调用者,等等。 When inlining the expected behavior is that the function will return the address of the function that will be returned to.当内联预期的行为是该函数将返回处理返回的函数将被。 To work around this behavior use the noinline function attribute.若要解决此问题使用noinline功能属性。

The level argument must be a constant integer.级别的参数必须是一个常数的整数。

On some machines it may be impossible to determine the return address of any function other than the current one; in such cases, or when the top of the stack has been reached, this function will return 0 or a random value.在某些机器上可能无法确定当前的一个返回地址以外的其他任何功能,在这种情况下,或当栈顶已经达成,这个函数将返回0或一个随机值。 In addition, __builtin_frame_address may be used to determine if the top of the stack has been reached.此外, __builtin_frame_address可用于确定是否在堆栈顶部已经达到。

This function should only be used with a nonzero argument for debugging purposes.此功能只能用于一个非零参数的调试目的。

 

void * __builtin_frame_address无效* __builtin_frame_address ( unsigned int level (无符号整数 水平 )

Built-in Function内置函数

 

This function is similar to __builtin_return_address , but it returns the address of the function frame rather than the return address of the function.此功能类似于__builtin_return_address ,但它返回的帧地址的功能,而不是函数的返回地址。 Calling __builtin_frame_address with a value of 0 yields the frame address of the current function, a value of 1 yields the frame address of the caller of the current function, and so forth.调用__builtin_frame_address与价值0产量的价值框架解决当前的函数, 1帧产生当前函数地址的调用者,等等。

The frame is the area on the stack which holds local variables and saved registers.该框架是该地区持有堆栈上的局部变量和保存的寄存器。 The frame address is normally the address of the first word pushed on to the stack by the function.帧地址通常是由函数的地址堆栈的第一个字推到。 However, the exact definition depends upon the processor and the calling convention.但是,确切的定义取决于处理器和调用约定。 If the processor has a dedicated frame pointer register, and the function has a frame, then __builtin_frame_address will return the value of the frame pointer register.如果处理器有一个专门的帧指针寄存器和函数有一个框架,然后__builtin_frame_address将返回寄存器值的帧指针。

On some machines it may be impossible to determine the frame address of any function other than the current one; in such cases, or when the top of the stack has been reached, this function will return 0 if the first frame pointer is properly initialized by the startup code.在某些机器上可能无法确定当前的一帧地址以外的其他任何功能,在这种情况下,或当栈顶已经达成,这个函数将返回0 ,如果在第一帧指针正确初始化启动代码。

This function should only be used with a nonzero argument for debugging purposes.此功能只能用于一个非零参数的调试目的。

使用向量指令通过内置的功能

On some targets, the instruction set contains SIMD vector instructions that operate on multiple values contained in one large register at the same time. For example, on the i386 the MMX, 3Dnow!在某些目标,指令集包含SIMD向量指令操作同一时间在多个值包含一个大的登记。例如,在i386上的MMX3DNow!的! and SSE extensions can be used this way.SSE扩展可以使用这种方式。

The first step in using these extensions is to provide the necessary data types.在这些扩展的第一步,使用的是提供必要的数据类型。 This should be done using an appropriate typedef :这项工作应使用适当的typedef

      typedef int v4si __attribute__ ((mode(V4SI)));类型定义诠释v4si __attribute__((模式(V4SI)));
     

The base type int is effectively ignored by the compiler, the actual properties of the new type v4si are defined by the __attribute__ .基本类型int是有效的编译器忽略,新类型的实际属性的v4si是指由__attribute__ It defines the machine mode to be used; for vector types these have the form V n它定义了要使用的机器模式,这些都为向量类型的形式V ñ B ; n should be the number of elements in the vector, and B should be the base mode of the individual elements. ; N应向量中的元素数量, B应该是单个元素基模式的。 The following can be used as base modes:以下可作为基础模式:

QI

An integer that is as wide as the smallest addressable unit, usually 8 bits.一个整数,它是作为最小的可寻址单元,通常是8位宽。

HI

An integer, twice as wide as a QI mode integer, usually 16 bits.一个整数,两倍,作为一个整数齐模式,通常为16位宽。

SI

An integer, four times as wide as a QI mode integer, usually 32 bits.一个整数,四倍宽,一齐模式整数,通常是32位。

DI

An integer, eight times as wide as a QI mode integer, usually 64 bits.一个整数,宽八倍一个整数齐模式,通常是64位。

SF

A floating point value, as wide as a SI mode integer, usually 32 bits.一个浮点值,只要一SI模式整数,通常是32位宽。

DF

A floating point value, as wide as a DI mode integer, usually 64 bits.一个浮点值,只要一个DI模式整数,通常是64位宽。

Specifying a combination that is not valid for the current architecture will cause gcc to synthesize the instructions using a narrower mode. For example, if you specify a variable of type V4SI and your architecture does not allow for this specific SIMD type, gcc will produce code that uses 4 SIs .指定一个组合,不架构有效电流将导致海湾合成的指示使用窄模式。例如,如果指定一个类型变量V4SI和你的架构不允许此特定的SIMD类型,海合会将生成的代码使用4 SIs

The types defined in this manner can be used with a subset of normal C operations.这种方式中的类型定义可以使用一个普通的C子集操作。 Currently, gcc will allow using the following operators on these types: +, -, *, /, unary minus .目前,海湾合作委员会将允许使用这些类型的下列运算符: +, -, *, /, unary minus

The operations behave like C++ valarrays .这些行动的行为像C + + valarrays Addition is defined as the addition of the corresponding elements of the operands.加法运算定义为添加元素的相应。 For example, in the code below, each of the 4 elements in a will be added to the corresponding 4 elements in b and the resulting vector will be stored in c .例如,在下面的代码,以及由此产生的每一个向量的四元素将被添加到相应的4个元素在B将存储 C

      typedef int v4si __attribute__ ((mode(V4SI)));类型定义诠释v4si __attribute__((模式(V4SI)));
     
     v4si a, b, c; v4si甲,乙,丙;
     
     c = a + b; ç =+ B;
     

Subtraction, multiplication, and division operate in a similar manner. Likewise, the result of using the unary minus operator on a vector type is a vector whose elements are the negative value of the corresponding elements in the operand.减法,乘法和除法的方式运作类似。同样,操作员类型的结果向量的使用负号是一个向量,其元素是负相应的操作价值的元素。

You can declare variables and use them in function calls and returns, as well as in assignments and some casts.你可以声明变量,并使用他们在函数调用返回,并在作业以及和一些转换。 You can specify a vector type as a return type for a function.您可以指定一个函数向量类型的类型,作为回报。 Vector types can also be used as function arguments.向量类型也可以被用来作为函数的参数。 It is possible to cast from one vector type to another, provided they are of the same size (in fact, you can also cast vectors to and from other datatypes of the same size).它可以从一种类型转换到另一个载体,只要大小是相同的(事实上,你也可以投载体和从其他数据类型相同的大小的)。

You cannot operate between vectors of different lengths or different signedness without a cast.你不能来往不同长度或不同载体的符号没有演员。

A port that supports hardware vector operations, usually provides a set of built-in functions that can be used to operate on vectors.一个端口,支持硬件向量运算,通常提供了一套内置的载体功能,可以用来操作。 For example, a function to add two vectors and multiply the result by a third could look like this:例如,一个函数将两个向量相乘的结果像这样由第三可以看:

      v4si f (v4si a, v4si b, v4si c) v4si楼(v4si一,v4si bv4si三)
     { 
       v4si tmp = __builtin_addv4si (a, b); v4si tmp= __builtin_addv4si(一,二);
       return __builtin_mulv4si (tmp, c);返回__builtin_mulv4sitmp目录,三);
     } 
     
     

其他内置功能提供了由海湾合作委员会

GCC provides a large number of built-in functions other than the ones mentioned above.海湾合作委员会在提供上述以外的其他功能的大型内建数。 Some of these are for internal use in the processing of exceptions or variable-length argument lists and will not be documented here because they may change from time to time; we do not recommend general use of these functions.其中有些是内部使用长度参数列表中的例外处理或变,并不会被记录在这里,因为他们可能会不时改变,我们不建议一般使用这些功能。

The remaining functions are provided for optimization purposes.其余的功能是提供优化的目的。

GCC includes built-in versions of many of the functions in the standard C library.海合会包括内置的库版本C的许多标准的功能研究。 The versions prefixed with __builtin_ will always be treated as having the same meaning as the C library function even if you specify the -fno-builtin option.前缀版本的__builtin_将永远被视为具有相同涵义库函数的C即使你指定-fno-builtin选项。 (see C Dialect Options ) Many of these functions are only optimized in certain cases; if they are not optimized in a particular case, a call to the library function will be emitted. (见ç方言选项 )的许多功能,这些只有在特定情况下的优化,如果他们不区分在特定的优化,函数调用库将被排放。

The functions abort , exit , _Exit and _exit are recognized and presumed not to return, but otherwise are not built in. _exit is not recognized in strict ISO C mode ( -ansi , -std=c89 or -std=c99 ). _Exit is not recognized in strict C89 mode ( -ansi or -std=c89 ).的职能abort exit _Exit_exit的承认和推定不回来,但除此之外没有内置_exit不承认严格的ISO模式的c-ansi -std=c89-std=c99 )。 _Exit是不承认在严格的C89模式( -ansi-std=c89 )。 All these functions have corresponding versions prefixed with __builtin_ , which may be used even in strict C89 mode.所有这些功能都带有前缀的版本相应__builtin_ ,这可能是所使用的模式,即使在严格的C89

Outside strict ISO C mode, the functions alloca , bcmp , bzero , index , rindex , ffs , fputs_unlocked , printf_unlocked and fprintf_unlocked may be handled as built-in functions.外部严格的ISO C模式,功能alloca bcmp bzero index rindex ffs fputs_unlocked printf_unlockedfprintf_unlocked可处理内置的功能。 All these functions have corresponding versions prefixed with __builtin_ , which may be used even in strict C89 mode.所有这些功能都带有前缀的版本相应__builtin_ ,这可能是所使用的模式,即使在严格的C89

The ISO C99 functions conj , conjf , conjl , creal , crealf , creall , cimag , cimagf , cimagl , imaxabs , llabs , snprintf , vscanf , vsnprintf and vsscanf are handled as built-in functions except in strict ISO C90 mode.ISO C99函数conj conjf conjl creal crealf creall cimag cimagf cimagl imaxabs llabs snprintf vscanf vsnprintfvsscanf处理内置的模式功能,除了在严格的ISO C90中。 There are also built-in versions of the ISO C99 functions cosf , cosl , expf , expl , fabsf , fabsl , logf , logl , sinf , sinl , sqrtf , and sqrtl , that are recognized in any mode since ISO C90 reserves these names for the purpose to which ISO C99 puts them.也有内置函数版本的ISO C99cosf cosl expf expl fabsf fabsl logf logl sinf sinl sqrtfsqrtl ,这是公认的在任何模式下由于ISO C90的储备为这些名称的宗旨,把他们的ISO C99中。 All these functions have corresponding versions prefixed with __builtin_ .所有这些功能都带有前缀版本相应__builtin_

The ISO C90 functions abs , cos , exp , fabs , fprintf , fputs , labs , log , memcmp , memcpy , memset , printf , putchar , puts , scanf , sin , snprintf , sprintf , sqrt , sscanf , strcat , strchr , strcmp , strcpy , strcspn , strlen , strncat , strncmp , strncpy , strpbrk , strrchr , strspn , strstr , vprintf and vsprintf are all recognized as built-in functions unless -fno-builtin is specified (or -fno-builtin- functionISO C90的功能abs cos exp fabs fprintf fputs labs log memcmp memcpy memset printf putchar puts scanf sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr vprintfvsprintf都是公认的内置函数,除非-fno-builtin指定(或-fno-builtin- 功能 is specified for an individual function).被指定为单个功能)。 All of these functions have corresponding versions prefixed with __builtin_ .所有这些功能都带有前缀版本相应__builtin_

GCC provides built-in versions of the ISO C99 floating point comparison macros that avoid raising exceptions for unordered operands.海湾合作委员会提供了内置的运算版本的ISO C99的浮点数比较宏,为避免无序引发异常。 They have the same names as the standard macros ( isgreater , isgreaterequal , isless , islessequal , islessgreater , and isunordered ) , with __builtin_ prefixed.他们有标准的宏(一样的名字isgreater isgreaterequal isless islessequal islessgreaterisunordered ),与__builtin_前缀。 We intend for a library implementor to be able to simply #define each standard macro to its built-in equivalent.我们打算对库的实现者能够简单#define宏,每一个标准的内置当量。

int __builtin_types_compatible_p诠释__builtin_types_compatible_p ( type1 , type2 1型,2 )

Built-in Function内置函数

 

You can use the built-in function __builtin_types_compatible_p to determine whether two types are the same.您可以使用内置函数__builtin_types_compatible_p ,以确定是否两个类型相同。

This built-in function returns 1 if the unqualified versions of the types type1 and type2 (which are types, not expressions) are compatible, 0 otherwise.这个内置的函数返回1,如果不是表达式)不合格的版本的类型Type1 Type2(这也是一种类型,是兼容的,否则为0The result of this built-in function can be used in integer constant expressions.在这个结果的内置功能,可用于整数常量表达式。

This built-in function ignores top level qualifiers (eg, const , volatile ).这个内置的函数忽略顶级限定符(如const volatile )。 For example, int is equivalent to const int .例如, int相当于const int

The type int[] and int[5] are compatible.类型int[]int[5]是相容的。 On the other hand, int and char * are not compatible, even if the size of their types, on the particular architecture are the same.另一方面, intchar *不兼容,即使它们的结构类型的大小,在特定的都是相同的。 Also, the amount of pointer indirection is taken into account when determining similarity.此外,间接金额指针是考虑到在确定的相似性。 Consequently, short * is not similar to short ** .因此, short *是不相似short ** Furthermore, two types that are typedefed are considered compatible if their underlying types are compatible.此外,两个类型定义类型是兼容的,如果他们被视为潜在的类型是兼容的。

An enum type is considered to be compatible with another enum type.一个enum类型会被认为是另一个兼容enum类型。 For example, enum {foo, bar} is similar to enum {hot, dog} .例如, enum {foo, bar}类似enum {hot, dog}

You would typically use this function in code whose execution varies depending on the arguments' types.您通常会使用'类型这个函数的代码,其论据取决于执行的。 For example:例如:

           #define foo(x)                                                  \ #定义函数foox)的\
            ({                                                           \ ((\
              typeof (x) tmp;                                             \ typeof运算(x)的tmp; \
              if (__builtin_types_compatible_p (typeof (x), long double)) \如果(__builtin_types_compatible_ptypeof运算(十),龙双))\
                tmp = foo_long_double (tmp);                              \ tmp= foo_long_doubleTMP)的; \
              else if (__builtin_types_compatible_p (typeof (x), double)) \否则,如果(__builtin_types_compatible_ptypeof运算(十),双))\
                tmp = foo_double (tmp);                                   \ tmp= foo_doubleTMP)的; \
              else if (__builtin_types_compatible_p (typeof (x), float))  \否则,如果(__builtin_types_compatible_ptypeof运算(x)的浮动))\
                tmp = foo_float (tmp);                                    \ tmp= foo_floatTMP)的; \
              else                                                        \其他\
                abort ();                                                 \中止(); \
              tmp;                                                        \ tmp; \
            }) ))
          

Note: This construct is only available for C. 注:此构造仅可用于三

 

type __builtin_choose_expr 类型 __builtin_choose_expr ( const_exp , exp1 , exp2 const_exp,实验一,exp2 )

Built-in Function内置函数

 

You can use the built-in function __builtin_choose_expr to evaluate code depending on the value of a constant expression.您可以使用内置函数__builtin_choose_expr评估代码依赖于一个常量表达式的值。 This built-in function returns exp1 if const_exp , which is a constant expression that must be able to be determined at compile time, is nonzero.这个内置的函数将返回实验一如果const_exp这是一个常数表达式必须能够在编译时确定,是非零。 Otherwise it returns 0.否则返回0

This built-in function is analogous to the ? :这个内置的函数是类似的? : ? : operator in C, except that the expression returned has its type unaltered by promotion rules. ? :运营商在C,但该表达式返回类型规则有其不变的推广。 Also, the built-in function does not evaluate the expression that was not chosen.此外,内置的功能不评估选择表情不。 For example, if const_exp evaluates to true, exp2 is not evaluated even if it has side-effects.例如,如果const_exp结果为真exp2不计算,即使它的副作用。

This built-in function can return an lvalue if the chosen argument is an lvalue.这个内置的函数可以返回一个左值,如果选择的参数是一个左值。

If exp1 is returned, the return type is the same as exp1 's type.如果实验一返回,返回类型是类型相同的实验一的。 Similarly, if exp2 is returned, its return type is the same as exp2 .同样,如果返回exp2 ,它的返回类型是exp2一样。

Example:例如:

           #define foo(x)                                                    \ #定义函数foox)的\
            __builtin_choose_expr (                                         \ __builtin_choose_expr\
              __builtin_types_compatible_p (typeof (x), double),            \ __builtin_types_compatible_ptypeof运算(十),双),\
              foo_double (x),                                               \ foo_double(十),\
              __builtin_choose_expr (                                       \ __builtin_choose_expr\
                __builtin_types_compatible_p (typeof (x), float),           \ __builtin_types_compatible_ptypeof运算(x)的浮动),\
                foo_float (x),                                              \ foo_float(十),\
                /* The void expression results in a compile-time error  \ / *在编译的空时表达结果的误差\
                   when assigning the result to something.当分配结果的东西。 */          \ * / \
                (void)0)) (无效)0))
          

Note: This construct is only available for C. Furthermore, the unused expression ( exp1 or exp2 depending on the value of const_exp ) may still generate syntax errors. 注:此构造仅可用于C此外,未使用的表达式( 实验一exp2const_exp取决于值)仍可能产生语法错误。 This may change in future revisions.这可能会改变在将来的版本。

 

int __builtin_constant_p诠释__builtin_constant_p ( exp 进出口 )

Built-in Function内置函数

 

You can use the built-in function __builtin_constant_p to determine if a value is known to be constant at compile-time and hence that GCC can perform constant-folding on expressions involving that value.您可以使用内置函数__builtin_constant_p ,以确定是否是已知的值是恒定在编译时间,从而可以执行的海湾合作委员会恒定值上的表现形式,涉及折叠。 The argument of the function is the value to test.这个函数的参数是值来测试。 The function returns the integer 1 if the argument is known to be a compile-time constant and 0 if it is not known to be a compile-time constant.该函数返回整数1如果参数是已知的是编译时常量和0如果不知道是编译时常量。 A return of 0 does not indicate that the value is not a constant, but merely that GCC cannot prove it is a constant with the specified value of the -O option.一个0返回并不表明该值不是一个常数,而只是GCC不能证明它是一个常数,值为指定的-O选项。

You would typically use this function in an embedded application where memory was a critical resource.您通常会使用这个功能的关键资源在嵌入式应用程序,其中记忆是一个。 If you have some complex calculation, you may want it to be folded if it involves constants, but need to call a function if it does not.如果你有一些复杂的计算,你可能希望它被折叠如涉及常量,但需要调用一个函数,如果它没有。 For example:例如:

           #define Scale_Value(X)      \ #定义Scale_ValueX)的\
            (__builtin_constant_p (X) \ __builtin_constant_pX)的\
            ? ((X) * SCALE + OFFSET) : Scale (X)) ((十)*规模+偏移):规模(十))
          

You may use this built-in function in either a macro or an inline function.你可以使用这个内置的函数的函数在任何一个宏或内联。 However, if you use it in an inlined function and pass an argument of the function as the argument to the built-in, GCC will never return 1 when you call the inline function with a string constant or compound literal (see Compound Literals ) and will not return 1 when you pass a constant numeric value to the inline function unless you specify the -O option.然而,如果您使用它在一个内联函数,并通过复合或看到文字(一个参数作为参数的函数的内置,海合会将永远不会返回1当你调用内联函数使用一个字符串常量复合文字 )和不会返回1当你传递一个恒定的数值内联函数,除非你指定-O选项。

You may also use __builtin_constant_p in initializers for static data.你也可以使用__builtin_constant_p初始化静态数据。 For instance, you can write例如,你可以写

           static const int table[] = {静态常量诠释表[] =
             __builtin_constant_p (EXPRESSION) ? __builtin_constant_p(表达式)? (EXPRESSION) : -1, (表达式):-1
             /* ... / * ... */ * /
          }; ;
          

This is an acceptable initializer even if EXPRESSION is not a constant expression.这是一个可以接受的初始值,即使表达的是不是一个常量表达式。 GCC must be more conservative about evaluating the built-in in this case, because it has no opportunity to perform optimization.海湾合作委员会必须更加保守的评估内置在这种情况下,因为它没有机会执行优化。

Previous versions of GCC did not accept this built-in in data initializers.以前版本的GCC不接受这个内置的数据初始化。 The earliest version where it is completely safe is 3.0.1.最早的版本是完全安全的地方是3.0.1

 

long __builtin_expect__builtin_expect ( long exp , long c 长时间 曝光 ,长 ç )

Built-in Function内置函数

 

You may use __builtin_expect to provide the compiler with branch prediction information.你可以使用__builtin_expect编译器提供的信息与分支预测。 In general, you should prefer to use actual profile feedback for this ( -fprofile-arcs ), as programmers are notoriously bad at predicting how their programs actually perform.一般来说,你应该更喜欢使用这个(实际取样-fprofile-arcs ),因为程序员们在预测出了名的坏如何执行他们的程序实际上。 However, there are applications in which this data is hard to collect.但是,也有应用中,这个数据是很难收集。

The return value is the value of exp , which should be an integral expression.返回值是曝光值,它应该是一个整数表达式。 The value of c must be a compile-time constant. C值必须是编译时常量。 The semantics of the built-in are that it is expected that exp == c .的语义内置的是,它预计进出口 == ç For example:例如:

           if (__builtin_expect (x, 0))如果(__builtin_expect(的x0))
            foo ();美孚();
          

would indicate that we do not expect to call foo , since we expect x to be zero.将表明,我们并不指望调用foo ,因为我们希望x是零。 Since you are limited to integral expressions for exp , you should use constructions such as既然你是仅限于进出口积分表达式,你应该使用结构,如

           if (__builtin_expect (ptr != NULL, 1))如果(__builtin_expect(指针!= NULL的,1))
            error ();错误();
          

when testing pointer or floating-point values.当测试指针或浮点值。

 

void __builtin_prefetch无效__builtin_prefetch ( const void * addr , ... ) 常量无效* 地址 ...

Built-in Function内置函数

 

This function is used to minimize cache-miss latency by moving data into a cache before it is accessed. You can insert calls to __builtin_prefetch into code for which you know addresses of data in memory that is likely to be accessed soon. If the target supports them, data prefetch instructions will be generated. If the prefetch is done early enough before the access then the data will be in the cache by the time it is accessed.此功能是用来减少缓存缓存延迟错过一个移动的数据进入,然后才访问。您可以插入呼吁__builtin_prefetch成代码,而您知道内存地址中的数据很可能很快被访问。如果目标支持其中,数据预取指令将会产生。如果预取足够早做访问之前访问的数据,然后将它在缓存的时间。

The value of addr is the address of the memory to prefetch. There are two optional arguments, rw and locality . The value of rw is a compile-time constant one or zero; one means that the prefetch is preparing for a write to the memory address and zero, the default, means that the prefetch is preparing for a read. The value locality must be a compile-time constant integer between zero and three.地址值是内存地址预取为零。有两个可选参数RW; 地方的价值。作者RW是编译时常量是指一个或一个预取正准备写的内存地址和零,默认,意味着预先撷取准备一读。价值地点必须是一个编译时间和三个常数之间的整为零。 A value of zero means that the data has no temporal locality, so it need not be left in the cache after the access. A指的零值,该数据没有时间地点,所以它不需要被留在缓存的访问后。 A value of three means that the data has a high degree of temporal locality and should be left in all levels of cache possible. A和价值三个意味着数据具有高度的地方时间应尽量留在各级缓存。 Values of one and two mean, respectively, a low or moderate degree of temporal locality.两个值之一,平均分别在一定程度上的时间局部性低或中度。 The default is three.默认是三。

           for (i = 0; i < n; i++)对(我= 0;<;+ +
            { 
              a[i] = a[i] + b[i];[] =一个[] + b[];
              __builtin_prefetch (&a[i+j], 1, 1); __builtin_prefetch(&一[+ J]11;
              __builtin_prefetch (&b[i+j], 0, 1); __builtin_prefetch(及B [+ J]01;
              /* ... / * ... */ * /
            } 
          

Data prefetch does not generate faults if addr is invalid, but the address expression itself must be valid.数据预取不产生故障,如果地址是无效的,但地址表达式本身必须是有效的。 For example, a prefetch of p->next will not fault if p->next is not a valid address, but evaluation will fault if p is not a valid address.例如,预取p->next不会错p->next是不是一个有效的地址,但评价将故障如果p不是一个有效的地址。

If the target does not support data prefetch, the address expression is evaluated if it includes side effects but no other code is generated and GCC does not issue a warning.如果目标不支持数据预取,地址表达式的计算,如果它包括副作用,但没有其他代码生成和GCC不会发出警告。

 

double __builtin_huge_val__builtin_huge_val ( void ) 无效

Built-in Function内置函数

 

Returns a positive infinity, if supported by the floating-point format, else DBL_MAX .返回一个正无穷大,如果其他支持浮点格式, DBL_MAX This function is suitable for implementing the ISO C macro HUGE_VAL .此功能是宏观适合实施ISO ç HUGE_VAL

 

float __builtin_huge_valf浮动__builtin_huge_valf ( void ) 无效

Built-in Function内置函数

 

Similar to __builtin_huge_val , except the return type is float .类似__builtin_huge_val类型,除了回报float

 

long double __builtin_huge_vall长双__builtin_huge_vall ( void ) 无效

Built-in Function内置函数

 

Similar to __builtin_huge_val , except the return type is long double .类似__builtin_huge_val类型,除了回报是long double

 

double __builtin_inf__builtin_inf ( void ) 无效

Built-in Function内置函数

 

Similar to __builtin_huge_val , except a warning is generated if the target floating-point format does not support infinities. This function is suitable for implementing the ISO C99 macro INFINITY .类似__builtin_huge_val ,除了生成一个警告,如果目标浮点格式不支持无穷。这项功能是宏观适合实施ISO C99INFINITY

 

float __builtin_inff浮动__builtin_inff ( void ) 无效

Built-in Function内置函数

 

Similar to __builtin_inf , except the return type is float .类似__builtin_inf ,返回类型为除float

 

long double __builtin_infl长双__builtin_infl ( void ) 无效

Built-in Function内置函数

 

Similar to __builtin_inf , except the return type is long double .类似__builtin_inf类型,除了回报是long double

 

double __builtin_nan__builtin_nan ( const char *str ) 常量字符* STR

Built-in Function内置函数

 

This is an implementation of the ISO C99 function nan .这是一个函数的实现的ISO C99nan

Since ISO C99 defines this function in terms of strtod , which we do not implement, a description of the parsing is in order.由于ISO C99的定义在这个功能上strtod ,我们没有实现,一个解析说明是适宜的。 The string is parsed as by strtol ; that is, the base is recognized by leading 0 or 0x prefixes.该字符串被解析的strtol ,也就是说,基地领导的认可00x前缀。 The number parsed is placed in the significand such that the least significant bit of the number is at the least significant bit of the significand.这个数字是有效数字解析放置在尾数,这样的最低有效位的数字是最低有效位。 The number is truncated to fit the significand field provided.这个数字被截断以适应尾数提供的字段。 The significand is forced to be a quiet NaN.有效位数是被迫成为一个安静的为NaN

This function, if given a string literal, is evaluated early enough that it is considered a compile-time constant.这个函数,如果给一个字符串,被评为足够早,它被认为是编译时常量。

 

float __builtin_nanf浮动__builtin_nanf ( const char *str ) 常量字符* STR

Built-in Function内置函数

 

Similar to __builtin_nan , except the return type is float .类似__builtin_nan类型,除了回报float

 

long double __builtin_nanl长双__builtin_nanl ( const char *str ) 常量字符* STR

Built-in Function内置函数

 

Similar to __builtin_nan , except the return type is long double .类似__builtin_nan类型,除了回报是long double

 

double __builtin_nans__builtin_nans ( const char *str ) 常量字符* STR

Built-in Function内置函数

 

Similar to __builtin_nan , except the significand is forced to be a signaling NaN.类似__builtin_nan ,除尾数是被迫成为一个信号为NaN The nans function is proposed by WG14 N965 .nans功能,提出了WG14 N965

 

float __builtin_nansf浮动__builtin_nansf ( const char *str ) 常量字符* STR

Built-in Function内置函数

 

Similar to __builtin_nans , except the return type is float .类似__builtin_nans类型,除了回报float

 

long double __builtin_nansl长双__builtin_nansl ( const char *str ) 常量字符* STR

Built-in Function内置函数

 

Similar to __builtin_nans , except the return type is long double .类似__builtin_nans类型,除了回报是long double

内建功能的具体到特定目标机

On some target machines, GCC supports many built-in functions specific to those machines.在某些目标机,海合会支持许多内置的功能特定于这些机器。 Generally these generate calls to specific machine instructions, but allow the compiler to schedule those calls.一般来说,这些要求的具体产生机器指令,但允许编译器安排那些电话。

GCC编译指示接受

GCC supports several types of pragmas, primarily in order to compile code originally written for other compilers. GCC支持的pragma几种类型,主要是为了编译器编译代码的其他最初写的。 Note that in general we do not recommend the use of pragmas; See Function Attributes , for further explanation.请注意,一般我们不建议使用编译指示,见功能属性的解释,为进一步。

内部结构的无名结构/联合/联盟领域。

For compatibility with other compilers, GCC allows you to define a structure or union that contains, as fields, structures and unions without names.与其他的编译器的兼容性,GCC允许你定义一个结构或联合的包含,为字段,结构和名称的工会没有。 For example:例如:

      struct {结构(
       int a;诠释了;
       union {工会(
         int b;诠释B;
         float c;℃;
       }; ;
       int d;诠释D;
     } foo; )富;
     

In this example, the user would be able to access members of the unnamed union with code like foo.b .在这个例子中,用户将能够访问诸如命名联盟成员的代码foo.b Note that only unnamed structs and unions are allowed, you may not have, for example, an unnamed int .请注意,只有无名结构和工会是允许的,您可能没有,例如,一个无名的int

You must never create such structures that cause ambiguous field definitions. For example, this structure:你千万创建字段定义这样的结构造成歧义结构。例如,这:

      struct {结构(
       int a;诠释了;
       struct {结构(
         int a;诠释了;
       }; ;
     } foo; )富;
     

It is ambiguous which a is being referred to with foo.a . Such constructs are not supported and must be avoided.这是暧昧的a被称为是与以foo.a 。这种结构不支持,必须避免。 In the future, such constructs may be detected and treated as compilation errors.在将来,这种结构可能被检测和错误视为汇编。

线程局部存储

Thread-local storage ( TLS ) is a mechanism by which variables are allocated such that there is one instance of the variable per extant thread.线程本地存储TLS是一个线程的机制,使变量被分配有这样一个实例,每现存的变量。 The run-time model GCC uses to implement this originates in the IA-64 processor-specific ABI, but has since been migrated to other processors as well.在运行时模型GCC使用实施这一ABI的起源在IA - 64处理器的,但后来被迁移到其他处理器。 It requires significant support from the linker ( ld ), dynamic linker ( ld.so ), and system libraries ( libc.so and libpthread.so ), so it is not available everywhere.它需要大量的支持,从连接器( ld ),动态链接程序( ld.so ),图书馆(系统libc.solibpthread.so ),所以它不是随处可见。

At the user level, the extension is visible with a new storage class keyword: __thread .在用户层面,扩展关键字可见一个新的存储类: __thread For example:例如:

      __thread int i; __thread诠释我;
     extern __thread struct state s;外部__thread结构状态的;
     static __thread char *p;静态__thread字符* p;
     

The __thread specifier may be used alone, with the extern or static specifiers, but with no other storage class specifier. When used with extern or static , __thread must appear immediately after the other storage class specifier.__thread说明可以单独使用,与externstatic说明符,但没有其他存储类说明。当与使用externstatic __thread必须出现说明后,立即与其他存储类。

The __thread specifier may be applied to any global, file-scoped static, function-scoped static, or static data member of a class.__thread符可应用于任何全局,档案范围的静态,功能范围的静态或静态数据成员的一类。 It may not be applied to block-scoped automatic or non-static data member.它可能无法应用于块作用域自动或非静态数据成员。

When the address-of operator is applied to a thread-local variable, it is evaluated at run-time and returns the address of the current thread's instance of that variable.当取地址运算符应用于线程局部变量,它是评估在运行时变量的地址并返回当前线程的实例。 An address so obtained may be used by any thread.这样得到的地址可以被任何线程。 When a thread terminates, any pointers to thread-local variables in that thread become invalid.当一个线程终止,线程在该线程局部变量的指针,成为无效。

No static initialization may refer to the address of a thread-local variable.没有静态初始化可能指的是线程局部变量的地址。

In C++, if an initializer is present for a thread-local variable, it must be a constant-expression , as defined in 5.19.2 of the ANSI/ISO C++ standard.C + +中,如果存在一个初始化的线程局部变量,它必须是一个常数表达式 ,如在5.19.2界定的ANSI / ISO C + +标准。

See ELF Handling For Thread-Local Storage for a detailed explanation of the four thread-local storage addressing models, and how the run-time is expected to function.本地存储的ELF处理线程的处理模型的详细说明这四个线程存储本地,以及如何在运行时预计的功能。

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。

    0条评论

    发表

    请遵守用户 评论公约

    类似文章
    喜欢该文的人也喜欢 更多

    ×
    ×

    ¥.00

    微信或支付宝扫码支付:

    开通即同意《个图VIP服务协议》

    全部>>