\f
;; divide instructions
-(define_insn "divhi3"
- [(set (match_operand:HI 0 "general_operand" "=d")
- (div:HI (match_operand:HI 1 "general_operand" "0")
- (match_operand:HI 2 "general_operand" "dmn")))]
- ""
- "*
-{
-#ifdef MOTOROLA
- return \"ext%.l %0\;divs%.w %2,%0\";
-#else
- return \"extl %0\;divs %2,%0\";
-#endif
-}")
-
-;; These patterns don't work because the divs instruction is undefined if
-;; the quotient is more than 16 bits. This valid C would be miscompiled:
-;; int n; short d; unsigned short q; ... q = (unsigned int) (n / d);
-;; Imagine what happens when n = 100000 and d = 1.
-;;(define_insn "divhisi3"
-;; [(set (match_operand:HI 0 "general_operand" "=d")
-;; (truncate:HI
-;; (div:SI
-;; (match_operand:SI 1 "general_operand" "0")
-;; (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
-;; ""
-;; "*
-;;{
-;;#ifdef MOTOROLA
-;; return \"divs%.w %2,%0\";
-;;#else
-;; return \"divs %2,%0\";
-;;#endif
-;;}")
-
-;;(define_insn ""
-;; [(set (match_operand:HI 0 "general_operand" "=d")
-;; (truncate:HI (div:SI (match_operand:SI 1 "general_operand" "0")
-;; (match_operand:SI 2 "const_int_operand" "n"))))]
-;; ""
-;; "*
-;;{
-;;#ifdef MOTOROLA
-;; return \"divs%.w %2,%0\";
-;;#else
-;; return \"divs %2,%0\";
-;;#endif
-;;}")
-
-(define_insn "udivhi3"
- [(set (match_operand:HI 0 "general_operand" "=d")
- (udiv:HI (match_operand:HI 1 "general_operand" "0")
- (match_operand:HI 2 "general_operand" "dmn")))]
- ""
- "*
-{
-#ifdef MOTOROLA
- return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\";
-#else
- return \"andl %#0xFFFF,%0\;divu %2,%0\";
-#endif
-}")
-
-;; See comment before divhisi3 why these are commented out.
-;;(define_insn "udivhisi3"
-;; [(set (match_operand:HI 0 "general_operand" "=d")
-;; (truncate:HI
-;; (udiv:SI
-;; (match_operand:SI 1 "general_operand" "0")
-;; (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
-;; ""
-;; "*
-;;{
-;;#ifdef MOTOROLA
-;; return \"divu%.w %2,%0\";
-;;#else
-;; return \"divu %2,%0\";
-;;#endif
-;;}")
-
-;;(define_insn ""
-;; [(set (match_operand:HI 0 "general_operand" "=d")
-;; (truncate:HI (udiv:SI (match_operand:SI 1 "general_operand" "0")
-;; (match_operand:SI 2 "const_int_operand" "n"))))]
-;; ""
-;; "*
-;;{
-;;#ifdef MOTOROLA
-;; return \"divu%.w %2,%0\";
-;;#else
-;; return \"divu %2,%0\";
-;;#endif
-;;}")
-
(define_expand "divdf3"
[(set (match_operand:DF 0 "general_operand" "")
(div:DF (match_operand:DF 1 "general_operand" "")
\f
;; Remainder instructions.
-(define_insn "modhi3"
- [(set (match_operand:HI 0 "general_operand" "=d")
- (mod:HI (match_operand:HI 1 "general_operand" "0")
- (match_operand:HI 2 "general_operand" "dmn")))]
- ""
- "*
-{
- /* The swap insn produces cc's that don't correspond to the result. */
- CC_STATUS_INIT;
-#ifdef MOTOROLA
- return \"ext%.l %0\;divs%.w %2,%0\;swap %0\";
-#else
- return \"extl %0\;divs %2,%0\;swap %0\";
-#endif
-}")
-
-;; See comment before divhisi3 why these are commented out.
-;;(define_insn "modhisi3"
-;; [(set (match_operand:HI 0 "general_operand" "=d")
-;; (truncate:HI
-;; (mod:SI
-;; (match_operand:SI 1 "general_operand" "0")
-;; (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
-;; ""
-;; "*
-;;{
-;; /* The swap insn produces cc's that don't correspond to the result. */
-;; CC_STATUS_INIT;
-;;#ifdef MOTOROLA
-;; return \"divs%.w %2,%0\;swap %0\";
-;;#else
-;; return \"divs %2,%0\;swap %0\";
-;;#endif
-;;}")
-
-;;(define_insn ""
-;; [(set (match_operand:HI 0 "general_operand" "=d")
-;; (truncate:HI (mod:SI (match_operand:SI 1 "general_operand" "0")
-;; (match_operand:SI 2 "const_int_operand" "n"))))]
-;; ""
-;; "*
-;;{
-;; /* The swap insn produces cc's that don't correspond to the result. */
-;; CC_STATUS_INIT;
-;;#ifdef MOTOROLA
-;; return \"divs%.w %2,%0\;swap %0\";
-;;#else
-;; return \"divs %2,%0\;swap %0\";
-;;#endif
-;;}")
-
-(define_insn "umodhi3"
- [(set (match_operand:HI 0 "general_operand" "=d")
- (umod:HI (match_operand:HI 1 "general_operand" "0")
- (match_operand:HI 2 "general_operand" "dmn")))]
- ""
- "*
-{
- /* The swap insn produces cc's that don't correspond to the result. */
- CC_STATUS_INIT;
-#ifdef MOTOROLA
- return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\;swap %0\";
-#else
- return \"andl %#0xFFFF,%0\;divu %2,%0\;swap %0\";
-#endif
-}")
-
-;; See comment before divhisi3 why these are commented out.
-;;(define_insn "umodhisi3"
-;; [(set (match_operand:HI 0 "general_operand" "=d")
-;; (truncate:HI
-;; (umod:SI
-;; (match_operand:SI 1 "general_operand" "0")
-;; (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
-;; ""
-;; "*
-;;{
-;; /* The swap insn produces cc's that don't correspond to the result. */
-;; CC_STATUS_INIT;
-;;#ifdef MOTOROLA
-;; return \"divu%.w %2,%0\;swap %0\";
-;;#else
-;; return \"divu %2,%0\;swap %0\";
-;;#endif
-;;}")
-
-;;(define_insn ""
-;; [(set (match_operand:HI 0 "general_operand" "=d")
-;; (truncate:HI (umod:SI (match_operand:SI 1 "general_operand" "0")
-;; (match_operand:SI 2 "const_int_operand" "n"))))]
-;; ""
-;; "*
-;;{
-;; /* The swap insn produces cc's that don't correspond to the result. */
-;; CC_STATUS_INIT;
-;;#ifdef MOTOROLA
-;; return \"divu%.w %2,%0\;swap %0\";
-;;#else
-;; return \"divu %2,%0\;swap %0\";
-;;#endif
-;;}")
-
(define_insn "divmodsi4"
[(set (match_operand:SI 0 "general_operand" "=d")
(div:SI (match_operand:SI 1 "general_operand" "0")
else
return \"divul%.l %2,%3:%0\";
}")
+
+(define_insn "divmodhi4"
+ [(set (match_operand:HI 0 "general_operand" "=d")
+ (div:HI (match_operand:HI 1 "general_operand" "0")
+ (match_operand:HI 2 "general_operand" "g")))
+ (set (match_operand:HI 3 "general_operand" "=d")
+ (mod:HI (match_dup 1) (match_dup 2)))]
+ ""
+ "*
+{
+#ifdef MOTOROLA
+ output_asm_insn(\"ext%.l %0\;divs%.w %2,%0\", operands);
+#else
+ output_asm_insn(\"extl %0\;divs %2,%0\", operands);
+#endif
+ if (!find_reg_note(insn, REG_UNUSED, operands[3]))
+ {
+ CC_STATUS_INIT;
+ return \"move%.l %0,%3\;swap %3\";
+ }
+ else
+ return \"\";
+}")
+
+(define_insn "udivmodhi4"
+ [(set (match_operand:HI 0 "general_operand" "=d")
+ (udiv:HI (match_operand:HI 1 "general_operand" "0")
+ (match_operand:HI 2 "general_operand" "g")))
+ (set (match_operand:HI 3 "general_operand" "=d")
+ (umod:HI (match_dup 1) (match_dup 2)))]
+ ""
+ "*
+{
+#ifdef MOTOROLA
+ output_asm_insn(\"and%.l %#0xFFFF,%0\;divs%.w %2,%0\", operands);
+#else
+ output_asm_insn(\"and%.l %#0xFFFF,%0\;divs %2,%0\", operands);
+#endif
+ if (!find_reg_note(insn, REG_UNUSED, operands[3]))
+ {
+ CC_STATUS_INIT;
+ return \"move%.l %0,%3\;swap %3\";
+ }
+ else
+ return \"\";
+}")
\f
;; logical-and instructions