aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPan Li <pan2.li@intel.com>2025-01-27 11:01:08 +0800
committerPan Li <pan2.li@intel.com>2025-01-29 17:36:29 +0800
commit7ab7829aef6b02d4022650566b2806af986be0cb (patch)
treee231abec43835857f534a3376e157dc9987b00b5 /gcc
parent7b02b8f65ef60be77f3f93945e2a6b463edaa0aa (diff)
downloadgcc-7ab7829aef6b02d4022650566b2806af986be0cb.zip
gcc-7ab7829aef6b02d4022650566b2806af986be0cb.tar.gz
gcc-7ab7829aef6b02d4022650566b2806af986be0cb.tar.bz2
RISC-V: Refactor SAT_* operand rtx extend to reg help func [NFC]
This patch would like to refactor the helper function of the SAT_* scalar. The helper function will convert the define_pattern ops to the xmode reg for the underlying code-gen. This patch add new parameter for ZERO_EXTEND or SIGN_EXTEND if the input is const_int or the mode is non-Xmode. The below test suites are passed for this patch. * The rv64gcv fully regression test. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_gen_zero_extend_rtx): Rename from ... (riscv_extend_to_xmode_reg): Rename to and add rtx_code for zero/sign extend if non-Xmode. (riscv_expand_usadd): Leverage the renamed function with ZERO_EXTEND. (riscv_expand_ussub): Ditto. Signed-off-by: Pan Li <pan2.li@intel.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/riscv/riscv.cc78
1 files changed, 49 insertions, 29 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index dd50fe4..5ee53d0 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -12644,14 +12644,27 @@ riscv_get_raw_result_mode (int regno)
/* Generate a REG rtx of Xmode from the given rtx and mode.
The rtx x can be REG (QI/HI/SI/DI) or const_int.
The machine_mode mode is the original mode from define pattern.
+ The rtx_code can be ZERO_EXTEND or SIGN_EXTEND.
- If rtx is REG and Xmode, the RTX x will be returned directly.
+ If rtx is REG:
- If rtx is REG and non-Xmode, the zero extended to new REG of Xmode will be
- returned.
+ 1. If rtx Xmode, the RTX x will be returned directly.
+ 2. If rtx non-Xmode, the value extended into a new REG of Xmode will be
+ returned.
- If rtx is const_int, a new REG rtx will be created to hold the value of
- const_int and then returned.
+ The scalar ALU like add don't support non-Xmode like QI/HI. Then the
+ gen_lowpart will have problem here. For example, when we would like
+ to add -1 (0xff if QImode) and 2 (0x2 if QImode). The 0xff and 0x2 will
+ be loaded to register for adding. Aka:
+
+ 0xff + 0x2 = 0x101 instead of -1 + 2 = 1.
+
+ Thus we need to sign extend 0xff to 0xffffffffffffffff if Xmode is DImode
+ for correctness. Similar the unsigned also need zero extend.
+
+ If rtx is const_int:
+
+ 1. A new REG rtx will be created to hold the value of const_int.
According to the gccint doc, the constants generated for modes with fewer
bits than in HOST_WIDE_INT must be sign extended to full width. Thus there
@@ -12669,34 +12682,41 @@ riscv_get_raw_result_mode (int regno)
the REG rtx of Xmode, instead of taking care of these in expand func. */
static rtx
-riscv_gen_zero_extend_rtx (rtx x, machine_mode mode)
+riscv_extend_to_xmode_reg (rtx x, machine_mode mode, enum rtx_code rcode)
{
+ gcc_assert (rcode == ZERO_EXTEND || rcode == SIGN_EXTEND);
+
rtx xmode_reg = gen_reg_rtx (Xmode);
- if (!CONST_INT_P (x))
+ if (CONST_INT_P (x))
{
if (mode == Xmode)
- return x;
-
- riscv_emit_unary (ZERO_EXTEND, xmode_reg, x);
- return xmode_reg;
- }
-
- if (mode == Xmode)
- emit_move_insn (xmode_reg, x);
- else
- {
- /* Combine deliberately does not simplify extensions of constants
- (long story). So try to generate the zero extended constant
- efficiently.
+ emit_move_insn (xmode_reg, x);
+ else if (rcode == ZERO_EXTEND)
+ {
+ /* Combine deliberately does not simplify extensions of constants
+ (long story). So try to generate the zero extended constant
+ efficiently.
- First extract the constant and mask off all the bits not in MODE. */
- HOST_WIDE_INT val = INTVAL (x);
- val &= GET_MODE_MASK (mode);
+ First extract the constant and mask off all the bits not in
+ MODE. */
+ HOST_WIDE_INT val = INTVAL (x);
+ val &= GET_MODE_MASK (mode);
- /* X may need synthesis, so do not blindly copy it. */
- xmode_reg = force_reg (Xmode, gen_int_mode (val, Xmode));
+ /* X may need synthesis, so do not blindly copy it. */
+ xmode_reg = force_reg (Xmode, gen_int_mode (val, Xmode));
+ }
+ else /* SIGN_EXTEND. */
+ {
+ rtx x_reg = gen_reg_rtx (mode);
+ emit_move_insn (x_reg, x);
+ riscv_emit_unary (rcode, xmode_reg, x_reg);
+ }
}
+ else if (mode == Xmode)
+ return x;
+ else
+ riscv_emit_unary (rcode, xmode_reg, x);
return xmode_reg;
}
@@ -12717,8 +12737,8 @@ riscv_expand_usadd (rtx dest, rtx x, rtx y)
machine_mode mode = GET_MODE (dest);
rtx xmode_sum = gen_reg_rtx (Xmode);
rtx xmode_lt = gen_reg_rtx (Xmode);
- rtx xmode_x = riscv_gen_zero_extend_rtx (x, mode);
- rtx xmode_y = riscv_gen_zero_extend_rtx (y, mode);
+ rtx xmode_x = riscv_extend_to_xmode_reg (x, mode, ZERO_EXTEND);
+ rtx xmode_y = riscv_extend_to_xmode_reg (y, mode, ZERO_EXTEND);
rtx xmode_dest = gen_reg_rtx (Xmode);
/* Step-1: sum = x + y */
@@ -12852,8 +12872,8 @@ void
riscv_expand_ussub (rtx dest, rtx x, rtx y)
{
machine_mode mode = GET_MODE (dest);
- rtx xmode_x = riscv_gen_zero_extend_rtx (x, mode);
- rtx xmode_y = riscv_gen_zero_extend_rtx (y, mode);
+ rtx xmode_x = riscv_extend_to_xmode_reg (x, mode, ZERO_EXTEND);
+ rtx xmode_y = riscv_extend_to_xmode_reg (y, mode, ZERO_EXTEND);
rtx xmode_lt = gen_reg_rtx (Xmode);
rtx xmode_minus = gen_reg_rtx (Xmode);
rtx xmode_dest = gen_reg_rtx (Xmode);