===================================================================
@@ -3130,6 +3130,20 @@ has an instruction for the division, and
unsigned int, (machine_mode mode),
default_min_divisions_for_recip_mul)
+DEFHOOK
+(truly_noop_truncation,
+ "This hook returns true if it is safe to ``convert'' a value of\n\
+@var{inprec} bits to one of @var{outprec} bits (where @var{outprec} is\n\
+smaller than @var{inprec}) by merely operating on it as if it had only\n\
+@var{outprec} bits. The default returns true unconditionally, which\n\
+is correct for most machines.\n\
+\n\
+If @code{TARGET_MODES_TIEABLE_P} returns false for a pair of modes,\n\
+suboptimal code can result if this hook returns true for the corresponding\n\
+mode sizes. Making this hook return false in such cases may improve things.",
+ bool, (unsigned int outprec, unsigned int inprec),
+ hook_bool_uint_uint_true)
+
/* If the representation of integral MODE is such that values are
always sign-extended to a wider mode MODE_REP then return
SIGN_EXTEND. Return UNKNOWN otherwise. */
@@ -3160,7 +3174,7 @@ to define @code{LOAD_EXTEND_OP (mode)} t
extension.\n\
\n\
In order to enforce the representation of @code{mode},\n\
-@code{TRULY_NOOP_TRUNCATION} should return false when truncating to\n\
+@code{TARGET_TRULY_NOOP_TRUNCATION} should return false when truncating to\n\
@code{mode}.",
int, (scalar_int_mode mode, scalar_int_mode rep_mode),
default_mode_rep_extended)
===================================================================
@@ -39,6 +39,7 @@ extern bool hook_bool_const_rtx_insn_con
const rtx_insn *);
extern bool hook_bool_mode_uhwi_false (machine_mode,
unsigned HOST_WIDE_INT);
+extern bool hook_bool_uint_uint_true (unsigned int, unsigned int);
extern bool hook_bool_uint_mode_false (unsigned int, machine_mode);
extern bool hook_bool_uint_mode_true (unsigned int, machine_mode);
extern bool hook_bool_tree_false (tree);
===================================================================
@@ -133,6 +133,13 @@ hook_bool_mode_uhwi_false (machine_mode,
return false;
}
+/* Generic hook that takes (unsigned int, unsigned int) and returns true. */
+bool
+hook_bool_uint_uint_true (unsigned int, unsigned int)
+{
+ return true;
+}
+
/* Generic hook that takes (unsigned int, machine_mode) and returns false. */
bool
hook_bool_uint_mode_false (unsigned int, machine_mode)
===================================================================
@@ -7482,21 +7482,7 @@ You need not define this macro if it wou
@anchor{TARGET_SHIFT_TRUNCATION_MASK}
@hook TARGET_SHIFT_TRUNCATION_MASK
-@defmac TRULY_NOOP_TRUNCATION (@var{outprec}, @var{inprec})
-A C expression which is nonzero if on this machine it is safe to
-``convert'' an integer of @var{inprec} bits to one of @var{outprec}
-bits (where @var{outprec} is smaller than @var{inprec}) by merely
-operating on it as if it had only @var{outprec} bits.
-
-On many machines, this expression can be 1.
-
-@c rearranged this, removed the phrase "it is reported that". this was
-@c to fix an overfull hbox. --mew 10feb93
-When @code{TRULY_NOOP_TRUNCATION} returns 1 for a pair of sizes for modes
-for which @code{TARGET_MODES_TIEABLE_P} is false, suboptimal code can result.
-If this is the case, making @code{TRULY_NOOP_TRUNCATION} return 0 in
-such cases may improve things.
-@end defmac
+@hook TARGET_TRULY_NOOP_TRUNCATION
@hook TARGET_MODE_REP_EXTENDED
===================================================================
@@ -10783,21 +10783,17 @@ nevertheless truncate the shift count, y
by overriding it.
@end deftypefn
-@defmac TRULY_NOOP_TRUNCATION (@var{outprec}, @var{inprec})
-A C expression which is nonzero if on this machine it is safe to
-``convert'' an integer of @var{inprec} bits to one of @var{outprec}
-bits (where @var{outprec} is smaller than @var{inprec}) by merely
-operating on it as if it had only @var{outprec} bits.
-
-On many machines, this expression can be 1.
-
-@c rearranged this, removed the phrase "it is reported that". this was
-@c to fix an overfull hbox. --mew 10feb93
-When @code{TRULY_NOOP_TRUNCATION} returns 1 for a pair of sizes for modes
-for which @code{TARGET_MODES_TIEABLE_P} is false, suboptimal code can result.
-If this is the case, making @code{TRULY_NOOP_TRUNCATION} return 0 in
-such cases may improve things.
-@end defmac
+@deftypefn {Target Hook} bool TARGET_TRULY_NOOP_TRUNCATION (unsigned int @var{outprec}, unsigned int @var{inprec})
+This hook returns true if it is safe to ``convert'' a value of
+@var{inprec} bits to one of @var{outprec} bits (where @var{outprec} is
+smaller than @var{inprec}) by merely operating on it as if it had only
+@var{outprec} bits. The default returns true unconditionally, which
+is correct for most machines.
+
+If @code{TARGET_MODES_TIEABLE_P} returns false for a pair of modes,
+suboptimal code can result if this hook returns true for the corresponding
+mode sizes. Making this hook return false in such cases may improve things.
+@end deftypefn
@deftypefn {Target Hook} int TARGET_MODE_REP_EXTENDED (scalar_int_mode @var{mode}, scalar_int_mode @var{rep_mode})
The representation of an integral mode can be such that the values
@@ -10823,7 +10819,7 @@ to define @code{LOAD_EXTEND_OP (mode)} t
extension.
In order to enforce the representation of @code{mode},
-@code{TRULY_NOOP_TRUNCATION} should return false when truncating to
+@code{TARGET_TRULY_NOOP_TRUNCATION} should return false when truncating to
@code{mode}.
@end deftypefn
===================================================================
@@ -7721,7 +7721,7 @@ make_extraction (machine_mode mode, rtx
else if (!MEM_P (inner))
{
/* On the LHS, don't create paradoxical subregs implicitely truncating
- the register unless TRULY_NOOP_TRUNCATION. */
+ the register unless TARGET_TRULY_NOOP_TRUNCATION. */
if (in_dest
&& !TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (inner),
wanted_inner_mode))
@@ -12496,7 +12496,7 @@ simplify_comparison (enum rtx_code code,
(ne:DI (and:DI (reg:DI 4) (const_int 0xffffffff)) (const_int 0))
-> (ne:DI (reg:SI 4) (const_int 0))
- unless TRULY_NOOP_TRUNCATION allows it or the register is
+ unless TARGET_TRULY_NOOP_TRUNCATION allows it or the register is
known to hold a value of the required mode the
transformation is invalid. */
if ((equality_comparison_p || unsigned_comparison_p)
@@ -13336,8 +13336,8 @@ reg_truncated_to_mode (machine_mode mode
}
/* If X is a hard reg or a subreg record the mode that the register is
- accessed in. For non-TRULY_NOOP_TRUNCATION targets we might be able
- to turn a truncate into a subreg using this information. Return true
+ accessed in. For non-TARGET_TRULY_NOOP_TRUNCATION targets we might be
+ able to turn a truncate into a subreg using this information. Return true
if traversing X is complete. */
static bool
===================================================================
@@ -1854,7 +1854,7 @@ extract_bit_field_1 (rtx str_rtx, unsign
&& !reverse
/* ??? We could limit the structure size to the part of OP0 that
contains the field, with appropriate checks for endianness
- and TRULY_NOOP_TRUNCATION. */
+ and TARGET_TRULY_NOOP_TRUNCATION. */
&& get_best_reg_extraction_insn (&extv, pattern,
GET_MODE_BITSIZE (op0_mode.require ()),
tmode))
@@ -2233,7 +2233,7 @@ extract_split_bit_field (rtx op0, opt_sc
a zero extension
- when MODE is smaller than SRC_MODE, the extraction involves
- a truncation (and is thus subject to TRULY_NOOP_TRUNCATION).
+ a truncation (and is thus subject to TARGET_TRULY_NOOP_TRUNCATION).
In other words, this routine performs a computation, whereas the
gen_lowpart* routines are conceptually lvalue or rvalue subreg
===================================================================
@@ -873,7 +873,7 @@ convert_to_integer_1 (tree type, tree ex
break;
if (outprec >= BITS_PER_WORD
- || TRULY_NOOP_TRUNCATION (outprec, inprec)
+ || targetm.truly_noop_truncation (outprec, inprec)
|| inprec > TYPE_PRECISION (TREE_TYPE (arg0))
|| inprec > TYPE_PRECISION (TREE_TYPE (arg1)))
{
===================================================================
@@ -2997,7 +2997,8 @@ assign_parm_setup_block (struct assign_p
to the value directly in mode MODE, otherwise we must
start with the register in word_mode and explicitly
convert it. */
- if (TRULY_NOOP_TRUNCATION (size * BITS_PER_UNIT, BITS_PER_WORD))
+ if (targetm.truly_noop_truncation (size * BITS_PER_UNIT,
+ BITS_PER_WORD))
reg = gen_rtx_REG (mode, REGNO (entry_parm));
else
{
===================================================================
@@ -781,8 +781,8 @@ get_narrowest_mode (T mode)
extern void init_adjust_machine_modes (void);
#define TRULY_NOOP_TRUNCATION_MODES_P(MODE1, MODE2) \
- TRULY_NOOP_TRUNCATION (GET_MODE_PRECISION (MODE1), \
- GET_MODE_PRECISION (MODE2))
+ (targetm.truly_noop_truncation (GET_MODE_PRECISION (MODE1), \
+ GET_MODE_PRECISION (MODE2)))
#define HWI_COMPUTABLE_MODE_P(MODE) \
(SCALAR_INT_MODE_P (MODE) \
===================================================================
@@ -30,6 +30,7 @@ Software Foundation; either version 3, o
#include "recog.h"
#include "rtlhooks-def.h"
#include "explow.h"
+#include "target.h"
/* For speed, we will copy the RTX hooks struct member-by-member
===================================================================
@@ -773,8 +773,6 @@ #define STRICT_ALIGNMENT TARGET_STRICT_
if we don't have to, for power-saving reasons. */
#define SLOW_BYTE_ACCESS 0
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
#define NO_FUNCTION_CSE 1
/* Specify the machine mode that the hardware addresses have.
===================================================================
@@ -800,10 +800,6 @@ #define LOAD_EXTEND_OP(MODE) ((MODE) ==
/* Define if loading short immediate values into registers sign extends. */
#define SHORT_IMMEDIATES_SIGN_EXTEND 1
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* The CIX ctlz and cttz instructions return 64 for zero. */
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, \
TARGET_CIX ? 1 : 0)
===================================================================
@@ -1449,10 +1449,6 @@ #define MOVE_RATIO(SPEED) ((SPEED) ? 15
*/
#define SHIFT_COUNT_TRUNCATED 1
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* We assume that the store-condition-codes instructions store 0 for false
and some other value for true. This is the value stored for true. */
#define STORE_FLAG_VALUE 1
===================================================================
@@ -1897,9 +1897,6 @@ #define SLOW_BYTE_ACCESS 0
rotates is modulo 32 used. */
/* #define SHIFT_COUNT_TRUNCATED 1 */
-/* All integers have the same format so truncation is easy. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* Calling from registers is a massive pain. */
#define NO_FUNCTION_CSE 1
===================================================================
@@ -471,8 +471,6 @@ #define MOVE_MAX_PIECES 2
#define MOVE_RATIO(speed) ((speed) ? 3 : 2)
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
#define Pmode HImode
#define FUNCTION_MODE HImode
===================================================================
@@ -799,10 +799,6 @@ #define SYMBOLIC_CONST(X) \
#define NOTICE_UPDATE_CC(EXPR, INSN) 0
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* Max number of bytes we can move from memory to memory
in one reasonably fast instruction. */
#define MOVE_MAX UNITS_PER_WORD
===================================================================
@@ -596,7 +596,6 @@ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, B
#define CASE_VECTOR_MODE SImode
#define MOVE_MAX 4
#define MOVE_RATIO(SPEED) 4
-#define TRULY_NOOP_TRUNCATION(outprec, inprec) 1
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
#define Pmode SImode
#define FUNCTION_MODE QImode
===================================================================
@@ -551,8 +551,6 @@ #define CASE_VECTOR_MODE Pmode
#define MOVE_MAX 4
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
#define STORE_FLAG_VALUE 1
#define Pmode SImode
===================================================================
@@ -1038,8 +1038,6 @@ #define MOVE_MAX 4
/* Maybe SHIFT_COUNT_TRUNCATED is safe to define? FIXME: Check later. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
===================================================================
@@ -840,10 +840,6 @@ #define MOVE_MAX 8
few bits. */
#define SHIFT_COUNT_TRUNCATED 1
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
between pointers and any other objects of this machine mode. */
===================================================================
@@ -776,18 +776,6 @@ #define CASE_VECTOR_MODE SImode
memory to memory. */
#define MOVE_MAX 8
-/* A C expression which is nonzero if on this machine it is safe to "convert"
- an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
- than INPREC) by merely operating on it as if it had only OUTPREC bits.
-
- On many machines, this expression can be 1.
-
- When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for modes for
- which `TARGET_MODES_TIEABLE_P' is 0, suboptimal code can result.
- If this is the case, making `TRULY_NOOP_TRUNCATION' return 0 in such
- cases may improve things. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* An alias for the machine mode for pointers. On most machines, define this
to be the integer mode corresponding to the width of a hardware pointer;
`SImode' on 32-bit machine or `DImode' on 64-bit machines. On some machines
===================================================================
@@ -1813,18 +1813,6 @@ #define SHORT_IMMEDIATES_SIGN_EXTEND 1
memory to memory. */
#define MOVE_MAX 8
-/* A C expression which is nonzero if on this machine it is safe to "convert"
- an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
- than INPREC) by merely operating on it as if it had only OUTPREC bits.
-
- On many machines, this expression can be 1.
-
- When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for modes
- for which `TARGET_MODES_TIEABLE_P' is 0, suboptimal code can result.
- If this is the case, making `TRULY_NOOP_TRUNCATION' return 0 in such
- cases may improve things. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* An alias for the machine mode for pointers. On most machines, define this
to be the integer mode corresponding to the width of a hardware pointer;
`SImode' on 32-bit machine or `DImode' on 64-bit machines. On some machines
===================================================================
@@ -449,7 +449,6 @@ #define REGNO_OK_FOR_INDEX_P(NUM) FT32_F
quickly between memory and registers or between two memory
locations. */
#define MOVE_MAX 4
-#define TRULY_NOOP_TRUNCATION(op,ip) 1
/* Define this to be nonzero if shift instructions ignore all but the low-order
few bits. */
===================================================================
@@ -561,10 +561,6 @@ #define SLOW_BYTE_ACCESS TARGET_SLOWBYTE
of a shift count. */
/* #define SHIFT_COUNT_TRUNCATED */
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
between pointers and any other objects of this machine mode. */
===================================================================
@@ -1911,10 +1911,6 @@ #define CLEAR_RATIO(speed) ((speed) ? MI
/* #define SHIFT_COUNT_TRUNCATED */
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* A macro to update M and UNSIGNEDP when an object whose type is
TYPE and which has the specified mode and signedness is to be
stored in a register. This macro is only called when TYPE is a
===================================================================
@@ -1567,12 +1567,6 @@ #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
memory to memory. */
#define MOVE_MAX 8
-/* A C expression which is nonzero if on this machine it is safe to "convert"
- an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
- than INPREC) by merely operating on it as if it had only OUTPREC bits. */
-
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* A C expression describing the value returned by a comparison operator with
an integral mode and stored by a store-flag instruction (`sCOND') when the
condition is true. */
===================================================================
@@ -526,8 +526,6 @@ #define MAX_MOVE_MAX 8
#define SHIFT_COUNT_TRUNCATED 1
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
#define STORE_FLAG_VALUE 1
#define Pmode SImode
===================================================================
@@ -519,8 +519,6 @@ #define MAX_MOVE_MAX 4
#define SHIFT_COUNT_TRUNCATED 1
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
#define Pmode SImode
#define FUNCTION_MODE SImode
===================================================================
@@ -629,7 +629,6 @@ #define CASE_VECTOR_MODE SImode
#define LOAD_EXTEND_OP(MEM) ZERO_EXTEND
#define MOVE_MAX 4
-#define TRULY_NOOP_TRUNCATION(op,ip) 1
#define STORE_FLAG_VALUE 1
===================================================================
@@ -981,10 +981,6 @@ #define MOVE_MAX 4
few bits. */
#define SHIFT_COUNT_TRUNCATED 1
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
between pointers and any other objects of this machine mode. */
===================================================================
@@ -665,8 +665,6 @@ #define DEFAULT_SIGNED_CHAR 1
#define MOVE_MAX 4
#define SLOW_BYTE_ACCESS 0
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* The 68020 BFFFO and ColdFire FF1 instructions return 32 for zero. */
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
===================================================================
@@ -549,9 +549,6 @@ #define SLOW_BYTE_ACCESS TARGET_SLOW_BYT
target. */
#define SHIFT_COUNT_TRUNCATED 0
-/* All integers have the same format so truncation is easy. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC,INPREC) 1
-
/* Define this if addresses of constant functions
shouldn't be put through pseudo regs where they can be cse'd.
Desirable on machines where ordinary constants are expensive
===================================================================
@@ -554,11 +554,6 @@ #define STORE_FLAG_VALUE 1
#define SHIFT_COUNT_TRUNCATED 1
-/* This results in inefficient code for 64 bit to 32 conversions.
- Something needs to be done about this. Perhaps not use any 32 bit
- instructions? Perhaps use PROMOTE_MODE? */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
#define Pmode SImode
#define FUNCTION_MODE SImode
===================================================================
@@ -2658,11 +2658,6 @@ #define SLOW_BYTE_ACCESS (!TARGET_MIPS16
do not truncate the shift amount at all. */
#define SHIFT_COUNT_TRUNCATED (!TARGET_LOONGSON_VECTORS)
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) \
- (TARGET_64BIT ? ((INPREC) <= 32 || (OUTPREC) > 32) : 1)
-
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
===================================================================
@@ -22328,6 +22328,14 @@ mips_promote_function_mode (const_tree t
*punsignedp = unsignedp;
return mode;
}
+
+/* Implement TARGET_TRULY_NOOP_TRUNCATION. */
+
+static bool
+mips_truly_noop_truncation (unsigned int outprec, unsigned int inprec)
+{
+ return !TARGET_64BIT || inprec <= 32 || outprec > 32;
+}
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
@@ -22623,6 +22631,9 @@ #define TARGET_SECONDARY_MEMORY_NEEDED m
#undef TARGET_CAN_CHANGE_MODE_CLASS
#define TARGET_CAN_CHANGE_MODE_CLASS mips_can_change_mode_class
+#undef TARGET_TRULY_NOOP_TRUNCATION
+#define TARGET_TRULY_NOOP_TRUNCATION mips_truly_noop_truncation
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-mips.h"
===================================================================
@@ -3242,9 +3242,9 @@ (define_expand "and<mode>3"
(match_operand:GPR 2 "and_reg_operand")))])
;; The middle-end is not allowed to convert ANDing with 0xffff_ffff into a
-;; zero_extendsidi2 because of TRULY_NOOP_TRUNCATION, so handle these here.
-;; Note that this variant does not trigger for SI mode because we require
-;; a 64-bit HOST_WIDE_INT and 0xffff_ffff wouldn't be a canonical
+;; zero_extendsidi2 because of TARGET_TRULY_NOOP_TRUNCATION, so handle these
+;; here. Note that this variant does not trigger for SI mode because we
+;; require a 64-bit HOST_WIDE_INT and 0xffff_ffff wouldn't be a canonical
;; sign-extended SImode value.
;;
;; These are possible combinations for operand 1 and 2. The table
@@ -3426,7 +3426,7 @@ (define_insn "truncdfsf2"
;; modes is a no-op, as it is for most other GCC ports. Truncating
;; DImode values to SImode is not a no-op for TARGET_64BIT since we
;; need to make sure that the lower 32 bits are properly sign-extended
-;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
+;; (see TARGET_TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
;; smaller than SImode is equivalent to two separate truncations:
;;
;; A B
@@ -3644,7 +3644,7 @@ (define_insn "*zero_extendhi_truncqi"
;; Those for integer source operand are ordered widest source type first.
;; When TARGET_64BIT, all SImode integer and accumulator registers
-;; should already be in sign-extended form (see TRULY_NOOP_TRUNCATION
+;; should already be in sign-extended form (see TARGET_TRULY_NOOP_TRUNCATION
;; and truncdisi2). We can therefore get rid of register->register
;; instructions if we constrain the source to be in the same register as
;; the destination.
===================================================================
@@ -788,8 +788,6 @@ #define LOAD_EXTEND_OP(MODE) (TARGET_ZER
#define MOVE_MAX 8
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* ??? MMIX allows a choice of STORE_FLAG_VALUE. Revisit later,
we don't have scc expanders yet. */
===================================================================
@@ -691,10 +691,6 @@ #define MOVE_MAX 4
of a shift count. */
#define SHIFT_COUNT_TRUNCATED 1
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
between pointers and any other objects of this machine mode. */
===================================================================
@@ -409,7 +409,6 @@ #define REGNO_OK_FOR_INDEX_P(NUM) MOXIE_
quickly between memory and registers or between two memory
locations. */
#define MOVE_MAX 4
-#define TRULY_NOOP_TRUNCATION(op,ip) 1
/* All load operations zero extend. */
#define LOAD_EXTEND_OP(MEM) ZERO_EXTEND
@@ -418,8 +417,6 @@ #define LOAD_EXTEND_OP(MEM) ZERO_EXTEND
valid memory address. */
#define MAX_REGS_PER_ADDRESS 1
-#define TRULY_NOOP_TRUNCATION(op,ip) 1
-
/* An alias for a machine mode name. This is the machine mode that
elements of a jump-table should have. */
#define CASE_VECTOR_MODE SImode
===================================================================
@@ -204,8 +204,6 @@ #define INCOMING_RETURN_ADDR_RTX \
#define RETURN_ADDR_RTX(COUNT, FA) \
msp430_return_addr_rtx (COUNT)
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
#define SLOW_BYTE_ACCESS 0
===================================================================
@@ -998,11 +998,6 @@ #define MOVE_MAX 4
of bits needed to represent the size of the object being shifted. */
#define SHIFT_COUNT_TRUNCATED 1
-/* A C expression which is nonzero if on this machine it is safe to "convert"
- an integer of 'inprec' bits to one of 'outprec' bits by merely operating
- on it as if it had only 'outprec' bits. */
-#define TRULY_NOOP_TRUNCATION(outprec, inprec) 1
-
/* A C expression describing the value returned by a comparison operator with
an integral mode and stored by a store-flag instruction ('cstoremode4')
when the condition is true. */
===================================================================
@@ -515,8 +515,6 @@ #define FUNCTION_MODE QImode
#define CASE_VECTOR_MODE Pmode
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
#define LOAD_EXTEND_OP(MODE) (ZERO_EXTEND)
#define WORD_REGISTER_OPERATIONS 1
===================================================================
@@ -310,7 +310,6 @@ #define FLOAT_STORE_FLAG_VALUE(MODE) REA
#define CASE_VECTOR_MODE SImode
#define MOVE_MAX 8
#define MOVE_RATIO(SPEED) 4
-#define TRULY_NOOP_TRUNCATION(outprec, inprec) 1
#define FUNCTION_MODE QImode
#define HAS_INIT_SECTION 1
===================================================================
@@ -1019,10 +1019,6 @@ #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
/* Nonzero if access to memory by bytes is slow and undesirable. */
#define SLOW_BYTE_ACCESS 1
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
between pointers and any other objects of this machine mode. */
===================================================================
@@ -432,10 +432,6 @@ #define SLOW_BYTE_ACCESS 0
/* Do not break .stabs pseudos into continuations. */
#define DBX_CONTIN_LENGTH 0
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* Give 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, CCFPmode
should be used. */
===================================================================
@@ -2108,10 +2108,6 @@ #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
/* Define if loading short immediate values into registers sign extends. */
#define SHORT_IMMEDIATES_SIGN_EXTEND 1
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* The cntlzw and cntlzd instructions return 32 and 64 for input of zero. */
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \
((VALUE) = GET_MODE_BITSIZE (MODE), 2)
===================================================================
@@ -637,8 +637,6 @@ #define SLOW_BYTE_ACCESS 0
#define SHIFT_COUNT_TRUNCATED 1
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
between pointers and any other objects of this machine mode. */
===================================================================
@@ -1307,7 +1307,8 @@ (define_insn "*movhi_internal"
(set_attr "mode" "HI")])
;; HImode constant generation; see riscv_move_integer for details.
-;; si+si->hi without truncation is legal because of TRULY_NOOP_TRUNCATION.
+;; si+si->hi without truncation is legal because of
+;; TARGET_TRULY_NOOP_TRUNCATION.
(define_insn "*add<mode>hi3"
[(set (match_operand:HI 0 "register_operand" "=r,r")
===================================================================
@@ -151,8 +151,6 @@ #define HAS_LONG_UNCOND_BRANCH 0
#define MOVE_MAX 2
#define STARTING_FRAME_OFFSET 0
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
#define ADDR_SPACE_NEAR 1
#define ADDR_SPACE_FAR 2
===================================================================
@@ -2005,10 +2005,6 @@ #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
/* Define if loading short immediate values into registers sign extends. */
#define SHORT_IMMEDIATES_SIGN_EXTEND 1
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* The cntlzw and cntlzd instructions return 32 and 64 for input of zero. */
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \
((VALUE) = GET_MODE_BITSIZE (MODE), 2)
===================================================================
@@ -171,8 +171,6 @@ #define HAS_LONG_UNCOND_BRANCH 0
#define MOVE_MAX 4
#define STARTING_FRAME_OFFSET 0
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
#define HAVE_PRE_DECREMENT 1
#define HAVE_POST_INCREMENT 1
===================================================================
@@ -963,10 +963,6 @@ #define ASM_DECLARE_FUNCTION_SIZE s390_a
tablejump instruction. */
#define CASE_VECTOR_MODE (TARGET_64BIT ? DImode : SImode)
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
between pointers and any other objects of this machine mode. */
===================================================================
@@ -1430,8 +1430,6 @@ #define PIC_REFERENCE_P(OP) \
#define MAYBE_BASE_REGISTER_RTX_P(X, STRICT) \
((REG_P (X) && REG_OK_FOR_BASE_P (X, STRICT)) \
|| (GET_CODE (X) == SUBREG \
- && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE ((X))), \
- GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (X)))) \
&& REG_P (SUBREG_REG (X)) \
&& REG_OK_FOR_BASE_P (SUBREG_REG (X), STRICT)))
@@ -1441,8 +1439,6 @@ #define MAYBE_BASE_REGISTER_RTX_P(X, STR
#define MAYBE_INDEX_REGISTER_RTX_P(X, STRICT) \
((REG_P (X) && REG_OK_FOR_INDEX_P (X, STRICT)) \
|| (GET_CODE (X) == SUBREG \
- && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE ((X))), \
- GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (X)))) \
&& REG_P (SUBREG_REG (X)) \
&& SUBREG_OK_FOR_INDEX_P (SUBREG_REG (X), SUBREG_BYTE (X), STRICT)))
@@ -1557,9 +1553,6 @@ #define SH_DYNAMIC_SHIFT_COST (TARGET_DY
more compact code. */
#define SHIFT_COUNT_TRUNCATED (0)
-/* All integers have the same format so truncation is easy. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC,INPREC) (true)
-
/* Define this if addresses of constant functions
shouldn't be put through pseudo regs where they can be cse'd.
Desirable on machines where ordinary constants are expensive
===================================================================
@@ -1447,10 +1447,6 @@ #define SLOW_BYTE_ACCESS 1
few bits. */
#define SHIFT_COUNT_TRUNCATED 1
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* For SImode, we make sure the top 32-bits of the register are clear and
then we subtract 32 from the lzd instruction result. */
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \
===================================================================
@@ -487,8 +487,6 @@ #define CASE_VECTOR_MODE SImode
#define MOVE_MAX 16
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) ((INPREC) <= 32 && (OUTPREC) <= (INPREC))
-
#define STORE_FLAG_VALUE -1
#define Pmode SImode
===================================================================
@@ -7173,6 +7173,14 @@ spu_can_change_mode_class (machine_mode
|| (GET_MODE_SIZE (from) <= 4 && GET_MODE_SIZE (to) <= 4)
|| (GET_MODE_SIZE (from) >= 16 && GET_MODE_SIZE (to) >= 16));
}
+
+/* Implement TARGET_TRULY_NOOP_TRUNCATION. */
+
+static bool
+spu_truly_noop_truncation (unsigned int outprec, unsigned int inprec)
+{
+ return inprec <= 32 && outprec <= inprec;
+}
/* Table of machine attributes. */
static const struct attribute_spec spu_attribute_table[] =
@@ -7407,6 +7415,9 @@ #define TARGET_HARD_REGNO_NREGS spu_hard
#undef TARGET_CAN_CHANGE_MODE_CLASS
#define TARGET_CAN_CHANGE_MODE_CLASS spu_can_change_mode_class
+#undef TARGET_TRULY_NOOP_TRUNCATION
+#define TARGET_TRULY_NOOP_TRUNCATION spu_truly_noop_truncation
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-spu.h"
===================================================================
@@ -478,8 +478,6 @@ #define MOVE_MAX 2
#define SHIFT_COUNT_TRUNCATED 1
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
#define Pmode HImode
#define FUNCTION_MODE HImode
===================================================================
@@ -378,11 +378,6 @@ #define SHIFT_COUNT_TRUNCATED 0
#define SHORT_IMMEDIATES_SIGN_EXTEND 1
-/* We represent all SI values as sign-extended DI values in
- registers. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) \
- ((INPREC) <= 32 || (OUTPREC) > 32)
-
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, 1)
#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, 1)
===================================================================
@@ -5560,7 +5560,14 @@ tilegx_file_end (void)
file_end_indicate_exec_stack ();
}
+/* Implement TARGET_TRULY_NOOP_TRUNCATION. We represent all SI values
+ as sign-extended DI values in registers. */
+static bool
+tilegx_truly_noop_truncation (unsigned int outprec, unsigned int inprec)
+{
+ return inprec <= 32 || outprec > 32;
+}
#undef TARGET_HAVE_TLS
#define TARGET_HAVE_TLS HAVE_AS_TLS
@@ -5724,6 +5731,9 @@ #define TARGET_ASM_ALIGNED_DI_OP "\t.qua
#undef TARGET_CAN_USE_DOLOOP_P
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
+#undef TARGET_TRULY_NOOP_TRUNCATION
+#define TARGET_TRULY_NOOP_TRUNCATION tilegx_truly_noop_truncation
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-tilegx.h"
===================================================================
@@ -2004,8 +2004,8 @@ (define_insn "extendhi<mode>2"
ld2s_add\t%0, %I1, %i1"
[(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
-;; All SImode integer registers should already be in sign-extended
-;; form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can therefore
+;; All SImode integer registers should already be in sign-extended form
+;; (see TARGET_TRULY_NOOP_TRUNCATION and truncdisi2). We can therefore
;; get rid of register->register instructions if we constrain the
;; source to be in the same register as the destination.
(define_insn_and_split "extendsidi2"
@@ -2028,7 +2028,7 @@ (define_insn_and_split "extendsidi2"
;; modes is a no-op, as it is for most other GCC ports. Truncating
;; DImode values to SImode is not a no-op since we
;; need to make sure that the lower 32 bits are properly sign-extended
-;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
+;; (see TARGET_TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
;; smaller than SImode is equivalent to two separate truncations:
;;
;; A B
===================================================================
@@ -337,8 +337,6 @@ #define SHIFT_COUNT_TRUNCATED 1
#define SHORT_IMMEDIATES_SIGN_EXTEND 1
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
===================================================================
@@ -766,10 +766,6 @@ #define MOVE_MAX 4
of a shift count. */
#define SHIFT_COUNT_TRUNCATED 1
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
between pointers and any other objects of this machine mode. */
===================================================================
@@ -448,10 +448,6 @@ #define SLOW_BYTE_ACCESS 0
of a shift count. */
/* #define SHIFT_COUNT_TRUNCATED */
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
between pointers and any other objects of this machine mode. */
===================================================================
@@ -1202,21 +1202,6 @@ #define MAX_MOVE_MAX 4
bitfield instructions. */
#define SHIFT_COUNT_TRUNCATED 0
-/* `TRULY_NOOP_TRUNCATION (OUTPREC, INPREC)'
-
- A C expression which is nonzero if on this machine it is safe to
- "convert" an integer of INPREC bits to one of OUTPREC bits (where
- OUTPREC is smaller than INPREC) by merely operating on it as if it
- had only OUTPREC bits.
-
- On many machines, this expression can be 1.
-
- When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for
- modes for which `TARGET_MODES_TIEABLE_P' is 0, suboptimal code can result.
- If this is the case, making `TRULY_NOOP_TRUNCATION' return 0 in
- such cases may improve things. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
/* `STORE_FLAG_VALUE'
A C expression describing the value returned by a comparison
===================================================================
@@ -669,10 +669,6 @@ #define SLOW_BYTE_ACCESS 1
/* Shift instructions ignore all but the low-order few bits. */
#define SHIFT_COUNT_TRUNCATED 1
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 1)
===================================================================
@@ -914,7 +914,8 @@ #define realloc xrealloc
HARD_REGNO_CALL_PART_CLOBBERED HARD_REGNO_MODE_OK \
MODES_TIEABLE_P FUNCTION_ARG_PADDING SLOW_UNALIGNED_ACCESS \
HARD_REGNO_NREGS SECONDARY_MEMORY_NEEDED_MODE \
- SECONDARY_MEMORY_NEEDED CANNOT_CHANGE_MODE_CLASS
+ SECONDARY_MEMORY_NEEDED CANNOT_CHANGE_MODE_CLASS \
+ TRULY_NOOP_TRUNCATION
/* Target macros only used for code built for the target, that have
moved to libgcc-tm.h or have never been present elsewhere. */