summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2013-12-06 11:31:56 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2013-12-06 11:31:56 +0000
commitd0e8b42e19303eaa9b433a341ac6d42c9ac945ed (patch)
tree696751ad82b90968d6718287d90a84b3fe9b59ba
parent098f44bcc537e52bb5436cb6599346391f3d77b3 (diff)
downloadppe42-gcc-d0e8b42e19303eaa9b433a341ac6d42c9ac945ed.tar.gz
ppe42-gcc-d0e8b42e19303eaa9b433a341ac6d42c9ac945ed.zip
PR target/59316
* config/sparc/sparc.h (SPARC_LOW_FE_EXCEPT_VALUES): Define. * config/sparc/sol2.h (SPARC_LOW_FE_EXCEPT_VALUES): Redefine. * config/sparc/sparc.c (TARGET_INIT_BUILTINS): Move around. (TARGET_BUILTIN_DECL): Define. (TARGET_ATOMIC_ASSIGN_EXPAND_FENV): Likewise. (sparc32_initialize_trampoline): Adjust call to gen_flush. (enum sparc_builtins): New enumeral type. (sparc_builtins): New static array. (sparc_builtins_icode): Likewise. (def_builtin): Accept a separate icode and save the result. (def_builtin_const): Likewise. (sparc_fpu_init_builtins): New function. (sparc_vis_init_builtins): Pass the builtin code. (sparc_init_builtins): Call it if TARGET_FPU. (sparc_builtin_decl): New function. (sparc_expand_builtin): Deal with SPARC_BUILTIN_{LD,ST}FSR. (sparc_handle_vis_mul8x16): Use the builtin code. (sparc_fold_builtin): Likewise. Deal with SPARC_BUILTIN_{LD,ST}FSR and SPARC_BUILTIN_PDISTN. (compound_expr): New helper function. (sparc_atomic_assign_expand_fenv): New function. * config/sparc/sparc.md (unspecv): Reorder values, add UNSPECV_LDFSR and UNSPECV_STFSR. (flush, flushdi): Merge into single pattern. (ldfsr): New instruction. (stfsr): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205735 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog30
-rw-r--r--gcc/config/sparc/sol2.h3
-rw-r--r--gcc/config/sparc/sparc.c701
-rw-r--r--gcc/config/sparc/sparc.h3
-rw-r--r--gcc/config/sparc/sparc.md42
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/sparc/pdistn-2.c16
-rw-r--r--gcc/testsuite/gcc.target/sparc/pdistn.c10
8 files changed, 581 insertions, 229 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2bb33efab5d..662fae31cf2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,33 @@
+2013-12-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR target/59316
+ * config/sparc/sparc.h (SPARC_LOW_FE_EXCEPT_VALUES): Define.
+ * config/sparc/sol2.h (SPARC_LOW_FE_EXCEPT_VALUES): Redefine.
+ * config/sparc/sparc.c (TARGET_INIT_BUILTINS): Move around.
+ (TARGET_BUILTIN_DECL): Define.
+ (TARGET_ATOMIC_ASSIGN_EXPAND_FENV): Likewise.
+ (sparc32_initialize_trampoline): Adjust call to gen_flush.
+ (enum sparc_builtins): New enumeral type.
+ (sparc_builtins): New static array.
+ (sparc_builtins_icode): Likewise.
+ (def_builtin): Accept a separate icode and save the result.
+ (def_builtin_const): Likewise.
+ (sparc_fpu_init_builtins): New function.
+ (sparc_vis_init_builtins): Pass the builtin code.
+ (sparc_init_builtins): Call it if TARGET_FPU.
+ (sparc_builtin_decl): New function.
+ (sparc_expand_builtin): Deal with SPARC_BUILTIN_{LD,ST}FSR.
+ (sparc_handle_vis_mul8x16): Use the builtin code.
+ (sparc_fold_builtin): Likewise. Deal with SPARC_BUILTIN_{LD,ST}FSR
+ and SPARC_BUILTIN_PDISTN.
+ (compound_expr): New helper function.
+ (sparc_atomic_assign_expand_fenv): New function.
+ * config/sparc/sparc.md (unspecv): Reorder values, add UNSPECV_LDFSR
+ and UNSPECV_STFSR.
+ (flush, flushdi): Merge into single pattern.
+ (ldfsr): New instruction.
+ (stfsr): Likewise.
+
2013-12-06 Oleg Endo <olegendo@gcc.gnu.org>
* asan.c: Remove struct tags when referring to class varpool_node.
diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h
index 4010939df6e..c9a3f43fd40 100644
--- a/gcc/config/sparc/sol2.h
+++ b/gcc/config/sparc/sol2.h
@@ -406,3 +406,6 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
#undef SUN_INTEGER_MULTIPLY_64
#define SUN_INTEGER_MULTIPLY_64 1
+
+#undef SPARC_LOW_FE_EXCEPT_VALUES
+#define SPARC_LOW_FE_EXCEPT_VALUES 1
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 983f2fab726..d7456722568 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -570,11 +570,11 @@ static void emit_hard_tfmode_operation (enum rtx_code, rtx *);
static bool sparc_function_ok_for_sibcall (tree, tree);
static void sparc_init_libfuncs (void);
static void sparc_init_builtins (void);
+static void sparc_fpu_init_builtins (void);
static void sparc_vis_init_builtins (void);
+static tree sparc_builtin_decl (unsigned, bool);
static rtx sparc_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
static tree sparc_fold_builtin (tree, int, tree *, bool);
-static int sparc_vis_mul8x16 (int, int);
-static void sparc_handle_vis_mul8x16 (tree *, int, tree, tree, tree);
static void sparc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree);
static bool sparc_can_output_mi_thunk (const_tree, HOST_WIDE_INT,
@@ -638,6 +638,7 @@ static reg_class_t sparc_secondary_reload (bool, rtx, reg_class_t,
enum machine_mode,
secondary_reload_info *);
static enum machine_mode sparc_cstore_mode (enum insn_code icode);
+static void sparc_atomic_assign_expand_fenv (tree *, tree *, tree *);
#ifdef SUBTARGET_ATTRIBUTE_TABLE
/* Table of valid machine attributes. */
@@ -693,8 +694,6 @@ char sparc_hard_reg_printed[8];
#undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS sparc_init_libfuncs
-#undef TARGET_INIT_BUILTINS
-#define TARGET_INIT_BUILTINS sparc_init_builtins
#undef TARGET_LEGITIMIZE_ADDRESS
#define TARGET_LEGITIMIZE_ADDRESS sparc_legitimize_address
@@ -703,6 +702,10 @@ char sparc_hard_reg_printed[8];
#undef TARGET_MODE_DEPENDENT_ADDRESS_P
#define TARGET_MODE_DEPENDENT_ADDRESS_P sparc_mode_dependent_address_p
+#undef TARGET_INIT_BUILTINS
+#define TARGET_INIT_BUILTINS sparc_init_builtins
+#undef TARGET_BUILTIN_DECL
+#define TARGET_BUILTIN_DECL sparc_builtin_decl
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN sparc_expand_builtin
#undef TARGET_FOLD_BUILTIN
@@ -843,6 +846,9 @@ char sparc_hard_reg_printed[8];
#undef TARGET_CSTORE_MODE
#define TARGET_CSTORE_MODE sparc_cstore_mode
+#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
+#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV sparc_atomic_assign_expand_fenv
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Return the memory reference contained in X if any, zero otherwise. */
@@ -9237,14 +9243,14 @@ sparc32_initialize_trampoline (rtx m_tramp, rtx fnaddr, rtx cxt)
/* On UltraSPARC a flush flushes an entire cache line. The trampoline is
aligned on a 16 byte boundary so one flush clears it all. */
- emit_insn (gen_flush (validize_mem (adjust_address (m_tramp, SImode, 0))));
+ emit_insn (gen_flushsi (validize_mem (adjust_address (m_tramp, SImode, 0))));
if (sparc_cpu != PROCESSOR_ULTRASPARC
&& sparc_cpu != PROCESSOR_ULTRASPARC3
&& sparc_cpu != PROCESSOR_NIAGARA
&& sparc_cpu != PROCESSOR_NIAGARA2
&& sparc_cpu != PROCESSOR_NIAGARA3
&& sparc_cpu != PROCESSOR_NIAGARA4)
- emit_insn (gen_flush (validize_mem (adjust_address (m_tramp, SImode, 8))));
+ emit_insn (gen_flushsi (validize_mem (adjust_address (m_tramp, SImode, 8))));
/* Call __enable_execute_stack after writing onto the stack to make sure
the stack address is accessible. */
@@ -9969,15 +9975,145 @@ sparc_init_libfuncs (void)
}
}
-static tree def_builtin(const char *name, int code, tree type)
+/* SPARC builtins. */
+enum sparc_builtins
+{
+ /* FPU builtins. */
+ SPARC_BUILTIN_LDFSR,
+ SPARC_BUILTIN_STFSR,
+
+ /* VIS 1.0 builtins. */
+ SPARC_BUILTIN_FPACK16,
+ SPARC_BUILTIN_FPACK32,
+ SPARC_BUILTIN_FPACKFIX,
+ SPARC_BUILTIN_FEXPAND,
+ SPARC_BUILTIN_FPMERGE,
+ SPARC_BUILTIN_FMUL8X16,
+ SPARC_BUILTIN_FMUL8X16AU,
+ SPARC_BUILTIN_FMUL8X16AL,
+ SPARC_BUILTIN_FMUL8SUX16,
+ SPARC_BUILTIN_FMUL8ULX16,
+ SPARC_BUILTIN_FMULD8SUX16,
+ SPARC_BUILTIN_FMULD8ULX16,
+ SPARC_BUILTIN_FALIGNDATAV4HI,
+ SPARC_BUILTIN_FALIGNDATAV8QI,
+ SPARC_BUILTIN_FALIGNDATAV2SI,
+ SPARC_BUILTIN_FALIGNDATADI,
+ SPARC_BUILTIN_WRGSR,
+ SPARC_BUILTIN_RDGSR,
+ SPARC_BUILTIN_ALIGNADDR,
+ SPARC_BUILTIN_ALIGNADDRL,
+ SPARC_BUILTIN_PDIST,
+ SPARC_BUILTIN_EDGE8,
+ SPARC_BUILTIN_EDGE8L,
+ SPARC_BUILTIN_EDGE16,
+ SPARC_BUILTIN_EDGE16L,
+ SPARC_BUILTIN_EDGE32,
+ SPARC_BUILTIN_EDGE32L,
+ SPARC_BUILTIN_FCMPLE16,
+ SPARC_BUILTIN_FCMPLE32,
+ SPARC_BUILTIN_FCMPNE16,
+ SPARC_BUILTIN_FCMPNE32,
+ SPARC_BUILTIN_FCMPGT16,
+ SPARC_BUILTIN_FCMPGT32,
+ SPARC_BUILTIN_FCMPEQ16,
+ SPARC_BUILTIN_FCMPEQ32,
+ SPARC_BUILTIN_FPADD16,
+ SPARC_BUILTIN_FPADD16S,
+ SPARC_BUILTIN_FPADD32,
+ SPARC_BUILTIN_FPADD32S,
+ SPARC_BUILTIN_FPSUB16,
+ SPARC_BUILTIN_FPSUB16S,
+ SPARC_BUILTIN_FPSUB32,
+ SPARC_BUILTIN_FPSUB32S,
+ SPARC_BUILTIN_ARRAY8,
+ SPARC_BUILTIN_ARRAY16,
+ SPARC_BUILTIN_ARRAY32,
+
+ /* VIS 2.0 builtins. */
+ SPARC_BUILTIN_EDGE8N,
+ SPARC_BUILTIN_EDGE8LN,
+ SPARC_BUILTIN_EDGE16N,
+ SPARC_BUILTIN_EDGE16LN,
+ SPARC_BUILTIN_EDGE32N,
+ SPARC_BUILTIN_EDGE32LN,
+ SPARC_BUILTIN_BMASK,
+ SPARC_BUILTIN_BSHUFFLEV4HI,
+ SPARC_BUILTIN_BSHUFFLEV8QI,
+ SPARC_BUILTIN_BSHUFFLEV2SI,
+ SPARC_BUILTIN_BSHUFFLEDI,
+
+ /* VIS 3.0 builtins. */
+ SPARC_BUILTIN_CMASK8,
+ SPARC_BUILTIN_CMASK16,
+ SPARC_BUILTIN_CMASK32,
+ SPARC_BUILTIN_FCHKSM16,
+ SPARC_BUILTIN_FSLL16,
+ SPARC_BUILTIN_FSLAS16,
+ SPARC_BUILTIN_FSRL16,
+ SPARC_BUILTIN_FSRA16,
+ SPARC_BUILTIN_FSLL32,
+ SPARC_BUILTIN_FSLAS32,
+ SPARC_BUILTIN_FSRL32,
+ SPARC_BUILTIN_FSRA32,
+ SPARC_BUILTIN_PDISTN,
+ SPARC_BUILTIN_FMEAN16,
+ SPARC_BUILTIN_FPADD64,
+ SPARC_BUILTIN_FPSUB64,
+ SPARC_BUILTIN_FPADDS16,
+ SPARC_BUILTIN_FPADDS16S,
+ SPARC_BUILTIN_FPSUBS16,
+ SPARC_BUILTIN_FPSUBS16S,
+ SPARC_BUILTIN_FPADDS32,
+ SPARC_BUILTIN_FPADDS32S,
+ SPARC_BUILTIN_FPSUBS32,
+ SPARC_BUILTIN_FPSUBS32S,
+ SPARC_BUILTIN_FUCMPLE8,
+ SPARC_BUILTIN_FUCMPNE8,
+ SPARC_BUILTIN_FUCMPGT8,
+ SPARC_BUILTIN_FUCMPEQ8,
+ SPARC_BUILTIN_FHADDS,
+ SPARC_BUILTIN_FHADDD,
+ SPARC_BUILTIN_FHSUBS,
+ SPARC_BUILTIN_FHSUBD,
+ SPARC_BUILTIN_FNHADDS,
+ SPARC_BUILTIN_FNHADDD,
+ SPARC_BUILTIN_UMULXHI,
+ SPARC_BUILTIN_XMULX,
+ SPARC_BUILTIN_XMULXHI,
+
+ SPARC_BUILTIN_MAX
+};
+
+static GTY (()) tree sparc_builtins[(int) SPARC_BUILTIN_MAX];
+static enum insn_code sparc_builtins_icode[(int) SPARC_BUILTIN_MAX];
+
+/* Add a SPARC builtin function with NAME, ICODE, CODE and TYPE. Return the
+ function decl or NULL_TREE if the builtin was not added. */
+
+static tree
+def_builtin (const char *name, enum insn_code icode, enum sparc_builtins code,
+ tree type)
{
- return add_builtin_function(name, type, code, BUILT_IN_MD, NULL,
- NULL_TREE);
+ tree t
+ = add_builtin_function (name, type, code, BUILT_IN_MD, NULL, NULL_TREE);
+
+ if (t)
+ {
+ sparc_builtins[code] = t;
+ sparc_builtins_icode[code] = icode;
+ }
+
+ return t;
}
-static tree def_builtin_const(const char *name, int code, tree type)
+/* Likewise, but also marks the function as "const". */
+
+static tree
+def_builtin_const (const char *name, enum insn_code icode,
+ enum sparc_builtins code, tree type)
{
- tree t = def_builtin(name, code, type);
+ tree t = def_builtin (name, icode, code, type);
if (t)
TREE_READONLY (t) = 1;
@@ -9991,11 +10127,28 @@ static tree def_builtin_const(const char *name, int code, tree type)
static void
sparc_init_builtins (void)
{
+ if (TARGET_FPU)
+ sparc_fpu_init_builtins ();
+
if (TARGET_VIS)
sparc_vis_init_builtins ();
}
-/* Create builtin functions for VIS 1.0 instructions. */
+/* Create builtin functions for FPU instructions. */
+
+static void
+sparc_fpu_init_builtins (void)
+{
+ tree ftype
+ = build_function_type_list (void_type_node,
+ build_pointer_type (unsigned_type_node), 0);
+ def_builtin ("__builtin_load_fsr", CODE_FOR_ldfsr,
+ SPARC_BUILTIN_LDFSR, ftype);
+ def_builtin ("__builtin_store_fsr", CODE_FOR_stfsr,
+ SPARC_BUILTIN_STFSR, ftype);
+}
+
+/* Create builtin functions for VIS instructions. */
static void
sparc_vis_init_builtins (void)
@@ -10069,223 +10222,225 @@ sparc_vis_init_builtins (void)
/* Packing and expanding vectors. */
def_builtin ("__builtin_vis_fpack16", CODE_FOR_fpack16_vis,
- v4qi_ftype_v4hi);
+ SPARC_BUILTIN_FPACK16, v4qi_ftype_v4hi);
def_builtin ("__builtin_vis_fpack32", CODE_FOR_fpack32_vis,
- v8qi_ftype_v2si_v8qi);
+ SPARC_BUILTIN_FPACK32, v8qi_ftype_v2si_v8qi);
def_builtin ("__builtin_vis_fpackfix", CODE_FOR_fpackfix_vis,
- v2hi_ftype_v2si);
+ SPARC_BUILTIN_FPACKFIX, v2hi_ftype_v2si);
def_builtin_const ("__builtin_vis_fexpand", CODE_FOR_fexpand_vis,
- v4hi_ftype_v4qi);
+ SPARC_BUILTIN_FEXPAND, v4hi_ftype_v4qi);
def_builtin_const ("__builtin_vis_fpmerge", CODE_FOR_fpmerge_vis,
- v8qi_ftype_v4qi_v4qi);
+ SPARC_BUILTIN_FPMERGE, v8qi_ftype_v4qi_v4qi);
/* Multiplications. */
def_builtin_const ("__builtin_vis_fmul8x16", CODE_FOR_fmul8x16_vis,
- v4hi_ftype_v4qi_v4hi);
+ SPARC_BUILTIN_FMUL8X16, v4hi_ftype_v4qi_v4hi);
def_builtin_const ("__builtin_vis_fmul8x16au", CODE_FOR_fmul8x16au_vis,
- v4hi_ftype_v4qi_v2hi);
+ SPARC_BUILTIN_FMUL8X16AU, v4hi_ftype_v4qi_v2hi);
def_builtin_const ("__builtin_vis_fmul8x16al", CODE_FOR_fmul8x16al_vis,
- v4hi_ftype_v4qi_v2hi);
+ SPARC_BUILTIN_FMUL8X16AL, v4hi_ftype_v4qi_v2hi);
def_builtin_const ("__builtin_vis_fmul8sux16", CODE_FOR_fmul8sux16_vis,
- v4hi_ftype_v8qi_v4hi);
+ SPARC_BUILTIN_FMUL8SUX16, v4hi_ftype_v8qi_v4hi);
def_builtin_const ("__builtin_vis_fmul8ulx16", CODE_FOR_fmul8ulx16_vis,
- v4hi_ftype_v8qi_v4hi);
+ SPARC_BUILTIN_FMUL8ULX16, v4hi_ftype_v8qi_v4hi);
def_builtin_const ("__builtin_vis_fmuld8sux16", CODE_FOR_fmuld8sux16_vis,
- v2si_ftype_v4qi_v2hi);
+ SPARC_BUILTIN_FMULD8SUX16, v2si_ftype_v4qi_v2hi);
def_builtin_const ("__builtin_vis_fmuld8ulx16", CODE_FOR_fmuld8ulx16_vis,
- v2si_ftype_v4qi_v2hi);
+ SPARC_BUILTIN_FMULD8ULX16, v2si_ftype_v4qi_v2hi);
/* Data aligning. */
def_builtin ("__builtin_vis_faligndatav4hi", CODE_FOR_faligndatav4hi_vis,
- v4hi_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FALIGNDATAV4HI, v4hi_ftype_v4hi_v4hi);
def_builtin ("__builtin_vis_faligndatav8qi", CODE_FOR_faligndatav8qi_vis,
- v8qi_ftype_v8qi_v8qi);
+ SPARC_BUILTIN_FALIGNDATAV8QI, v8qi_ftype_v8qi_v8qi);
def_builtin ("__builtin_vis_faligndatav2si", CODE_FOR_faligndatav2si_vis,
- v2si_ftype_v2si_v2si);
+ SPARC_BUILTIN_FALIGNDATAV2SI, v2si_ftype_v2si_v2si);
def_builtin ("__builtin_vis_faligndatadi", CODE_FOR_faligndatav1di_vis,
- di_ftype_di_di);
+ SPARC_BUILTIN_FALIGNDATADI, di_ftype_di_di);
def_builtin ("__builtin_vis_write_gsr", CODE_FOR_wrgsr_vis,
- void_ftype_di);
+ SPARC_BUILTIN_WRGSR, void_ftype_di);
def_builtin ("__builtin_vis_read_gsr", CODE_FOR_rdgsr_vis,
- di_ftype_void);
+ SPARC_BUILTIN_RDGSR, di_ftype_void);
if (TARGET_ARCH64)
{
def_builtin ("__builtin_vis_alignaddr", CODE_FOR_alignaddrdi_vis,
- ptr_ftype_ptr_di);
+ SPARC_BUILTIN_ALIGNADDR, ptr_ftype_ptr_di);
def_builtin ("__builtin_vis_alignaddrl", CODE_FOR_alignaddrldi_vis,
- ptr_ftype_ptr_di);
+ SPARC_BUILTIN_ALIGNADDRL, ptr_ftype_ptr_di);
}
else
{
def_builtin ("__builtin_vis_alignaddr", CODE_FOR_alignaddrsi_vis,
- ptr_ftype_ptr_si);
+ SPARC_BUILTIN_ALIGNADDR, ptr_ftype_ptr_si);
def_builtin ("__builtin_vis_alignaddrl", CODE_FOR_alignaddrlsi_vis,
- ptr_ftype_ptr_si);
+ SPARC_BUILTIN_ALIGNADDRL, ptr_ftype_ptr_si);
}
/* Pixel distance. */
def_builtin_const ("__builtin_vis_pdist", CODE_FOR_pdist_vis,
- di_ftype_v8qi_v8qi_di);
+ SPARC_BUILTIN_PDIST, di_ftype_v8qi_v8qi_di);
/* Edge handling. */
if (TARGET_ARCH64)
{
def_builtin_const ("__builtin_vis_edge8", CODE_FOR_edge8di_vis,
- di_ftype_ptr_ptr);
+ SPARC_BUILTIN_EDGE8, di_ftype_ptr_ptr);
def_builtin_const ("__builtin_vis_edge8l", CODE_FOR_edge8ldi_vis,
- di_ftype_ptr_ptr);
+ SPARC_BUILTIN_EDGE8L, di_ftype_ptr_ptr);
def_builtin_const ("__builtin_vis_edge16", CODE_FOR_edge16di_vis,
- di_ftype_ptr_ptr);
+ SPARC_BUILTIN_EDGE16, di_ftype_ptr_ptr);
def_builtin_const ("__builtin_vis_edge16l", CODE_FOR_edge16ldi_vis,
- di_ftype_ptr_ptr);
+ SPARC_BUILTIN_EDGE16L, di_ftype_ptr_ptr);
def_builtin_const ("__builtin_vis_edge32", CODE_FOR_edge32di_vis,
- di_ftype_ptr_ptr);
+ SPARC_BUILTIN_EDGE32, di_ftype_ptr_ptr);
def_builtin_const ("__builtin_vis_edge32l", CODE_FOR_edge32ldi_vis,
- di_ftype_ptr_ptr);
- if (TARGET_VIS2)
- {
- def_builtin_const ("__builtin_vis_edge8n", CODE_FOR_edge8ndi_vis,
- di_ftype_ptr_ptr);
- def_builtin_const ("__builtin_vis_edge8ln", CODE_FOR_edge8lndi_vis,
- di_ftype_ptr_ptr);
- def_builtin_const ("__builtin_vis_edge16n", CODE_FOR_edge16ndi_vis,
- di_ftype_ptr_ptr);
- def_builtin_const ("__builtin_vis_edge16ln", CODE_FOR_edge16lndi_vis,
- di_ftype_ptr_ptr);
- def_builtin_const ("__builtin_vis_edge32n", CODE_FOR_edge32ndi_vis,
- di_ftype_ptr_ptr);
- def_builtin_const ("__builtin_vis_edge32ln", CODE_FOR_edge32lndi_vis,
- di_ftype_ptr_ptr);
- }
+ SPARC_BUILTIN_EDGE32L, di_ftype_ptr_ptr);
}
else
{
def_builtin_const ("__builtin_vis_edge8", CODE_FOR_edge8si_vis,
- si_ftype_ptr_ptr);
+ SPARC_BUILTIN_EDGE8, si_ftype_ptr_ptr);
def_builtin_const ("__builtin_vis_edge8l", CODE_FOR_edge8lsi_vis,
- si_ftype_ptr_ptr);
+ SPARC_BUILTIN_EDGE8L, si_ftype_ptr_ptr);
def_builtin_const ("__builtin_vis_edge16", CODE_FOR_edge16si_vis,
- si_ftype_ptr_ptr);
+ SPARC_BUILTIN_EDGE16, si_ftype_ptr_ptr);
def_builtin_const ("__builtin_vis_edge16l", CODE_FOR_edge16lsi_vis,
- si_ftype_ptr_ptr);
+ SPARC_BUILTIN_EDGE16L, si_ftype_ptr_ptr);
def_builtin_const ("__builtin_vis_edge32", CODE_FOR_edge32si_vis,
- si_ftype_ptr_ptr);
+ SPARC_BUILTIN_EDGE32, si_ftype_ptr_ptr);
def_builtin_const ("__builtin_vis_edge32l", CODE_FOR_edge32lsi_vis,
- si_ftype_ptr_ptr);
- if (TARGET_VIS2)
- {
- def_builtin_const ("__builtin_vis_edge8n", CODE_FOR_edge8nsi_vis,
- si_ftype_ptr_ptr);
- def_builtin_const ("__builtin_vis_edge8ln", CODE_FOR_edge8lnsi_vis,
- si_ftype_ptr_ptr);
- def_builtin_const ("__builtin_vis_edge16n", CODE_FOR_edge16nsi_vis,
- si_ftype_ptr_ptr);
- def_builtin_const ("__builtin_vis_edge16ln", CODE_FOR_edge16lnsi_vis,
- si_ftype_ptr_ptr);
- def_builtin_const ("__builtin_vis_edge32n", CODE_FOR_edge32nsi_vis,
- si_ftype_ptr_ptr);
- def_builtin_const ("__builtin_vis_edge32ln", CODE_FOR_edge32lnsi_vis,
- si_ftype_ptr_ptr);
- }
+ SPARC_BUILTIN_EDGE32L, si_ftype_ptr_ptr);
}
/* Pixel compare. */
if (TARGET_ARCH64)
{
def_builtin_const ("__builtin_vis_fcmple16", CODE_FOR_fcmple16di_vis,
- di_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FCMPLE16, di_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fcmple32", CODE_FOR_fcmple32di_vis,
- di_ftype_v2si_v2si);
+ SPARC_BUILTIN_FCMPLE32, di_ftype_v2si_v2si);
def_builtin_const ("__builtin_vis_fcmpne16", CODE_FOR_fcmpne16di_vis,
- di_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FCMPNE16, di_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fcmpne32", CODE_FOR_fcmpne32di_vis,
- di_ftype_v2si_v2si);
+ SPARC_BUILTIN_FCMPNE32, di_ftype_v2si_v2si);
def_builtin_const ("__builtin_vis_fcmpgt16", CODE_FOR_fcmpgt16di_vis,
- di_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FCMPGT16, di_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fcmpgt32", CODE_FOR_fcmpgt32di_vis,
- di_ftype_v2si_v2si);
+ SPARC_BUILTIN_FCMPGT32, di_ftype_v2si_v2si);
def_builtin_const ("__builtin_vis_fcmpeq16", CODE_FOR_fcmpeq16di_vis,
- di_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FCMPEQ16, di_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fcmpeq32", CODE_FOR_fcmpeq32di_vis,
- di_ftype_v2si_v2si);
+ SPARC_BUILTIN_FCMPEQ32, di_ftype_v2si_v2si);
}
else
{
def_builtin_const ("__builtin_vis_fcmple16", CODE_FOR_fcmple16si_vis,
- si_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FCMPLE16, si_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fcmple32", CODE_FOR_fcmple32si_vis,
- si_ftype_v2si_v2si);
+ SPARC_BUILTIN_FCMPLE32, si_ftype_v2si_v2si);
def_builtin_const ("__builtin_vis_fcmpne16", CODE_FOR_fcmpne16si_vis,
- si_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FCMPNE16, si_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fcmpne32", CODE_FOR_fcmpne32si_vis,
- si_ftype_v2si_v2si);
+ SPARC_BUILTIN_FCMPNE32, si_ftype_v2si_v2si);
def_builtin_const ("__builtin_vis_fcmpgt16", CODE_FOR_fcmpgt16si_vis,
- si_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FCMPGT16, si_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fcmpgt32", CODE_FOR_fcmpgt32si_vis,
- si_ftype_v2si_v2si);
+ SPARC_BUILTIN_FCMPGT32, si_ftype_v2si_v2si);
def_builtin_const ("__builtin_vis_fcmpeq16", CODE_FOR_fcmpeq16si_vis,
- si_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FCMPEQ16, si_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fcmpeq32", CODE_FOR_fcmpeq32si_vis,
- si_ftype_v2si_v2si);
+ SPARC_BUILTIN_FCMPEQ32, si_ftype_v2si_v2si);
}
/* Addition and subtraction. */
def_builtin_const ("__builtin_vis_fpadd16", CODE_FOR_addv4hi3,
- v4hi_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FPADD16, v4hi_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fpadd16s", CODE_FOR_addv2hi3,
- v2hi_ftype_v2hi_v2hi);
+ SPARC_BUILTIN_FPADD16S, v2hi_ftype_v2hi_v2hi);
def_builtin_const ("__builtin_vis_fpadd32", CODE_FOR_addv2si3,
- v2si_ftype_v2si_v2si);
+ SPARC_BUILTIN_FPADD32, v2si_ftype_v2si_v2si);
def_builtin_const ("__builtin_vis_fpadd32s", CODE_FOR_addv1si3,
- v1si_ftype_v1si_v1si);
+ SPARC_BUILTIN_FPADD32S, v1si_ftype_v1si_v1si);
def_builtin_const ("__builtin_vis_fpsub16", CODE_FOR_subv4hi3,
- v4hi_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FPSUB16, v4hi_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fpsub16s", CODE_FOR_subv2hi3,
- v2hi_ftype_v2hi_v2hi);
+ SPARC_BUILTIN_FPSUB16S, v2hi_ftype_v2hi_v2hi);
def_builtin_const ("__builtin_vis_fpsub32", CODE_FOR_subv2si3,
- v2si_ftype_v2si_v2si);
+ SPARC_BUILTIN_FPSUB32, v2si_ftype_v2si_v2si);
def_builtin_const ("__builtin_vis_fpsub32s", CODE_FOR_subv1si3,
- v1si_ftype_v1si_v1si);
+ SPARC_BUILTIN_FPSUB32S, v1si_ftype_v1si_v1si);
/* Three-dimensional array addressing. */
if (TARGET_ARCH64)
{
def_builtin_const ("__builtin_vis_array8", CODE_FOR_array8di_vis,
- di_ftype_di_di);
+ SPARC_BUILTIN_ARRAY8, di_ftype_di_di);
def_builtin_const ("__builtin_vis_array16", CODE_FOR_array16di_vis,
- di_ftype_di_di);
+ SPARC_BUILTIN_ARRAY16, di_ftype_di_di);
def_builtin_const ("__builtin_vis_array32", CODE_FOR_array32di_vis,
- di_ftype_di_di);
+ SPARC_BUILTIN_ARRAY32, di_ftype_di_di);
}
else
{
def_builtin_const ("__builtin_vis_array8", CODE_FOR_array8si_vis,
- si_ftype_si_si);
+ SPARC_BUILTIN_ARRAY8, si_ftype_si_si);
def_builtin_const ("__builtin_vis_array16", CODE_FOR_array16si_vis,
- si_ftype_si_si);
+ SPARC_BUILTIN_ARRAY16, si_ftype_si_si);
def_builtin_const ("__builtin_vis_array32", CODE_FOR_array32si_vis,
- si_ftype_si_si);
- }
+ SPARC_BUILTIN_ARRAY32, si_ftype_si_si);
+ }
if (TARGET_VIS2)
{
- /* Byte mask and shuffle */
+ /* Edge handling. */
+ if (TARGET_ARCH64)
+ {
+ def_builtin_const ("__builtin_vis_edge8n", CODE_FOR_edge8ndi_vis,
+ SPARC_BUILTIN_EDGE8N, di_ftype_ptr_ptr);
+ def_builtin_const ("__builtin_vis_edge8ln", CODE_FOR_edge8lndi_vis,
+ SPARC_BUILTIN_EDGE8LN, di_ftype_ptr_ptr);
+ def_builtin_const ("__builtin_vis_edge16n", CODE_FOR_edge16ndi_vis,
+ SPARC_BUILTIN_EDGE16N, di_ftype_ptr_ptr);
+ def_builtin_const ("__builtin_vis_edge16ln", CODE_FOR_edge16lndi_vis,
+ SPARC_BUILTIN_EDGE16LN, di_ftype_ptr_ptr);
+ def_builtin_const ("__builtin_vis_edge32n", CODE_FOR_edge32ndi_vis,
+ SPARC_BUILTIN_EDGE32N, di_ftype_ptr_ptr);
+ def_builtin_const ("__builtin_vis_edge32ln", CODE_FOR_edge32lndi_vis,
+ SPARC_BUILTIN_EDGE32LN, di_ftype_ptr_ptr);
+ }
+ else
+ {
+ def_builtin_const ("__builtin_vis_edge8n", CODE_FOR_edge8nsi_vis,
+ SPARC_BUILTIN_EDGE8N, si_ftype_ptr_ptr);
+ def_builtin_const ("__builtin_vis_edge8ln", CODE_FOR_edge8lnsi_vis,
+ SPARC_BUILTIN_EDGE8LN, si_ftype_ptr_ptr);
+ def_builtin_const ("__builtin_vis_edge16n", CODE_FOR_edge16nsi_vis,
+ SPARC_BUILTIN_EDGE16N, si_ftype_ptr_ptr);
+ def_builtin_const ("__builtin_vis_edge16ln", CODE_FOR_edge16lnsi_vis,
+ SPARC_BUILTIN_EDGE16LN, si_ftype_ptr_ptr);
+ def_builtin_const ("__builtin_vis_edge32n", CODE_FOR_edge32nsi_vis,
+ SPARC_BUILTIN_EDGE32N, si_ftype_ptr_ptr);
+ def_builtin_const ("__builtin_vis_edge32ln", CODE_FOR_edge32lnsi_vis,
+ SPARC_BUILTIN_EDGE32LN, si_ftype_ptr_ptr);
+ }
+
+ /* Byte mask and shuffle. */
if (TARGET_ARCH64)
def_builtin ("__builtin_vis_bmask", CODE_FOR_bmaskdi_vis,
- di_ftype_di_di);
+ SPARC_BUILTIN_BMASK, di_ftype_di_di);
else
def_builtin ("__builtin_vis_bmask", CODE_FOR_bmasksi_vis,
- si_ftype_si_si);
+ SPARC_BUILTIN_BMASK, si_ftype_si_si);
def_builtin ("__builtin_vis_bshufflev4hi", CODE_FOR_bshufflev4hi_vis,
- v4hi_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_BSHUFFLEV4HI, v4hi_ftype_v4hi_v4hi);
def_builtin ("__builtin_vis_bshufflev8qi", CODE_FOR_bshufflev8qi_vis,
- v8qi_ftype_v8qi_v8qi);
+ SPARC_BUILTIN_BSHUFFLEV8QI, v8qi_ftype_v8qi_v8qi);
def_builtin ("__builtin_vis_bshufflev2si", CODE_FOR_bshufflev2si_vis,
- v2si_ftype_v2si_v2si);
+ SPARC_BUILTIN_BSHUFFLEV2SI, v2si_ftype_v2si_v2si);
def_builtin ("__builtin_vis_bshuffledi", CODE_FOR_bshufflev1di_vis,
- di_ftype_di_di);
+ SPARC_BUILTIN_BSHUFFLEDI, di_ftype_di_di);
}
if (TARGET_VIS3)
@@ -10293,120 +10448,130 @@ sparc_vis_init_builtins (void)
if (TARGET_ARCH64)
{
def_builtin ("__builtin_vis_cmask8", CODE_FOR_cmask8di_vis,
- void_ftype_di);
+ SPARC_BUILTIN_CMASK8, void_ftype_di);
def_builtin ("__builtin_vis_cmask16", CODE_FOR_cmask16di_vis,
- void_ftype_di);
+ SPARC_BUILTIN_CMASK16, void_ftype_di);
def_builtin ("__builtin_vis_cmask32", CODE_FOR_cmask32di_vis,
- void_ftype_di);
+ SPARC_BUILTIN_CMASK32, void_ftype_di);
}
else
{
def_builtin ("__builtin_vis_cmask8", CODE_FOR_cmask8si_vis,
- void_ftype_si);
+ SPARC_BUILTIN_CMASK8, void_ftype_si);
def_builtin ("__builtin_vis_cmask16", CODE_FOR_cmask16si_vis,
- void_ftype_si);
+ SPARC_BUILTIN_CMASK16, void_ftype_si);
def_builtin ("__builtin_vis_cmask32", CODE_FOR_cmask32si_vis,
- void_ftype_si);
+ SPARC_BUILTIN_CMASK32, void_ftype_si);
}
def_builtin_const ("__builtin_vis_fchksm16", CODE_FOR_fchksm16_vis,
- v4hi_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FCHKSM16, v4hi_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fsll16", CODE_FOR_vashlv4hi3,
- v4hi_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FSLL16, v4hi_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fslas16", CODE_FOR_vssashlv4hi3,
- v4hi_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FSLAS16, v4hi_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fsrl16", CODE_FOR_vlshrv4hi3,
- v4hi_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FSRL16, v4hi_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fsra16", CODE_FOR_vashrv4hi3,
- v4hi_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FSRA16, v4hi_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fsll32", CODE_FOR_vashlv2si3,
- v2si_ftype_v2si_v2si);
+ SPARC_BUILTIN_FSLL32, v2si_ftype_v2si_v2si);
def_builtin_const ("__builtin_vis_fslas32", CODE_FOR_vssashlv2si3,
- v2si_ftype_v2si_v2si);
+ SPARC_BUILTIN_FSLAS32, v2si_ftype_v2si_v2si);
def_builtin_const ("__builtin_vis_fsrl32", CODE_FOR_vlshrv2si3,
- v2si_ftype_v2si_v2si);
+ SPARC_BUILTIN_FSRL32, v2si_ftype_v2si_v2si);
def_builtin_const ("__builtin_vis_fsra32", CODE_FOR_vashrv2si3,
- v2si_ftype_v2si_v2si);
+ SPARC_BUILTIN_FSRA32, v2si_ftype_v2si_v2si);
if (TARGET_ARCH64)
def_builtin_const ("__builtin_vis_pdistn", CODE_FOR_pdistndi_vis,
- di_ftype_v8qi_v8qi);
+ SPARC_BUILTIN_PDISTN, di_ftype_v8qi_v8qi);
else
def_builtin_const ("__builtin_vis_pdistn", CODE_FOR_pdistnsi_vis,
- si_ftype_v8qi_v8qi);
+ SPARC_BUILTIN_PDISTN, si_ftype_v8qi_v8qi);
def_builtin_const ("__builtin_vis_fmean16", CODE_FOR_fmean16_vis,
- v4hi_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FMEAN16, v4hi_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fpadd64", CODE_FOR_fpadd64_vis,
- di_ftype_di_di);
+ SPARC_BUILTIN_FPADD64, di_ftype_di_di);
def_builtin_const ("__builtin_vis_fpsub64", CODE_FOR_fpsub64_vis,
- di_ftype_di_di);
+ SPARC_BUILTIN_FPSUB64, di_ftype_di_di);
def_builtin_const ("__builtin_vis_fpadds16", CODE_FOR_ssaddv4hi3,
- v4hi_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FPADDS16, v4hi_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fpadds16s", CODE_FOR_ssaddv2hi3,
- v2hi_ftype_v2hi_v2hi);
+ SPARC_BUILTIN_FPADDS16S, v2hi_ftype_v2hi_v2hi);
def_builtin_const ("__builtin_vis_fpsubs16", CODE_FOR_sssubv4hi3,
- v4hi_ftype_v4hi_v4hi);
+ SPARC_BUILTIN_FPSUBS16, v4hi_ftype_v4hi_v4hi);
def_builtin_const ("__builtin_vis_fpsubs16s", CODE_FOR_sssubv2hi3,
- v2hi_ftype_v2hi_v2hi);
+ SPARC_BUILTIN_FPSUBS16S, v2hi_ftype_v2hi_v2hi);
def_builtin_const ("__builtin_vis_fpadds32", CODE_FOR_ssaddv2si3,
- v2si_ftype_v2si_v2si);
+ SPARC_BUILTIN_FPADDS32, v2si_ftype_v2si_v2si);
def_builtin_const ("__builtin_vis_fpadds32s", CODE_FOR_ssaddv1si3,
- v1si_ftype_v1si_v1si);
+ SPARC_BUILTIN_FPADDS32S, v1si_ftype_v1si_v1si);
def_builtin_const ("__builtin_vis_fpsubs32", CODE_FOR_sssubv2si3,
- v2si_ftype_v2si_v2si);
+ SPARC_BUILTIN_FPSUBS32, v2si_ftype_v2si_v2si);
def_builtin_const ("__builtin_vis_fpsubs32s", CODE_FOR_sssubv1si3,
- v1si_ftype_v1si_v1si);
+ SPARC_BUILTIN_FPSUBS32S, v1si_ftype_v1si_v1si);
if (TARGET_ARCH64)
{
def_builtin_const ("__builtin_vis_fucmple8", CODE_FOR_fucmple8di_vis,
- di_ftype_v8qi_v8qi);
+ SPARC_BUILTIN_FUCMPLE8, di_ftype_v8qi_v8qi);
def_builtin_const ("__builtin_vis_fucmpne8", CODE_FOR_fucmpne8di_vis,
- di_ftype_v8qi_v8qi);
+ SPARC_BUILTIN_FUCMPNE8, di_ftype_v8qi_v8qi);
def_builtin_const ("__builtin_vis_fucmpgt8", CODE_FOR_fucmpgt8di_vis,
- di_ftype_v8qi_v8qi);
+ SPARC_BUILTIN_FUCMPGT8, di_ftype_v8qi_v8qi);
def_builtin_const ("__builtin_vis_fucmpeq8", CODE_FOR_fucmpeq8di_vis,
- di_ftype_v8qi_v8qi);
+ SPARC_BUILTIN_FUCMPEQ8, di_ftype_v8qi_v8qi);
}
else
{
def_builtin_const ("__builtin_vis_fucmple8", CODE_FOR_fucmple8si_vis,
- si_ftype_v8qi_v8qi);
+ SPARC_BUILTIN_FUCMPLE8, si_ftype_v8qi_v8qi);
def_builtin_const ("__builtin_vis_fucmpne8", CODE_FOR_fucmpne8si_vis,
- si_ftype_v8qi_v8qi);
+ SPARC_BUILTIN_FUCMPNE8, si_ftype_v8qi_v8qi);
def_builtin_const ("__builtin_vis_fucmpgt8", CODE_FOR_fucmpgt8si_vis,
- si_ftype_v8qi_v8qi);
+ SPARC_BUILTIN_FUCMPGT8, si_ftype_v8qi_v8qi);
def_builtin_const ("__builtin_vis_fucmpeq8", CODE_FOR_fucmpeq8si_vis,
- si_ftype_v8qi_v8qi);
+ SPARC_BUILTIN_FUCMPEQ8, si_ftype_v8qi_v8qi);
}
def_builtin_const ("__builtin_vis_fhadds", CODE_FOR_fhaddsf_vis,
- sf_ftype_sf_sf);
+ SPARC_BUILTIN_FHADDS, sf_ftype_sf_sf);
def_builtin_const ("__builtin_vis_fhaddd", CODE_FOR_fhadddf_vis,
- df_ftype_df_df);
+ SPARC_BUILTIN_FHADDD, df_ftype_df_df);
def_builtin_const ("__builtin_vis_fhsubs", CODE_FOR_fhsubsf_vis,
- sf_ftype_sf_sf);
+ SPARC_BUILTIN_FHSUBS, sf_ftype_sf_sf);
def_builtin_const ("__builtin_vis_fhsubd", CODE_FOR_fhsubdf_vis,
- df_ftype_df_df);
+ SPARC_BUILTIN_FHSUBD, df_ftype_df_df);
def_builtin_const ("__builtin_vis_fnhadds", CODE_FOR_fnhaddsf_vis,
- sf_ftype_sf_sf);
+ SPARC_BUILTIN_FNHADDS, sf_ftype_sf_sf);
def_builtin_const ("__builtin_vis_fnhaddd", CODE_FOR_fnhadddf_vis,
- df_ftype_df_df);
+ SPARC_BUILTIN_FNHADDD, df_ftype_df_df);
def_builtin_const ("__builtin_vis_umulxhi", CODE_FOR_umulxhi_vis,
- di_ftype_di_di);
+ SPARC_BUILTIN_UMULXHI, di_ftype_di_di);
def_builtin_const ("__builtin_vis_xmulx", CODE_FOR_xmulx_vis,
- di_ftype_di_di);
+ SPARC_BUILTIN_XMULX, di_ftype_di_di);
def_builtin_const ("__builtin_vis_xmulxhi", CODE_FOR_xmulxhi_vis,
- di_ftype_di_di);
+ SPARC_BUILTIN_XMULXHI, di_ftype_di_di);
}
}
-/* Handle TARGET_EXPAND_BUILTIN target hook.
- Expand builtin functions for sparc intrinsics. */
+/* Implement TARGET_BUILTIN_DECL hook. */
+
+static tree
+sparc_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
+{
+ if (code >= SPARC_BUILTIN_MAX)
+ return error_mark_node;
+
+ return sparc_builtins[code];
+}
+
+/* Implemented TARGET_EXPAND_BUILTIN hook. */
static rtx
sparc_expand_builtin (tree exp, rtx target,
@@ -10414,15 +10579,14 @@ sparc_expand_builtin (tree exp, rtx target,
enum machine_mode tmode ATTRIBUTE_UNUSED,
int ignore ATTRIBUTE_UNUSED)
{
- tree arg;
- call_expr_arg_iterator iter;
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int icode = DECL_FUNCTION_CODE (fndecl);
- rtx pat, op[4];
+ enum sparc_builtins code = (enum sparc_builtins) DECL_FUNCTION_CODE (fndecl);
+ enum insn_code icode = sparc_builtins_icode[code];
+ bool nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
+ call_expr_arg_iterator iter;
int arg_count = 0;
- bool nonvoid;
-
- nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
+ rtx pat, op[4];
+ tree arg;
if (nonvoid)
{
@@ -10434,6 +10598,7 @@ sparc_expand_builtin (tree exp, rtx target,
else
op[0] = target;
}
+
FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
{
const struct insn_operand_data *insn_op;
@@ -10447,11 +10612,22 @@ sparc_expand_builtin (tree exp, rtx target,
insn_op = &insn_data[icode].operand[idx];
op[arg_count] = expand_normal (arg);
- if (insn_op->mode == V1DImode
- && GET_MODE (op[arg_count]) == DImode)
+ if (code == SPARC_BUILTIN_LDFSR || code == SPARC_BUILTIN_STFSR)
+ {
+ if (!address_operand (op[arg_count], SImode))
+ {
+ op[arg_count] = convert_memory_address (Pmode, op[arg_count]);
+ op[arg_count] = copy_addr_to_reg (op[arg_count]);
+ }
+ op[arg_count] = gen_rtx_MEM (SImode, op[arg_count]);
+ }
+
+ else if (insn_op->mode == V1DImode
+ && GET_MODE (op[arg_count]) == DImode)
op[arg_count] = gen_lowpart (V1DImode, op[arg_count]);
+
else if (insn_op->mode == V1SImode
- && GET_MODE (op[arg_count]) == SImode)
+ && GET_MODE (op[arg_count]) == SImode)
op[arg_count] = gen_lowpart (V1SImode, op[arg_count]);
if (! (*insn_data[icode].operand[idx].predicate) (op[arg_count],
@@ -10485,12 +10661,11 @@ sparc_expand_builtin (tree exp, rtx target,
emit_insn (pat);
- if (nonvoid)
- return op[0];
- else
- return const0_rtx;
+ return (nonvoid ? op[0] : const0_rtx);
}
+/* Return the upper 16 bits of the 8x16 multiplication. */
+
static int
sparc_vis_mul8x16 (int e8, int e16)
{
@@ -10501,15 +10676,15 @@ sparc_vis_mul8x16 (int e8, int e16)
the result into the array N_ELTS, whose elements are of INNER_TYPE. */
static void
-sparc_handle_vis_mul8x16 (tree *n_elts, int fncode, tree inner_type,
- tree cst0, tree cst1)
+sparc_handle_vis_mul8x16 (tree *n_elts, enum sparc_builtins fncode,
+ tree inner_type, tree cst0, tree cst1)
{
unsigned i, num = VECTOR_CST_NELTS (cst0);
int scale;
switch (fncode)
{
- case CODE_FOR_fmul8x16_vis:
+ case SPARC_BUILTIN_FMUL8X16:
for (i = 0; i < num; ++i)
{
int val
@@ -10519,7 +10694,7 @@ sparc_handle_vis_mul8x16 (tree *n_elts, int fncode, tree inner_type,
}
break;
- case CODE_FOR_fmul8x16au_vis:
+ case SPARC_BUILTIN_FMUL8X16AU:
scale = TREE_INT_CST_LOW (VECTOR_CST_ELT (cst1, 0));
for (i = 0; i < num; ++i)
@@ -10531,7 +10706,7 @@ sparc_handle_vis_mul8x16 (tree *n_elts, int fncode, tree inner_type,
}
break;
- case CODE_FOR_fmul8x16al_vis:
+ case SPARC_BUILTIN_FMUL8X16AL:
scale = TREE_INT_CST_LOW (VECTOR_CST_ELT (cst1, 1));
for (i = 0; i < num; ++i)
@@ -10548,7 +10723,8 @@ sparc_handle_vis_mul8x16 (tree *n_elts, int fncode, tree inner_type,
}
}
-/* Handle TARGET_FOLD_BUILTIN target hook.
+/* Implement TARGET_FOLD_BUILTIN hook.
+
Fold builtin functions for SPARC intrinsics. If IGNORE is true the
result of the function call is ignored. NULL_TREE is returned if the
function could not be folded. */
@@ -10557,34 +10733,30 @@ static tree
sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
tree *args, bool ignore)
{
- tree arg0, arg1, arg2;
+ enum sparc_builtins code = (enum sparc_builtins) DECL_FUNCTION_CODE (fndecl);
tree rtype = TREE_TYPE (TREE_TYPE (fndecl));
- enum insn_code icode = (enum insn_code) DECL_FUNCTION_CODE (fndecl);
+ tree arg0, arg1, arg2;
if (ignore)
- {
- /* Note that a switch statement instead of the sequence of tests would
- be incorrect as many of the CODE_FOR values could be CODE_FOR_nothing
- and that would yield multiple alternatives with identical values. */
- if (icode == CODE_FOR_alignaddrsi_vis
- || icode == CODE_FOR_alignaddrdi_vis
- || icode == CODE_FOR_wrgsr_vis
- || icode == CODE_FOR_bmasksi_vis
- || icode == CODE_FOR_bmaskdi_vis
- || icode == CODE_FOR_cmask8si_vis
- || icode == CODE_FOR_cmask8di_vis
- || icode == CODE_FOR_cmask16si_vis
- || icode == CODE_FOR_cmask16di_vis
- || icode == CODE_FOR_cmask32si_vis
- || icode == CODE_FOR_cmask32di_vis)
- ;
- else
+ switch (code)
+ {
+ case SPARC_BUILTIN_LDFSR:
+ case SPARC_BUILTIN_STFSR:
+ case SPARC_BUILTIN_ALIGNADDR:
+ case SPARC_BUILTIN_WRGSR:
+ case SPARC_BUILTIN_BMASK:
+ case SPARC_BUILTIN_CMASK8:
+ case SPARC_BUILTIN_CMASK16:
+ case SPARC_BUILTIN_CMASK32:
+ break;
+
+ default:
return build_zero_cst (rtype);
- }
+ }
- switch (icode)
+ switch (code)
{
- case CODE_FOR_fexpand_vis:
+ case SPARC_BUILTIN_FEXPAND:
arg0 = args[0];
STRIP_NOPS (arg0);
@@ -10603,9 +10775,9 @@ sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
}
break;
- case CODE_FOR_fmul8x16_vis:
- case CODE_FOR_fmul8x16au_vis:
- case CODE_FOR_fmul8x16al_vis:
+ case SPARC_BUILTIN_FMUL8X16:
+ case SPARC_BUILTIN_FMUL8X16AU:
+ case SPARC_BUILTIN_FMUL8X16AL:
arg0 = args[0];
arg1 = args[1];
STRIP_NOPS (arg0);
@@ -10615,12 +10787,12 @@ sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
{
tree inner_type = TREE_TYPE (rtype);
tree *n_elts = XALLOCAVEC (tree, VECTOR_CST_NELTS (arg0));
- sparc_handle_vis_mul8x16 (n_elts, icode, inner_type, arg0, arg1);
+ sparc_handle_vis_mul8x16 (n_elts, code, inner_type, arg0, arg1);
return build_vector (rtype, n_elts);
}
break;
- case CODE_FOR_fpmerge_vis:
+ case SPARC_BUILTIN_FPMERGE:
arg0 = args[0];
arg1 = args[1];
STRIP_NOPS (arg0);
@@ -10640,13 +10812,19 @@ sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
}
break;
- case CODE_FOR_pdist_vis:
+ case SPARC_BUILTIN_PDIST:
+ case SPARC_BUILTIN_PDISTN:
arg0 = args[0];
arg1 = args[1];
- arg2 = args[2];
STRIP_NOPS (arg0);
STRIP_NOPS (arg1);
- STRIP_NOPS (arg2);
+ if (code == SPARC_BUILTIN_PDIST)
+ {
+ arg2 = args[2];
+ STRIP_NOPS (arg2);
+ }
+ else
+ arg2 = integer_zero_node;
if (TREE_CODE (arg0) == VECTOR_CST
&& TREE_CODE (arg1) == VECTOR_CST
@@ -12325,9 +12503,106 @@ sparc_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
return true;
}
-static enum machine_mode sparc_cstore_mode (enum insn_code icode ATTRIBUTE_UNUSED)
+/* Implement TARGET_CSTORE_MODE. */
+
+static enum machine_mode
+sparc_cstore_mode (enum insn_code icode ATTRIBUTE_UNUSED)
{
return (TARGET_ARCH64 ? DImode : SImode);
}
+/* Return the compound expression made of T1 and T2. */
+
+static inline tree
+compound_expr (tree t1, tree t2)
+{
+ return build2 (COMPOUND_EXPR, void_type_node, t1, t2);
+}
+
+/* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV hook. */
+
+static void
+sparc_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
+{
+ if (!TARGET_FPU)
+ return;
+
+ const unsigned HOST_WIDE_INT accrued_exception_mask = 0x1f << 5;
+ const unsigned HOST_WIDE_INT trap_enable_mask = 0x1f << 23;
+
+ /* We generate the equivalent of feholdexcept (&fenv_var):
+
+ unsigned int fenv_var;
+ __builtin_store_fsr (&fenv_var);
+
+ unsigned int tmp1_var;
+ tmp1_var = fenv_var & ~(accrued_exception_mask | trap_enable_mask);
+
+ __builtin_load_fsr (&tmp1_var); */
+
+ tree fenv_var = create_tmp_var (unsigned_type_node, NULL);
+ mark_addressable (fenv_var);
+ tree fenv_addr = build_fold_addr_expr (fenv_var);
+ tree stfsr = sparc_builtins[SPARC_BUILTIN_STFSR];
+ tree hold_stfsr = build_call_expr (stfsr, 1, fenv_addr);
+
+ tree tmp1_var = create_tmp_var (unsigned_type_node, NULL);
+ mark_addressable (tmp1_var);
+ tree masked_fenv_var
+ = build2 (BIT_AND_EXPR, unsigned_type_node, fenv_var,
+ build_int_cst (unsigned_type_node,
+ ~(accrued_exception_mask | trap_enable_mask)));
+ tree hold_mask
+ = build2 (MODIFY_EXPR, void_type_node, tmp1_var, masked_fenv_var);
+
+ tree tmp1_addr = build_fold_addr_expr (tmp1_var);
+ tree ldfsr = sparc_builtins[SPARC_BUILTIN_LDFSR];
+ tree hold_ldfsr = build_call_expr (ldfsr, 1, tmp1_addr);
+
+ *hold = compound_expr (compound_expr (hold_stfsr, hold_mask), hold_ldfsr);
+
+ /* We reload the value of tmp1_var to clear the exceptions:
+
+ __builtin_load_fsr (&tmp1_var); */
+
+ *clear = build_call_expr (ldfsr, 1, tmp1_addr);
+
+ /* We generate the equivalent of feupdateenv (&fenv_var):
+
+ unsigned int tmp2_var;
+ __builtin_store_fsr (&tmp2_var);
+
+ __builtin_load_fsr (&fenv_var);
+
+ if (SPARC_LOW_FE_EXCEPT_VALUES)
+ tmp2_var >>= 5;
+ __atomic_feraiseexcept ((int) tmp2_var); */
+
+ tree tmp2_var = create_tmp_var (unsigned_type_node, NULL);
+ mark_addressable (tmp2_var);
+ tree tmp3_addr = build_fold_addr_expr (tmp2_var);
+ tree update_stfsr = build_call_expr (stfsr, 1, tmp3_addr);
+
+ tree update_ldfsr = build_call_expr (ldfsr, 1, fenv_addr);
+
+ tree atomic_feraiseexcept
+ = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
+ tree update_call
+ = build_call_expr (atomic_feraiseexcept, 1,
+ fold_convert (integer_type_node, tmp2_var));
+
+ if (SPARC_LOW_FE_EXCEPT_VALUES)
+ {
+ tree shifted_tmp2_var
+ = build2 (RSHIFT_EXPR, unsigned_type_node, tmp2_var,
+ build_int_cst (unsigned_type_node, 5));
+ tree update_shift
+ = build2 (MODIFY_EXPR, void_type_node, tmp2_var, shifted_tmp2_var);
+ update_call = compound_expr (update_shift, update_call);
+ }
+
+ *update
+ = compound_expr (compound_expr (update_stfsr, update_ldfsr), update_call);
+}
+
#include "gt-sparc.h"
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index d96c1b6b422..7533e88491b 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1777,3 +1777,6 @@ extern int sparc_indent_opcode;
#ifndef SUBTARGET_DEFAULT_MEMORY_MODEL
#define SUBTARGET_DEFAULT_MEMORY_MODEL SMM_DEFAULT
#endif
+
+/* Define this to 1 if the FE_EXCEPT values defined in fenv.h start at 1. */
+#define SPARC_LOW_FE_EXCEPT_VALUES 0
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index be7bbe977a2..b3fb2eb18fb 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -96,13 +96,19 @@
(define_c_enum "unspecv" [
UNSPECV_BLOCKAGE
+ UNSPECV_PROBE_STACK_RANGE
+
UNSPECV_FLUSHW
- UNSPECV_FLUSH
UNSPECV_SAVEW
- UNSPECV_CAS
- UNSPECV_SWAP
+
+ UNSPECV_FLUSH
+
UNSPECV_LDSTUB
- UNSPECV_PROBE_STACK_RANGE
+ UNSPECV_SWAP
+ UNSPECV_CAS
+
+ UNSPECV_LDFSR
+ UNSPECV_STFSR
])
(define_constants
@@ -6783,22 +6789,26 @@
;; Special pattern for the FLUSH instruction.
-; We do SImode and DImode versions of this to quiet down genrecog's complaints
-; of the define_insn otherwise missing a mode. We make "flush", aka
-; gen_flush, the default one since sparc_initialize_trampoline uses
-; it on SImode mem values.
-
-(define_insn "flush"
- [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
+(define_insn "flush<P:mode>"
+ [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)]
""
{ return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
[(set_attr "type" "iflush")])
-(define_insn "flushdi"
- [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
- ""
- { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
- [(set_attr "type" "iflush")])
+;; Special insns to load and store the 32-bit FP Status Register.
+
+(define_insn "ldfsr"
+ [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)]
+ "TARGET_FPU"
+ "ld\t%0, %%fsr"
+ [(set_attr "type" "load")])
+
+(define_insn "stfsr"
+ [(set (match_operand:SI 0 "memory_operand" "=m")
+ (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))]
+ "TARGET_FPU"
+ "st\t%%fsr, %0"
+ [(set_attr "type" "store")])
;; Find first set instructions.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b3be3e0436d..c47187d351d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-12-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.target/sparc/pdistn.c: New test.
+ * gcc.target/sparc/pdistn-2.c: Likewise.
+
2013-12-06 Richard Biener <rguenther@suse.de>
PR tree-optimization/59058
diff --git a/gcc/testsuite/gcc.target/sparc/pdistn-2.c b/gcc/testsuite/gcc.target/sparc/pdistn-2.c
new file mode 100644
index 00000000000..008496f9ae7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sparc/pdistn-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=ultrasparc -mvis3 -O1 -fdump-tree-optimized" } */
+
+typedef unsigned char vec8 __attribute__((vector_size(8)));
+
+#define _(A) (unsigned char)A
+
+long foo () {
+ vec8 a = { _(1), _(2), _(3), _(4), _(5), _(6), _(7), _(255) };
+ vec8 b = { _(2), _(4), _(8), _(16), _(32), _(64), _(128), _(8) };
+ return __builtin_vis_pdistn (a, b);
+}
+
+/* { dg-final { scan-assembler-not "pdistn\t%" } } */
+/* { dg-final { scan-tree-dump "return 473" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/sparc/pdistn.c b/gcc/testsuite/gcc.target/sparc/pdistn.c
new file mode 100644
index 00000000000..2f534f70b7d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sparc/pdistn.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=ultrasparc -mvis3" } */
+
+typedef unsigned char vec8 __attribute__((vector_size(8)));
+
+long foo (vec8 a, vec8 b) {
+ return __builtin_vis_pdistn (a, b);
+}
+
+/* { dg-final { scan-assembler-times "pdistn\t%" 1 } } */
OpenPOWER on IntegriCloud