{
if (!target)
target = gen_reg_rtx (GET_MODE (value));
- op1 = force_operand (XEXP (value, 0), NULL_RTX);
+ /* FIX or UNSIGNED_FIX with integral mode has unspecified rounding,
+ while FIX with floating point mode rounds toward zero. So, some
+ targets use expressions like (fix:SI (fix:DF (reg:DF ...)))
+ to express rounding toward zero during the conversion to int.
+ expand_fix isn't able to handle that, it can only handle
+ FIX/UNSIGNED_FIX from floating point mode to integral one. */
+ if ((code == FIX || code == UNSIGNED_FIX)
+ && GET_CODE (XEXP (value, 0)) == FIX
+ && (GET_MODE (XEXP (value, 0))
+ == GET_MODE (XEXP (XEXP (value, 0), 0))))
+ op1 = force_operand (XEXP (XEXP (value, 0), 0), NULL_RTX);
+ else
+ op1 = force_operand (XEXP (value, 0), NULL_RTX);
switch (code)
{
case ZERO_EXTEND: