| From 8c61566116d23063ff597271884f8e00d94ab1a1 Mon Sep 17 00:00:00 2001 |
| From: segher <segher@138bc75d-0d04-0410-961f-82ee72b054a4> |
| Date: Fri, 30 Aug 2019 13:48:48 +0000 |
| Subject: [PATCH] Backport from trunk 2019-08-22 Segher Boessenkool |
| <segher@kernel.crashing.org> |
| |
| * config/rs6000/altivec.md (unspec): Delete UNSPEC_DARN, UNSPEC_DARN_32, |
| UNSPEC_DARN_RAW, UNSPEC_CMPRB, UNSPEC_CMPRB2, UNSPEC_CMPEQB; move to... |
| * config/rs6000/rs6000.md (unspec): ... here. |
| * config/rs6000/altivec.md (darn_32, darn_raw, darn, cmprb, |
| *cmprb_internal, setb_signed, setb_unsigned, cmprb2, *cmprb2_internal, |
| cmpeqb, *cmpeqb_internal): Delete, move to... |
| * config/rs6000/rs6000.md (darn_32, darn_raw, darn, cmprb, |
| *cmprb_internal, setb_signed, setb_unsigned, cmprb2, *cmprb2_internal, |
| cmpeqb, *cmpeqb_internal): ... here. |
| |
| |
| git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-9-branch@275170 138bc75d-0d04-0410-961f-82ee72b054a4 |
| |
| Upstream-Status: Backport |
| CVE: CVE-2019-15847 p1 |
| Affects <= 9.2.0 |
| Dropped Changelog changes |
| Signed-off-by: Armin Kuster <akuster@mvista.com> |
| |
| --- |
| gcc/config/rs6000/altivec.md | 223 ---------------------------------- |
| gcc/config/rs6000/rs6000.md | 224 +++++++++++++++++++++++++++++++++++ |
| 3 files changed, 239 insertions(+), 223 deletions(-) |
| |
| Index: gcc-9.2.0/gcc/config/rs6000/altivec.md |
| =================================================================== |
| --- gcc-9.2.0.orig/gcc/config/rs6000/altivec.md |
| +++ gcc-9.2.0/gcc/config/rs6000/altivec.md |
| @@ -80,9 +80,6 @@ |
| UNSPEC_VUPKHPX |
| UNSPEC_VUPKLPX |
| UNSPEC_CONVERT_4F32_8I16 |
| - UNSPEC_DARN |
| - UNSPEC_DARN_32 |
| - UNSPEC_DARN_RAW |
| UNSPEC_DST |
| UNSPEC_DSTT |
| UNSPEC_DSTST |
| @@ -161,9 +158,6 @@ |
| UNSPEC_BCDADD |
| UNSPEC_BCDSUB |
| UNSPEC_BCD_OVERFLOW |
| - UNSPEC_CMPRB |
| - UNSPEC_CMPRB2 |
| - UNSPEC_CMPEQB |
| UNSPEC_VRLMI |
| UNSPEC_VRLNM |
| ]) |
| @@ -4101,223 +4095,6 @@ |
| "bcd<bcd_add_sub>. %0,%1,%2,%3" |
| [(set_attr "type" "vecsimple")]) |
| |
| -(define_insn "darn_32" |
| - [(set (match_operand:SI 0 "register_operand" "=r") |
| - (unspec:SI [(const_int 0)] UNSPEC_DARN_32))] |
| - "TARGET_P9_MISC" |
| - "darn %0,0" |
| - [(set_attr "type" "integer")]) |
| - |
| -(define_insn "darn_raw" |
| - [(set (match_operand:DI 0 "register_operand" "=r") |
| - (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))] |
| - "TARGET_P9_MISC && TARGET_64BIT" |
| - "darn %0,2" |
| - [(set_attr "type" "integer")]) |
| - |
| -(define_insn "darn" |
| - [(set (match_operand:DI 0 "register_operand" "=r") |
| - (unspec:DI [(const_int 0)] UNSPEC_DARN))] |
| - "TARGET_P9_MISC && TARGET_64BIT" |
| - "darn %0,1" |
| - [(set_attr "type" "integer")]) |
| - |
| -;; Test byte within range. |
| -;; |
| -;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx |
| -;; represents a byte whose value is ignored in this context and |
| -;; vv, the least significant byte, holds the byte value that is to |
| -;; be tested for membership within the range specified by operand 2. |
| -;; The bytes of operand 2 are organized as xx:xx:hi:lo. |
| -;; |
| -;; Return in target register operand 0 a value of 1 if lo <= vv and |
| -;; vv <= hi. Otherwise, set register operand 0 to 0. |
| -;; |
| -;; Though the instructions to which this expansion maps operate on |
| -;; 64-bit registers, the current implementation only operates on |
| -;; SI-mode operands as the high-order bits provide no information |
| -;; that is not already available in the low-order bits. To avoid the |
| -;; costs of data widening operations, future enhancements might allow |
| -;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. |
| -(define_expand "cmprb" |
| - [(set (match_dup 3) |
| - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") |
| - (match_operand:SI 2 "gpc_reg_operand" "r")] |
| - UNSPEC_CMPRB)) |
| - (set (match_operand:SI 0 "gpc_reg_operand" "=r") |
| - (if_then_else:SI (lt (match_dup 3) |
| - (const_int 0)) |
| - (const_int -1) |
| - (if_then_else (gt (match_dup 3) |
| - (const_int 0)) |
| - (const_int 1) |
| - (const_int 0))))] |
| - "TARGET_P9_MISC" |
| -{ |
| - operands[3] = gen_reg_rtx (CCmode); |
| -}) |
| - |
| -;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx |
| -;; represents a byte whose value is ignored in this context and |
| -;; vv, the least significant byte, holds the byte value that is to |
| -;; be tested for membership within the range specified by operand 2. |
| -;; The bytes of operand 2 are organized as xx:xx:hi:lo. |
| -;; |
| -;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if |
| -;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other |
| -;; 3 bits of the target CR register are all set to 0. |
| -(define_insn "*cmprb_internal" |
| - [(set (match_operand:CC 0 "cc_reg_operand" "=y") |
| - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") |
| - (match_operand:SI 2 "gpc_reg_operand" "r")] |
| - UNSPEC_CMPRB))] |
| - "TARGET_P9_MISC" |
| - "cmprb %0,0,%1,%2" |
| - [(set_attr "type" "logical")]) |
| - |
| -;; Set operand 0 register to -1 if the LT bit (0x8) of condition |
| -;; register operand 1 is on. Otherwise, set operand 0 register to 1 |
| -;; if the GT bit (0x4) of condition register operand 1 is on. |
| -;; Otherwise, set operand 0 to 0. Note that the result stored into |
| -;; register operand 0 is non-zero iff either the LT or GT bits are on |
| -;; within condition register operand 1. |
| -(define_insn "setb_signed" |
| - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") |
| - (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y") |
| - (const_int 0)) |
| - (const_int -1) |
| - (if_then_else (gt (match_dup 1) |
| - (const_int 0)) |
| - (const_int 1) |
| - (const_int 0))))] |
| - "TARGET_P9_MISC" |
| - "setb %0,%1" |
| - [(set_attr "type" "logical")]) |
| - |
| -(define_insn "setb_unsigned" |
| - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") |
| - (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y") |
| - (const_int 0)) |
| - (const_int -1) |
| - (if_then_else (gtu (match_dup 1) |
| - (const_int 0)) |
| - (const_int 1) |
| - (const_int 0))))] |
| - "TARGET_P9_MISC" |
| - "setb %0,%1" |
| - [(set_attr "type" "logical")]) |
| - |
| -;; Test byte within two ranges. |
| -;; |
| -;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx |
| -;; represents a byte whose value is ignored in this context and |
| -;; vv, the least significant byte, holds the byte value that is to |
| -;; be tested for membership within the range specified by operand 2. |
| -;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. |
| -;; |
| -;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and |
| -;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register |
| -;; operand 0 to 0. |
| -;; |
| -;; Though the instructions to which this expansion maps operate on |
| -;; 64-bit registers, the current implementation only operates on |
| -;; SI-mode operands as the high-order bits provide no information |
| -;; that is not already available in the low-order bits. To avoid the |
| -;; costs of data widening operations, future enhancements might allow |
| -;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. |
| -(define_expand "cmprb2" |
| - [(set (match_dup 3) |
| - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") |
| - (match_operand:SI 2 "gpc_reg_operand" "r")] |
| - UNSPEC_CMPRB2)) |
| - (set (match_operand:SI 0 "gpc_reg_operand" "=r") |
| - (if_then_else:SI (lt (match_dup 3) |
| - (const_int 0)) |
| - (const_int -1) |
| - (if_then_else (gt (match_dup 3) |
| - (const_int 0)) |
| - (const_int 1) |
| - (const_int 0))))] |
| - "TARGET_P9_MISC" |
| -{ |
| - operands[3] = gen_reg_rtx (CCmode); |
| -}) |
| - |
| -;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx |
| -;; represents a byte whose value is ignored in this context and |
| -;; vv, the least significant byte, holds the byte value that is to |
| -;; be tested for membership within the ranges specified by operand 2. |
| -;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. |
| -;; |
| -;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if |
| -;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). |
| -;; Otherwise, set the GT bit to 0. The other 3 bits of the target |
| -;; CR register are all set to 0. |
| -(define_insn "*cmprb2_internal" |
| - [(set (match_operand:CC 0 "cc_reg_operand" "=y") |
| - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") |
| - (match_operand:SI 2 "gpc_reg_operand" "r")] |
| - UNSPEC_CMPRB2))] |
| - "TARGET_P9_MISC" |
| - "cmprb %0,1,%1,%2" |
| - [(set_attr "type" "logical")]) |
| - |
| -;; Test byte membership within set of 8 bytes. |
| -;; |
| -;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx |
| -;; represents a byte whose value is ignored in this context and |
| -;; vv, the least significant byte, holds the byte value that is to |
| -;; be tested for membership within the set specified by operand 2. |
| -;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. |
| -;; |
| -;; Return in target register operand 0 a value of 1 if vv equals one |
| -;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set |
| -;; register operand 0 to 0. Note that the 8 byte values held within |
| -;; operand 2 need not be unique. |
| -;; |
| -;; Though the instructions to which this expansion maps operate on |
| -;; 64-bit registers, the current implementation requires that operands |
| -;; 0 and 1 have mode SI as the high-order bits provide no information |
| -;; that is not already available in the low-order bits. To avoid the |
| -;; costs of data widening operations, future enhancements might allow |
| -;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. |
| -(define_expand "cmpeqb" |
| - [(set (match_dup 3) |
| - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") |
| - (match_operand:DI 2 "gpc_reg_operand" "r")] |
| - UNSPEC_CMPEQB)) |
| - (set (match_operand:SI 0 "gpc_reg_operand" "=r") |
| - (if_then_else:SI (lt (match_dup 3) |
| - (const_int 0)) |
| - (const_int -1) |
| - (if_then_else (gt (match_dup 3) |
| - (const_int 0)) |
| - (const_int 1) |
| - (const_int 0))))] |
| - "TARGET_P9_MISC && TARGET_64BIT" |
| -{ |
| - operands[3] = gen_reg_rtx (CCmode); |
| -}) |
| - |
| -;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx |
| -;; represents a byte whose value is ignored in this context and |
| -;; vv, the least significant byte, holds the byte value that is to |
| -;; be tested for membership within the set specified by operand 2. |
| -;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. |
| -;; |
| -;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv |
| -;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, |
| -;; set the GT bit to zero. The other 3 bits of the target CR register |
| -;; are all set to 0. |
| -(define_insn "*cmpeqb_internal" |
| - [(set (match_operand:CC 0 "cc_reg_operand" "=y") |
| - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") |
| - (match_operand:DI 2 "gpc_reg_operand" "r")] |
| - UNSPEC_CMPEQB))] |
| - "TARGET_P9_MISC && TARGET_64BIT" |
| - "cmpeqb %0,%1,%2" |
| - [(set_attr "type" "logical")]) |
| - |
| (define_expand "bcd<bcd_add_sub>_<code>" |
| [(parallel [(set (reg:CCFP CR6_REGNO) |
| (compare:CCFP |
| Index: gcc-9.2.0/gcc/config/rs6000/rs6000.md |
| =================================================================== |
| --- gcc-9.2.0.orig/gcc/config/rs6000/rs6000.md |
| +++ gcc-9.2.0/gcc/config/rs6000/rs6000.md |
| @@ -137,6 +137,12 @@ |
| UNSPEC_LSQ |
| UNSPEC_FUSION_GPR |
| UNSPEC_STACK_CHECK |
| + UNSPEC_DARN |
| + UNSPEC_DARN_32 |
| + UNSPEC_DARN_RAW |
| + UNSPEC_CMPRB |
| + UNSPEC_CMPRB2 |
| + UNSPEC_CMPEQB |
| UNSPEC_ADD_ROUND_TO_ODD |
| UNSPEC_SUB_ROUND_TO_ODD |
| UNSPEC_MUL_ROUND_TO_ODD |
| @@ -14322,7 +14328,225 @@ |
| "xscmpuqp %0,%1,%2" |
| [(set_attr "type" "veccmp") |
| (set_attr "size" "128")]) |
| + |
| +;; Miscellaneous ISA 3.0 (power9) instructions |
| + |
| +(define_insn "darn_32" |
| + [(set (match_operand:SI 0 "register_operand" "=r") |
| + (unspec:SI [(const_int 0)] UNSPEC_DARN_32))] |
| + "TARGET_P9_MISC" |
| + "darn %0,0" |
| + [(set_attr "type" "integer")]) |
| + |
| +(define_insn "darn_raw" |
| + [(set (match_operand:DI 0 "register_operand" "=r") |
| + (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))] |
| + "TARGET_P9_MISC && TARGET_64BIT" |
| + "darn %0,2" |
| + [(set_attr "type" "integer")]) |
| + |
| +(define_insn "darn" |
| + [(set (match_operand:DI 0 "register_operand" "=r") |
| + (unspec:DI [(const_int 0)] UNSPEC_DARN))] |
| + "TARGET_P9_MISC && TARGET_64BIT" |
| + "darn %0,1" |
| + [(set_attr "type" "integer")]) |
| + |
| +;; Test byte within range. |
| +;; |
| +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx |
| +;; represents a byte whose value is ignored in this context and |
| +;; vv, the least significant byte, holds the byte value that is to |
| +;; be tested for membership within the range specified by operand 2. |
| +;; The bytes of operand 2 are organized as xx:xx:hi:lo. |
| +;; |
| +;; Return in target register operand 0 a value of 1 if lo <= vv and |
| +;; vv <= hi. Otherwise, set register operand 0 to 0. |
| +;; |
| +;; Though the instructions to which this expansion maps operate on |
| +;; 64-bit registers, the current implementation only operates on |
| +;; SI-mode operands as the high-order bits provide no information |
| +;; that is not already available in the low-order bits. To avoid the |
| +;; costs of data widening operations, future enhancements might allow |
| +;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. |
| +(define_expand "cmprb" |
| + [(set (match_dup 3) |
| + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") |
| + (match_operand:SI 2 "gpc_reg_operand" "r")] |
| + UNSPEC_CMPRB)) |
| + (set (match_operand:SI 0 "gpc_reg_operand" "=r") |
| + (if_then_else:SI (lt (match_dup 3) |
| + (const_int 0)) |
| + (const_int -1) |
| + (if_then_else (gt (match_dup 3) |
| + (const_int 0)) |
| + (const_int 1) |
| + (const_int 0))))] |
| + "TARGET_P9_MISC" |
| +{ |
| + operands[3] = gen_reg_rtx (CCmode); |
| +}) |
| + |
| +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx |
| +;; represents a byte whose value is ignored in this context and |
| +;; vv, the least significant byte, holds the byte value that is to |
| +;; be tested for membership within the range specified by operand 2. |
| +;; The bytes of operand 2 are organized as xx:xx:hi:lo. |
| +;; |
| +;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if |
| +;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other |
| +;; 3 bits of the target CR register are all set to 0. |
| +(define_insn "*cmprb_internal" |
| + [(set (match_operand:CC 0 "cc_reg_operand" "=y") |
| + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") |
| + (match_operand:SI 2 "gpc_reg_operand" "r")] |
| + UNSPEC_CMPRB))] |
| + "TARGET_P9_MISC" |
| + "cmprb %0,0,%1,%2" |
| + [(set_attr "type" "logical")]) |
| + |
| +;; Set operand 0 register to -1 if the LT bit (0x8) of condition |
| +;; register operand 1 is on. Otherwise, set operand 0 register to 1 |
| +;; if the GT bit (0x4) of condition register operand 1 is on. |
| +;; Otherwise, set operand 0 to 0. Note that the result stored into |
| +;; register operand 0 is non-zero iff either the LT or GT bits are on |
| +;; within condition register operand 1. |
| +(define_insn "setb_signed" |
| + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") |
| + (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y") |
| + (const_int 0)) |
| + (const_int -1) |
| + (if_then_else (gt (match_dup 1) |
| + (const_int 0)) |
| + (const_int 1) |
| + (const_int 0))))] |
| + "TARGET_P9_MISC" |
| + "setb %0,%1" |
| + [(set_attr "type" "logical")]) |
| |
| +(define_insn "setb_unsigned" |
| + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") |
| + (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y") |
| + (const_int 0)) |
| + (const_int -1) |
| + (if_then_else (gtu (match_dup 1) |
| + (const_int 0)) |
| + (const_int 1) |
| + (const_int 0))))] |
| + "TARGET_P9_MISC" |
| + "setb %0,%1" |
| + [(set_attr "type" "logical")]) |
| + |
| +;; Test byte within two ranges. |
| +;; |
| +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx |
| +;; represents a byte whose value is ignored in this context and |
| +;; vv, the least significant byte, holds the byte value that is to |
| +;; be tested for membership within the range specified by operand 2. |
| +;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. |
| +;; |
| +;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and |
| +;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register |
| +;; operand 0 to 0. |
| +;; |
| +;; Though the instructions to which this expansion maps operate on |
| +;; 64-bit registers, the current implementation only operates on |
| +;; SI-mode operands as the high-order bits provide no information |
| +;; that is not already available in the low-order bits. To avoid the |
| +;; costs of data widening operations, future enhancements might allow |
| +;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. |
| +(define_expand "cmprb2" |
| + [(set (match_dup 3) |
| + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") |
| + (match_operand:SI 2 "gpc_reg_operand" "r")] |
| + UNSPEC_CMPRB2)) |
| + (set (match_operand:SI 0 "gpc_reg_operand" "=r") |
| + (if_then_else:SI (lt (match_dup 3) |
| + (const_int 0)) |
| + (const_int -1) |
| + (if_then_else (gt (match_dup 3) |
| + (const_int 0)) |
| + (const_int 1) |
| + (const_int 0))))] |
| + "TARGET_P9_MISC" |
| +{ |
| + operands[3] = gen_reg_rtx (CCmode); |
| +}) |
| + |
| +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx |
| +;; represents a byte whose value is ignored in this context and |
| +;; vv, the least significant byte, holds the byte value that is to |
| +;; be tested for membership within the ranges specified by operand 2. |
| +;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. |
| +;; |
| +;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if |
| +;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). |
| +;; Otherwise, set the GT bit to 0. The other 3 bits of the target |
| +;; CR register are all set to 0. |
| +(define_insn "*cmprb2_internal" |
| + [(set (match_operand:CC 0 "cc_reg_operand" "=y") |
| + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") |
| + (match_operand:SI 2 "gpc_reg_operand" "r")] |
| + UNSPEC_CMPRB2))] |
| + "TARGET_P9_MISC" |
| + "cmprb %0,1,%1,%2" |
| + [(set_attr "type" "logical")]) |
| + |
| +;; Test byte membership within set of 8 bytes. |
| +;; |
| +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx |
| +;; represents a byte whose value is ignored in this context and |
| +;; vv, the least significant byte, holds the byte value that is to |
| +;; be tested for membership within the set specified by operand 2. |
| +;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. |
| +;; |
| +;; Return in target register operand 0 a value of 1 if vv equals one |
| +;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set |
| +;; register operand 0 to 0. Note that the 8 byte values held within |
| +;; operand 2 need not be unique. |
| +;; |
| +;; Though the instructions to which this expansion maps operate on |
| +;; 64-bit registers, the current implementation requires that operands |
| +;; 0 and 1 have mode SI as the high-order bits provide no information |
| +;; that is not already available in the low-order bits. To avoid the |
| +;; costs of data widening operations, future enhancements might allow |
| +;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. |
| +(define_expand "cmpeqb" |
| + [(set (match_dup 3) |
| + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") |
| + (match_operand:DI 2 "gpc_reg_operand" "r")] |
| + UNSPEC_CMPEQB)) |
| + (set (match_operand:SI 0 "gpc_reg_operand" "=r") |
| + (if_then_else:SI (lt (match_dup 3) |
| + (const_int 0)) |
| + (const_int -1) |
| + (if_then_else (gt (match_dup 3) |
| + (const_int 0)) |
| + (const_int 1) |
| + (const_int 0))))] |
| + "TARGET_P9_MISC && TARGET_64BIT" |
| +{ |
| + operands[3] = gen_reg_rtx (CCmode); |
| +}) |
| + |
| +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx |
| +;; represents a byte whose value is ignored in this context and |
| +;; vv, the least significant byte, holds the byte value that is to |
| +;; be tested for membership within the set specified by operand 2. |
| +;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. |
| +;; |
| +;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv |
| +;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, |
| +;; set the GT bit to zero. The other 3 bits of the target CR register |
| +;; are all set to 0. |
| +(define_insn "*cmpeqb_internal" |
| + [(set (match_operand:CC 0 "cc_reg_operand" "=y") |
| + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") |
| + (match_operand:DI 2 "gpc_reg_operand" "r")] |
| + UNSPEC_CMPEQB))] |
| + "TARGET_P9_MISC && TARGET_64BIT" |
| + "cmpeqb %0,%1,%2" |
| + [(set_attr "type" "logical")]) |
| |
| |
| (include "sync.md") |