diff options
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/m68k/m68k.md | 16 | ||||
-rw-r--r-- | gcc/config/riscv/bitmanip.md | 16 | ||||
-rw-r--r-- | gcc/config/riscv/predicates.md | 11 | ||||
-rw-r--r-- | gcc/config/riscv/riscv.md | 39 |
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); } |