+2000-05-26 Geoffrey Keating <geoffk@cygnus.com>
+
+ * config/rs6000/rs6000.md: Correct order of operands for DImode
+ boolean patterns.
+
+ * config/rs6000/rs6000.c (boolean_or_operator): New function.
+ * config/rs6000/rs6000-protos.h (boolean_or_operator): Prototype it.
+ * config/rs6000/rs6000.h (PREDICATE_CODES): Add boolean_or_operator.
+ * config/rs6000/rs6000.md: Use boolean_or_operator instead of
+ boolean_operator for the boolean patterns without NOTs.
+
+ * config/rs6000/rs6000.c (reg_or_logical_cint_operand): Rename
+ from reg_or_u_cint_operand. Change comment and behaviour.
+ (logical_operand): Clean up, add assertion.
+ (non_logical_cint_operand): Also check for
+ reg_or_logical_cint_operand.
+ * config/rs6000/rs6000.h (PREDICATE_CODES): Update.
+ * config/rs6000/rs6000.md (iorsi3): Use reg_or_logical_cint_operand
+ in the expander.
+ (xorsi3): Likewise.
+ (iordi3): Likewise.
+ (xordi3): Likewise.
+
2000-05-26 Mark Mitchell <mark@codesourcery.com>
* tree.h (struct record_layout_info): Rename to (struct
extern int reg_or_neg_short_operand PARAMS ((rtx, enum machine_mode));
extern int reg_or_u_short_operand PARAMS ((rtx, enum machine_mode));
extern int reg_or_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_u_cint_operand PARAMS ((rtx, enum machine_mode));
+extern int reg_or_logical_cint_operand PARAMS ((rtx, enum machine_mode));
extern int got_operand PARAMS ((rtx, enum machine_mode));
extern int got_no_const_operand PARAMS ((rtx, enum machine_mode));
extern int num_insns_constant PARAMS ((rtx, enum machine_mode));
extern int add_operand PARAMS ((rtx, enum machine_mode));
extern int non_add_cint_operand PARAMS ((rtx, enum machine_mode));
extern int non_logical_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int non_logical_u_cint_operand PARAMS ((rtx, enum machine_mode));
extern int logical_operand PARAMS ((rtx, enum machine_mode));
-extern int logical_u_operand PARAMS ((rtx, enum machine_mode));
extern int mask_operand PARAMS ((rtx, enum machine_mode));
extern int mask64_operand PARAMS ((rtx, enum machine_mode));
extern int and64_operand PARAMS ((rtx, enum machine_mode));
extern int scc_comparison_operator PARAMS ((rtx, enum machine_mode));
extern int trap_comparison_operator PARAMS ((rtx, enum machine_mode));
extern int boolean_operator PARAMS ((rtx, enum machine_mode));
+extern int boolean_or_operator PARAMS ((rtx, enum machine_mode));
extern int includes_lshift_p PARAMS ((rtx, rtx));
extern int includes_rshift_p PARAMS ((rtx, rtx));
extern int registers_ok_for_quad_peep PARAMS ((rtx, rtx));
32-bit unsigned constant integer. */
int
-reg_or_u_cint_operand (op, mode)
+reg_or_logical_cint_operand (op, mode)
register rtx op;
enum machine_mode mode;
{
- return (gpc_reg_operand (op, mode)
- || (GET_CODE (op) == CONST_INT
-#if HOST_BITS_PER_WIDE_INT != 32
- && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32)
-#endif
- && INTVAL (op) > 0)
-#if HOST_BITS_PER_WIDE_INT == 32
- || (GET_CODE (op) == CONST_DOUBLE
- && CONST_DOUBLE_HIGH (op) == 0)
-#endif
- );
+ if (GET_CODE (op) == CONST_INT)
+ {
+ if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
+ {
+ if (GET_MODE_BITSIZE (mode) <= 32)
+ abort();
+
+ if (INTVAL (op) < 0)
+ return 0;
+ }
+
+ return ((INTVAL (op) & GET_MODE_MASK (mode)
+ & (~ (unsigned HOST_WIDE_INT) 0xffffffffu)) == 0);
+ }
+ else if (GET_CODE (op) == CONST_DOUBLE)
+ {
+ if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
+ || mode != DImode)
+ abort();
+
+ return CONST_DOUBLE_HIGH (op) == 0;
+ }
+ else
+ return gpc_reg_operand (op, mode);
}
/* Return 1 if the operand is an operand that can be loaded via the GOT */
register rtx op;
enum machine_mode mode;
{
+ /* an unsigned representation of 'op'. */
+ unsigned HOST_WIDE_INT opl, oph;
+
if (gpc_reg_operand (op, mode))
return 1;
+
if (GET_CODE (op) == CONST_INT)
{
- unsigned HOST_WIDE_INT cval = INTVAL (op) & GET_MODE_MASK (mode);
- return ((cval & (~ (HOST_WIDE_INT) 0xffff)) == 0
- || (cval & (~ (HOST_WIDE_INT) 0xffff0000u)) == 0);
+ opl = INTVAL (op) & GET_MODE_MASK (mode);
+ if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
+ oph = 0;
+ else
+ oph = INTVAL (op) >> (HOST_BITS_PER_WIDE_INT - 1);
}
else if (GET_CODE (op) == CONST_DOUBLE)
{
- return (CONST_DOUBLE_HIGH (op) == 0
- && ((CONST_DOUBLE_LOW (op)
- & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) == 0));
+ if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
+ abort();
+
+ opl = CONST_DOUBLE_LOW (op);
+ oph = CONST_DOUBLE_HIGH (op);
}
else
return 0;
+
+ return (oph == 0
+ && ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
+ || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000u) == 0));
}
/* Return 1 if C is a constant that is not a logical operand (as
- above). */
+ above), but could be split into one. */
int
non_logical_cint_operand (op, mode)
enum machine_mode mode;
{
return ((GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
- && ! logical_operand (op, mode));
+ && ! logical_operand (op, mode)
+ && reg_or_logical_cint_operand (op, mode));
}
/* Return 1 if C is a constant that can be encoded in a 32-bit mask on the
enum rtx_code code = GET_CODE (op);
return (code == AND || code == IOR || code == XOR);
}
+
+int
+boolean_or_operator (op, mode)
+ rtx op;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+ enum rtx_code code = GET_CODE (op);
+ return (code == IOR || code == XOR);
+}
\f
/* Return 1 if ANDOP is a mask that has no bits on that are not in the
mask required to convert the result of a rotate insn into a shift
{"reg_or_neg_short_operand", {SUBREG, REG, CONST_INT}}, \
{"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}}, \
{"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \
- {"reg_or_u_cint_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
+ {"reg_or_logical_cint_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
{"got_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{"got_no_const_operand", {SYMBOL_REF, LABEL_REF}}, \
{"easy_fp_constant", {CONST_DOUBLE}}, \
GT, LEU, LTU, GEU, GTU}}, \
{"trap_comparison_operator", {EQ, NE, LE, LT, GE, \
GT, LEU, LTU, GEU, GTU}}, \
- {"boolean_operator", {AND, IOR, XOR}},
+ {"boolean_operator", {AND, IOR, XOR}}, \
+ {"boolean_or_operator", {IOR, XOR}},
/* uncomment for disabling the corresponding default options */
/* #define MACHINE_no_sched_interblock */
(define_expand "iorsi3"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
- (match_operand:SI 2 "reg_or_cint_operand" "")))]
+ (match_operand:SI 2 "reg_or_logical_cint_operand" "")))]
""
"
{
(define_expand "xorsi3"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
- (match_operand:SI 2 "reg_or_cint_operand" "")))]
+ (match_operand:SI 2 "reg_or_logical_cint_operand" "")))]
""
"
{
(define_insn "*boolsi3_internal1"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
- (match_operator:SI 3 "boolean_operator"
+ (match_operator:SI 3 "boolean_or_operator"
[(match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
(match_operand:SI 2 "logical_operand" "r,K,L")]))]
""
(define_insn "*boolsi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
- (compare:CC (match_operator:SI 4 "boolean_operator"
+ (compare:CC (match_operator:SI 4 "boolean_or_operator"
[(match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(define_split
[(set (match_operand:SI 0 "gpc_reg_operand" "")
- (match_operator:SI 3 "boolean_operator"
+ (match_operator:SI 3 "boolean_or_operator"
[(match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "non_logical_cint_operand" "")]))]
""
(define_expand "iordi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
- (match_operand:DI 2 "reg_or_cint_operand" "")))]
+ (match_operand:DI 2 "reg_or_logical_cint_operand" "")))]
"TARGET_POWERPC64"
"
{
(define_expand "xordi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
- (match_operand:DI 2 "reg_or_cint_operand" "")))]
+ (match_operand:DI 2 "reg_or_logical_cint_operand" "")))]
"TARGET_POWERPC64"
"
{
(define_insn "*booldi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
- (match_operator:DI 3 "boolean_operator"
+ (match_operator:DI 3 "boolean_or_operator"
[(match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
(match_operand:DI 2 "logical_operand" "r,K,JF")]))]
"TARGET_POWERPC64"
(define_insn "*booldi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
- (compare:CC (match_operator:DI 4 "boolean_operator"
+ (compare:CC (match_operator:DI 4 "boolean_or_operator"
[(match_operand:DI 1 "gpc_reg_operand" "%r,r")
(match_operand:DI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
- (match_operator:DI 3 "boolean_operator"
+ (match_operator:DI 3 "boolean_or_operator"
[(match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "non_logical_cint_operand" "")]))]
"TARGET_POWERPC64"
[(not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
(match_operand:DI 2 "logical_operand" "r")]))]
"TARGET_POWERPC64"
- "%q3 %0,%1,%2")
+ "%q3 %0,%2,%1")
(define_insn "*boolcdi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(clobber (match_scratch:DI 3 "=r,r"))]
"TARGET_POWERPC64"
"@
- %q4. %3,%1,%2
+ %q4. %3,%2,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(match_dup 4))]
"TARGET_POWERPC64"
"@
- %q4. %0,%1,%2
+ %q4. %0,%2,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])