On 07/15/2010 02:26 PM, Uros Bizjak wrote:
The reason you pointed out is for SHIFT_COUNT_TRUNCATED. Please note,
that we don't use memory_operands, but even in register operand case,
"bt" insn doesn't truncate the bit-count operand, but performs modulo
operation on it. I.E, "bt %reg, 75" will not return 0, but shift insn
with the same operands will.
Yes, only for memory_operands.
You can take a look at the attached patch. I never got round to finish
it, but I think it bootstrapped. It unifies SHIFT_COUNT_TRUNCATED and
TARGET_SHIFT_TRUNCATION_MASK, I think it can be useful for x86.
Paolo
patch 1/4:
2009-03-13 Paolo Bonzini
* combine.c (expand_compound_operation): Fix thinko.
(simplify_shift_const_1): Avoid noncanonical rtx.
Index: gcc/combine.c
===
--- gcc/combine.c (branch rebase-shift-count-trunc)
+++ gcc/combine.c (working copy)
@@ -6191,7 +6191,7 @@ expand_compound_operation (rtx x)
a such a position. */
modewidth = GET_MODE_BITSIZE (GET_MODE (x));
- if (modewidth + len >= pos)
+ if (modewidth >= pos + len)
{
enum machine_mode mode = GET_MODE (x);
tem = gen_lowpart (mode, XEXP (x, 0));
@@ -9613,10 +9613,11 @@ simplify_shift_const_1 (enum rtx_code co
rtx varop_inner = XEXP (varop, 0);
varop_inner
- = gen_rtx_LSHIFTRT (GET_MODE (varop_inner),
- XEXP (varop_inner, 0),
- GEN_INT
- (count + INTVAL (XEXP (varop_inner, 1;
+ = simplify_gen_binary (LSHIFTRT,
+ GET_MODE (varop_inner),
+ XEXP (varop_inner, 0),
+ GEN_INT
+ (count + INTVAL (XEXP (varop_inner,
1;
varop = gen_rtx_TRUNCATE (GET_MODE (varop), varop_inner);
count = 0;
continue;
patch 2/4:
2009-03-13 Paolo Bonzini
* gcc/config/bfin/bfin.h (SHIFT_COUNT_TRUNCATED): Define to 0.
* gcc/config/cris/cris.h (SHIFT_COUNT_TRUNCATED): Define to 0.
* gcc/config/h8300/h8300.h (SHIFT_COUNT_TRUNCATED): Define to 0.
* gcc/config/mcore/mcore.h (SHIFT_COUNT_TRUNCATED): Define to 0.
* gcc/config/mmix/mmix.h (SHIFT_COUNT_TRUNCATED): Define to 0.
* gcc/config/pdp11/pdp11.h (SHIFT_COUNT_TRUNCATED): Define to 0.
* gcc/config/vax/vax.h (SHIFT_COUNT_TRUNCATED): Define to 0.
Index: gcc/config/pdp11/pdp11.h
===
--- gcc/config/pdp11/pdp11.h(branch rebase-shift-count-trunc)
+++ gcc/config/pdp11/pdp11.h(working copy)
@@ -780,6 +780,9 @@ extern int may_call_alloca;
#define MOVE_MAX 2
+/* Check later if we can set SHIFT_COUNT_TRUNCATED to 1. */
+#define SHIFT_COUNT_TRUNCATED 0
+
/* Nonzero if access to memory by byte is slow and undesirable. -
*/
#define SLOW_BYTE_ACCESS 0
Index: gcc/config/cris/cris.h
===
--- gcc/config/cris/cris.h (branch rebase-shift-count-trunc)
+++ gcc/config/cris/cris.h (working copy)
@@ -1521,6 +1521,7 @@ enum cris_pic_symbol_type
#define MOVE_MAX 4
/* Maybe SHIFT_COUNT_TRUNCATED is safe to define? FIXME: Check later. */
+#define SHIFT_COUNT_TRUNCATED 0
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
Index: gcc/config/mcore/mcore.h
===
--- gcc/config/mcore/mcore.h(branch rebase-shift-count-trunc)
+++ gcc/config/mcore/mcore.h(working copy)
@@ -820,7 +820,7 @@ extern const enum reg_class reg_class_fr
/* Shift counts are truncated to 6-bits (0 to 63) instead of the expected
5-bits, so we can not define SHIFT_COUNT_TRUNCATED to true for this
- target. */
+ target. TODO: we could define TARGET_SHIFT_TRUNCATION_MASK. */
#define SHIFT_COUNT_TRUNCATED 0
/* All integers have the same format so truncation is easy. */
Index: gcc/config/vax/vax.h
===
--- gcc/config/vax/vax.h(branch rebase-shift-count-trunc)
+++ gcc/config/vax/vax.h(working copy)
@@ -627,7 +627,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_
/* Define if shifts truncate the shift count
which implies one can omit a sign-extension or zero-extension
of a shift count. */
-/* #define SHIFT_COUNT_TRUNCATED */
+#define SHIFT_COUNT_TRUNCATED 0
/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
is done just by pretending it is already truncated. */
Index: gcc/config/h8300/h8300.h
===
--- gcc/config/h8300/h8300.h(branch rebase-shift-count-trunc)
+++ gcc/config/h8300/h8300.h(working copy)
@@ -981,7 +981,7 @@ struct cum_arg
/* Defin