return end_sequence ();
}
+/* A method that generates two machine instructions for assigning a value
+ between -32 and 95, followed by a CONST16 instruction to synthesize a
+ value in the range -2097151 to 6291455. This method only works when
+ TARGET_CONST16 is enabled. */
+
+static rtx_insn *
+constantsynth_method_const16 (rtx dest, HOST_WIDE_INT v)
+{
+ rtx x;
+
+ if (!TARGET_CONST16
+ || ! IN_RANGE (v >> 16, -32, 95)
+ || ! IN_RANGE (v & 65535, 1, 65535))
+ return NULL;
+
+ start_sequence ();
+ emit_insn (gen_rtx_SET (dest, GEN_INT (v >> 16)));
+ x = gen_rtx_ASHIFT (SImode, dest, GEN_INT (16));
+ x = gen_rtx_IOR (SImode, x, GEN_INT (v & 65535));
+ emit_insn (gen_rtx_SET (dest, x));
+ return end_sequence ();
+}
+
/* List of all available synthesis methods. */
struct constantsynth_method_info
{ constantsynth_method_16bits, "16bits" },
{ constantsynth_method_32bits, "32bits" },
{ constantsynth_method_square, "square" },
+ { constantsynth_method_const16, "const16" },
};
/* Information that mediates between synthesis pass 1 and 2. */
hash_map<rtx, int> usage;
constantsynth_info ()
{
- /* To avoid wasting literal pool entries, we use fake references to
- estimate the costs of an L32R instruction. */
- rtx x = gen_rtx_SYMBOL_REF (Pmode, "*.LC-1");
- SYMBOL_REF_FLAGS (x) |= SYMBOL_FLAG_LOCAL;
- CONSTANT_POOL_ADDRESS_P (x) = 1;
- x = gen_const_mem (SImode, x);
- gcc_assert (constantpool_mem_p (x));
+ rtx x;
+ if (TARGET_CONST16)
+ x = GEN_INT (0x5A5A5A5A);
+ else
+ {
+ /* To avoid wasting literal pool entries, we use fake references
+ to estimate the costs of an L32R instruction. */
+ x = gen_rtx_SYMBOL_REF (Pmode, "*.LC-1");
+ SYMBOL_REF_FLAGS (x) |= SYMBOL_FLAG_LOCAL;
+ CONSTANT_POOL_ADDRESS_P (x) = 1;
+ x = gen_const_mem (SImode, x);
+ gcc_assert (constantpool_mem_p (x));
+ }
costs += make_insn_raw (gen_rtx_SET (gen_rtx_REG (SImode, A9_REG),
x));
}
number of occurrences of the constant if optimizing for size. If the
constant fits in the immediate field, update the insn to re-assign the
constant. */
- if (TARGET_CONST16
- || GET_CODE (pat = PATTERN (insn)) != SET
+ if (GET_CODE (pat = PATTERN (insn)) != SET
|| ! REG_P (dest = SET_DEST (pat)) || ! GP_REG_P (REGNO (dest))
|| GET_MODE (dest) != SImode
|| ! CONST_INT_P (src = avoid_constant_pool_reference (SET_SRC (pat))))