[PATCH V2 6/7] sparc: support for VIS4B instructions
Jose E. Marchesi
jose.marchesi@oracle.com
Wed Jul 5 14:16:00 GMT 2017
This patch adds suppport for the following VIS instructions, which are
introduced in the Oracle SPARC Architecture 2017 and implemented by the
SPARC M8 cpu:
- Dictionary unpack.
- Partitioned compare with shifted result.
- Unsigned partitioned compare with shifted result.
- Partitioned dual-equal compare with shifted result.
- Partitioned unsigned range compare with shifted result.
The facilities introduced are:
- A new option -mvis4b.
- Compiler built-ins for the above mentioned instructions.
Tests and documentation are also provided.
gcc/ChangeLog:
* config/sparc/sparc.opt: New option -mvis4b.
* config/sparc/sparc.c (dump_target_flag_bits): Handle MASK_VIS4B.
(sparc_option_override): Handle VIS4B.
(enum sparc_builtins): Define
SPARC_BUILTIN_DICTUNPACK{8,16,32},
SPARC_BUILTIN_FPCMP{LE,GT,EQ,NE}{8,16,32}SHL,
SPARC_BUILTIN_FPCMPU{LE,GT}{8,16,32}SHL,
SPARC_BUILTIN_FPCMPDE{8,16,32}SHL and
SPARC_BUILTIN_FPCMPUR{8,16,32}SHL.
(check_constant_argument): New function.
(sparc_vis_init_builtins): Define builtins
__builtin_vis_dictunpack{8,16,32},
__builtin_vis_fpcmp{le,gt,eq,ne}{8,16,32}shl,
__builtin_vis_fpcmpu{le,gt}{8,16,32}shl,
__builtin_vis_fpcmpde{8,16,32}shl and
__builtin_vis_fpcmpur{8,16,32}shl.
(sparc_expand_builtin): Check that the constant operands to
__builtin_vis_fpcmp*shl and _builtin_vis_dictunpack* are indeed
constant and in range.
* config/sparc/sparc-c.c (sparc_target_macros): Handle
TARGET_VIS4B.
* config/sparc/sparc.h (SPARC_IMM2_P): Define.
(SPARC_IMM5_P): Likewise.
* config/sparc/sparc.md (cpu_feature): Add new feagure "vis4b".
(enabled): Handle vis4b.
(UNSPEC_DICTUNPACK): New unspec.
(UNSPEC_FPCMPSHL): Likewise.
(UNSPEC_FPUCMPSHL): Likewise.
(UNSPEC_FPCMPDESHL): Likewise.
(UNSPEC_FPCMPURSHL): Likewise.
(cpu_feature): New CPU feature `vis4b'.
(dictunpack{8,16,32}): New insns.
(FPCSMODE): New mode iterator.
(fpcscond): New code iterator.
(fpcsucond): Likewise.
(fpcmp{le,gt,eq,ne}{8,16,32}{si,di}shl): New insns.
(fpcmpu{le,gt}{8,16,32}{si,di}shl): Likewise.
(fpcmpde{8,16,32}{si,di}shl): Likewise.
(fpcmpur{8,16,32}{si,di}shl): Likewise.
* config/sparc/constraints.md: Define constraints `q' for unsigned
2-bit integer constants and `t' for unsigned 5-bit integer
constants.
* config/sparc/predicates.md (imm5_operand_dictunpack8): New
predicate.
(imm5_operand_dictunpack16): Likewise.
(imm5_operand_dictunpack32): Likewise.
(imm2_operand): Likewise.
* doc/invoke.texi (SPARC Options): Document -mvis4b.
* doc/extend.texi (SPARC VIS Built-in Functions): Document the
ditunpack* and fpcmp*shl builtins.
gcc/testsuite/ChangeLog:
* gcc.target/sparc/dictunpack.c: New file.
* gcc.target/sparc/fpcmpdeshl.c: Likewise.
* gcc.target/sparc/fpcmpshl.c: Likewise.
* gcc.target/sparc/fpcmpurshl.c: Likewise.
* gcc.target/sparc/fpcmpushl.c: Likewise.
---
gcc/ChangeLog | 53 ++++++
gcc/config/sparc/constraints.md | 12 +-
gcc/config/sparc/predicates.md | 27 +++
gcc/config/sparc/sparc-c.c | 7 +-
gcc/config/sparc/sparc.c | 247 +++++++++++++++++++++++++++-
gcc/config/sparc/sparc.h | 4 +
gcc/config/sparc/sparc.md | 73 +++++++-
gcc/config/sparc/sparc.opt | 4 +
gcc/doc/extend.texi | 39 +++++
gcc/doc/invoke.texi | 13 ++
gcc/testsuite/ChangeLog | 8 +
gcc/testsuite/gcc.target/sparc/dictunpack.c | 25 +++
gcc/testsuite/gcc.target/sparc/fpcmpdeshl.c | 25 +++
gcc/testsuite/gcc.target/sparc/fpcmpshl.c | 81 +++++++++
gcc/testsuite/gcc.target/sparc/fpcmpurshl.c | 25 +++
gcc/testsuite/gcc.target/sparc/fpcmpushl.c | 43 +++++
16 files changed, 677 insertions(+), 9 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/sparc/dictunpack.c
create mode 100644 gcc/testsuite/gcc.target/sparc/fpcmpdeshl.c
create mode 100644 gcc/testsuite/gcc.target/sparc/fpcmpshl.c
create mode 100644 gcc/testsuite/gcc.target/sparc/fpcmpurshl.c
create mode 100644 gcc/testsuite/gcc.target/sparc/fpcmpushl.c
diff --git a/gcc/config/sparc/constraints.md b/gcc/config/sparc/constraints.md
index 7c9ef74..cff5a61 100644
--- a/gcc/config/sparc/constraints.md
+++ b/gcc/config/sparc/constraints.md
@@ -19,7 +19,7 @@
;;; Unused letters:
;;; B
-;;; a jkl q tuv xyz
+;;; a jkl uv xyz
;; Register constraints
@@ -58,6 +58,16 @@
;; Integer constant constraints
+(define_constraint "q"
+ "Unsigned 2-bit integer constant"
+ (and (match_code "const_int")
+ (match_test "SPARC_IMM2_P (ival)")))
+
+(define_constraint "t"
+ "Unsigned 5-bit integer constant"
+ (and (match_code "const_int")
+ (match_test "SPARC_IMM5_P (ival)")))
+
(define_constraint "A"
"Signed 5-bit integer constant"
(and (match_code "const_int")
diff --git a/gcc/config/sparc/predicates.md b/gcc/config/sparc/predicates.md
index 951933e..3f8526d 100644
--- a/gcc/config/sparc/predicates.md
+++ b/gcc/config/sparc/predicates.md
@@ -328,6 +328,33 @@
(and (match_code "const_int")
(match_test "SPARC_SIMM5_P (INTVAL (op))"))))
+;; Return true if OP is a constant in the range 0..7. This is an
+;; acceptable second operand for dictunpack instructions setting a
+;; V8QI mode in the destination register.
+(define_predicate "imm5_operand_dictunpack8"
+ (and (match_code "const_int")
+ (match_test "(INTVAL (op) >= 0 && INTVAL (op) < 8)")))
+
+;; Return true if OP is a constant in the range 7..15. This is an
+;; acceptable second operand for dictunpack instructions setting a
+;; V4HI mode in the destination register.
+(define_predicate "imm5_operand_dictunpack16"
+ (and (match_code "const_int")
+ (match_test "(INTVAL (op) >= 8 && INTVAL (op) < 16)")))
+
+;; Return true if OP is a constant in the range 15..31. This is an
+;; acceptable second operand for dictunpack instructions setting a
+;; V2SI mode in the destination register.
+(define_predicate "imm5_operand_dictunpack32"
+ (and (match_code "const_int")
+ (match_test "(INTVAL (op) >= 16 && INTVAL (op) < 32)")))
+
+;; Return true if OP is a constant that is representable by a 2-bit
+;; unsigned field. This is an acceptable third operand for
+;; fpcmp*shl instructions.
+(define_predicate "imm2_operand"
+ (and (match_code "const_int")
+ (match_test "SPARC_IMM2_P (INTVAL (op))")))
;; Predicates for miscellaneous instructions.
diff --git a/gcc/config/sparc/sparc-c.c b/gcc/config/sparc/sparc-c.c
index 9603173..4aacfff 100644
--- a/gcc/config/sparc/sparc-c.c
+++ b/gcc/config/sparc/sparc-c.c
@@ -40,7 +40,12 @@ sparc_target_macros (void)
cpp_assert (parse_in, "machine=sparc");
}
- if (TARGET_VIS4)
+ if (TARGET_VIS4B)
+ {
+ cpp_define (parse_in, "__VIS__=0x410");
+ cpp_define (parse_in, "__VIS=0x410");
+ }
+ else if (TARGET_VIS4)
{
cpp_define (parse_in, "__VIS__=0x400");
cpp_define (parse_in, "__VIS=0x400");
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 0644ab5..9f9a29a 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1246,6 +1246,8 @@ dump_target_flag_bits (const int flags)
fprintf (stderr, "VIS3 ");
if (flags & MASK_VIS4)
fprintf (stderr, "VIS4 ");
+ if (flags & MASK_VIS4B)
+ fprintf (stderr, "VIS4B ");
if (flags & MASK_CBCOND)
fprintf (stderr, "CBCOND ");
if (flags & MASK_DEPRECATED_V8_INSNS)
@@ -1365,7 +1367,8 @@ sparc_option_override (void)
MASK_V9|MASK_POPC|MASK_VIS4|MASK_FMAF|MASK_CBCOND|MASK_SUBXC },
/* UltraSPARC M8 */
{ "m8", MASK_ISA,
- MASK_V9|MASK_POPC|MASK_VIS4|MASK_FMAF|MASK_CBCOND|MASK_SUBXC }
+ MASK_V9|MASK_POPC|MASK_VIS4|MASK_FMAF|MASK_CBCOND|MASK_SUBXC
+ |MASK_VIS4B }
};
const struct cpu_table *cpu;
unsigned int i;
@@ -1495,6 +1498,9 @@ sparc_option_override (void)
#ifndef HAVE_AS_SPARC5_VIS4
& ~(MASK_VIS4 | MASK_SUBXC)
#endif
+#ifndef HAVE_AS_SPARC6
+ & ~(MASK_VIS4B)
+#endif
#ifndef HAVE_AS_LEON
& ~(MASK_LEON | MASK_LEON3)
#endif
@@ -1513,11 +1519,15 @@ sparc_option_override (void)
if (TARGET_VIS4)
target_flags |= MASK_VIS3 | MASK_VIS2 | MASK_VIS;
- /* Don't allow -mvis, -mvis2, -mvis3, -mvis4 or -mfmaf if FPU is
- disabled. */
+ /* -mvis4b implies -mvis4, -mvis3, -mvis2 and -mvis */
+ if (TARGET_VIS4B)
+ target_flags |= MASK_VIS4 | MASK_VIS3 | MASK_VIS2 | MASK_VIS;
+
+ /* Don't allow -mvis, -mvis2, -mvis3, -mvis4, -mvis4b and -mfmaf if
+ FPU is disabled. */
if (! TARGET_FPU)
target_flags &= ~(MASK_VIS | MASK_VIS2 | MASK_VIS3 | MASK_VIS4
- | MASK_FMAF);
+ | MASK_VIS4B | MASK_FMAF);
/* -mvis assumes UltraSPARC+, so we are sure v9 instructions
are available; -m64 also implies v9. */
@@ -10384,6 +10394,45 @@ enum sparc_builtins
SPARC_BUILTIN_FPSUBS8,
SPARC_BUILTIN_FPSUBUS8,
SPARC_BUILTIN_FPSUBUS16,
+
+ /* VIS 4.0B builtins. */
+
+ /* Note that all the DICTUNPACK* entries should be kept
+ contiguous. */
+ SPARC_BUILTIN_FIRST_DICTUNPACK,
+ SPARC_BUILTIN_DICTUNPACK8 = SPARC_BUILTIN_FIRST_DICTUNPACK,
+ SPARC_BUILTIN_DICTUNPACK16,
+ SPARC_BUILTIN_DICTUNPACK32,
+ SPARC_BUILTIN_LAST_DICTUNPACK = SPARC_BUILTIN_DICTUNPACK32,
+
+ /* Note that all the FPCMP*SHL entries should be kept
+ contiguous. */
+ SPARC_BUILTIN_FIRST_FPCMPSHL,
+ SPARC_BUILTIN_FPCMPLE8SHL = SPARC_BUILTIN_FIRST_FPCMPSHL,
+ SPARC_BUILTIN_FPCMPGT8SHL,
+ SPARC_BUILTIN_FPCMPEQ8SHL,
+ SPARC_BUILTIN_FPCMPNE8SHL,
+ SPARC_BUILTIN_FPCMPLE16SHL,
+ SPARC_BUILTIN_FPCMPGT16SHL,
+ SPARC_BUILTIN_FPCMPEQ16SHL,
+ SPARC_BUILTIN_FPCMPNE16SHL,
+ SPARC_BUILTIN_FPCMPLE32SHL,
+ SPARC_BUILTIN_FPCMPGT32SHL,
+ SPARC_BUILTIN_FPCMPEQ32SHL,
+ SPARC_BUILTIN_FPCMPNE32SHL,
+ SPARC_BUILTIN_FPCMPULE8SHL,
+ SPARC_BUILTIN_FPCMPUGT8SHL,
+ SPARC_BUILTIN_FPCMPULE16SHL,
+ SPARC_BUILTIN_FPCMPUGT16SHL,
+ SPARC_BUILTIN_FPCMPULE32SHL,
+ SPARC_BUILTIN_FPCMPUGT32SHL,
+ SPARC_BUILTIN_FPCMPDE8SHL,
+ SPARC_BUILTIN_FPCMPDE16SHL,
+ SPARC_BUILTIN_FPCMPDE32SHL,
+ SPARC_BUILTIN_FPCMPUR8SHL,
+ SPARC_BUILTIN_FPCMPUR16SHL,
+ SPARC_BUILTIN_FPCMPUR32SHL,
+ SPARC_BUILTIN_LAST_FPCMPSHL = SPARC_BUILTIN_FPCMPUR32SHL,
SPARC_BUILTIN_MAX
};
@@ -10391,6 +10440,27 @@ enum sparc_builtins
static GTY (()) tree sparc_builtins[(int) SPARC_BUILTIN_MAX];
static enum insn_code sparc_builtins_icode[(int) SPARC_BUILTIN_MAX];
+/* Return true if OPVAL can be used for operand OPNUM of instruction ICODE.
+ The instruction should require a constant operand of some sort. The
+ function prints an error if OPVAL is not valid. */
+
+static int
+check_constant_argument (enum insn_code icode, int opnum, rtx opval)
+{
+ if (GET_CODE (opval) != CONST_INT)
+ {
+ error ("%qs expects a constant argument", insn_data[icode].name);
+ return false;
+ }
+
+ if (!(*insn_data[icode].operand[opnum].predicate) (opval, VOIDmode))
+ {
+ error ("constant argument out of range for %qs", insn_data[icode].name);
+ return false;
+ }
+ return true;
+}
+
/* Add a SPARC builtin function with NAME, ICODE, CODE and TYPE. Return the
function decl or NULL_TREE if the builtin was not added. */
@@ -10484,6 +10554,12 @@ sparc_vis_init_builtins (void)
v8qi, v8qi, 0);
tree si_ftype_v8qi_v8qi = build_function_type_list (intSI_type_node,
v8qi, v8qi, 0);
+ tree v8qi_ftype_df_si = build_function_type_list (v8qi, double_type_node,
+ intSI_type_node, 0);
+ tree v4hi_ftype_df_si = build_function_type_list (v4hi, double_type_node,
+ intSI_type_node, 0);
+ tree v2si_ftype_df_si = build_function_type_list (v2si, double_type_node,
+ intDI_type_node, 0);
tree di_ftype_di_di = build_function_type_list (intDI_type_node,
intDI_type_node,
intDI_type_node, 0);
@@ -10938,6 +11014,156 @@ sparc_vis_init_builtins (void)
def_builtin_const ("__builtin_vis_fpsubus16", CODE_FOR_ussubv4hi3,
SPARC_BUILTIN_FPSUBUS16, v4hi_ftype_v4hi_v4hi);
}
+
+ if (TARGET_VIS4B)
+ {
+ def_builtin_const ("__builtin_vis_dictunpack8", CODE_FOR_dictunpack8,
+ SPARC_BUILTIN_DICTUNPACK8, v8qi_ftype_df_si);
+ def_builtin_const ("__builtin_vis_dictunpack16", CODE_FOR_dictunpack16,
+ SPARC_BUILTIN_DICTUNPACK16, v4hi_ftype_df_si);
+ def_builtin_const ("__builtin_vis_dictunpack32", CODE_FOR_dictunpack32,
+ SPARC_BUILTIN_DICTUNPACK32, v2si_ftype_df_si);
+
+ if (TARGET_ARCH64)
+ {
+ tree di_ftype_v8qi_v8qi_si = build_function_type_list (intDI_type_node,
+ v8qi, v8qi,
+ intSI_type_node, 0);
+ tree di_ftype_v4hi_v4hi_si = build_function_type_list (intDI_type_node,
+ v4hi, v4hi,
+ intSI_type_node, 0);
+ tree di_ftype_v2si_v2si_si = build_function_type_list (intDI_type_node,
+ v2si, v2si,
+ intSI_type_node, 0);
+
+ def_builtin_const ("__builtin_vis_fpcmple8shl", CODE_FOR_fpcmple8dishl,
+ SPARC_BUILTIN_FPCMPLE8SHL, di_ftype_v8qi_v8qi_si);
+ def_builtin_const ("__builtin_vis_fpcmpgt8shl", CODE_FOR_fpcmpgt8dishl,
+ SPARC_BUILTIN_FPCMPGT8SHL, di_ftype_v8qi_v8qi_si);
+ def_builtin_const ("__builtin_vis_fpcmpeq8shl", CODE_FOR_fpcmpeq8dishl,
+ SPARC_BUILTIN_FPCMPEQ8SHL, di_ftype_v8qi_v8qi_si);
+ def_builtin_const ("__builtin_vis_fpcmpne8shl", CODE_FOR_fpcmpne8dishl,
+ SPARC_BUILTIN_FPCMPNE8SHL, di_ftype_v8qi_v8qi_si);
+
+ def_builtin_const ("__builtin_vis_fpcmple16shl", CODE_FOR_fpcmple16dishl,
+ SPARC_BUILTIN_FPCMPLE16SHL, di_ftype_v4hi_v4hi_si);
+ def_builtin_const ("__builtin_vis_fpcmpgt16shl", CODE_FOR_fpcmpgt16dishl,
+ SPARC_BUILTIN_FPCMPGT16SHL, di_ftype_v4hi_v4hi_si);
+ def_builtin_const ("__builtin_vis_fpcmpeq16shl", CODE_FOR_fpcmpeq16dishl,
+ SPARC_BUILTIN_FPCMPEQ16SHL, di_ftype_v4hi_v4hi_si);
+ def_builtin_const ("__builtin_vis_fpcmpne16shl", CODE_FOR_fpcmpne16dishl,
+ SPARC_BUILTIN_FPCMPNE16SHL, di_ftype_v4hi_v4hi_si);
+
+ def_builtin_const ("__builtin_vis_fpcmple32shl", CODE_FOR_fpcmple32dishl,
+ SPARC_BUILTIN_FPCMPLE32SHL, di_ftype_v2si_v2si_si);
+ def_builtin_const ("__builtin_vis_fpcmpgt32shl", CODE_FOR_fpcmpgt32dishl,
+ SPARC_BUILTIN_FPCMPGT32SHL, di_ftype_v2si_v2si_si);
+ def_builtin_const ("__builtin_vis_fpcmpeq32shl", CODE_FOR_fpcmpeq32dishl,
+ SPARC_BUILTIN_FPCMPEQ32SHL, di_ftype_v2si_v2si_si);
+ def_builtin_const ("__builtin_vis_fpcmpne32shl", CODE_FOR_fpcmpne32dishl,
+ SPARC_BUILTIN_FPCMPNE32SHL, di_ftype_v2si_v2si_si);
+
+
+ def_builtin_const ("__builtin_vis_fpcmpule8shl", CODE_FOR_fpcmpule8dishl,
+ SPARC_BUILTIN_FPCMPULE8SHL, di_ftype_v8qi_v8qi_si);
+ def_builtin_const ("__builtin_vis_fpcmpugt8shl", CODE_FOR_fpcmpugt8dishl,
+ SPARC_BUILTIN_FPCMPUGT8SHL, di_ftype_v8qi_v8qi_si);
+
+ def_builtin_const ("__builtin_vis_fpcmpule16shl", CODE_FOR_fpcmpule16dishl,
+ SPARC_BUILTIN_FPCMPULE16SHL, di_ftype_v4hi_v4hi_si);
+ def_builtin_const ("__builtin_vis_fpcmpugt16shl", CODE_FOR_fpcmpugt16dishl,
+ SPARC_BUILTIN_FPCMPUGT16SHL, di_ftype_v4hi_v4hi_si);
+
+ def_builtin_const ("__builtin_vis_fpcmpule32shl", CODE_FOR_fpcmpule32dishl,
+ SPARC_BUILTIN_FPCMPULE32SHL, di_ftype_v2si_v2si_si);
+ def_builtin_const ("__builtin_vis_fpcmpugt32shl", CODE_FOR_fpcmpugt32dishl,
+ SPARC_BUILTIN_FPCMPUGT32SHL, di_ftype_v2si_v2si_si);
+
+ def_builtin_const ("__builtin_vis_fpcmpde8shl", CODE_FOR_fpcmpde8dishl,
+ SPARC_BUILTIN_FPCMPDE8SHL, di_ftype_v8qi_v8qi_si);
+ def_builtin_const ("__builtin_vis_fpcmpde16shl", CODE_FOR_fpcmpde16dishl,
+ SPARC_BUILTIN_FPCMPDE16SHL, di_ftype_v4hi_v4hi_si);
+ def_builtin_const ("__builtin_vis_fpcmpde32shl", CODE_FOR_fpcmpde32dishl,
+ SPARC_BUILTIN_FPCMPDE32SHL, di_ftype_v2si_v2si_si);
+
+ def_builtin_const ("__builtin_vis_fpcmpur8shl", CODE_FOR_fpcmpur8dishl,
+ SPARC_BUILTIN_FPCMPUR8SHL, di_ftype_v8qi_v8qi_si);
+ def_builtin_const ("__builtin_vis_fpcmpur16shl", CODE_FOR_fpcmpur16dishl,
+ SPARC_BUILTIN_FPCMPUR16SHL, di_ftype_v4hi_v4hi_si);
+ def_builtin_const ("__builtin_vis_fpcmpur32shl", CODE_FOR_fpcmpur32dishl,
+ SPARC_BUILTIN_FPCMPUR32SHL, di_ftype_v2si_v2si_si);
+
+ }
+ else
+ {
+ tree si_ftype_v8qi_v8qi_si = build_function_type_list (intSI_type_node,
+ v8qi, v8qi,
+ intSI_type_node, 0);
+ tree si_ftype_v4hi_v4hi_si = build_function_type_list (intSI_type_node,
+ v4hi, v4hi,
+ intSI_type_node, 0);
+ tree si_ftype_v2si_v2si_si = build_function_type_list (intSI_type_node,
+ v2si, v2si,
+ intSI_type_node, 0);
+
+ def_builtin_const ("__builtin_vis_fpcmple8shl", CODE_FOR_fpcmple8sishl,
+ SPARC_BUILTIN_FPCMPLE8SHL, si_ftype_v8qi_v8qi_si);
+ def_builtin_const ("__builtin_vis_fpcmpgt8shl", CODE_FOR_fpcmpgt8sishl,
+ SPARC_BUILTIN_FPCMPGT8SHL, si_ftype_v8qi_v8qi_si);
+ def_builtin_const ("__builtin_vis_fpcmpeq8shl", CODE_FOR_fpcmpeq8sishl,
+ SPARC_BUILTIN_FPCMPEQ8SHL, si_ftype_v8qi_v8qi_si);
+ def_builtin_const ("__builtin_vis_fpcmpne8shl", CODE_FOR_fpcmpne8sishl,
+ SPARC_BUILTIN_FPCMPNE8SHL, si_ftype_v8qi_v8qi_si);
+
+ def_builtin_const ("__builtin_vis_fpcmple16shl", CODE_FOR_fpcmple16sishl,
+ SPARC_BUILTIN_FPCMPLE16SHL, si_ftype_v4hi_v4hi_si);
+ def_builtin_const ("__builtin_vis_fpcmpgt16shl", CODE_FOR_fpcmpgt16sishl,
+ SPARC_BUILTIN_FPCMPGT16SHL, si_ftype_v4hi_v4hi_si);
+ def_builtin_const ("__builtin_vis_fpcmpeq16shl", CODE_FOR_fpcmpeq16sishl,
+ SPARC_BUILTIN_FPCMPEQ16SHL, si_ftype_v4hi_v4hi_si);
+ def_builtin_const ("__builtin_vis_fpcmpne16shl", CODE_FOR_fpcmpne16sishl,
+ SPARC_BUILTIN_FPCMPNE16SHL, si_ftype_v4hi_v4hi_si);
+
+ def_builtin_const ("__builtin_vis_fpcmple32shl", CODE_FOR_fpcmple32sishl,
+ SPARC_BUILTIN_FPCMPLE32SHL, si_ftype_v2si_v2si_si);
+ def_builtin_const ("__builtin_vis_fpcmpgt32shl", CODE_FOR_fpcmpgt32sishl,
+ SPARC_BUILTIN_FPCMPGT32SHL, si_ftype_v2si_v2si_si);
+ def_builtin_const ("__builtin_vis_fpcmpeq32shl", CODE_FOR_fpcmpeq32sishl,
+ SPARC_BUILTIN_FPCMPEQ32SHL, si_ftype_v2si_v2si_si);
+ def_builtin_const ("__builtin_vis_fpcmpne32shl", CODE_FOR_fpcmpne32sishl,
+ SPARC_BUILTIN_FPCMPNE32SHL, si_ftype_v2si_v2si_si);
+
+
+ def_builtin_const ("__builtin_vis_fpcmpule8shl", CODE_FOR_fpcmpule8sishl,
+ SPARC_BUILTIN_FPCMPULE8SHL, si_ftype_v8qi_v8qi_si);
+ def_builtin_const ("__builtin_vis_fpcmpugt8shl", CODE_FOR_fpcmpugt8sishl,
+ SPARC_BUILTIN_FPCMPUGT8SHL, si_ftype_v8qi_v8qi_si);
+
+ def_builtin_const ("__builtin_vis_fpcmpule16shl", CODE_FOR_fpcmpule16sishl,
+ SPARC_BUILTIN_FPCMPULE16SHL, si_ftype_v4hi_v4hi_si);
+ def_builtin_const ("__builtin_vis_fpcmpugt16shl", CODE_FOR_fpcmpugt16sishl,
+ SPARC_BUILTIN_FPCMPUGT16SHL, si_ftype_v4hi_v4hi_si);
+
+ def_builtin_const ("__builtin_vis_fpcmpule32shl", CODE_FOR_fpcmpule32sishl,
+ SPARC_BUILTIN_FPCMPULE32SHL, si_ftype_v2si_v2si_si);
+ def_builtin_const ("__builtin_vis_fpcmpugt32shl", CODE_FOR_fpcmpugt32sishl,
+ SPARC_BUILTIN_FPCMPUGT32SHL, si_ftype_v2si_v2si_si);
+
+ def_builtin_const ("__builtin_vis_fpcmpde8shl", CODE_FOR_fpcmpde8sishl,
+ SPARC_BUILTIN_FPCMPDE8SHL, si_ftype_v8qi_v8qi_si);
+ def_builtin_const ("__builtin_vis_fpcmpde16shl", CODE_FOR_fpcmpde16sishl,
+ SPARC_BUILTIN_FPCMPDE16SHL, si_ftype_v4hi_v4hi_si);
+ def_builtin_const ("__builtin_vis_fpcmpde32shl", CODE_FOR_fpcmpde32sishl,
+ SPARC_BUILTIN_FPCMPDE32SHL, si_ftype_v2si_v2si_si);
+
+ def_builtin_const ("__builtin_vis_fpcmpur8shl", CODE_FOR_fpcmpur8sishl,
+ SPARC_BUILTIN_FPCMPUR8SHL, si_ftype_v8qi_v8qi_si);
+ def_builtin_const ("__builtin_vis_fpcmpur16shl", CODE_FOR_fpcmpur16sishl,
+ SPARC_BUILTIN_FPCMPUR16SHL, si_ftype_v4hi_v4hi_si);
+ def_builtin_const ("__builtin_vis_fpcmpur32shl", CODE_FOR_fpcmpur32sishl,
+ SPARC_BUILTIN_FPCMPUR32SHL, si_ftype_v2si_v2si_si);
+ }
+ }
}
/* Implement TARGET_BUILTIN_DECL hook. */
@@ -10992,6 +11218,19 @@ sparc_expand_builtin (tree exp, rtx target,
insn_op = &insn_data[icode].operand[idx];
op[arg_count] = expand_normal (arg);
+ /* Some of the builtins require constant arguments. We check
+ for this here. */
+ if ((code >= SPARC_BUILTIN_FIRST_FPCMPSHL
+ && code <= SPARC_BUILTIN_LAST_FPCMPSHL
+ && arg_count == 3)
+ || (code >= SPARC_BUILTIN_FIRST_DICTUNPACK
+ && code <= SPARC_BUILTIN_LAST_DICTUNPACK
+ && arg_count == 2))
+ {
+ if (!check_constant_argument (icode, idx, op[arg_count]))
+ return const0_rtx;
+ }
+
if (code == SPARC_BUILTIN_LDFSR || code == SPARC_BUILTIN_STFSR)
{
if (!address_operand (op[arg_count], SImode))
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 2bd667f..d7c617e 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1047,6 +1047,10 @@ extern char leaf_reg_remap[];
/* Local macro to handle the two v9 classes of FP regs. */
#define FP_REG_CLASS_P(CLASS) ((CLASS) == FP_REGS || (CLASS) == EXTRA_FP_REGS)
+/* Predicate for 2-bit and 5-bit unsigned constants. */
+#define SPARC_IMM2_P(X) (((unsigned HOST_WIDE_INT) (X) & ~0x3) == 0)
+#define SPARC_IMM5_P(X) (((unsigned HOST_WIDE_INT) (X) & ~0x1F) == 0)
+
/* Predicates for 5-bit, 10-bit, 11-bit and 13-bit signed constants. */
#define SPARC_SIMM5_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x10 < 0x20)
#define SPARC_SIMM10_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x200 < 0x400)
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index b666992..407544b 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -94,6 +94,12 @@
UNSPEC_ADDV
UNSPEC_SUBV
UNSPEC_NEGV
+
+ UNSPEC_DICTUNPACK
+ UNSPEC_FPCMPSHL
+ UNSPEC_FPUCMPSHL
+ UNSPEC_FPCMPDESHL
+ UNSPEC_FPCMPURSHL
])
(define_c_enum "unspecv" [
@@ -252,7 +258,7 @@
(symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
(const_string "v7"))))
-(define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3,vis4"
+(define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3,vis4,vis4b"
(const_string "none"))
(define_attr "lra" "disabled,enabled"
@@ -266,7 +272,8 @@
(eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9")
(eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS")
(eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3")
- (eq_attr "cpu_feature" "vis4") (symbol_ref "TARGET_VIS4")]
+ (eq_attr "cpu_feature" "vis4") (symbol_ref "TARGET_VIS4")
+ (eq_attr "cpu_feature" "vis4b") (symbol_ref "TARGET_VIS4B")]
(const_int 0)))
;; The SPARC instructions used by the backend are organized into a
@@ -329,7 +336,7 @@
;; fga/maxmin: FP{MAX,MIN}[U]{8,16,32}
;; fga/cmask: CMASK{8,16,32}
;; fga/other: BSHUFFLE FALIGNDATAg FP{ADD,SUB}[S]{8,16,32}
-;; FP{ADD,SUB}US{8,16}
+;; FP{ADD,SUB}US{8,16} DICTUNPACK
;; gsr/reg: RDGSR WRGSR
;; gsr/alignaddr: ALIGNADDRESS[_LITTLE]
;; vismv/double: FSRC2d
@@ -343,6 +350,8 @@
;; visl/double: FONEd FZEROd FNOT1d F{OR,AND,XOR}d F{NOR,NAND,XNOR}d
;; F{OR,AND}NOT1d F{OR,AND}NOT2d
;; viscmp: FPCMP{LE,GT,NE,EQ}{8,16,32} FPCMPU{LE,GT,NE,EQ}{8,16,32}
+;; FPCMP{LE,GT,EQ,NE}{8,16,32}SHL FPCMPU{LE,GT,EQ,NE}{8,16,32}SHL
+;; FPCMPDE{8,16,32}SHL FPCMPUR{8,16,32}SHL
;; fgm_pack: FPACKFIX FPACK{8,16,32}
;; fgm_mul: FMUL8SUx16 FMUL8ULx16 FMUL8x16 FMUL8x16AL
;; FMUL8x16AU FMULD8SUx16 FMULD8ULx16
@@ -9656,4 +9665,62 @@ visl")
[(set_attr "type" "fp")
(set_attr "fptype" "double")])
+;; VIS4B instructions.
+
+(define_mode_iterator DUMODE [V2SI V4HI V8QI])
+
+(define_insn "dictunpack<DUMODE:vbits>"
+ [(set (match_operand:DUMODE 0 "register_operand" "=e")
+ (unspec:DUMODE [(match_operand:DF 1 "register_operand" "e")
+ (match_operand:SI 2 "imm5_operand_dictunpack<DUMODE:vbits>" "t")]
+ UNSPEC_DICTUNPACK))]
+ "TARGET_VIS4B"
+ "dictunpack\t%1, %2, %0"
+ [(set_attr "type" "fga")
+ (set_attr "subtype" "other")])
+
+(define_mode_iterator FPCSMODE [V2SI V4HI V8QI])
+(define_code_iterator fpcscond [le gt eq ne])
+(define_code_iterator fpcsucond [le gt])
+
+(define_insn "fpcmp<fpcscond:code><FPCSMODE:vbits><P:mode>shl"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec:P [(fpcscond:FPCSMODE (match_operand:FPCSMODE 1 "register_operand" "e")
+ (match_operand:FPCSMODE 2 "register_operand" "e"))
+ (match_operand:SI 3 "imm2_operand" "q")]
+ UNSPEC_FPCMPSHL))]
+ "TARGET_VIS4B"
+ "fpcmp<fpcscond:code><FPCSMODE:vbits>shl\t%1, %2, %3, %0"
+ [(set_attr "type" "viscmp")])
+
+(define_insn "fpcmpu<fpcsucond:code><FPCSMODE:vbits><P:mode>shl"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec:P [(fpcsucond:FPCSMODE (match_operand:FPCSMODE 1 "register_operand" "e")
+ (match_operand:FPCSMODE 2 "register_operand" "e"))
+ (match_operand:SI 3 "imm2_operand" "q")]
+ UNSPEC_FPUCMPSHL))]
+ "TARGET_VIS4B"
+ "fpcmpu<fpcsucond:code><FPCSMODE:vbits>shl\t%1, %2, %3, %0"
+ [(set_attr "type" "viscmp")])
+
+(define_insn "fpcmpde<FPCSMODE:vbits><P:mode>shl"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec:P [(match_operand:FPCSMODE 1 "register_operand" "e")
+ (match_operand:FPCSMODE 2 "register_operand" "e")
+ (match_operand:SI 3 "imm2_operand" "q")]
+ UNSPEC_FPCMPDESHL))]
+ "TARGET_VIS4B"
+ "fpcmpde<FPCSMODE:vbits>shl\t%1, %2, %3, %0"
+ [(set_attr "type" "viscmp")])
+
+(define_insn "fpcmpur<FPCSMODE:vbits><P:mode>shl"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec:P [(match_operand:FPCSMODE 1 "register_operand" "e")
+ (match_operand:FPCSMODE 2 "register_operand" "e")
+ (match_operand:SI 3 "imm2_operand" "q")]
+ UNSPEC_FPCMPURSHL))]
+ "TARGET_VIS4B"
+ "fpcmpur<FPCSMODE:vbits>shl\t%1, %2, %3, %0"
+ [(set_attr "type" "viscmp")])
+
(include "sync.md")
diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index 4f30cc4..cc51bd4 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/gcc/config/sparc/sparc.opt
@@ -81,6 +81,10 @@ mvis4
Target Report Mask(VIS4)
Use UltraSPARC Visual Instruction Set version 4.0 extensions.
+mvis4b
+Target Report Mask(VIS4B)
+Use additional VIS instructions introduced in OSA2017.
+
mcbcond
Target Report Mask(CBCOND)
Use UltraSPARC Compare-and-Branch extensions.
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 03ba8fc..07360aa 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -19226,6 +19226,45 @@ v4hi __builtin_vis_fpminu16 (v4hi, v4hi);
v2si __builtin_vis_fpminu32 (v2si, v2si);
@end smallexample
+When you use the @option{-mvis4b} switch, the VIS version 4.0B
+built-in functions also become available:
+
+@smallexample
+v8qi __builtin_vis_dictunpack8 (double, int);
+v4hi __builtin_vis_dictunpack16 (double, int);
+v2si __builtin_vis_dictunpack32 (double, int);
+
+long __builtin_vis_fpcmple8shl (v8qi, v8qi, int);
+long __builtin_vis_fpcmpgt8shl (v8qi, v8qi, int);
+long __builtin_vis_fpcmpeq8shl (v8qi, v8qi, int);
+long __builtin_vis_fpcmpne8shl (v8qi, v8qi, int);
+
+long __builtin_vis_fpcmple16shl (v4hi, v4hi, int);
+long __builtin_vis_fpcmpgt16shl (v4hi, v4hi, int);
+long __builtin_vis_fpcmpeq16shl (v4hi, v4hi, int);
+long __builtin_vis_fpcmpne16shl (v4hi, v4hi, int);
+
+long __builtin_vis_fpcmple32shl (v2si, v2si, int);
+long __builtin_vis_fpcmpgt32shl (v2si, v2si, int);
+long __builtin_vis_fpcmpeq32shl (v2si, v2si, int);
+long __builtin_vis_fpcmpne32shl (v2si, v2si, int);
+
+long __builtin_vis_fpcmpule8shl (v8qi, v8qi, int);
+long __builtin_vis_fpcmpugt8shl (v8qi, v8qi, int);
+long __builtin_vis_fpcmpule16shl (v4hi, v4hi, int);
+long __builtin_vis_fpcmpugt16shl (v4hi, v4hi, int);
+long __builtin_vis_fpcmpule32shl (v2si, v2si, int);
+long __builtin_vis_fpcmpugt32shl (v2si, v2si, int);
+
+long __builtin_vis_fpcmpde8shl (v8qi, v8qi, int);
+long __builtin_vis_fpcmpde16shl (v4hi, v4hi, int);
+long __builtin_vis_fpcmpde32shl (v2si, v2si, int);
+
+long __builtin_vis_fpcmpur8shl (v8qi, v8qi, int);
+long __builtin_vis_fpcmpur16shl (v4hi, v4hi, int);
+long __builtin_vis_fpcmpur32shl (v2si, v2si, int);
+@end smallexample
+
@node SPU Built-in Functions
@subsection SPU Built-in Functions
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d1ce94c..1fd85bc 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1125,6 +1125,7 @@ See RS/6000 and PowerPC Options.
-muser-mode -mno-user-mode @gol
-mv8plus -mno-v8plus -mvis -mno-vis @gol
-mvis2 -mno-vis2 -mvis3 -mno-vis3 @gol
+-mvis4 -mno-vis4 -mvis4b -mno-vis4b @gol
-mcbcond -mno-cbcond -mfmaf -mno-fmaf @gol
-mpopc -mno-popc -msubxc -mno-subxc@gol
-mfix-at697f -mfix-ut699 @gol
@@ -24017,6 +24018,18 @@ default is @option{-mvis4} when targeting a cpu that supports such
instructions, such as niagara-7 and later. Setting @option{-mvis4}
also sets @option{-mvis3}, @option{-mvis2} and @option{-mvis}.
+@item -mvis4b
+@itemx -mno-vis4b
+@opindex mvis4b
+@opindex mno-vis4b
+With @option{-mvis4b}, GCC generates code that takes advantage of
+version 4.0 of the UltraSPARC Visual Instruction Set extensions, plus
+the additional VIS instructions introduced in the Oracle SPARC
+Architecture 2017. The default is @option{-mvis4b} when targeting a
+cpu that supports such instructions, such as m8 and later. Setting
+@option{-mvis4b} also sets @option{-mvis4}, @option{-mvis3},
+@option{-mvis2} and @option{-mvis}.
+
@item -mcbcond
@itemx -mno-cbcond
@opindex mcbcond
diff --git a/gcc/testsuite/gcc.target/sparc/dictunpack.c b/gcc/testsuite/gcc.target/sparc/dictunpack.c
new file mode 100644
index 0000000..4334dee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sparc/dictunpack.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-mvis4b" } */
+
+typedef unsigned char vec8 __attribute__((vector_size(8)));
+typedef short vec16 __attribute__((vector_size(8)));
+typedef int vec32 __attribute__((vector_size(8)));
+
+vec8 test_dictunpack8 (double a)
+{
+ return __builtin_vis_dictunpack8 (a, 6);
+}
+
+vec16 test_dictunpack16 (double a)
+{
+ return __builtin_vis_dictunpack16 (a, 14);
+}
+
+vec32 test_dictunpack32 (double a)
+{
+ return __builtin_vis_dictunpack32 (a, 30);
+}
+
+/* { dg-final { scan-assembler "dictunpack\t%" } } */
+/* { dg-final { scan-assembler "dictunpack\t%" } } */
+/* { dg-final { scan-assembler "dictunpack\t%" } } */
diff --git a/gcc/testsuite/gcc.target/sparc/fpcmpdeshl.c b/gcc/testsuite/gcc.target/sparc/fpcmpdeshl.c
new file mode 100644
index 0000000..3e3daa6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sparc/fpcmpdeshl.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-mvis4b" } */
+
+typedef unsigned char vec8 __attribute__((vector_size(8)));
+typedef short vec16 __attribute__((vector_size(8)));
+typedef int vec32 __attribute__((vector_size(8)));
+
+long test_fpcmpde8shl (vec8 a, vec8 b)
+{
+ return __builtin_vis_fpcmpde8shl (a, b, 2);
+}
+
+long test_fpcmpde16shl (vec16 a, vec16 b)
+{
+ return __builtin_vis_fpcmpde16shl (a, b, 2);
+}
+
+long test_fpcmpde32shl (vec32 a, vec32 b)
+{
+ return __builtin_vis_fpcmpde32shl (a, b, 2);
+}
+
+/* { dg-final { scan-assembler "fpcmpde8shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpde16shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpde32shl\t%" } } */
diff --git a/gcc/testsuite/gcc.target/sparc/fpcmpshl.c b/gcc/testsuite/gcc.target/sparc/fpcmpshl.c
new file mode 100644
index 0000000..0985251
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sparc/fpcmpshl.c
@@ -0,0 +1,81 @@
+/* { dg-do compile } */
+/* { dg-options "-mvis4b" } */
+
+typedef unsigned char vec8 __attribute__((vector_size(8)));
+typedef short vec16 __attribute__((vector_size(8)));
+typedef int vec32 __attribute__((vector_size(8)));
+
+long test_fpcmple8shl (vec8 a, vec8 b)
+{
+ return __builtin_vis_fpcmple8shl (a, b, 2);
+}
+
+long test_fpcmpgt8shl (vec8 a, vec8 b)
+{
+ return __builtin_vis_fpcmpgt8shl (a, b, 2);
+}
+
+long test_fpcmpeq8shl (vec8 a, vec8 b)
+{
+ return __builtin_vis_fpcmpeq8shl (a, b, 2);
+}
+
+long test_fpcmpne8shl (vec8 a, vec8 b)
+{
+ return __builtin_vis_fpcmpne8shl (a, b, 2);
+}
+
+long test_fpcmple16shl (vec16 a, vec16 b)
+{
+ return __builtin_vis_fpcmple16shl (a, b, 2);
+}
+
+long test_fpcmpgt16shl (vec16 a, vec16 b)
+{
+ return __builtin_vis_fpcmpgt16shl (a, b, 2);
+}
+
+long test_fpcmpeq16shl (vec16 a, vec16 b)
+{
+ return __builtin_vis_fpcmpeq16shl (a, b, 2);
+}
+
+long test_fpcmpne16shl (vec16 a, vec16 b)
+{
+ return __builtin_vis_fpcmpne16shl (a, b, 2);
+}
+
+long test_fpcmple32shl (vec32 a, vec32 b)
+{
+ return __builtin_vis_fpcmple32shl (a, b, 2);
+}
+
+long test_fpcmpgt32shl (vec32 a, vec32 b)
+{
+ return __builtin_vis_fpcmpgt32shl (a, b, 2);
+}
+
+long test_fpcmpeq32shl (vec32 a, vec32 b)
+{
+ return __builtin_vis_fpcmpeq32shl (a, b, 2);
+}
+
+long test_fpcmpne32shl (vec32 a, vec32 b)
+{
+ return __builtin_vis_fpcmpne32shl (a, b, 2);
+}
+
+/* { dg-final { scan-assembler "fpcmple8shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpgt8shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpeq8shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpne8shl\t%" } } */
+
+/* { dg-final { scan-assembler "fpcmple16shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpgt16shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpeq16shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpne16shl\t%" } } */
+
+/* { dg-final { scan-assembler "fpcmple32shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpgt32shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpeq32shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpne32shl\t%" } } */
diff --git a/gcc/testsuite/gcc.target/sparc/fpcmpurshl.c b/gcc/testsuite/gcc.target/sparc/fpcmpurshl.c
new file mode 100644
index 0000000..db74e01
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sparc/fpcmpurshl.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-mvis4b" } */
+
+typedef unsigned char vec8 __attribute__((vector_size(8)));
+typedef short vec16 __attribute__((vector_size(8)));
+typedef int vec32 __attribute__((vector_size(8)));
+
+long test_fpcmpur8shl (vec8 a, vec8 b)
+{
+ return __builtin_vis_fpcmpur8shl (a, b, 2);
+}
+
+long test_fpcmpur16shl (vec16 a, vec16 b)
+{
+ return __builtin_vis_fpcmpur16shl (a, b, 2);
+}
+
+long test_fpcmpur32shl (vec32 a, vec32 b)
+{
+ return __builtin_vis_fpcmpur32shl (a, b, 2);
+}
+
+/* { dg-final { scan-assembler "fpcmpur8shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpur16shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpur32shl\t%" } } */
diff --git a/gcc/testsuite/gcc.target/sparc/fpcmpushl.c b/gcc/testsuite/gcc.target/sparc/fpcmpushl.c
new file mode 100644
index 0000000..fc58dedd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sparc/fpcmpushl.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-mvis4b" } */
+
+typedef unsigned char vec8 __attribute__((vector_size(8)));
+typedef short vec16 __attribute__((vector_size(8)));
+typedef int vec32 __attribute__((vector_size(8)));
+
+long test_fpcmpule8shl (vec8 a, vec8 b)
+{
+ return __builtin_vis_fpcmpule8shl (a, b, 2);
+}
+
+long test_fpcmpugt8shl (vec8 a, vec8 b)
+{
+ return __builtin_vis_fpcmpugt8shl (a, b, 2);
+}
+
+long test_fpcmpule16shl (vec16 a, vec16 b)
+{
+ return __builtin_vis_fpcmpule16shl (a, b, 2);
+}
+
+long test_fpcmpugt16shl (vec16 a, vec16 b)
+{
+ return __builtin_vis_fpcmpugt16shl (a, b, 2);
+}
+
+long test_fpcmpule32shl (vec32 a, vec32 b)
+{
+ return __builtin_vis_fpcmpule32shl (a, b, 2);
+}
+
+long test_fpcmpugt32shl (vec32 a, vec32 b)
+{
+ return __builtin_vis_fpcmpugt32shl (a, b, 2);
+}
+
+/* { dg-final { scan-assembler "fpcmpule8shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpugt8shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpule16shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpugt16shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpule32shl\t%" } } */
+/* { dg-final { scan-assembler "fpcmpugt32shl\t%" } } */
--
2.3.4
More information about the Gcc-patches
mailing list