aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/m68k/m68k.md16
-rw-r--r--gcc/config/riscv/bitmanip.md16
-rw-r--r--gcc/config/riscv/predicates.md11
-rw-r--r--gcc/config/riscv/riscv.md39
4 files changed, 48 insertions, 34 deletions
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index c96937f..7f345bf 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -2442,14 +2442,15 @@
gcc_assert (GET_CODE (operands[0]) == MEM);
if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
{
- operands[1] = gen_rtx_MEM (SImode,
- plus_constant (Pmode,
- XEXP(operands[0], 0), -8));
+ operands[1]
+ = gen_rtx_MEM (SImode,
+ plus_constant (Pmode,
+ XEXP (XEXP (operands[0], 0), 0), -8));
return "move%.l %0,%3\;add%.l %R2,%0\;addx%.l %2,%3\;move%.l %3,%1";
}
else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
{
- operands[1] = XEXP(operands[0], 0);
+ operands[1] = XEXP (XEXP (operands[0], 0), 0);
return "add%.l %R2,%0\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%1";
}
else
@@ -2949,13 +2950,14 @@
if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
{
operands[1]
- = gen_rtx_MEM (SImode, plus_constant (Pmode,
- XEXP (operands[0], 0), -8));
+ = gen_rtx_MEM (SImode,
+ plus_constant (Pmode,
+ XEXP (XEXP (operands[0], 0), 0), -8));
return "move%.l %0,%3\;sub%.l %R2,%0\;subx%.l %2,%3\;move%.l %3,%1";
}
else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
{
- operands[1] = XEXP(operands[0], 0);
+ operands[1] = XEXP (XEXP (operands[0], 0), 0);
return "sub%.l %R2,%0\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%1";
}
else
diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 5fd139a..59b71ed 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -1218,13 +1218,13 @@
;; Reversed CRC 8, 16, 32 for TARGET_64
(define_expand "crc_rev<ANYI1:mode><ANYI:mode>4"
;; return value (calculated CRC)
- [(set (match_operand:ANYI 0 "register_operand" "=r")
+ [(set (match_operand:ANYI 0 "register_operand")
;; initial CRC
- (unspec:ANYI [(match_operand:ANYI 1 "register_operand" "r")
+ (unspec:ANYI [(match_operand:ANYI 1 "register_operand")
;; data
- (match_operand:ANYI1 2 "register_operand" "r")
+ (match_operand:ANYI1 2 "register_operand")
;; polynomial without leading 1
- (match_operand:ANYI 3)]
+ (match_operand:ANYI 3 "const_int_operand")]
UNSPEC_CRC_REV))]
/* We don't support the case when data's size is bigger than CRC's size. */
"<ANYI:MODE>mode >= <ANYI1:MODE>mode"
@@ -1258,13 +1258,13 @@
;; CRC 8, 16, (32 for TARGET_64)
(define_expand "crc<SUBX1:mode><SUBX:mode>4"
;; return value (calculated CRC)
- [(set (match_operand:SUBX 0 "register_operand" "=r")
+ [(set (match_operand:SUBX 0 "register_operand")
;; initial CRC
- (unspec:SUBX [(match_operand:SUBX 1 "register_operand" "r")
+ (unspec:SUBX [(match_operand:SUBX 1 "register_operand")
;; data
- (match_operand:SUBX1 2 "register_operand" "r")
+ (match_operand:SUBX1 2 "register_operand")
;; polynomial without leading 1
- (match_operand:SUBX 3)]
+ (match_operand:SUBX 3 "const_int_operand")]
UNSPEC_CRC))]
/* We don't support the case when data's size is bigger than CRC's size. */
"(TARGET_ZBKC || TARGET_ZBC || TARGET_ZVBC)
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index 777e71b..056f9e2 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -607,13 +607,12 @@
(define_predicate "ge_operator"
(match_code "ge,geu"))
-;; pmode_reg_or_uimm5_operand can be used by vsll.vx/vsrl.vx/vsra.vx instructions.
-;; Since it has the same predicate with vector_length_operand which allows register
-;; or immediate (0 ~ 31), we define this predicate same as vector_length_operand here.
-;; We don't use vector_length_operand directly to predicate vsll.vx/vsrl.vx/vsra.vx
-;; since it may be confusing.
+;; pmode_reg_or_uimm5_operand can be used by vsll.vx/vsrl.vx/vsra.vx instructions
+;; It is *not* equivalent to vector_length_operand due to the vector_length_operand
+;; needing to conditionalize some behavior on XTHEADVECTOR.
(define_special_predicate "pmode_reg_or_uimm5_operand"
- (match_operand 0 "vector_length_operand"))
+ (ior (match_operand 0 "pmode_register_operand")
+ (match_operand 0 "const_csr_operand")))
(define_special_predicate "pmode_reg_or_0_operand"
(ior (match_operand 0 "const_0_operand")
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 843a048..78a01ef 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2322,27 +2322,38 @@
else
{
rtx reg;
- rtx label = gen_label_rtx ();
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+ rtx label3 = gen_label_rtx ();
rtx end_label = gen_label_rtx ();
rtx abs_reg = gen_reg_rtx (<ANYF:MODE>mode);
rtx coeff_reg = gen_reg_rtx (<ANYF:MODE>mode);
rtx tmp_reg = gen_reg_rtx (<ANYF:MODE>mode);
- rtx fflags = gen_reg_rtx (SImode);
riscv_emit_move (tmp_reg, operands[1]);
+
+ if (flag_trapping_math)
+ {
+ /* Check if the input is a NaN. */
+ riscv_expand_conditional_branch (label1, EQ,
+ operands[1], operands[1]);
+
+ emit_jump_insn (gen_jump (label3));
+ emit_barrier ();
+
+ emit_label (label1);
+ }
+
riscv_emit_move (coeff_reg,
riscv_vector::get_fp_rounding_coefficient (<ANYF:MODE>mode));
emit_insn (gen_abs<ANYF:mode>2 (abs_reg, operands[1]));
- /* fp compare can set invalid flag for NaN, so backup fflags. */
- if (flag_trapping_math)
- emit_insn (gen_riscv_frflags (fflags));
- riscv_expand_conditional_branch (label, LT, abs_reg, coeff_reg);
+ riscv_expand_conditional_branch (label2, LT, abs_reg, coeff_reg);
emit_jump_insn (gen_jump (end_label));
emit_barrier ();
- emit_label (label);
+ emit_label (label2);
switch (<ANYF:MODE>mode)
{
case SFmode:
@@ -2361,15 +2372,17 @@
emit_insn (gen_copysign<ANYF:mode>3 (tmp_reg, abs_reg, operands[1]));
- emit_label (end_label);
+ emit_jump_insn (gen_jump (end_label));
+ emit_barrier ();
- /* Restore fflags, but after label. This is slightly different
- than glibc implementation which only needs to restore under
- the label, since it checks for NaN first, meaning following fp
- compare can't raise fp exceptons and thus not clobber fflags. */
if (flag_trapping_math)
- emit_insn (gen_riscv_fsflags (fflags));
+ {
+ emit_label (label3);
+ /* Generate a qNaN from an sNaN if needed. */
+ emit_insn (gen_add<ANYF:mode>3 (tmp_reg, operands[1], operands[1]));
+ }
+ emit_label (end_label);
riscv_emit_move (operands[0], tmp_reg);
}