[gcc(refs/users/meissner/heads/work251-float)] Add BF/HF neg, abs operands and logical insns.

Michael Meissner via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:ebacc33bb22544c505e624805394a6a934145701

commit ebacc33bb22544c505e624805394a6a934145701
Author: Michael Meissner <[email protected]>
Date:   Thu Jul 16 15:37:37 2026 -0400

    Add BF/HF neg, abs operands and logical insns.
    
    This patch adds support for 16-bit floating point negation, absolute value, and
    negative absolute value.  In order to add this support, various logical (and,
    xor, ior) operations on 16-bit values are defined.
    
    I have committed all of the patches in my backlog (dense math registers, other
    -mcpu=future instructions, random bug fixes, support for _Float16 and
    __bfloat16, and optimizations for vector logical operations on power10/power11)
    into the IBM vendor branch:
    
            vendors/ibm/gcc-17-future
    
    2026-07-16  Michael Meissner  <[email protected]>
    
    gcc/
    
            * config/rs6000/float16.md (neg<mode>2): Add BFmode/HFmode negate,
            absolute value and negative absolute value operations.  Add logical
            insns operating on BFmode/HFmode.
            (abs<mode>2): Likewise.
            (nabs<mode>2): Likewise.
            (and<mode>3): Likewise.
            (ior<mode>): Likewise.
            (xor<mode>3): Likewise.
            (nor<mode>3): Likewise.
            (andn<mode>3): Likewise.
            (eqv<mode>3): Likewise.
            (nand<mode>3): Likewise.
            (iorn<mode>3): Likewise.
            (bool<mode>3): Likewise.
            (boolc<mode>3): Likewise.
            (boolcc<mode>): Likewise.

Diff:
---
 gcc/config/rs6000/float16.md | 203 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 203 insertions(+)

diff --git a/gcc/config/rs6000/float16.md b/gcc/config/rs6000/float16.md
index 45c61dca9890..e695febf9cae 100644
--- a/gcc/config/rs6000/float16.md
+++ b/gcc/config/rs6000/float16.md
@@ -653,3 +653,206 @@
   emit_insn (gen_fixuns_truncdf<GPR:mode>2 (operands[0], df_tmp));
   DONE;
 })
+
+;; Negate 16-bit floating point by XOR with -0.0.
+
+(define_insn_and_split "neg<mode>2"
+  [(set (match_operand:FP16 0 "gpc_reg_operand" "=wa,?wr")
+	(neg:FP16 (match_operand:FP16 1 "gpc_reg_operand" "wa,wr")))
+   (clobber (match_scratch:FP16 2 "=&wa,&r"))]
+  "TARGET_FLOAT16"
+  "#"
+  "&& 1"
+  [(set (match_dup 2)
+	(match_dup 3))
+   (set (match_dup 0)
+	(xor:FP16 (match_dup 1)
+		  (match_dup 2)))]
+{
+  if (GET_CODE (operands[2]) == SCRATCH)
+    operands[2] = gen_reg_rtx (<MODE>mode);
+
+  REAL_VALUE_TYPE dconst;
+
+  gcc_assert (real_from_string (&dconst, "-0.0") == 0);
+
+  rtx rc = const_double_from_real_value (dconst, <MODE>mode);
+  if (!TARGET_PREFIXED)
+    rc = force_const_mem (<MODE>mode, rc);
+
+  operands[3] = rc;
+}
+  [(set_attr "type" "veclogical,integer")
+   (set_attr "length" "16")])
+
+;; 16-bit floating point absolute value
+
+(define_insn_and_split "abs<mode>2"
+  [(set (match_operand:FP16 0 "gpc_reg_operand" "=wa,?wr")
+	(abs:FP16
+	 (match_operand:FP16 1 "gpc_reg_operand" "wa,wr")))
+   (clobber (match_scratch:FP16 2 "=&wa,&r"))]
+  "TARGET_FLOAT16"
+  "#"
+  "&& 1"
+  [(set (match_dup 2)
+	(match_dup 3))
+   (set (match_dup 0)
+	(and:FP16 (not:FP16 (match_dup 2))
+		  (match_dup 1)))]
+		  
+{
+  if (GET_CODE (operands[2]) == SCRATCH)
+    operands[2] = gen_reg_rtx (<MODE>mode);
+
+  REAL_VALUE_TYPE dconst;
+
+  gcc_assert (real_from_string (&dconst, "-0.0") == 0);
+
+  rtx rc = const_double_from_real_value (dconst, <MODE>mode);
+
+  if (!TARGET_PREFIXED)
+    rc = force_const_mem (<MODE>mode, rc);
+
+  operands[3] = rc;
+}
+  [(set_attr "type" "veclogical,integer")
+   (set_attr "length" "16")])
+
+;; 16-bit negative floating point absolute value
+
+(define_insn_and_split "*nabs<mode>2"
+  [(set (match_operand:FP16 0 "gpc_reg_operand" "=wa,?wr")
+	(neg:FP16
+	 (abs:FP16
+	  (match_operand:FP16 1 "gpc_reg_operand" "wa,wr"))))
+   (clobber (match_scratch:FP16 2 "=&wa,&r"))]
+  "TARGET_FLOAT16"
+  "#"
+  "&& 1"
+  [(set (match_dup 2)
+	(match_dup 3))
+   (set (match_dup 0)
+	(ior:FP16 (match_dup 1)
+		  (match_dup 2)))]
+{
+  if (GET_CODE (operands[2]) == SCRATCH)
+    operands[2] = gen_reg_rtx (<MODE>mode);
+
+  REAL_VALUE_TYPE dconst;
+
+  gcc_assert (real_from_string (&dconst, "-0.0") == 0);
+  rtx rc = const_double_from_real_value (dconst, <MODE>mode);
+
+  if (!TARGET_PREFIXED)
+    rc = force_const_mem (<MODE>mode, rc);
+
+  operands[3] = rc;
+}
+  [(set_attr "type" "veclogical,integer")
+   (set_attr "length" "16")])
+
+;; Add logical operations for 16-bit floating point types that are used
+;; for things like negate, abs, and negative abs.  Possibly in the
+;; future we might need logical operators for extracting exponents and
+;; mantissas.
+(define_expand "and<mode>3"
+  [(set (match_operand:FP16 0 "gpc_reg_operand")
+	(and:FP16 (match_operand:FP16 1 "gpc_reg_operand")
+		  (match_operand:FP16 2 "gpc_reg_operand")))]
+  "TARGET_FLOAT16"
+  "")
+
+(define_expand "ior<mode>3"
+  [(set (match_operand:FP16 0 "gpc_reg_operand")
+        (ior:FP16 (match_operand:FP16 1 "gpc_reg_operand")
+		  (match_operand:FP16 2 "gpc_reg_operand")))]
+  "TARGET_FLOAT16"
+  "")
+
+(define_expand "xor<mode>3"
+  [(set (match_operand:FP16 0 "gpc_reg_operand")
+        (xor:FP16 (match_operand:FP16 1 "gpc_reg_operand")
+		  (match_operand:FP16 2 "gpc_reg_operand")))]
+  "TARGET_FLOAT16"
+  "")
+
+(define_expand "nor<mode>3"
+  [(set (match_operand:FP16 0 "gpc_reg_operand")
+	(and:FP16
+	 (not:FP16 (match_operand:FP16 1 "gpc_reg_operand"))
+	 (not:FP16 (match_operand:FP16 2 "gpc_reg_operand"))))]
+  "TARGET_FLOAT16"
+  "")
+
+(define_expand "andn<mode>3"
+  [(set (match_operand:FP16 0 "gpc_reg_operand")
+        (and:FP16
+	 (not:FP16 (match_operand:FP16 2 "gpc_reg_operand"))
+	 (match_operand:FP16 1 "gpc_reg_operand")))]
+  "TARGET_FLOAT16"
+  "")
+
+(define_expand "eqv<mode>3"
+  [(set (match_operand:FP16 0 "gpc_reg_operand")
+	(not:FP16
+	 (xor:FP16 (match_operand:FP16 1 "gpc_reg_operand")
+		   (match_operand:FP16 2 "gpc_reg_operand"))))]
+  "TARGET_FLOAT16"
+  "")
+
+;; Rewrite nand into canonical form
+(define_expand "nand<mode>3"
+  [(set (match_operand:FP16 0 "gpc_reg_operand")
+	(ior:FP16
+	 (not:FP16 (match_operand:FP16 1 "gpc_reg_operand"))
+	 (not:FP16 (match_operand:FP16 2 "gpc_reg_operand"))))]
+  "TARGET_FLOAT16"
+  "")
+
+;; The canonical form is to have the negated element first, so we need to
+;; reverse arguments.
+(define_expand "iorn<mode>3"
+  [(set (match_operand:FP16 0 "gpc_reg_operand")
+	(ior:FP16
+	 (not:FP16 (match_operand:FP16 2 "gpc_reg_operand"))
+	 (match_operand:FP16 1 "gpc_reg_operand")))]
+  "TARGET_FLOAT16"
+  "")
+
+;; AND, IOR, and XOR insns.  Unlike HImode operations prefer using
+;; floating point/vector registers over GPRs.
+(define_insn "*bool<mode>3"
+  [(set (match_operand:FP16 0 "gpc_reg_operand" "=wa,r")
+	(match_operator:FP16 3 "boolean_operator"
+	 [(match_operand:FP16 1 "gpc_reg_operand" "wa,r")
+	  (match_operand:FP16 2 "gpc_reg_operand" "wa,r")]))]
+  "TARGET_FLOAT16"
+  "@
+   xxl%q3 %x0,%x1,%x2
+   %q3 %0,%1,%2"
+  [(set_attr "type" "veclogical,logical")])
+
+;; ANDC, IORC, and EQV insns.
+(define_insn "*boolc<mode>3"
+  [(set (match_operand:FP16 0 "gpc_reg_operand" "=wa,r")
+	(match_operator:FP16 3 "boolean_operator"
+	 [(not:FP16 (match_operand:FP16 2 "gpc_reg_operand" "wa,r"))
+	  (match_operand:FP16 1 "gpc_reg_operand" "wa,r")]))]
+  "TARGET_FLOAT16"
+  "@
+   xxl%q3 %x0,%x1,%x2
+   %q3 %0,%1,%2"
+  [(set_attr "type" "veclogical,logical")])
+
+;; NOR and NAND insns.
+(define_insn "*boolcc<mode>3"
+  [(set (match_operand:FP16 0 "gpc_reg_operand" "=wa,r")
+	(match_operator:FP16 3 "boolean_operator"
+	 [(not:FP16 (match_operand:FP16 1 "gpc_reg_operand" "wa,r"))
+	  (not:FP16 (match_operand:FP16 2 "gpc_reg_operand" "wa,r"))]))]
+  "TARGET_FLOAT16"
+  "@
+   xxl%q3 %x0,%x1,%x2
+   %q3 %0,%1,%2"
+  [(set_attr "type" "veclogical,logical")])
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.