===================================================================
@@ -7619,7 +7619,23 @@ simplified) from the PDP-11 target:
@smallexample
@group
-(define_insn "doloop_end"
+(define_expand "doloop_end"
+ [(parallel [(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)))])]
+ "TARGET_40_PLUS"
+ "@{
+ if (GET_MODE (operands[0]) != HImode)
+ FAIL;
+ @}")
+
+(define_insn "doloop_end_nocc"
[(set (pc)
(if_then_else
(ne (match_operand:HI 0 "nonimmediate_operand" "+r,!m")
@@ -7628,17 +7644,28 @@ simplified) from the PDP-11 target:
(pc)))
(set (match_dup 0)
(plus:HI (match_dup 0)
- (const_int -1)))]
- ""
-
+ (const_int -1)))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_40_PLUS && reload_completed"
+ "*
@{
+ rtx lb[1];
+
if (which_alternative == 0)
- return "sob %0,%l1";
+ return \"sob\t%0,%l1\";
+
+ /* emulate sob */
+ lb[0] = gen_label_rtx ();
+ output_asm_insn (\"dec\t%0\", operands);
+ output_asm_insn (\"beq\t%l0\", lb);
+ output_asm_insn (\"jmp\t%l1\", operands);
+
+ output_asm_label (lb[0]);
+ fputs (\":\\n\", asm_out_file);
+
+ return \"\";
+ @}")
- /* emulate sob */
- output_asm_insn ("dec %0", operands);
- return "bne %l1";
- @})
@end group
@end smallexample
@@ -7662,10 +7689,18 @@ will be non-negative.
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.
+register. In the example shown above, that is handled (in the
+@code{doloop_end_nocc} pattern) by using a loop instruction sequence
+that can handle memory operands when the memory alternative appears.
+GCC does not check the mode of the loop register operand when generating
+the @code{doloop_end} pattern. If the pattern is only valid for some
+modes but not others, the pattern should be a @code{define_expand}
+pattern that checks the operand mode in the preparation code, and issues
+@code{FAIL} if an unsupported mode is found. The example above does
+this, since the machine instruction to be used only exists for
+@code{HImode}.
+
@end ifset
@ifset INTERNALS
@node Insn Canonicalizations