that the jump optimizer will not delete the table as unreachable code.
-@cindex @code{decrement_and_branch_until_zero} instruction pattern
-@item @samp{decrement_and_branch_until_zero}
-Conditional branch instruction that decrements a register and
-jumps if the register is nonzero. Operand 0 is the register to
-decrement and test; operand 1 is the label to jump to if the
-register is nonzero. @xref{Looping Patterns}.
-
-This optional instruction pattern is only used by the combiner,
-typically for loops reversed by the loop optimizer when strength
-reduction is enabled.
-
@cindex @code{doloop_end} instruction pattern
@item @samp{doloop_end}
Conditional branch instruction that decrements a register and
@samp{dbra}-like instruction and avoids pipeline stalls associated with
the jump.
-GCC has three special named patterns to support low overhead looping.
-They are @samp{decrement_and_branch_until_zero}, @samp{doloop_begin},
-and @samp{doloop_end}. The first pattern,
-@samp{decrement_and_branch_until_zero}, is not emitted during RTL
-generation but may be emitted during the instruction combination phase.
-This requires the assistance of the loop optimizer, using information
-collected during strength reduction, to reverse a loop to count down to
-zero. Some targets also require the loop optimizer to add a
-@code{REG_NONNEG} note to indicate that the iteration count is always
-positive. This is needed if the target performs a signed loop
-termination test. For example, the 68000 uses a pattern similar to the
-following for its @code{dbra} instruction:
-
-@smallexample
-@group
-(define_insn "decrement_and_branch_until_zero"
- [(set (pc)
- (if_then_else
- (ge (plus:SI (match_operand:SI 0 "general_operand" "+d*am")
- (const_int -1))
- (const_int 0))
- (label_ref (match_operand 1 "" ""))
- (pc)))
- (set (match_dup 0)
- (plus:SI (match_dup 0)
- (const_int -1)))]
- "find_reg_note (insn, REG_NONNEG, 0)"
- "@dots{}")
-@end group
-@end smallexample
-
-Note that since the insn is both a jump insn and has an output, it must
-deal with its own reloads, hence the `m' constraints. Also note that
-since this insn is generated by the instruction combination phase
-combining two sequential insns together into an implicit parallel insn,
-the iteration counter needs to be biased by the same amount as the
-decrement operation, in this case @minus{}1. Note that the following similar
-pattern will not be matched by the combiner.
-
-@smallexample
-@group
-(define_insn "decrement_and_branch_until_zero"
- [(set (pc)
- (if_then_else
- (ge (match_operand:SI 0 "general_operand" "+d*am")
- (const_int 1))
- (label_ref (match_operand 1 "" ""))
- (pc)))
- (set (match_dup 0)
- (plus:SI (match_dup 0)
- (const_int -1)))]
- "find_reg_note (insn, REG_NONNEG, 0)"
- "@dots{}")
-@end group
-@end smallexample
-
-The other two special looping patterns, @samp{doloop_begin} and
-@samp{doloop_end}, are emitted by the loop optimizer for certain
-well-behaved loops with a finite number of loop iterations using
-information collected during strength reduction.
+GCC has two special named patterns to support low overhead looping.
+They are @samp{doloop_begin} and @samp{doloop_end}. These are emitted
+by the loop optimizer for certain well-behaved loops with a finite
+number of loop iterations using information collected during strength
+reduction.
The @samp{doloop_end} pattern describes the actual looping instruction
(or the implicit looping operation) and the @samp{doloop_begin} pattern
machine dependent reorg pass could emit a traditional compare and jump
instruction pair.
-The essential difference between the
-@samp{decrement_and_branch_until_zero} and the @samp{doloop_end}
-patterns is that the loop optimizer allocates an additional pseudo
-register for the latter as an iteration counter. This pseudo register
-cannot be used within the loop (i.e., general induction variables cannot
-be derived from it), however, in many cases the loop induction variable
-may become redundant and removed by the flow pass.
+For the @samp{doloop_end} pattern, the loop optimizer allocates an
+additional pseudo register as an iteration counter. This pseudo
+register cannot be used within the loop (i.e., general induction
+variables cannot be derived from it), however, in many cases the loop
+induction variable may become redundant and removed by the flow pass.
+
+The @samp{doloop_end} pattern must have a specific structure to be
+handled correctly by GCC. The example below is taken (slightly
+simplified) from the PDP-11 target:
+
+@smallexample
+@group
+(define_insn "doloop_end"
+ [(set (pc)
+ (if_then_else
+ (ne (match_operand:HI 0 "nonimmediate_operand" "+r,!m")
+ (const_int 1))
+ (label_ref (match_operand 1 "" ""))
+ (pc)))
+ (set (match_dup 0)
+ (plus:HI (match_dup 0)
+ (const_int -1)))]
+ ""
+
+ @{
+ if (which_alternative == 0)
+ return "sob %0,%l1";
+
+ /* emulate sob */
+ output_asm_insn ("dec %0", operands);
+ return "bne %l1";
+ @})
+@end group
+@end smallexample
+
+The first part of the pattern describes the branch condition. GCC
+supports three cases for the way the target machine handles the loop
+counter:
+@itemize @bullet
+@item Loop terminates when the loop register decrements to zero. This
+is represented by a @code{ne} comparison of the register (its old value)
+with constant 1 (as in the example above).
+@item Loop terminates when the loop register decrements to @minus{}1.
+This is represented by a @code{ne} comparison of the register with
+constant zero.
+@item Loop terminates when the loop register decrements to a negative
+value. This is represented by a @code{ge} comparison of the register
+with constant zero. For this case, GCC will attach a @code{REG_NONNEG}
+note to the @code{doloop_end} insn if it can determine that the register
+will be non-negative.
+@end itemize
+Since the @code{doloop_end} insn is a jump insn that also has an output,
+the reload pass does not handle the output operand. Therefore, the
+constraint must allow for that operand to be in memory rather than a
+register. In the example shown above, that is handled by using a loop
+instruction sequence that can handle memory operands when the memory
+alternative appears.
@end ifset
@ifset INTERNALS