This patch refactors the three places in the i386.md backend that we set the carry flag into a new ix86_expand_carry helper function, that allows Jakub's recently added uaddc<mode>5 and usubc<mode>5 expanders to take advantage of the recently added support for the stc instruction.
This patch has been tested on x86_64-pc-linux-gnu with make bootstrap and make -k check, both with and without --target_board=unix{-m32} with no new failures. Ok for mainline? 2023-06-18 Roger Sayle <ro...@nextmovesoftware.com> gcc/ChangeLog * config/i386/i386-expand.cc (ix86_expand_carry): New helper function for setting the carry flag. (ix86_expand_builtin) <handlecarry>: Use it here. * config/i386/i386-protos.h (ix86_expand_carry): Prototype here. * config/i386/i386.md (uaddc<mode>5): Use ix86_expand_carry. (usubc<mode>5): Likewise. Thanks in advance, Roger --
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index def060a..3d5eca6 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -12644,6 +12644,21 @@ ix86_check_builtin_isa_match (unsigned int fcode, return (bisa & isa) == bisa && (bisa2 & isa2) == bisa2; } +/* Emit instructions to set the carry flag from ARG. */ + +void +ix86_expand_carry (rtx arg) +{ + if (!CONST_INT_P (arg) || arg == const0_rtx) + { + arg = convert_to_mode (QImode, arg, 1); + arg = copy_to_mode_reg (QImode, arg); + emit_insn (gen_addqi3_cconly_overflow (arg, constm1_rtx)); + } + else + emit_insn (gen_x86_stc ()); +} + /* Expand an expression EXP that calls a built-in function, with result going to TARGET if that's convenient (and in mode MODE if that's convenient). @@ -13975,14 +13990,7 @@ rdseed_step: else { /* Generate CF from input operand. */ - if (!CONST_INT_P (op1)) - { - op1 = convert_to_mode (QImode, op1, 1); - op1 = copy_to_mode_reg (QImode, op1); - emit_insn (gen_addqi3_cconly_overflow (op1, constm1_rtx)); - } - else - emit_insn (gen_x86_stc ()); + ix86_expand_carry (op1); /* Generate instruction that consumes CF. */ op1 = gen_rtx_REG (CCCmode, FLAGS_REG); diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index af01299..27fe73c 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -155,6 +155,7 @@ extern void ix86_expand_sse_movcc (rtx, rtx, rtx, rtx); extern void ix86_expand_sse_unpack (rtx, rtx, bool, bool); extern void ix86_expand_fp_spaceship (rtx, rtx, rtx); extern bool ix86_expand_int_addcc (rtx[]); +extern void ix86_expand_carry (rtx arg); extern rtx_insn *ix86_expand_call (rtx, rtx, rtx, rtx, rtx, bool); extern bool ix86_call_use_plt_p (rtx); extern void ix86_split_call_vzeroupper (rtx, rtx); diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 93794c1..a50cbc8 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -8601,9 +8601,7 @@ emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3])); else { - rtx op4 = copy_to_mode_reg (QImode, - convert_to_mode (QImode, operands[4], 1)); - emit_insn (gen_addqi3_cconly_overflow (op4, constm1_rtx)); + ix86_expand_carry (operands[4]); pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx); pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx); emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3], @@ -8634,9 +8632,7 @@ else { cf = gen_rtx_REG (CCCmode, FLAGS_REG); - rtx op4 = copy_to_mode_reg (QImode, - convert_to_mode (QImode, operands[4], 1)); - emit_insn (gen_addqi3_cconly_overflow (op4, constm1_rtx)); + ix86_expand_carry (operands[4]); pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx); pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx); emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],