return default_get_reg_raw_mode (regno);
}
+/* Generate a new rtx of Xmode based on the rtx and mode in define pattern.
+ The rtx x will be zero extended to Xmode if the mode is HI/QImode, and
+ the new zero extended Xmode rtx will be returned.
+ Or the gen_lowpart rtx of Xmode will be returned. */
+
+static rtx
+riscv_gen_zero_extend_rtx (rtx x, machine_mode mode)
+{
+ if (mode == Xmode)
+ return x;
+
+ rtx xmode_reg = gen_reg_rtx (Xmode);
+ riscv_emit_unary (ZERO_EXTEND, xmode_reg, x);
+
+ return xmode_reg;
+}
+
/* Implements the unsigned saturation add standard name usadd for int mode.
z = SAT_ADD(x, y).
=>
1. sum = x + y.
- 2. sum = truncate (sum) for QI and HI only.
+ 2. sum = truncate (sum) for non-Xmode.
3. lt = sum < x.
4. lt = -lt.
5. z = sum | lt. */
machine_mode mode = GET_MODE (dest);
rtx xmode_sum = gen_reg_rtx (Xmode);
rtx xmode_lt = gen_reg_rtx (Xmode);
- rtx xmode_x = gen_lowpart (Xmode, x);
+ rtx xmode_x = riscv_gen_zero_extend_rtx (x, mode);
rtx xmode_y = gen_lowpart (Xmode, y);
rtx xmode_dest = gen_reg_rtx (Xmode);
/* Step-1: sum = x + y */
- if (mode == SImode && mode != Xmode)
- { /* Take addw to avoid the sum truncate. */
- rtx simode_sum = gen_reg_rtx (SImode);
- riscv_emit_binary (PLUS, simode_sum, x, y);
- emit_move_insn (xmode_sum, gen_lowpart (Xmode, simode_sum));
- }
- else
- riscv_emit_binary (PLUS, xmode_sum, xmode_x, xmode_y);
+ riscv_emit_binary (PLUS, xmode_sum, xmode_x, xmode_y);
- /* Step-1.1: truncate sum for HI and QI as we have no insn for add QI/HI. */
- if (mode == HImode || mode == QImode)
+ /* Step-1.1: truncate sum for non-Xmode for overflow check. */
+ if (mode != Xmode)
{
int shift_bits = GET_MODE_BITSIZE (Xmode)
- GET_MODE_BITSIZE (mode).to_constant ();
--- /dev/null
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-options "-O2 -fdump-rtl-expand-details" } */
+
+#include <stdint-gcc.h>
+
+int8_t b[1];
+int8_t *d = b;
+int32_t c;
+
+int main() {
+ b[0] = -40;
+ uint16_t t = (uint16_t)d[0];
+
+ c = (t < 0xFFF6 ? t : 0xFFF6) + 9;
+
+ if (c != 65505)
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
--- /dev/null
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-options "-O2 -fdump-rtl-expand-details" } */
+
+#include <stdint-gcc.h>
+
+int16_t b[1];
+int16_t *d = b;
+int64_t c;
+
+int main() {
+ b[0] = -40;
+ uint32_t t = (uint32_t)d[0];
+
+ c = (t < 0xFFFFFFF6u ? t : 0xFFFFFFF6u) + 9;
+
+ if (c != 4294967265)
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
/*
** sat_u_add_uint32_t_fmt_3:
-** addw\s+[atx][0-9]+,\s*a0,\s*a1
+** slli\s+[atx][0-9]+,\s*a0,\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
+** add\s+[atx][0-9]+,\s*a0,\s*a1
+** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
** neg\s+[atx][0-9]+,\s*[atx][0-9]+
** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
/*
** sat_u_add_uint32_t_fmt_4:
-** addw\s+[atx][0-9]+,\s*a0,\s*a1
+** slli\s+[atx][0-9]+,\s*a0,\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
+** add\s+[atx][0-9]+,\s*a0,\s*a1
+** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
** neg\s+[atx][0-9]+,\s*[atx][0-9]+
** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
/*
** sat_u_add_uint32_t_fmt_5:
-** addw\s+[atx][0-9]+,\s*a0,\s*a1
+** slli\s+[atx][0-9]+,\s*a0,\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
+** add\s+[atx][0-9]+,\s*a0,\s*a1
+** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
** neg\s+[atx][0-9]+,\s*[atx][0-9]+
** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
/*
** sat_u_add_uint32_t_fmt_6:
-** addw\s+[atx][0-9]+,\s*a0,\s*a1
+** slli\s+[atx][0-9]+,\s*a0,\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
+** add\s+[atx][0-9]+,\s*a0,\s*a1
+** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
** neg\s+[atx][0-9]+,\s*[atx][0-9]+
** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
/*
** sat_u_add_uint32_t_fmt_1:
-** addw\s+[atx][0-9]+,\s*a0,\s*a1
+** slli\s+[atx][0-9]+,\s*a0,\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
+** add\s+[atx][0-9]+,\s*a0,\s*a1
+** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
** neg\s+[atx][0-9]+,\s*[atx][0-9]+
** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
/*
** sat_u_add_uint32_t_fmt_2:
-** addw\s+[atx][0-9]+,\s*a0,\s*a1
+** slli\s+[atx][0-9]+,\s*a0,\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
+** add\s+[atx][0-9]+,\s*a0,\s*a1
+** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
** neg\s+[atx][0-9]+,\s*[atx][0-9]+
** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
/*
** sat_u_add_imm7_uint32_t_fmt_3:
-** addiw\s+[atx][0-9]+,\s*a0,\s*7
+** slli\s+[atx][0-9]+,\s*a0,\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
+** addi\s+[atx][0-9]+,\s*a0,\s*7
+** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
** neg\s+[atx][0-9]+,\s*[atx][0-9]+
** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
/*
** sat_u_add_imm7_uint32_t_fmt_4:
-** addiw\s+[atx][0-9]+,\s*a0,\s*7
+** slli\s+[atx][0-9]+,\s*a0,\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
+** addi\s+[atx][0-9]+,\s*a0,\s*7
+** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
** neg\s+[atx][0-9]+,\s*[atx][0-9]+
** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
/*
** sat_u_add_imm7_uint32_t_fmt_1:
-** addiw\s+[atx][0-9]+,\s*a0,\s*7
+** slli\s+[atx][0-9]+,\s*a0,\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
+** addi\s+[atx][0-9]+,\s*a0,\s*7
+** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
** neg\s+[atx][0-9]+,\s*[atx][0-9]+
** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
/*
** sat_u_add_imm7_uint32_t_fmt_2:
-** addiw\s+[atx][0-9]+,\s*a0,\s*7
+** slli\s+[atx][0-9]+,\s*a0,\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
+** addi\s+[atx][0-9]+,\s*a0,\s*7
+** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32
** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
** neg\s+[atx][0-9]+,\s*[atx][0-9]+
** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+