* config/sparc/sparc.h (TARGET_SUPPORTS_WIDE_INT): Define to 1.
* config/sparc/sparc.c (sparc_emit_set_const64): Remove code
conditionalized on HOST_BITS_PER_WIDE_INT == 32.
(sparc_cannot_force_const_mem) <CONST_WIDE_INT>: New case.
<CONST_DOUBLE>: Remove VOIDmode test.
(epilogue_renumber) <CONST_WIDE_INT>: New case.
(sparc_print_operand): Remove support for CONST_DOUBLE with VOIDmode.
(sparc_assemble_integer): Likewise.
(set_extends): Likewise.
(sparc_rtx_costs) <CONST_INT>: Use SMALL_INT.
<CONST_WIDE_INT>: New case.
<CONST_DOUBLE>: Remove support for VOIDmode.
<MULT>: Remove support for CONST_DOUBLE with VOIDmode.
* config/sparc/predicates.md (const_zero_operand): Add const_wide_int.
(const_all_ones_operand): Likewise.
(uns_small_int_operand): Remove const_double and code conditionalized
on HOST_BITS_PER_WIDE_INT == 32.
(arith_double_operand): Likewise.
(arith_double_add_operand): Likewise.
(input_operand): Remove support for CONST_DOUBLE with DImode.
* config/sparc/sparc.md (DImode CONST_INT splitter): Remove code
conditionalized on HOST_BITS_PER_WIDE_INT == 32.
(DFmode CONST_DOUBLE splitter): Likewise.
(*adddi3_insn_sp32): Likewise.
(*subdi3_insn_sp32): Likewise.
(DImode logical splitter): Likewise.
(DImode CONST_DOUBLE splitter): Delete.
From-SVN: r231586
+2015-12-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/sparc/sparc.h (TARGET_SUPPORTS_WIDE_INT): Define to 1.
+ * config/sparc/sparc.c (sparc_emit_set_const64): Remove code
+ conditionalized on HOST_BITS_PER_WIDE_INT == 32.
+ (sparc_cannot_force_const_mem) <CONST_WIDE_INT>: New case.
+ <CONST_DOUBLE>: Remove VOIDmode test.
+ (epilogue_renumber) <CONST_WIDE_INT>: New case.
+ (sparc_print_operand): Remove support for CONST_DOUBLE with VOIDmode.
+ (sparc_assemble_integer): Likewise.
+ (set_extends): Likewise.
+ (sparc_rtx_costs) <CONST_INT>: Use SMALL_INT.
+ <CONST_WIDE_INT>: New case.
+ <CONST_DOUBLE>: Remove support for VOIDmode.
+ <MULT>: Remove support for CONST_DOUBLE with VOIDmode.
+ * config/sparc/predicates.md (const_zero_operand): Add const_wide_int.
+ (const_all_ones_operand): Likewise.
+ (uns_small_int_operand): Remove const_double and code conditionalized
+ on HOST_BITS_PER_WIDE_INT == 32.
+ (arith_double_operand): Likewise.
+ (arith_double_add_operand): Likewise.
+ (input_operand): Remove support for CONST_DOUBLE with DImode.
+ * config/sparc/sparc.md (DImode CONST_INT splitter): Remove code
+ conditionalized on HOST_BITS_PER_WIDE_INT == 32.
+ (DFmode CONST_DOUBLE splitter): Likewise.
+ (*adddi3_insn_sp32): Likewise.
+ (*subdi3_insn_sp32): Likewise.
+ (DImode logical splitter): Likewise.
+ (DImode CONST_DOUBLE splitter): Delete.
+
2015-12-12 Paolo Bonzini <bonzini@gnu.org>
PR sanitizer/68418
;; Return true if OP is the zero constant for MODE.
(define_predicate "const_zero_operand"
- (and (match_code "const_int,const_double,const_vector")
+ (and (match_code "const_int,const_wide_int,const_double,const_vector")
(match_test "op == CONST0_RTX (mode)")))
-;; Return true if the integer representation of OP is
-;; all-ones.
+;; Return true if the integer representation of OP is all ones.
(define_predicate "const_all_ones_operand"
- (and (match_code "const_int,const_double,const_vector")
+ (and (match_code "const_int,const_wide_int,const_double,const_vector")
(match_test "INTEGRAL_MODE_P (GET_MODE (op))")
(match_test "op == CONSTM1_RTX (GET_MODE (op))")))
;; instruction sign-extends immediate values just like all other SPARC
;; instructions, but interprets the extended result as an unsigned number.
(define_predicate "uns_small_int_operand"
- (match_code "const_int,const_double")
-{
-#if HOST_BITS_PER_WIDE_INT == 32
- return ((GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 0x1000)
- || (GET_CODE (op) == CONST_DOUBLE
- && CONST_DOUBLE_HIGH (op) == 0
- && (unsigned) CONST_DOUBLE_LOW (op) - 0xFFFFF000 < 0x1000));
-#else
- return (GET_CODE (op) == CONST_INT
- && ((INTVAL (op) >= 0 && INTVAL (op) < 0x1000)
- || (INTVAL (op) >= 0xFFFFF000
- && INTVAL (op) <= 0xFFFFFFFF)));
-#endif
-})
+ (and (match_code "const_int")
+ (match_test "((INTVAL (op) >= 0 && INTVAL (op) < 0x1000)
+ || (INTVAL (op) >= 0xFFFFF000
+ && INTVAL (op) <= 0xFFFFFFFF))")))
;; Return true if OP is a constant that can be loaded by the sethi instruction.
;; The first test avoids emitting sethi to load zero for example.
;; representable by a couple of 13-bit signed fields. This is an
;; acceptable operand for most 3-address splitters.
(define_predicate "arith_double_operand"
- (match_code "const_int,const_double,reg,subreg")
+ (match_code "const_int,reg,subreg")
{
bool arith_simple_operand = arith_operand (op, mode);
HOST_WIDE_INT m1, m2;
if (TARGET_ARCH64 || arith_simple_operand)
return arith_simple_operand;
-#if HOST_BITS_PER_WIDE_INT == 32
- if (GET_CODE (op) != CONST_DOUBLE)
- return false;
- m1 = CONST_DOUBLE_LOW (op);
- m2 = CONST_DOUBLE_HIGH (op);
-#else
if (GET_CODE (op) != CONST_INT)
return false;
+
m1 = trunc_int_for_mode (INTVAL (op), SImode);
m2 = trunc_int_for_mode (INTVAL (op) >> 32, SImode);
-#endif
return SPARC_SIMM13_P (m1) && SPARC_SIMM13_P (m2);
})
;; Return true if OP is suitable as second double operand for add/sub.
(define_predicate "arith_double_add_operand"
- (match_code "const_int,const_double,reg,subreg")
+ (match_code "const_int,reg,subreg")
{
- bool _arith_double_operand = arith_double_operand (op, mode);
-
- if (_arith_double_operand)
+ if (arith_double_operand (op, mode))
return true;
return TARGET_ARCH64 && const_4096_operand (op, mode);
|| (TARGET_ARCH64
&& mode == DImode
&& INTVAL (XEXP (op, 2)) > 51)));
- else
- return register_operand (op, mode);
+
+ return register_operand (op, mode);
})
;; Return true if OP is a valid operand for the source of a move insn.
/* If 32-bit mode and this is a DImode constant, allow it
so that the splits can be generated. */
- if (TARGET_ARCH32
- && mode == DImode
- && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
+ if (TARGET_ARCH32 && mode == DImode && GET_CODE (op) == CONST_INT)
return true;
if (mclass == MODE_FLOAT && GET_CODE (op) == CONST_DOUBLE)
}
}
-#if HOST_BITS_PER_WIDE_INT == 32
-static void
-sparc_emit_set_const64 (rtx op0 ATTRIBUTE_UNUSED, rtx op1 ATTRIBUTE_UNUSED)
-{
- gcc_unreachable ();
-}
-#else
/* These avoid problems when cross compiling. If we do not
go through all this hair then the optimizer will see
invalid REG_EQUAL notes or in some cases none at all. */
* sllx %reg, 32, %reg
* or %reg, low_bits, %reg
*/
- if (SPARC_SIMM13_P(low_bits)
- && ((int)low_bits > 0))
+ if (SPARC_SIMM13_P (low_bits) && ((int)low_bits > 0))
{
sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_bits, 32);
return;
/* The easiest way when all else fails, is full decomposition. */
sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits);
}
-#endif /* HOST_BITS_PER_WIDE_INT == 32 */
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
return the mode to be used for the comparison. For floating-point,
switch (GET_CODE (x))
{
case CONST_INT:
+ case CONST_WIDE_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
/* Accept all non-symbolic constants. */
break;
case CONST_DOUBLE:
- if (GET_MODE (x) == VOIDmode)
- return true;
-
/* Floating point constants are generally not ok.
The only exception is 0.0 and all-ones in VIS. */
if (TARGET_VIS
/* Nonzero if the constant value X is a legitimate general operand
when generating PIC code. It is given that flag_pic is on and
- that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
+ that X satisfies CONSTANT_P. */
bool
legitimate_pic_operand_p (rtx x)
case CC0:
case PC:
case CONST_INT:
+ case CONST_WIDE_INT:
case CONST_DOUBLE:
return 0;
HOST_WIDE_INT i;
if (GET_CODE(x) == CONST_INT)
i = INTVAL (x);
- else if (GET_CODE(x) == CONST_DOUBLE)
- i = CONST_DOUBLE_LOW (x);
else
{
output_operand_lossage ("invalid %%s operand");
output_addr_const (file, XEXP (x, 1));
fputc (')', file);
}
- else if (GET_CODE (x) == CONST_DOUBLE
- && (GET_MODE (x) == VOIDmode
- || GET_MODE_CLASS (GET_MODE (x)) == MODE_INT))
- {
- if (CONST_DOUBLE_HIGH (x) == 0)
- fprintf (file, "%u", (unsigned int) CONST_DOUBLE_LOW (x));
- else if (CONST_DOUBLE_HIGH (x) == -1
- && CONST_DOUBLE_LOW (x) < 0)
- fprintf (file, "%d", (int) CONST_DOUBLE_LOW (x));
- else
- output_operand_lossage ("long long constant not a valid immediate operand");
- }
else if (GET_CODE (x) == CONST_DOUBLE)
- output_operand_lossage ("floating point constant not a valid immediate operand");
- else { output_addr_const (file, x); }
+ output_operand_lossage ("floating-point constant not a valid immediate operand");
+ else
+ output_addr_const (file, x);
}
/* Implement TARGET_PRINT_OPERAND_ADDRESS. */
{
/* ??? We only output .xword's for symbols and only then in environments
where the assembler can handle them. */
- if (aligned_p && size == 8
- && (GET_CODE (x) != CONST_INT && GET_CODE (x) != CONST_DOUBLE))
+ if (aligned_p && size == 8 && GET_CODE (x) != CONST_INT)
{
if (TARGET_V9)
{
case LSHIFTRT:
return GET_MODE (SET_SRC (pat)) == SImode;
/* Positive integers leave the high bits zero. */
- case CONST_DOUBLE:
- return ! (CONST_DOUBLE_LOW (SET_SRC (pat)) & 0x80000000);
case CONST_INT:
- return ! (INTVAL (SET_SRC (pat)) & 0x80000000);
+ return !(INTVAL (SET_SRC (pat)) & 0x80000000);
case ASHIFTRT:
case SIGN_EXTEND:
return - (GET_MODE (SET_SRC (pat)) == SImode);
switch (code)
{
case CONST_INT:
- if (INTVAL (x) < 0x1000 && INTVAL (x) >= -0x1000)
- {
- *total = 0;
- return true;
- }
- /* FALLTHRU */
+ if (SMALL_INT (x))
+ *total = 0;
+ else
+ *total = 2;
+ return true;
+
+ case CONST_WIDE_INT:
+ *total = 0;
+ if (!SPARC_SIMM13_P (CONST_WIDE_INT_ELT (x, 0)))
+ *total += 2;
+ if (!SPARC_SIMM13_P (CONST_WIDE_INT_ELT (x, 1)))
+ *total += 2;
+ return true;
case HIGH:
*total = 2;
return true;
case CONST_DOUBLE:
- if (mode == VOIDmode
- && ((CONST_DOUBLE_HIGH (x) == 0
- && CONST_DOUBLE_LOW (x) < 0x1000)
- || (CONST_DOUBLE_HIGH (x) == -1
- && CONST_DOUBLE_LOW (x) < 0
- && CONST_DOUBLE_LOW (x) >= -0x1000)))
- *total = 0;
- else
- *total = 8;
+ *total = 8;
return true;
case MEM:
for (nbits = 0; value != 0; value &= value - 1)
nbits++;
}
- else if (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
- && GET_MODE (XEXP (x, 1)) == VOIDmode)
- {
- rtx x1 = XEXP (x, 1);
- unsigned HOST_WIDE_INT value1 = CONST_DOUBLE_LOW (x1);
- unsigned HOST_WIDE_INT value2 = CONST_DOUBLE_HIGH (x1);
-
- for (nbits = 0; value1 != 0; value1 &= value1 - 1)
- nbits++;
- for (; value2 != 0; value2 &= value2 - 1)
- nbits++;
- }
else
nbits = 7;
/* FIXME, this is wrong when TARGET_ARCH64 and TARGET_STACK_BIAS, because
then %sp+2047 is 128-bit aligned so %sp is really only byte-aligned. */
#define STACK_BOUNDARY (TARGET_ARCH64 ? 128 : 64)
+
/* Temporary hack until the FIXME above is fixed. */
#define SPARC_STACK_BOUNDARY_HACK (TARGET_ARCH64 && TARGET_STACK_BIAS)
/* Define this to 1 if the FE_EXCEPT values defined in fenv.h start at 1. */
#define SPARC_LOW_FE_EXCEPT_VALUES 0
+
+#define TARGET_SUPPORTS_WIDE_INT 1
&& reload_completed"
[(clobber (const_int 0))]
{
-#if HOST_BITS_PER_WIDE_INT == 32
- emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
- (INTVAL (operands[1]) < 0) ?
- constm1_rtx :
- const0_rtx));
- emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
- operands[1]));
-#else
HOST_WIDE_INT low, high;
low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
gen_highpart (SImode, operands[0])));
else
emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
-#endif
- DONE;
-})
-
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "const_double_operand" ""))]
- "reload_completed
- && (! TARGET_V9
- || (! TARGET_ARCH64
- && ((GET_CODE (operands[0]) == REG
- && SPARC_INT_REG_P (REGNO (operands[0])))
- || (GET_CODE (operands[0]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[0])) == REG
- && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))"
- [(clobber (const_int 0))]
-{
- emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
- GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
- /* Slick... but this trick loses if this subreg constant part
- can be done in one insn. */
- if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
- && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
- && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
- {
- emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
- gen_highpart (SImode, operands[0])));
- }
- else
- {
- emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
- GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
- }
DONE;
})
if (TARGET_ARCH64)
{
-#if HOST_BITS_PER_WIDE_INT == 32
- gcc_unreachable ();
-#else
machine_mode mode = GET_MODE (operands[1]);
rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
emit_insn (gen_movdi (operands[0], tem));
-#endif
}
else
{
operands[5] = gen_lowpart (SImode, operands[2]);
operands[6] = gen_highpart (SImode, operands[0]);
operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
-#if HOST_BITS_PER_WIDE_INT == 32
- if (GET_CODE (operands[2]) == CONST_INT)
- {
- if (INTVAL (operands[2]) < 0)
- operands[8] = constm1_rtx;
- else
- operands[8] = const0_rtx;
- }
- else
-#endif
- operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
}
[(set_attr "length" "2")])
operands[5] = gen_lowpart (SImode, operands[2]);
operands[6] = gen_highpart (SImode, operands[0]);
operands[7] = gen_highpart (SImode, operands[1]);
-#if HOST_BITS_PER_WIDE_INT == 32
- if (GET_CODE (operands[2]) == CONST_INT)
- {
- if (INTVAL (operands[2]) < 0)
- operands[8] = constm1_rtx;
- else
- operands[8] = const0_rtx;
- }
- else
-#endif
- operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
}
[(set_attr "length" "2")])
operands[5] = gen_lowpart (SImode, operands[0]);
operands[6] = gen_highpart (SImode, operands[2]);
operands[7] = gen_lowpart (SImode, operands[2]);
-#if HOST_BITS_PER_WIDE_INT == 32
- if (GET_CODE (operands[3]) == CONST_INT)
- {
- if (INTVAL (operands[3]) < 0)
- operands[8] = constm1_rtx;
- else
- operands[8] = const0_rtx;
- }
- else
-#endif
- operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
+ operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
operands[9] = gen_lowpart (SImode, operands[3]);
})