From: Takayuki 'January June' Suwa Date: Thu, 9 Oct 2025 21:29:16 +0000 (+0900) Subject: xtensa: Make individual use of CONST16 instruction X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3aecdeb56c5421d073a7060b4477f5e1e9b61859;p=thirdparty%2Fgcc.git xtensa: Make individual use of CONST16 instruction Until now, in Xtensa ISA, the CONST16 machine instruction (which shifts a specified register left by half a word and stores a 16-bit constant value in the low halfword of the register) has always been used in pairs and only for full-word constant value assignments. This patch provides a new insn definition for using CONST16 alone, and also adds a constantsynth method that saves one byte for constant assign- ments within a certain range when TARGET_DENSITY is also enabled. gcc/ChangeLog: * config/xtensa/xtensa.cc (constantsynth_method_const16): New. (constantsynth_methods): Append constantsynth_method_const16(). (constantsynth_info): Add cost calculation for full-word constant assignment when TARGET_CONST16 is enabled. (constantsynth_pass1): Change it so that it works regardless of TARGET_CONST16. * config/xtensa/xtensa.md (*xtensa_const16): New. --- diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc index 4ece2cacb38..f09123d5c33 100644 --- a/gcc/config/xtensa/xtensa.cc +++ b/gcc/config/xtensa/xtensa.cc @@ -5954,6 +5954,29 @@ constantsynth_method_square (rtx dest, HOST_WIDE_INT v) 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 @@ -5968,6 +5991,7 @@ static const struct constantsynth_method_info constantsynth_methods[] = { 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. */ @@ -5979,13 +6003,19 @@ struct constantsynth_info hash_map 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)); } @@ -6005,8 +6035,7 @@ constantsynth_pass1 (rtx_insn *insn, constantsynth_info &info) 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)))) diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index cb047b0f655..950c33f859f 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -1281,6 +1281,18 @@ } [(set_attr "mode" "SI")]) +(define_insn "*xtensa_const16" + [(set (match_operand:SI 0 "register_operand" "=a") + (match_operator:SI 3 "xtensa_bit_join_operator" + [(ashift:SI (match_operand:SI 1 "register_operand" "0") + (const_int 16)) + (match_operand:SI 2 "const_int_operand" "")]))] + "TARGET_CONST16 && IN_RANGE (INTVAL (operands[2]), 1, 65535)" + "const16\t%0, %2" + [(set_attr "type" "move") + (set_attr "mode" "SI") + (set_attr "length" "3")]) + ;; 16-bit Integer moves (define_expand "movhi"