diff options
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r-- | gcc/expmed.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c index 735fe987fc1..7ee5964853b 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -4337,10 +4337,24 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, target = 0; if (quotient == 0) - /* No divide instruction either. Use library for remainder. */ - remainder = sign_expand_binop (compute_mode, umod_optab, smod_optab, - op0, op1, target, - unsignedp, OPTAB_LIB_WIDEN); + { + /* No divide instruction either. Use library for remainder. */ + remainder = sign_expand_binop (compute_mode, umod_optab, smod_optab, + op0, op1, target, + unsignedp, OPTAB_LIB_WIDEN); + /* No remainder function. Try a quotient-and-remainder + function, keeping the remainder. */ + if (!remainder) + { + remainder = gen_reg_rtx (compute_mode); + if (!expand_twoval_binop_libfunc + (unsignedp ? udivmod_optab : sdivmod_optab, + op0, op1, + NULL_RTX, remainder, + unsignedp ? UMOD : MOD)) + remainder = NULL_RTX; + } + } else { /* We divided. Now finish doing X - Y * (X / Y). */ |