From 1c384bf142c81baaad7f04c5d3fdaebcbafc5b0c Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 14 Sep 2009 13:17:24 -0700 Subject: builtins.c (expand_builtin_synchronize): Use gimple_build_asm_vec. * builtins.c (expand_builtin_synchronize): Use gimple_build_asm_vec. * cfgbuild.c (make_edges): Handle asm goto. * cfglayout.c (fixup_reorder_chain): Likewise. * cfgrtl.c (patch_jump_insn): Likewise. * gimple-pretty-print.c (dump_gimple_asm): Likewise. * gimple.c (gimple_build_asm_1): Add and use nlabels parameter. (gimple_build_asm_vec): Add and use labels parameter. (gimple_build_asm): Remove. (walk_gimple_asm): Walk labels too. * gimple.def (GIMPLE_ASM): Update docs. * gimple.h: Update decls. (struct gimple_statement_asm): Change nc to use unsigned char; add nl member. (gimple_asm_nlabels): New. (gimple_asm_label_op, gimple_asm_set_label_op): New. * gimplify.c (gimplify_asm_expr): Copy labels from ASM_EXPR into gimple_build_asm_vec. * jump.c (mark_jump_label_asm): New. (mark_jump_label): Use it. (redirect_jump_1): Handle asm goto. (invert_jump_1): Soft fail if X is null. * recog.c (extract_asm_operands): New. (asm_noperands): Use it; handle asm labels. (decode_asm_operands): Use extract_asm_operands. (asm_operand_ok): Properly handle empty string. * reg-stack.c (get_asm_operands_in_out): Rename from get_asm_operand_n_inputs; use extract_asm_operands; return both inputs and outputs by reference; update all callers. * rtl.def (ASM_OPERANDS): Add label vector as operand 6. * rtl.h (ASM_OPERANDS_LABEL_VEC): New. (ASM_OPERANDS_LABEL_LENGTH, ASM_OPERANDS_LABEL): New. (ASM_OPERANDS_SOURCE_LOCATION): Renumber. (extract_asm_operands): Declare. * stmt.c (expand_asm_operands): Add and use labels parameter. (check_unique_operand_names): Likewise. (resolve_asm_operand_names, resolve_operand_name_1): Likewise. (expand_asm_stmt): Handle asm labels. * tree-cfg.c (make_gimple_asm_edges): New. (make_edges): Use it. (cleanup_dead_labels): Handle asm labels. (is_ctrl_altering_stmt): Likewise. (gimple_redirect_edge_and_branch): Likewise. * tree.def (ASM_EXPR): Add 5th operand. * tree.h (ASM_LABELS): New. (resolve_asm_operand_names): Update decl. * c-parser.c (c_parser_asm_statement): Parse asm goto. (c_parser_asm_goto_operands): New. * c-tree.h (build_asm_expr): Update decl. * c-typeck.c (build_asm_expr): Add and use labels parameter. * doc/extend.texi: Document asm goto. gcc/ada/ * gcc-interface/trans.c (Pragma_to_gnu): Use build5 for ASM_EXPR. gcc/cp/ * cp-tree.h (finish_asm_stmt): Update decl. * parser.c (cp_parser_asm_definition): Parse asm goto. (cp_parser_asm_label_list): New. * pt.c (tsubst_copy_asm_operands): Don't recurse on labels. (tsubst_expr): Handle asm labels. * semantics.c (finish_asm_stmt): Add and use labels parameter. gcc/testsuite/ * c-c++-common/asmgoto-1.c, c-c++-common/asmgoto-2.c, c-c++-common/asmgoto-3.c, gcc.c-torture/compile/asmgoto-1.c, gcc.dg/tree-ssa/asmgoto-1.c: New files. Co-Authored-By: Jakub Jelinek From-SVN: r151701 --- gcc/doc/extend.texi | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) (limited to 'gcc/doc/extend.texi') diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 92f26e5..22d9f6e 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -5251,7 +5251,7 @@ and most Unix assemblers do. Speaking of labels, jumps from one @code{asm} to another are not supported. The compiler's optimizers do not know about these jumps, and therefore they cannot take account of them when deciding how to -optimize. +optimize. @xref{Extended asm with goto}. @cindex macros containing @code{asm} Usually the most convenient way to use these @code{asm} instructions is to @@ -5350,6 +5350,94 @@ 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. +@anchor{Extended asm with goto} +As of GCC version 4.5, @code{asm goto} may be used to have the assembly +jump to one or more C labels. In this form, a fifth section after the +clobber list contains a list of all C labels to which the assembly may jump. +Each label operand is implicitly self-named. The @code{asm} is also assumed +to fall through to the next statement. + +This form of @code{asm} is restricted to not have outputs. This is due +to a internal restriction in the compiler that control transfer instructions +cannot have outputs. This restriction on @code{asm goto} may be lifted +in some future version of the compiler. In the mean time, @code{asm goto} +may include a memory clobber, and so leave outputs in memory. + +@smallexample +int frob(int x) +@{ + int y; + asm goto ("frob %%r5, %1; jc %l[error]; mov (%2), %%r5" + : : "r"(x), "r"(&y) : "r5", "memory" : error); + return y; + error: + return -1; +@} +@end smallexample + +In this (inefficient) example, the @code{frob} instruction sets the +carry bit to indicate an error. The @code{jc} instruction detects +this and branches to the @code{error} label. Finally, the output +of the @code{frob} instruction (@code{%r5}) is stored into the memory +for variable @code{y}, which is later read by the @code{return} statement. + +@smallexample +void doit(void) +@{ + int i = 0; + asm goto ("mfsr %%r1, 123; jmp %%r1;" + ".pushsection doit_table;" + ".long %l0, %l1, %l2, %l3;" + ".popsection" + : : : "r1" : label1, label2, label3, label4); + __builtin_unreachable (); + + label1: + f1(); + return; + label2: + f2(); + return; + label3: + i = 1; + label4: + f3(i); +@} +@end smallexample + +In this (also inefficient) example, the @code{mfsr} instruction reads +an address from some out-of-band machine register, and the following +@code{jmp} instruction branches to that address. The address read by +the @code{mfsr} instruction is assumed to have been previously set via +some application-specific mechanism to be one of the four values stored +in the @code{doit_table} section. Finally, the @code{asm} is followed +by a call to @code{__builtin_unreachable} to indicate that the @code{asm} +does not in fact fall through. + +@smallexample +#define TRACE1(NUM) \ + do @{ \ + asm goto ("0: nop;" \ + ".pushsection trace_table;" \ + ".long 0b, %l0;" \ + ".popsection" \ + : : : : trace#NUM); \ + if (0) @{ trace#NUM: trace(); @} \ + @} while (0) +#define TRACE TRACE1(__COUNTER__) +@end smallexample + +In this example (which in fact inspired the @code{asm goto} feature) +we want on rare occasions to call the @code{trace} function; on other +occasions we'd like to keep the overhead to the absolute minimum. +The normal code path consists of a single @code{nop} instruction. +However, we record the address of this @code{nop} together with the +address of a label that calls the @code{trace} function. This allows +the @code{nop} instruction to be patched at runtime to be an +unconditional branch to the stored label. It is assumed that an +optimizing compiler will move the labeled block out of line, to +optimize the fall through path from the @code{asm}. + If you are writing a header file that should be includable in ISO C programs, write @code{__asm__} instead of @code{asm}. @xref{Alternate Keywords}. -- cgit v1.1