diff options
author | Mark Mitchell <mark@codesourcery.com> | 2005-09-29 03:31:23 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2005-09-29 03:31:23 +0000 |
commit | 0f8594eee973eb004228f171b4649cb3cb9aa536 (patch) | |
tree | 31982fcfb5affaad07795757ddfef347ec078819 /gcc/optabs.c | |
parent | 4bc7cba79582442c601bf69094b351833ad61b76 (diff) | |
download | gcc-0f8594eee973eb004228f171b4649cb3cb9aa536.zip gcc-0f8594eee973eb004228f171b4649cb3cb9aa536.tar.gz gcc-0f8594eee973eb004228f171b4649cb3cb9aa536.tar.bz2 |
re PR middle-end/17886 (variable rotate and unsigned long long rotate should be better optimized)
PR 17886
* expmed.c (expand_shift): Move logic to reverse rotation
direction when rotating by constants ...
* optabs.c (expand_binop): ... here.
* config/i386/i386.md (rotrdi3): Handle 32-bit mode.
(ix86_rotrdi3): New pattern.
(rotldi3): Handle 32-bit mode.
(ix86_rotldi3): New pattern.
From-SVN: r104761
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index 31212cb..bc859205 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -1049,6 +1049,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1, || binoptab->code == ROTATERT); rtx entry_last = get_last_insn (); rtx last; + bool first_pass_p; class = GET_MODE_CLASS (mode); @@ -1098,6 +1099,8 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1, } } + retry: + /* If we can do it with a three-operand insn, do so. */ if (methods != OPTAB_MUST_WIDEN @@ -1183,6 +1186,22 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1, delete_insns_since (last); } + /* If we were trying to rotate by a constant value, and that didn't + work, try rotating the other direction before falling back to + shifts and bitwise-or. */ + if (first_pass_p + && (binoptab == rotl_optab || binoptab == rotr_optab) + && class == MODE_INT + && GET_CODE (op1) == CONST_INT + && INTVAL (op1) > 0 + && (unsigned int) INTVAL (op1) < GET_MODE_BITSIZE (mode)) + { + first_pass_p = false; + op1 = GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (op1)); + binoptab = binoptab == rotl_optab ? rotr_optab : rotl_optab; + goto retry; + } + /* If this is a multiply, see if we can do a widening operation that takes operands of this mode and makes a wider mode. */ |