===================================================================
@@ -31952,25 +31952,26 @@ enum ix86_builtins
IX86_BUILTIN__BDESC_MAX_LAST = IX86_BUILTIN__BDESC_MAX_FIRST
};
/* Table for the ix86 builtin decls. */
static GTY(()) tree ix86_builtins[(int) IX86_BUILTIN_MAX];
/* Table of all of the builtin functions that are possible with different ISA's
but are waiting to be built until a function is declared to use that
ISA. */
struct builtin_isa {
- const char *name; /* function name */
- enum ix86_builtin_func_type tcode; /* type to use in the declaration */
HOST_WIDE_INT isa; /* isa_flags this builtin is defined for */
HOST_WIDE_INT isa2; /* additional isa_flags this builtin is defined for */
- bool const_p; /* true if the declaration is constant */
+ const char *name; /* function name */
+ enum ix86_builtin_func_type tcode; /* type to use in the declaration */
+ unsigned char const_p:1; /* true if the declaration is constant */
+ unsigned char pure_p:1; /* true if the declaration has pure attribute */
bool leaf_p; /* true if the declaration has leaf attribute */
bool nothrow_p; /* true if the declaration has nothrow attribute */
bool set_and_not_built_p;
};
static struct builtin_isa ix86_builtins_isa[(int) IX86_BUILTIN_MAX];
/* Bits that can still enable any inclusion of a builtin. */
static HOST_WIDE_INT deferred_isa_values = 0;
static HOST_WIDE_INT deferred_isa_values2 = 0;
@@ -32027,20 +32028,21 @@ def_builtin (HOST_WIDE_INT mask, const c
{
/* Just a MASK where set_and_not_built_p == true can potentially
include a builtin. */
deferred_isa_values |= mask;
ix86_builtins[(int) code] = NULL_TREE;
ix86_builtins_isa[(int) code].tcode = tcode;
ix86_builtins_isa[(int) code].name = name;
ix86_builtins_isa[(int) code].leaf_p = false;
ix86_builtins_isa[(int) code].nothrow_p = false;
ix86_builtins_isa[(int) code].const_p = false;
+ ix86_builtins_isa[(int) code].pure_p = false;
ix86_builtins_isa[(int) code].set_and_not_built_p = true;
}
}
return decl;
}
/* Like def_builtin, but also marks the function decl "const". */
static inline tree
@@ -32049,20 +32051,35 @@ def_builtin_const (HOST_WIDE_INT mask, c
{
tree decl = def_builtin (mask, name, tcode, code);
if (decl)
TREE_READONLY (decl) = 1;
else
ix86_builtins_isa[(int) code].const_p = true;
return decl;
}
+/* Like def_builtin, but also marks the function decl "pure". */
+
+static inline tree
+def_builtin_pure (HOST_WIDE_INT mask, const char *name,
+ enum ix86_builtin_func_type tcode, enum ix86_builtins code)
+{
+ tree decl = def_builtin (mask, name, tcode, code);
+ if (decl)
+ DECL_PURE_P (decl) = 1;
+ else
+ ix86_builtins_isa[(int) code].pure_p = true;
+
+ return decl;
+}
+
/* Like def_builtin, but for additional isa2 flags. */
static inline tree
def_builtin2 (HOST_WIDE_INT mask, const char *name,
enum ix86_builtin_func_type tcode,
enum ix86_builtins code)
{
tree decl = NULL_TREE;
ix86_builtins_isa[(int) code].isa2 = mask;
@@ -32083,20 +32100,21 @@ def_builtin2 (HOST_WIDE_INT mask, const
{
/* Just a MASK where set_and_not_built_p == true can potentially
include a builtin. */
deferred_isa_values2 |= mask;
ix86_builtins[(int) code] = NULL_TREE;
ix86_builtins_isa[(int) code].tcode = tcode;
ix86_builtins_isa[(int) code].name = name;
ix86_builtins_isa[(int) code].leaf_p = false;
ix86_builtins_isa[(int) code].nothrow_p = false;
ix86_builtins_isa[(int) code].const_p = false;
+ ix86_builtins_isa[(int) code].pure_p = false;
ix86_builtins_isa[(int) code].set_and_not_built_p = true;
}
return decl;
}
/* Like def_builtin, but also marks the function decl "const". */
static inline tree
def_builtin_const2 (HOST_WIDE_INT mask, const char *name,
@@ -32104,20 +32122,35 @@ def_builtin_const2 (HOST_WIDE_INT mask,
{
tree decl = def_builtin2 (mask, name, tcode, code);
if (decl)
TREE_READONLY (decl) = 1;
else
ix86_builtins_isa[(int) code].const_p = true;
return decl;
}
+/* Like def_builtin, but also marks the function decl "pure". */
+
+static inline tree
+def_builtin_pure2 (HOST_WIDE_INT mask, const char *name,
+ enum ix86_builtin_func_type tcode, enum ix86_builtins code)
+{
+ tree decl = def_builtin2 (mask, name, tcode, code);
+ if (decl)
+ DECL_PURE_P (decl) = 1;
+ else
+ ix86_builtins_isa[(int) code].pure_p = true;
+
+ return decl;
+}
+
/* Add any new builtin functions for a given ISA that may not have been
declared. This saves a bit of space compared to adding all of the
declarations to the tree, even if we didn't use them. */
static void
ix86_add_new_builtins (HOST_WIDE_INT isa, HOST_WIDE_INT isa2)
{
if ((isa & deferred_isa_values) == 0
&& (isa2 & deferred_isa_values2) == 0)
return;
@@ -32142,20 +32175,22 @@ ix86_add_new_builtins (HOST_WIDE_INT isa
ix86_builtins_isa[i].set_and_not_built_p = false;
type = ix86_get_builtin_func_type (ix86_builtins_isa[i].tcode);
decl = add_builtin_function_ext_scope (ix86_builtins_isa[i].name,
type, i, BUILT_IN_MD, NULL,
NULL_TREE);
ix86_builtins[i] = decl;
if (ix86_builtins_isa[i].const_p)
TREE_READONLY (decl) = 1;
+ if (ix86_builtins_isa[i].pure_p)
+ DECL_PURE_P (decl) = 1;
if (ix86_builtins_isa[i].leaf_p)
DECL_ATTRIBUTES (decl) = build_tree_list (get_identifier ("leaf"),
NULL_TREE);
if (ix86_builtins_isa[i].nothrow_p)
TREE_NOTHROW (decl) = 1;
}
}
current_target_pragma = saved_current_target_pragma;
}
@@ -32495,22 +32530,22 @@ ix86_init_mmx_sse_builtins (void)
ftype = INT_FTYPE_V4SF_V4SF;
def_builtin_const (d->mask, d->name, ftype, d->code);
}
BDESC_VERIFYS (IX86_BUILTIN__BDESC_COMI_LAST,
IX86_BUILTIN__BDESC_COMI_FIRST,
ARRAY_SIZE (bdesc_comi) - 1);
/* SSE */
def_builtin (OPTION_MASK_ISA_SSE, "__builtin_ia32_ldmxcsr",
VOID_FTYPE_UNSIGNED, IX86_BUILTIN_LDMXCSR);
- def_builtin (OPTION_MASK_ISA_SSE, "__builtin_ia32_stmxcsr",
- UNSIGNED_FTYPE_VOID, IX86_BUILTIN_STMXCSR);
+ def_builtin_pure (OPTION_MASK_ISA_SSE, "__builtin_ia32_stmxcsr",
+ UNSIGNED_FTYPE_VOID, IX86_BUILTIN_STMXCSR);
/* SSE or 3DNow!A */
def_builtin (OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A,
"__builtin_ia32_maskmovq", VOID_FTYPE_V8QI_V8QI_PCHAR,
IX86_BUILTIN_MASKMOVQ);
/* SSE2 */
def_builtin (OPTION_MASK_ISA_SSE2, "__builtin_ia32_maskmovdqu",
VOID_FTYPE_V16QI_V16QI_PCHAR, IX86_BUILTIN_MASKMOVDQU);
===================================================================
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O -msse" } */
+
+#include <xmmintrin.h>
+
+unsigned save;
+
+void f(unsigned mode){
+ unsigned tmp = _MM_GET_ROUNDING_MODE();
+ _MM_SET_ROUNDING_MODE(mode);
+ save = tmp;
+}
+
+/* { dg-final { scan-assembler-times "stmxcsr" 1 } } */