From: Takayuki 'January June' Suwa Date: Wed, 16 Dec 2020 20:53:56 +0000 (-0800) Subject: gcc: xtensa: rearrange DI mode constant loading X-Git-Tag: basepoints/gcc-12~2094 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=64a54505ec8249178b9767d1420354f8eb55de50;p=thirdparty%2Fgcc.git gcc: xtensa: rearrange DI mode constant loading 2020-12-16 Takayuki 'January June' Suwa gcc/ * config/xtensa/xtensa.c (xtensa_emit_move_sequence): Try to replace 'l32r' with 'movi' + 'slli' when optimizing for size. * config/xtensa/xtensa.md (movdi): Split loading DI mode constant into register pair into two loads of SI mode constants. --- diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index be1eb21a0b60..1cdc39acfffa 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -1082,6 +1082,21 @@ xtensa_emit_move_sequence (rtx *operands, machine_mode mode) if (! TARGET_AUTO_LITPOOLS && ! TARGET_CONST16) { + /* Try to emit MOVI + SLLI sequence, that is smaller + than L32R + literal. */ + if (optimize_size && mode == SImode && register_operand (dst, mode)) + { + HOST_WIDE_INT srcval = INTVAL (src); + int shift = ctz_hwi (srcval); + + if (xtensa_simm12b (srcval >> shift)) + { + emit_move_insn (dst, GEN_INT (srcval >> shift)); + emit_insn (gen_ashlsi3_internal (dst, dst, GEN_INT (shift))); + return 1; + } + } + src = force_const_mem (SImode, src); operands[1] = src; } diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index 671c4bea144f..5fbe4ad4af9f 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -727,8 +727,23 @@ (match_operand:DI 1 "general_operand" ""))] "" { - if (CONSTANT_P (operands[1]) && !TARGET_CONST16) - operands[1] = force_const_mem (DImode, operands[1]); + if (CONSTANT_P (operands[1])) + { + /* Split in halves if 64-bit Const-to-Reg moves + because of offering further optimization opportunities. */ + if (register_operand (operands[0], DImode)) + { + rtx first, second; + + split_double (operands[1], &first, &second); + emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), first)); + emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), second)); + DONE; + } + + if (!TARGET_CONST16) + operands[1] = force_const_mem (DImode, operands[1]); + } if (!register_operand (operands[0], DImode) && !register_operand (operands[1], DImode))