;; Base name for insn mnemonic.
(define_code_attr rotate [(rotate "rol") (rotatert "ror")])
-;; Base name for insn mnemonic of rotation in the other direction.
-(define_code_attr rotateinv [(rotate "ror") (rotatert "rol")])
-
;; Mapping of abs neg operators
(define_code_iterator absneg [abs neg])
return "#";
default:
- if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
- {
- if (operands[2] == const1_rtx)
- return "<rotate>{<imodesuffix>}\t%0";
- if (CONST_INT_P (operands[2])
- && INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode) - 1)
- return "<rotateinv>{<imodesuffix>}\t%0";
- }
- return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
+ if (operands[2] == const1_rtx
+ && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+ return "<rotate>{<imodesuffix>}\t%0";
+ else
+ return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
}
}
[(set_attr "isa" "*,bmi2")
return "#";
default:
- if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
- {
- if (operands[2] == const1_rtx)
- return "<rotate>{l}\t%k0";
- if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 31)
- return "<rotateinv>{l}\t%k0";
- }
- return "<rotate>{l}\t{%2, %k0|%k0, %2}";
+ if (operands[2] == const1_rtx
+ && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+ return "<rotate>{l}\t%k0";
+ else
+ return "<rotate>{l}\t{%2, %k0|%k0, %2}";
}
}
[(set_attr "isa" "*,bmi2")
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
{
- if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
- {
- if (operands[2] == const1_rtx)
- return "<rotate>{<imodesuffix>}\t%0";
- if (CONST_INT_P (operands[2])
- && INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode) - 1)
- return "<rotateinv>{<imodesuffix>}\t%0";
- }
- return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
+ if (operands[2] == const1_rtx
+ && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+ return "<rotate>{<imodesuffix>}\t%0";
+ else
+ return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
}
[(set_attr "type" "rotate")
(set (attr "length_immediate")
|| (operands[1] == const1_rtx
&& TARGET_SHIFT1))"
{
- if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
- {
- if (operands[2] == const1_rtx)
- return "<rotate>{b}\t%0";
- if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 7)
- return "<rotateinv>{b}\t%0";
- }
- return "<rotate>{b}\t{%1, %0|%0, %1}";
+ if (operands[1] == const1_rtx
+ && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+ return "<rotate>{b}\t%0";
+ else
+ return "<rotate>{b}\t{%1, %0|%0, %1}";
}
[(set_attr "type" "rotate1")
(set (attr "length_immediate")
case ROTATERT:
case ROTATE:
+ /* Canonicalize rotates by constant amount. If op1 is bitsize / 2,
+ prefer left rotation, if op1 is from bitsize / 2 + 1 to
+ bitsize - 1, use other direction of rotate with 1 .. bitsize / 2 - 1
+ amount instead. */
+ if (CONST_INT_P (trueop1)
+ && IN_RANGE (INTVAL (trueop1),
+ GET_MODE_BITSIZE (mode) / 2 + (code == ROTATE),
+ GET_MODE_BITSIZE (mode) - 1))
+ return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
+ mode, op0, GEN_INT (GET_MODE_BITSIZE (mode)
+ - INTVAL (trueop1)));
+ /* FALLTHRU */
case ASHIFTRT:
if (trueop1 == CONST0_RTX (mode))
return op0;