summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2011-05-20 08:22:38 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2011-05-20 08:22:38 +0000
commitccf4f3ae98386198926269817844b5bb67d3ebe4 (patch)
tree15db9a73406c618d2f18f1e9696a3f9549e5ace6 /gcc/config
parent79fb55a1f085a3c03a9168b97773ddd9a4ad054a (diff)
downloadgcc-ccf4f3ae98386198926269817844b5bb67d3ebe4.tar.gz
2011-05-20 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 173935 using svnmerge git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@173937 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arm/arm-fpus.def48
-rw-r--r--gcc/config/arm/arm-opts.h35
-rw-r--r--gcc/config/arm/arm-tables.opt61
-rw-r--r--gcc/config/arm/arm.c217
-rw-r--r--gcc/config/arm/arm.h43
-rw-r--r--gcc/config/arm/arm.opt84
-rwxr-xr-xgcc/config/arm/genopt.sh22
-rw-r--r--gcc/config/arm/t-arm5
-rw-r--r--gcc/config/avr/avr.c14
-rw-r--r--gcc/config/avr/avr.md39
-rwxr-xr-xgcc/config/avr/predicates.md7
-rw-r--r--gcc/config/bfin/bfin-opts.h3
-rw-r--r--gcc/config/bfin/bfin.c5
-rw-r--r--gcc/config/bfin/bfin.h4
-rw-r--r--gcc/config/bfin/elf.h1
-rw-r--r--gcc/config/bfin/t-bfin-elf1
-rw-r--r--gcc/config/bfin/t-bfin-linux1
-rw-r--r--gcc/config/bfin/t-bfin-uclinux1
-rw-r--r--gcc/config/i386/constraints.md18
-rw-r--r--gcc/config/i386/i386-c.c4
-rw-r--r--gcc/config/i386/i386-opts.h85
-rw-r--r--gcc/config/i386/i386-protos.h13
-rw-r--r--gcc/config/i386/i386.c832
-rw-r--r--gcc/config/i386/i386.h60
-rw-r--r--gcc/config/i386/i386.md1343
-rw-r--r--gcc/config/i386/i386.opt160
-rw-r--r--gcc/config/i386/sol2-10.h3
-rw-r--r--gcc/config/i386/sol2.h3
-rw-r--r--gcc/config/i386/sse.md13
-rw-r--r--gcc/config/i386/sync.md61
-rw-r--r--gcc/config/i386/t-i3862
-rw-r--r--gcc/config/mips/mips.c1
-rw-r--r--gcc/config/rx/rx-protos.h2
-rw-r--r--gcc/config/rx/rx.c49
-rw-r--r--gcc/config/rx/rx.h2
-rw-r--r--gcc/config/rx/rx.md70
-rw-r--r--gcc/config/sol2-protos.h2
-rw-r--r--gcc/config/sol2.c131
-rw-r--r--gcc/config/sol2.h8
-rw-r--r--gcc/config/sparc/sol2.h13
-rw-r--r--gcc/config/sparc/sparc.c22
-rw-r--r--gcc/config/sparc/sparc.h60
-rw-r--r--gcc/config/t-sol24
43 files changed, 1763 insertions, 1789 deletions
diff --git a/gcc/config/arm/arm-fpus.def b/gcc/config/arm/arm-fpus.def
new file mode 100644
index 00000000000..9f7e62acc4b
--- /dev/null
+++ b/gcc/config/arm/arm-fpus.def
@@ -0,0 +1,48 @@
+/* ARM FPU variants.
+ Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+/* Before using #include to read this file, define a macro:
+
+ ARM_FPU(NAME, MODEL, REV, VFP_REGS, NEON, FP16)
+
+ The arguments are the fields of struct arm_fpu_desc.
+
+ genopt.sh assumes no whitespace up to the first "," in each entry. */
+
+ARM_FPU("fpa", ARM_FP_MODEL_FPA, 0, VFP_NONE, false, false)
+ARM_FPU("fpe2", ARM_FP_MODEL_FPA, 2, VFP_NONE, false, false)
+ARM_FPU("fpe3", ARM_FP_MODEL_FPA, 3, VFP_NONE, false, false)
+ARM_FPU("maverick", ARM_FP_MODEL_MAVERICK, 0, VFP_NONE, false, false)
+ARM_FPU("vfp", ARM_FP_MODEL_VFP, 2, VFP_REG_D16, false, false)
+ARM_FPU("vfpv3", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, false)
+ARM_FPU("vfpv3-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, true)
+ARM_FPU("vfpv3-d16", ARM_FP_MODEL_VFP, 3, VFP_REG_D16, false, false)
+ARM_FPU("vfpv3-d16-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D16, false, true)
+ARM_FPU("vfpv3xd", ARM_FP_MODEL_VFP, 3, VFP_REG_SINGLE, false, false)
+ARM_FPU("vfpv3xd-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_SINGLE, false, true)
+ARM_FPU("neon", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, true , false)
+ARM_FPU("neon-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, true, true)
+ARM_FPU("vfpv4", ARM_FP_MODEL_VFP, 4, VFP_REG_D32, false, true)
+ARM_FPU("vfpv4-d16", ARM_FP_MODEL_VFP, 4, VFP_REG_D16, false, true)
+ARM_FPU("fpv4-sp-d16", ARM_FP_MODEL_VFP, 4, VFP_REG_SINGLE, false, true)
+ARM_FPU("neon-vfpv4", ARM_FP_MODEL_VFP, 4, VFP_REG_D32, true, true)
+/* Compatibility aliases. */
+ARM_FPU("vfp3", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, false)
diff --git a/gcc/config/arm/arm-opts.h b/gcc/config/arm/arm-opts.h
index f9f18036b92..c35224eaf5c 100644
--- a/gcc/config/arm/arm-opts.h
+++ b/gcc/config/arm/arm-opts.h
@@ -33,4 +33,39 @@ enum processor_type
arm_none
};
+/* Which __fp16 format to use.
+ The enumeration values correspond to the numbering for the
+ Tag_ABI_FP_16bit_format attribute.
+ */
+enum arm_fp16_format_type
+{
+ ARM_FP16_FORMAT_NONE = 0,
+ ARM_FP16_FORMAT_IEEE = 1,
+ ARM_FP16_FORMAT_ALTERNATIVE = 2
+};
+
+/* Which ABI to use. */
+enum arm_abi_type
+{
+ ARM_ABI_APCS,
+ ARM_ABI_ATPCS,
+ ARM_ABI_AAPCS,
+ ARM_ABI_IWMMXT,
+ ARM_ABI_AAPCS_LINUX
+};
+
+enum float_abi_type
+{
+ ARM_FLOAT_ABI_SOFT,
+ ARM_FLOAT_ABI_SOFTFP,
+ ARM_FLOAT_ABI_HARD
+};
+
+/* Which thread pointer access sequence to use. */
+enum arm_tp_type {
+ TP_AUTO,
+ TP_SOFT,
+ TP_CP15
+};
+
#endif
diff --git a/gcc/config/arm/arm-tables.opt b/gcc/config/arm/arm-tables.opt
index 36cf2019682..f984480a01e 100644
--- a/gcc/config/arm/arm-tables.opt
+++ b/gcc/config/arm/arm-tables.opt
@@ -1,5 +1,6 @@
; -*- buffer-read-only: t -*-
-; Generated automatically by genopt.sh from arm-cores.def and arm-arches.def.
+; Generated automatically by genopt.sh from arm-cores.def, arm-arches.def
+; and arm-fpus.def.
; Copyright (C) 2011 Free Software Foundation, Inc.
;
@@ -339,3 +340,61 @@ Enum(arm_arch) String(iwmmxt) Value(23)
EnumValue
Enum(arm_arch) String(iwmmxt2) Value(24)
+Enum
+Name(arm_fpu) Type(int)
+Known ARM FPUs (for use with the -mfpu= option):
+
+EnumValue
+Enum(arm_fpu) String(fpa) Value(0)
+
+EnumValue
+Enum(arm_fpu) String(fpe2) Value(1)
+
+EnumValue
+Enum(arm_fpu) String(fpe3) Value(2)
+
+EnumValue
+Enum(arm_fpu) String(maverick) Value(3)
+
+EnumValue
+Enum(arm_fpu) String(vfp) Value(4)
+
+EnumValue
+Enum(arm_fpu) String(vfpv3) Value(5)
+
+EnumValue
+Enum(arm_fpu) String(vfpv3-fp16) Value(6)
+
+EnumValue
+Enum(arm_fpu) String(vfpv3-d16) Value(7)
+
+EnumValue
+Enum(arm_fpu) String(vfpv3-d16-fp16) Value(8)
+
+EnumValue
+Enum(arm_fpu) String(vfpv3xd) Value(9)
+
+EnumValue
+Enum(arm_fpu) String(vfpv3xd-fp16) Value(10)
+
+EnumValue
+Enum(arm_fpu) String(neon) Value(11)
+
+EnumValue
+Enum(arm_fpu) String(neon-fp16) Value(12)
+
+EnumValue
+Enum(arm_fpu) String(vfpv4) Value(13)
+
+EnumValue
+Enum(arm_fpu) String(vfpv4-d16) Value(14)
+
+EnumValue
+Enum(arm_fpu) String(fpv4-sp-d16) Value(15)
+
+EnumValue
+Enum(arm_fpu) String(neon-vfpv4) Value(16)
+
+EnumValue
+Enum(arm_fpu) String(vfp3) Value(17)
+
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 4f9c2aa7063..47c7a3a4ca9 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -636,21 +636,6 @@ int arm_fpu_attr;
/* Which floating popint hardware to use. */
const struct arm_fpu_desc *arm_fpu_desc;
-/* Whether to use floating point hardware. */
-enum float_abi_type arm_float_abi;
-
-/* Which __fp16 format to use. */
-enum arm_fp16_format_type arm_fp16_format;
-
-/* Which ABI to use. */
-enum arm_abi_type arm_abi;
-
-/* Which thread pointer model to use. */
-enum arm_tp_type target_thread_pointer = TP_AUTO;
-
-/* Used to parse -mstructure_size_boundary command line option. */
-int arm_structure_size_boundary = DEFAULT_STRUCTURE_SIZE_BOUNDARY;
-
/* Used for Thumb call_via trampolines. */
rtx thumb_call_via_label[14];
static int thumb_call_reg_needed;
@@ -954,80 +939,13 @@ char arm_arch_name[] = "__ARM_ARCH_0UNK__";
static const struct arm_fpu_desc all_fpus[] =
{
- {"fpa", ARM_FP_MODEL_FPA, 0, VFP_NONE, false, false},
- {"fpe2", ARM_FP_MODEL_FPA, 2, VFP_NONE, false, false},
- {"fpe3", ARM_FP_MODEL_FPA, 3, VFP_NONE, false, false},
- {"maverick", ARM_FP_MODEL_MAVERICK, 0, VFP_NONE, false, false},
- {"vfp", ARM_FP_MODEL_VFP, 2, VFP_REG_D16, false, false},
- {"vfpv3", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, false},
- {"vfpv3-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, true},
- {"vfpv3-d16", ARM_FP_MODEL_VFP, 3, VFP_REG_D16, false, false},
- {"vfpv3-d16-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D16, false, true},
- {"vfpv3xd", ARM_FP_MODEL_VFP, 3, VFP_REG_SINGLE, false, false},
- {"vfpv3xd-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_SINGLE, false, true},
- {"neon", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, true , false},
- {"neon-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, true , true },
- {"vfpv4", ARM_FP_MODEL_VFP, 4, VFP_REG_D32, false, true},
- {"vfpv4-d16", ARM_FP_MODEL_VFP, 4, VFP_REG_D16, false, true},
- {"fpv4-sp-d16", ARM_FP_MODEL_VFP, 4, VFP_REG_SINGLE, false, true},
- {"neon-vfpv4", ARM_FP_MODEL_VFP, 4, VFP_REG_D32, true, true},
- /* Compatibility aliases. */
- {"vfp3", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, false},
-};
-
-
-struct float_abi
-{
- const char * name;
- enum float_abi_type abi_type;
+#define ARM_FPU(NAME, MODEL, REV, VFP_REGS, NEON, FP16) \
+ { NAME, MODEL, REV, VFP_REGS, NEON, FP16 },
+#include "arm-fpus.def"
+#undef ARM_FPU
};
-/* Available values for -mfloat-abi=. */
-
-static const struct float_abi all_float_abis[] =
-{
- {"soft", ARM_FLOAT_ABI_SOFT},
- {"softfp", ARM_FLOAT_ABI_SOFTFP},
- {"hard", ARM_FLOAT_ABI_HARD}
-};
-
-
-struct fp16_format
-{
- const char *name;
- enum arm_fp16_format_type fp16_format_type;
-};
-
-
-/* Available values for -mfp16-format=. */
-
-static const struct fp16_format all_fp16_formats[] =
-{
- {"none", ARM_FP16_FORMAT_NONE},
- {"ieee", ARM_FP16_FORMAT_IEEE},
- {"alternative", ARM_FP16_FORMAT_ALTERNATIVE}
-};
-
-
-struct abi_name
-{
- const char *name;
- enum arm_abi_type abi_type;
-};
-
-
-/* Available values for -mabi=. */
-
-static const struct abi_name arm_all_abis[] =
-{
- {"apcs-gnu", ARM_ABI_APCS},
- {"atpcs", ARM_ABI_ATPCS},
- {"aapcs", ARM_ABI_AAPCS},
- {"iwmmxt", ARM_ABI_IWMMXT},
- {"aapcs-linux", ARM_ABI_AAPCS_LINUX}
-};
-
/* Supported TLS relocations. */
enum tls_reloc {
@@ -1311,8 +1229,6 @@ arm_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
static void
arm_option_override (void)
{
- unsigned i;
-
if (global_options_set.x_arm_arch_option)
arm_selected_arch = &all_architectures[arm_arch_option];
@@ -1447,39 +1363,6 @@ arm_option_override (void)
tune_flags = arm_selected_tune->flags;
current_tune = arm_selected_tune->tune;
- if (target_fp16_format_name)
- {
- for (i = 0; i < ARRAY_SIZE (all_fp16_formats); i++)
- {
- if (streq (all_fp16_formats[i].name, target_fp16_format_name))
- {
- arm_fp16_format = all_fp16_formats[i].fp16_format_type;
- break;
- }
- }
- if (i == ARRAY_SIZE (all_fp16_formats))
- error ("invalid __fp16 format option: -mfp16-format=%s",
- target_fp16_format_name);
- }
- else
- arm_fp16_format = ARM_FP16_FORMAT_NONE;
-
- if (target_abi_name)
- {
- for (i = 0; i < ARRAY_SIZE (arm_all_abis); i++)
- {
- if (streq (arm_all_abis[i].name, target_abi_name))
- {
- arm_abi = arm_all_abis[i].abi_type;
- break;
- }
- }
- if (i == ARRAY_SIZE (arm_all_abis))
- error ("invalid ABI option: -mabi=%s", target_abi_name);
- }
- else
- arm_abi = ARM_DEFAULT_ABI;
-
/* Make sure that the processor choice does not conflict with any of the
other command line choices. */
if (TARGET_ARM && !(insn_flags & FL_NOTM))
@@ -1607,19 +1490,11 @@ arm_option_override (void)
if (TARGET_IWMMXT_ABI && !TARGET_IWMMXT)
error ("iwmmxt abi requires an iwmmxt capable cpu");
- if (target_fpu_name == NULL && target_fpe_name != NULL)
+ if (!global_options_set.x_arm_fpu_index)
{
- if (streq (target_fpe_name, "2"))
- target_fpu_name = "fpe2";
- else if (streq (target_fpe_name, "3"))
- target_fpu_name = "fpe3";
- else
- error ("invalid floating point emulation option: -mfpe=%s",
- target_fpe_name);
- }
+ const char *target_fpu_name;
+ bool ok;
- if (target_fpu_name == NULL)
- {
#ifdef FPUTYPE_DEFAULT
target_fpu_name = FPUTYPE_DEFAULT;
#else
@@ -1628,23 +1503,13 @@ arm_option_override (void)
else
target_fpu_name = "fpe2";
#endif
- }
- arm_fpu_desc = NULL;
- for (i = 0; i < ARRAY_SIZE (all_fpus); i++)
- {
- if (streq (all_fpus[i].name, target_fpu_name))
- {
- arm_fpu_desc = &all_fpus[i];
- break;
- }
+ ok = opt_enum_arg_to_value (OPT_mfpu_, target_fpu_name, &arm_fpu_index,
+ CL_TARGET);
+ gcc_assert (ok);
}
- if (!arm_fpu_desc)
- {
- error ("invalid floating point option: -mfpu=%s", target_fpu_name);
- return;
- }
+ arm_fpu_desc = &all_fpus[arm_fpu_index];
switch (arm_fpu_desc->model)
{
@@ -1669,24 +1534,6 @@ arm_option_override (void)
gcc_unreachable();
}
- if (target_float_abi_name != NULL)
- {
- /* The user specified a FP ABI. */
- for (i = 0; i < ARRAY_SIZE (all_float_abis); i++)
- {
- if (streq (all_float_abis[i].name, target_float_abi_name))
- {
- arm_float_abi = all_float_abis[i].abi_type;
- break;
- }
- }
- if (i == ARRAY_SIZE (all_float_abis))
- error ("invalid floating point abi: -mfloat-abi=%s",
- target_float_abi_name);
- }
- else
- arm_float_abi = TARGET_DEFAULT_FLOAT_ABI;
-
if (TARGET_AAPCS_BASED
&& (arm_fpu_desc->model == ARM_FP_MODEL_FPA))
error ("FPA is unsupported in the AAPCS");
@@ -1747,18 +1594,6 @@ arm_option_override (void)
&& (tune_flags & FL_MODE32) == 0)
flag_schedule_insns = flag_schedule_insns_after_reload = 0;
- if (target_thread_switch)
- {
- if (strcmp (target_thread_switch, "soft") == 0)
- target_thread_pointer = TP_SOFT;
- else if (strcmp (target_thread_switch, "auto") == 0)
- target_thread_pointer = TP_AUTO;
- else if (strcmp (target_thread_switch, "cp15") == 0)
- target_thread_pointer = TP_CP15;
- else
- error ("invalid thread pointer option: -mtp=%s", target_thread_switch);
- }
-
/* Use the cp15 method if it is available. */
if (target_thread_pointer == TP_AUTO)
{
@@ -1772,19 +1607,25 @@ arm_option_override (void)
error ("can not use -mtp=cp15 with 16-bit Thumb");
/* Override the default structure alignment for AAPCS ABI. */
- if (TARGET_AAPCS_BASED)
- arm_structure_size_boundary = 8;
-
- if (structure_size_string != NULL)
+ if (!global_options_set.x_arm_structure_size_boundary)
{
- int size = strtol (structure_size_string, NULL, 0);
-
- if (size == 8 || size == 32
- || (ARM_DOUBLEWORD_ALIGN && size == 64))
- arm_structure_size_boundary = size;
- else
- warning (0, "structure size boundary can only be set to %s",
- ARM_DOUBLEWORD_ALIGN ? "8, 32 or 64": "8 or 32");
+ if (TARGET_AAPCS_BASED)
+ arm_structure_size_boundary = 8;
+ }
+ else
+ {
+ if (arm_structure_size_boundary != 8
+ && arm_structure_size_boundary != 32
+ && !(ARM_DOUBLEWORD_ALIGN && arm_structure_size_boundary == 64))
+ {
+ if (ARM_DOUBLEWORD_ALIGN)
+ warning (0,
+ "structure size boundary can only be set to 8, 32 or 64");
+ else
+ warning (0, "structure size boundary can only be set to 8 or 32");
+ arm_structure_size_boundary
+ = (TARGET_AAPCS_BASED ? 8 : DEFAULT_STRUCTURE_SIZE_BOUNDARY);
+ }
}
if (!TARGET_ARM && TARGET_VXWORKS_RTP && flag_pic)
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 43323942a44..86d842ddf4a 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -349,59 +349,17 @@ extern const struct arm_fpu_desc
/* Which floating point hardware to schedule for. */
extern int arm_fpu_attr;
-enum float_abi_type
-{
- ARM_FLOAT_ABI_SOFT,
- ARM_FLOAT_ABI_SOFTFP,
- ARM_FLOAT_ABI_HARD
-};
-
-extern enum float_abi_type arm_float_abi;
-
#ifndef TARGET_DEFAULT_FLOAT_ABI
#define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_SOFT
#endif
-/* Which __fp16 format to use.
- The enumeration values correspond to the numbering for the
- Tag_ABI_FP_16bit_format attribute.
- */
-enum arm_fp16_format_type
-{
- ARM_FP16_FORMAT_NONE = 0,
- ARM_FP16_FORMAT_IEEE = 1,
- ARM_FP16_FORMAT_ALTERNATIVE = 2
-};
-
-extern enum arm_fp16_format_type arm_fp16_format;
#define LARGEST_EXPONENT_IS_NORMAL(bits) \
((bits) == 16 && arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
-/* Which ABI to use. */
-enum arm_abi_type
-{
- ARM_ABI_APCS,
- ARM_ABI_ATPCS,
- ARM_ABI_AAPCS,
- ARM_ABI_IWMMXT,
- ARM_ABI_AAPCS_LINUX
-};
-
-extern enum arm_abi_type arm_abi;
-
#ifndef ARM_DEFAULT_ABI
#define ARM_DEFAULT_ABI ARM_ABI_APCS
#endif
-/* Which thread pointer access sequence to use. */
-enum arm_tp_type {
- TP_AUTO,
- TP_SOFT,
- TP_CP15
-};
-
-extern enum arm_tp_type target_thread_pointer;
-
/* Nonzero if this chip supports the ARM Architecture 3M extensions. */
extern int arm_arch3m;
@@ -614,7 +572,6 @@ extern int arm_arch_hwdiv;
0020D) page 2-20 says "Structures are aligned on word boundaries".
The AAPCS specifies a value of 8. */
#define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
-extern int arm_structure_size_boundary;
/* This is the value used to initialize arm_structure_size_boundary. If a
particular arm target wants to change the default value it should change
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index 89c8cbd47d4..c45bc774bdc 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -22,9 +22,28 @@ HeaderInclude
config/arm/arm-opts.h
mabi=
-Target RejectNegative Joined Var(target_abi_name)
+Target RejectNegative Joined Enum(arm_abi_type) Var(arm_abi) Init(ARM_DEFAULT_ABI)
Specify an ABI
+Enum
+Name(arm_abi_type) Type(enum arm_abi_type)
+Known ARM ABIs (for use with the -mabi= option):
+
+EnumValue
+Enum(arm_abi_type) String(apcs-gnu) Value(ARM_ABI_APCS)
+
+EnumValue
+Enum(arm_abi_type) String(atpcs) Value(ARM_ABI_ATPCS)
+
+EnumValue
+Enum(arm_abi_type) String(aapcs) Value(ARM_ABI_AAPCS)
+
+EnumValue
+Enum(arm_abi_type) String(iwmmxt) Value(ARM_ABI_IWMMXT)
+
+EnumValue
+Enum(arm_abi_type) String(aapcs-linux) Value(ARM_ABI_AAPCS_LINUX)
+
mabort-on-noreturn
Target Report Mask(ABORT_NORETURN)
Generate a call to abort if a noreturn function returns
@@ -76,25 +95,57 @@ Target RejectNegative Joined Enum(processor_type) Var(arm_cpu_option) Init(arm_n
Specify the name of the target CPU
mfloat-abi=
-Target RejectNegative Joined Var(target_float_abi_name)
+Target RejectNegative Joined Enum(float_abi_type) Var(arm_float_abi) Init(TARGET_DEFAULT_FLOAT_ABI)
Specify if floating point hardware should be used
-mfp=
-Target RejectNegative Joined Undocumented Var(target_fpe_name)
+Enum
+Name(float_abi_type) Type(enum float_abi_type)
+Known floating-point ABIs (for use with the -mfloat-abi= option):
+
+EnumValue
+Enum(float_abi_type) String(soft) Value(ARM_FLOAT_ABI_SOFT)
+
+EnumValue
+Enum(float_abi_type) String(softfp) Value(ARM_FLOAT_ABI_SOFTFP)
+
+EnumValue
+Enum(float_abi_type) String(hard) Value(ARM_FLOAT_ABI_HARD)
+
+mfp=2
+Target RejectNegative Undocumented Alias(mfpu=, fpe2)
+
+mfp=3
+Target RejectNegative Undocumented Alias(mfpu=, fpe3)
mfp16-format=
-Target RejectNegative Joined Var(target_fp16_format_name)
+Target RejectNegative Joined Enum(arm_fp16_format_type) Var(arm_fp16_format) Init(ARM_FP16_FORMAT_NONE)
Specify the __fp16 floating-point format
+Enum
+Name(arm_fp16_format_type) Type(enum arm_fp16_format_type)
+Known __fp16 formats (for use with the -mfp16-format= option):
+
+EnumValue
+Enum(arm_fp16_format_type) String(none) Value(ARM_FP16_FORMAT_NONE)
+
+EnumValue
+Enum(arm_fp16_format_type) String(ieee) Value(ARM_FP16_FORMAT_IEEE)
+
+EnumValue
+Enum(arm_fp16_format_type) String(alternative) Value(ARM_FP16_FORMAT_ALTERNATIVE)
+
;; Now ignored.
mfpe
Target RejectNegative Mask(FPE) Undocumented
-mfpe=
-Target RejectNegative Joined Undocumented Var(target_fpe_name)
+mfpe=2
+Target RejectNegative Undocumented Alias(mfpu=, fpe2)
+
+mfpe=3
+Target RejectNegative Undocumented Alias(mfpu=, fpe3)
mfpu=
-Target RejectNegative Joined Var(target_fpu_name)
+Target RejectNegative Joined Enum(arm_fpu) Var(arm_fpu_index)
Specify the name of the target floating point hardware/format
mhard-float
@@ -128,7 +179,7 @@ msoft-float
Target RejectNegative Alias(mfloat-abi=, soft) Undocumented
mstructure-size-boundary=
-Target RejectNegative Joined Var(structure_size_string)
+Target RejectNegative Joined UInteger Var(arm_structure_size_boundary) Init(DEFAULT_STRUCTURE_SIZE_BOUNDARY)
Specify the minimum bit alignment of structures
mthumb
@@ -140,9 +191,22 @@ Target Report Mask(INTERWORK)
Support calls between Thumb and ARM instruction sets
mtp=
-Target RejectNegative Joined Var(target_thread_switch)
+Target RejectNegative Joined Enum(arm_tp_type) Var(target_thread_pointer) Init(TP_AUTO)
Specify how to access the thread pointer
+Enum
+Name(arm_tp_type) Type(enum arm_tp_type)
+Valid arguments to -mtp=:
+
+EnumValue
+Enum(arm_tp_type) String(soft) Value(TP_SOFT)
+
+EnumValue
+Enum(arm_tp_type) String(auto) Value(TP_AUTO)
+
+EnumValue
+Enum(arm_tp_type) String(cp15) Value(TP_CP15)
+
mtpcs-frame
Target Report Mask(TPCS_FRAME)
Thumb: Generate (non-leaf) stack frames even if not needed
diff --git a/gcc/config/arm/genopt.sh b/gcc/config/arm/genopt.sh
index 28cee6caabe..6b31896d8f5 100755
--- a/gcc/config/arm/genopt.sh
+++ b/gcc/config/arm/genopt.sh
@@ -20,7 +20,8 @@
cat <<EOF
; -*- buffer-read-only: t -*-
-; Generated automatically by genopt.sh from arm-cores.def and arm-arches.def.
+; Generated automatically by genopt.sh from arm-cores.def, arm-arches.def
+; and arm-fpus.def.
; Copyright (C) 2011 Free Software Foundation, Inc.
;
@@ -73,3 +74,22 @@ awk -F'[(, ]+' 'BEGIN {
print ""
value++
}' $1/arm-arches.def
+
+cat <<EOF
+Enum
+Name(arm_fpu) Type(int)
+Known ARM FPUs (for use with the -mfpu= option):
+
+EOF
+
+awk -F'[(, ]+' 'BEGIN {
+ value = 0
+}
+/^ARM_FPU/ {
+ name = $2
+ gsub("\"", "", name)
+ print "EnumValue"
+ print "Enum(arm_fpu) String(" name ") Value(" value ")"
+ print ""
+ value++
+}' $1/arm-fpus.def
diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm
index 18a548a3f74..826ec0af5c2 100644
--- a/gcc/config/arm/t-arm
+++ b/gcc/config/arm/t-arm
@@ -52,7 +52,8 @@ $(srcdir)/config/arm/arm-tune.md: $(srcdir)/config/arm/gentune.sh \
$(srcdir)/config/arm/arm-tune.md
$(srcdir)/config/arm/arm-tables.opt: $(srcdir)/config/arm/genopt.sh \
- $(srcdir)/config/arm/arm-cores.def $(srcdir)/config/arm/arm-arches.def
+ $(srcdir)/config/arm/arm-cores.def $(srcdir)/config/arm/arm-arches.def \
+ $(srcdir)/config/arm/arm-fpus.def
$(SHELL) $(srcdir)/config/arm/genopt.sh $(srcdir)/config/arm > \
$(srcdir)/config/arm/arm-tables.opt
@@ -64,7 +65,7 @@ arm.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(GGC_H) except.h $(C_PRAGMA_H) $(INTEGRATE_H) $(TM_P_H) \
$(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \
intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) $(srcdir)/config/arm/arm-cores.def \
- $(srcdir)/config/arm/arm-arches.def
+ $(srcdir)/config/arm/arm-arches.def $(srcdir)/config/arm/arm-fpus.def
arm-c.o: $(srcdir)/config/arm/arm-c.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H)
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index ac4b3182d81..c8c363ad948 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -1796,6 +1796,20 @@ avr_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
cfun->machine->sibcall_fails = 1;
}
+ /* Test if all registers needed by the ABI are actually available. If the
+ user has fixed a GPR needed to pass an argument, an (implicit) function
+ call would clobber that fixed register. See PR45099 for an example. */
+
+ if (cum->regno >= 0)
+ {
+ int regno;
+
+ for (regno = cum->regno; regno < cum->regno + bytes; regno++)
+ if (fixed_regs[regno])
+ error ("Register %s is needed to pass a parameter but is fixed",
+ reg_names[regno]);
+ }
+
if (cum->nregs <= 0)
{
cum->nregs = 0;
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 1ab30332bdb..efe6bb6914f 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -3388,3 +3388,42 @@
clr __zero_reg__"
[(set_attr "length" "3")
(set_attr "cc" "clobber")])
+
+
+;; Some combine patterns that try to fix bad code when a value is composed
+;; from byte parts like in PR27663.
+;; The patterns give some release but the code still is not optimal,
+;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
+;; That switch obfuscates things here and in many other places.
+
+(define_insn_and_split "*ior<mode>qi.byte0"
+ [(set (match_operand:HISI 0 "register_operand" "=r")
+ (ior:HISI
+ (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
+ (match_operand:HISI 2 "register_operand" "0")))]
+ ""
+ "#"
+ "reload_completed"
+ [(set (match_dup 3)
+ (ior:QI (match_dup 3)
+ (match_dup 1)))]
+ {
+ operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
+ })
+
+(define_insn_and_split "*ior<mode>qi.byte1-3"
+ [(set (match_operand:HISI 0 "register_operand" "=r")
+ (ior:HISI
+ (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
+ (match_operand:QI 2 "const_8_16_24_operand" "n"))
+ (match_operand:HISI 3 "register_operand" "0")))]
+ "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4)
+ (ior:QI (match_dup 4)
+ (match_dup 1)))]
+ {
+ int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
+ operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
+ })
diff --git a/gcc/config/avr/predicates.md b/gcc/config/avr/predicates.md
index 9a3473bf88f..a7cc2ba052f 100755
--- a/gcc/config/avr/predicates.md
+++ b/gcc/config/avr/predicates.md
@@ -138,3 +138,10 @@
(define_predicate "pseudo_register_operand"
(and (match_code "reg")
(match_test "!HARD_REGISTER_P (op)")))
+
+;; Return true if OP is a constant integer that is either
+;; 8 or 16 or 24.
+(define_predicate "const_8_16_24_operand"
+ (and (match_code "const_int")
+ (match_test "8 == INTVAL(op) || 16 == INTVAL(op) || 24 == INTVAL(op)")))
+
diff --git a/gcc/config/bfin/bfin-opts.h b/gcc/config/bfin/bfin-opts.h
index d0780a6b52c..329fa1e625c 100644
--- a/gcc/config/bfin/bfin-opts.h
+++ b/gcc/config/bfin/bfin-opts.h
@@ -53,7 +53,8 @@ typedef enum bfin_cpu_type
BFIN_CPU_BF548M,
BFIN_CPU_BF549,
BFIN_CPU_BF549M,
- BFIN_CPU_BF561
+ BFIN_CPU_BF561,
+ BFIN_CPU_BF592
} bfin_cpu_t;
#endif
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index 2d4e33e5cf4..4f371fd928f 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -350,6 +350,11 @@ static const struct bfin_cpu bfin_cpus[] =
| WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
| WA_05000074},
+ {"bf592", BFIN_CPU_BF592, 0x0001,
+ WA_SPECULATIVE_LOADS | WA_05000074},
+ {"bf592", BFIN_CPU_BF592, 0x0000,
+ WA_SPECULATIVE_LOADS | WA_05000074},
+
{NULL, BFIN_CPU_UNKNOWN, 0, 0}
};
diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h
index 0d83ad82126..4f21a1c8a32 100644
--- a/gcc/config/bfin/bfin.h
+++ b/gcc/config/bfin/bfin.h
@@ -140,6 +140,10 @@
case BFIN_CPU_BF561: \
builtin_define ("__ADSPBF561__"); \
break; \
+ case BFIN_CPU_BF592: \
+ builtin_define ("__ADSPBF592__"); \
+ builtin_define ("__ADSPBF59x__"); \
+ break; \
} \
\
if (bfin_si_revision != -1) \
diff --git a/gcc/config/bfin/elf.h b/gcc/config/bfin/elf.h
index 975212faa23..14e209aa494 100644
--- a/gcc/config/bfin/elf.h
+++ b/gcc/config/bfin/elf.h
@@ -51,6 +51,7 @@ crti%O%s crtbegin%O%s crtlibid%O%s"
%{mmulticore:%{mcorea:-T bf561a.ld%s}} \
%{mmulticore:%{mcoreb:-T bf561b.ld%s}} \
%{mmulticore:%{!mcorea:%{!mcoreb:-T bf561m.ld%s}}}} \
+ %{mcpu=bf592*:-T bf592.ld%s} \
%{!mcpu=*:%eno processor type specified for linking} \
%{!mcpu=bf561*:-T bfin-common-sc.ld%s} \
%{mcpu=bf561*:%{!mmulticore:-T bfin-common-sc.ld%s} \
diff --git a/gcc/config/bfin/t-bfin-elf b/gcc/config/bfin/t-bfin-elf
index da242a08a21..867a71dce77 100644
--- a/gcc/config/bfin/t-bfin-elf
+++ b/gcc/config/bfin/t-bfin-elf
@@ -58,6 +58,7 @@ MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf548m-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf549-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf549m-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf561-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf592-none
MULTILIB_EXCEPTIONS=mleaf-id-shared-library*
MULTILIB_EXCEPTIONS+=mcpu=bf532-none/mleaf-id-shared-library*
diff --git a/gcc/config/bfin/t-bfin-linux b/gcc/config/bfin/t-bfin-linux
index daa1e059ce4..65d8f7a97f3 100644
--- a/gcc/config/bfin/t-bfin-linux
+++ b/gcc/config/bfin/t-bfin-linux
@@ -57,6 +57,7 @@ MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf548m-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf549-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf549m-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf561-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf592-none
SHLIB_MAPFILES=$(srcdir)/config/bfin/libgcc-bfin.ver
diff --git a/gcc/config/bfin/t-bfin-uclinux b/gcc/config/bfin/t-bfin-uclinux
index 0be258f2f11..9990c0d4f2b 100644
--- a/gcc/config/bfin/t-bfin-uclinux
+++ b/gcc/config/bfin/t-bfin-uclinux
@@ -58,6 +58,7 @@ MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf548m-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf549-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf549m-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf561-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf592-none
MULTILIB_EXCEPTIONS=mleaf-id-shared-library*
MULTILIB_EXCEPTIONS+=mcpu=bf532-none/mleaf-id-shared-library*
diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index 89722bb92da..458364bca4a 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -19,7 +19,7 @@
;;; Unused letters:
;;; B H T W
-;;; h jk vw z
+;;; h jk vw
;; Integer register constraints.
;; It is not necessary to define 'r' here.
@@ -90,6 +90,8 @@
;; 2 SSE2 enabled
;; i SSE2 inter-unit moves enabled
;; m MMX inter-unit moves enabled
+;; d Integer register when integer DFmode moves are enabled
+;; x Integer register when integer XFmode moves are enabled
(define_register_constraint "Yz" "TARGET_SSE ? SSE_FIRST_REG : NO_REGS"
"First SSE register (@code{%xmm0}).")
@@ -105,6 +107,18 @@
"TARGET_MMX && TARGET_INTER_UNIT_MOVES ? MMX_REGS : NO_REGS"
"@internal Any MMX register, when inter-unit moves are enabled.")
+(define_register_constraint "Yd"
+ "TARGET_INTEGER_DFMODE_MOVES ? GENERAL_REGS : NO_REGS"
+ "@internal Any integer register when integer DFmode moves are enabled.")
+
+(define_register_constraint "Yx"
+ "optimize_function_for_speed_p (cfun) ? GENERAL_REGS : NO_REGS"
+ "@internal Any integer register when integer XFmode moves are enabled.")
+
+(define_constraint "z"
+ "@internal Constant call address operand."
+ (match_operand 0 "constant_call_address_operand"))
+
;; Integer constant constraints.
(define_constraint "I"
"Integer constant in the range 0 @dots{} 31, for 32-bit shifts."
@@ -149,7 +163,7 @@
(define_constraint "G"
"Standard 80387 floating point constant."
(and (match_code "const_double")
- (match_test "standard_80387_constant_p (op)")))
+ (match_test "standard_80387_constant_p (op) > 0")))
;; This can theoretically be any mode's CONST0_RTX.
(define_constraint "C"
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index 14973513334..56765484364 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -340,14 +340,14 @@ ix86_pragma_target_parse (tree args, tree pop_target)
ix86_target_macros_internal (prev_isa & diff_isa,
prev_arch,
prev_tune,
- (enum fpmath_unit) prev_opt->fpmath,
+ (enum fpmath_unit) prev_opt->x_ix86_fpmath,
cpp_undef);
/* Define all of the macros for new options that were just turned on. */
ix86_target_macros_internal (cur_isa & diff_isa,
cur_arch,
cur_tune,
- (enum fpmath_unit) cur_opt->fpmath,
+ (enum fpmath_unit) cur_opt->x_ix86_fpmath,
cpp_define);
return true;
diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
new file mode 100644
index 00000000000..3cc2253c3c2
--- /dev/null
+++ b/gcc/config/i386/i386-opts.h
@@ -0,0 +1,85 @@
+/* Definitions for option handling for IA-32.
+ Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef I386_OPTS_H
+#define I386_OPTS_H
+
+/* Algorithm to expand string function with. */
+enum stringop_alg
+{
+ no_stringop,
+ libcall,
+ rep_prefix_1_byte,
+ rep_prefix_4_byte,
+ rep_prefix_8_byte,
+ loop_1_byte,
+ loop,
+ unrolled_loop
+};
+
+/* Available call abi. */
+enum calling_abi
+{
+ SYSV_ABI = 0,
+ MS_ABI = 1
+};
+
+enum fpmath_unit
+{
+ FPMATH_387 = 1,
+ FPMATH_SSE = 2
+};
+
+enum tls_dialect
+{
+ TLS_DIALECT_GNU,
+ TLS_DIALECT_GNU2,
+ TLS_DIALECT_SUN
+};
+
+enum cmodel {
+ CM_32, /* The traditional 32-bit ABI. */
+ CM_SMALL, /* Assumes all code and data fits in the low 31 bits. */
+ CM_KERNEL, /* Assumes all code and data fits in the high 31 bits. */
+ CM_MEDIUM, /* Assumes code fits in the low 31 bits; data unlimited. */
+ CM_LARGE, /* No assumptions. */
+ CM_SMALL_PIC, /* Assumes code+data+got/plt fits in a 31 bit region. */
+ CM_MEDIUM_PIC,/* Assumes code+got/plt fits in a 31 bit region. */
+ CM_LARGE_PIC /* No assumptions. */
+};
+
+enum asm_dialect {
+ ASM_ATT,
+ ASM_INTEL
+};
+
+enum ix86_veclibabi {
+ ix86_veclibabi_type_none,
+ ix86_veclibabi_type_svml,
+ ix86_veclibabi_type_acml
+};
+
+#endif
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index ccba8484bdc..5643153ac39 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -67,8 +67,8 @@ extern void split_double_mode (enum machine_mode, rtx[], int, rtx[], rtx[]);
extern const char *output_set_got (rtx, rtx);
extern const char *output_387_binary_op (rtx, rtx*);
extern const char *output_387_reg_move (rtx, rtx*);
-extern const char *output_fix_trunc (rtx, rtx*, int);
-extern const char *output_fp_compare (rtx, rtx*, int, int);
+extern const char *output_fix_trunc (rtx, rtx*, bool);
+extern const char *output_fp_compare (rtx, rtx*, bool, bool);
extern const char *output_adjust_stack_and_probe (rtx);
extern const char *output_probe_stack_range (rtx, rtx);
@@ -114,7 +114,7 @@ extern bool ix86_expand_fp_vcond (rtx[]);
extern bool ix86_expand_int_vcond (rtx[]);
extern void ix86_expand_sse_unpack (rtx[], bool, bool);
extern bool ix86_expand_int_addcc (rtx[]);
-extern rtx ix86_expand_call (rtx, rtx, rtx, rtx, rtx, int);
+extern rtx ix86_expand_call (rtx, rtx, rtx, rtx, rtx, bool);
extern void ix86_split_call_vzeroupper (rtx, rtx);
extern void x86_initialize_trampoline (rtx, rtx, rtx);
extern rtx ix86_zero_extend_to_Pmode (rtx);
@@ -127,9 +127,9 @@ extern bool ix86_check_movabs (rtx, int);
extern void ix86_split_idivmod (enum machine_mode, rtx[], bool);
extern rtx assign_386_stack_local (enum machine_mode, enum ix86_stack_slot);
-extern int ix86_attr_length_immediate_default (rtx, int);
+extern int ix86_attr_length_immediate_default (rtx, bool);
extern int ix86_attr_length_address_default (rtx);
-extern int ix86_attr_length_vex_default (rtx, int, int);
+extern int ix86_attr_length_vex_default (rtx, bool, bool);
extern enum machine_mode ix86_fp_compare_mode (enum rtx_code);
@@ -193,7 +193,6 @@ extern unsigned int ix86_get_callcvt (const_tree);
#endif
-extern rtx ix86_tls_get_addr (void);
extern rtx ix86_tls_module_base (void);
extern void ix86_expand_vector_init (bool, rtx, rtx);
@@ -271,7 +270,7 @@ extern int asm_preferred_eh_data_format (int, int);
extern enum attr_cpu ix86_schedule;
#endif
-extern const char * ix86_output_call_insn (rtx insn, rtx call_op, int addr_op);
+extern const char * ix86_output_call_insn (rtx insn, rtx call_op);
#ifdef RTX_CODE
/* Target data for multipass lookahead scheduling.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index afba1a7049d..0709be819fd 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see
#include "sbitmap.h"
#include "fibheap.h"
#include "opts.h"
+#include "diagnostic.h"
enum upper_128bits_state
{
@@ -2120,8 +2121,6 @@ static const unsigned int x86_arch_always_fancy_math_387
= m_PENT | m_ATOM | m_PPRO | m_AMD_MULTIPLE | m_PENT4
| m_NOCONA | m_CORE2I7 | m_GENERIC;
-static enum stringop_alg stringop_alg = no_stringop;
-
/* In case the average insn count for single function invocation is
lower than this constant, emit fast (but longer) prologue and
epilogue code. */
@@ -2327,16 +2326,6 @@ struct ix86_frame
bool save_regs_using_mov;
};
-/* Code model option. */
-enum cmodel ix86_cmodel;
-/* Asm dialect. */
-enum asm_dialect ix86_asm_dialect = ASM_ATT;
-/* TLS dialects. */
-enum tls_dialect ix86_tls_dialect = TLS_DIALECT_GNU;
-
-/* Which unit we are generating floating point math for. */
-enum fpmath_unit ix86_fpmath;
-
/* Which cpu are we scheduling for. */
enum attr_cpu ix86_schedule;
@@ -2349,9 +2338,6 @@ enum processor_type ix86_arch;
/* true if sse prefetch instruction is not NOOP. */
int x86_prefetch_sse;
-/* ix86_regparm_string as a number */
-static int ix86_regparm;
-
/* -mstackrealign option */
static const char ix86_force_align_arg_pointer_string[]
= "force_align_arg_pointer";
@@ -2380,21 +2366,10 @@ static unsigned int ix86_default_incoming_stack_boundary;
/* Alignment for incoming stack boundary in bits. */
unsigned int ix86_incoming_stack_boundary;
-/* The abi used by target. */
-enum calling_abi ix86_abi;
-
-/* Values 1-5: see jump.c */
-int ix86_branch_cost;
-
/* Calling abi specific va_list type nodes. */
static GTY(()) tree sysv_va_list_type_node;
static GTY(()) tree ms_va_list_type_node;
-/* Variables which are this size or smaller are put in the data/bss
- or ldata/lbss sections. */
-
-int ix86_section_threshold = 65536;
-
/* Prefix built by ASM_GENERATE_INTERNAL_LABEL. */
char internal_label_prefix[16];
int internal_label_prefix_len;
@@ -2452,19 +2427,19 @@ enum ix86_function_specific_strings
{
IX86_FUNCTION_SPECIFIC_ARCH,
IX86_FUNCTION_SPECIFIC_TUNE,
- IX86_FUNCTION_SPECIFIC_FPMATH,
IX86_FUNCTION_SPECIFIC_MAX
};
static char *ix86_target_string (int, int, const char *, const char *,
- const char *, bool);
+ enum fpmath_unit, bool);
static void ix86_debug_options (void) ATTRIBUTE_UNUSED;
static void ix86_function_specific_save (struct cl_target_option *);
static void ix86_function_specific_restore (struct cl_target_option *);
static void ix86_function_specific_print (FILE *, int,
struct cl_target_option *);
static bool ix86_valid_target_attribute_p (tree, tree, tree, int);
-static bool ix86_valid_target_attribute_inner_p (tree, char *[]);
+static bool ix86_valid_target_attribute_inner_p (tree, char *[],
+ struct gcc_options *);
static bool ix86_can_inline_p (tree, tree);
static void ix86_set_current_function (tree);
static unsigned int ix86_minimum_incoming_stack_boundary (bool);
@@ -2688,7 +2663,7 @@ static bool
ix86_handle_option (struct gcc_options *opts,
struct gcc_options *opts_set ATTRIBUTE_UNUSED,
const struct cl_decoded_option *decoded,
- location_t loc ATTRIBUTE_UNUSED)
+ location_t loc)
{
size_t code = decoded->opt_index;
int value = decoded->value;
@@ -3059,6 +3034,45 @@ ix86_handle_option (struct gcc_options *opts,
}
return true;
+ /* Comes from final.c -- no real reason to change it. */
+#define MAX_CODE_ALIGN 16
+
+ case OPT_malign_loops_:
+ warning_at (loc, 0, "-malign-loops is obsolete, use -falign-loops");
+ if (value > MAX_CODE_ALIGN)
+ error_at (loc, "-malign-loops=%d is not between 0 and %d",
+ value, MAX_CODE_ALIGN);
+ else
+ opts->x_align_loops = 1 << value;
+ return true;
+
+ case OPT_malign_jumps_:
+ warning_at (loc, 0, "-malign-jumps is obsolete, use -falign-jumps");
+ if (value > MAX_CODE_ALIGN)
+ error_at (loc, "-malign-jumps=%d is not between 0 and %d",
+ value, MAX_CODE_ALIGN);
+ else
+ opts->x_align_jumps = 1 << value;
+ return true;
+
+ case OPT_malign_functions_:
+ warning_at (loc, 0,
+ "-malign-functions is obsolete, use -falign-functions");
+ if (value > MAX_CODE_ALIGN)
+ error_at (loc, "-malign-functions=%d is not between 0 and %d",
+ value, MAX_CODE_ALIGN);
+ else
+ opts->x_align_functions = 1 << value;
+ return true;
+
+ case OPT_mbranch_cost_:
+ if (value > 5)
+ {
+ error_at (loc, "-mbranch-cost=%d is not between 0 and 5", value);
+ opts->x_ix86_branch_cost = 5;
+ }
+ return true;
+
default:
return true;
}
@@ -3069,7 +3083,7 @@ ix86_handle_option (struct gcc_options *opts,
static char *
ix86_target_string (int isa, int flags, const char *arch, const char *tune,
- const char *fpmath, bool add_nl_p)
+ enum fpmath_unit fpmath, bool add_nl_p)
{
struct ix86_target_opts
{
@@ -3203,7 +3217,23 @@ ix86_target_string (int isa, int flags, const char *arch, const char *tune,
if (fpmath)
{
opts[num][0] = "-mfpmath=";
- opts[num++][1] = fpmath;
+ switch ((int) fpmath)
+ {
+ case FPMATH_387:
+ opts[num++][1] = "387";
+ break;
+
+ case FPMATH_SSE:
+ opts[num++][1] = "sse";
+ break;
+
+ case FPMATH_387 | FPMATH_SSE:
+ opts[num++][1] = "sse+387";
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
}
/* Any options? */
@@ -3278,7 +3308,7 @@ ix86_debug_options (void)
{
char *opts = ix86_target_string (ix86_isa_flags, target_flags,
ix86_arch_string, ix86_tune_string,
- ix86_fpmath_string, true);
+ ix86_fpmath, true);
if (opts)
{
@@ -3305,9 +3335,6 @@ ix86_option_override_internal (bool main_args_p)
const char *suffix;
const char *sw;
- /* Comes from final.c -- no real reason to change it. */
-#define MAX_CODE_ALIGN 16
-
enum pta_flags
{
PTA_SSE = 1 << 0,
@@ -3530,27 +3557,11 @@ ix86_option_override_internal (bool main_args_p)
}
}
- if (ix86_stringop_string)
- {
- if (!strcmp (ix86_stringop_string, "rep_byte"))
- stringop_alg = rep_prefix_1_byte;
- else if (!strcmp (ix86_stringop_string, "libcall"))
- stringop_alg = libcall;
- else if (!strcmp (ix86_stringop_string, "rep_4byte"))
- stringop_alg = rep_prefix_4_byte;
- else if (!strcmp (ix86_stringop_string, "rep_8byte")
- && TARGET_64BIT)
- /* rep; movq isn't available in 32-bit code. */
- stringop_alg = rep_prefix_8_byte;
- else if (!strcmp (ix86_stringop_string, "byte_loop"))
- stringop_alg = loop_1_byte;
- else if (!strcmp (ix86_stringop_string, "loop"))
- stringop_alg = loop;
- else if (!strcmp (ix86_stringop_string, "unrolled_loop"))
- stringop_alg = unrolled_loop;
- else
- error ("bad value (%s) for %sstringop-strategy=%s %s",
- ix86_stringop_string, prefix, suffix, sw);
+ if (ix86_stringop_alg == rep_prefix_8_byte && !TARGET_64BIT)
+ {
+ /* rep; movq isn't available in 32-bit code. */
+ error ("-mstringop-strategy=rep_8byte not supported for 32-bit code");
+ ix86_stringop_alg = no_stringop;
}
if (!ix86_arch_string)
@@ -3558,37 +3569,62 @@ ix86_option_override_internal (bool main_args_p)
else
ix86_arch_specified = 1;
- /* Validate -mabi= value. */
- if (ix86_abi_string)
- {
- if (strcmp (ix86_abi_string, "sysv") == 0)
- ix86_abi = SYSV_ABI;
- else if (strcmp (ix86_abi_string, "ms") == 0)
- ix86_abi = MS_ABI;
- else
- error ("unknown ABI (%s) for %sabi=%s %s",
- ix86_abi_string, prefix, suffix, sw);
- }
- else
+ if (!global_options_set.x_ix86_abi)
ix86_abi = DEFAULT_ABI;
- if (ix86_cmodel_string != 0)
+ if (global_options_set.x_ix86_cmodel)
{
- if (!strcmp (ix86_cmodel_string, "small"))
- ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
- else if (!strcmp (ix86_cmodel_string, "medium"))
- ix86_cmodel = flag_pic ? CM_MEDIUM_PIC : CM_MEDIUM;
- else if (!strcmp (ix86_cmodel_string, "large"))
- ix86_cmodel = flag_pic ? CM_LARGE_PIC : CM_LARGE;
- else if (flag_pic)
- error ("code model %s does not support PIC mode", ix86_cmodel_string);
- else if (!strcmp (ix86_cmodel_string, "32"))
- ix86_cmodel = CM_32;
- else if (!strcmp (ix86_cmodel_string, "kernel") && !flag_pic)
- ix86_cmodel = CM_KERNEL;
- else
- error ("bad value (%s) for %scmodel=%s %s",
- ix86_cmodel_string, prefix, suffix, sw);
+ switch (ix86_cmodel)
+ {
+ case CM_SMALL:
+ case CM_SMALL_PIC:
+ if (flag_pic)
+ ix86_cmodel = CM_SMALL_PIC;
+ if (!TARGET_64BIT)
+ error ("code model %qs not supported in the %s bit mode",
+ "small", "32");
+ break;
+
+ case CM_MEDIUM:
+ case CM_MEDIUM_PIC:
+ if (flag_pic)
+ ix86_cmodel = CM_MEDIUM_PIC;
+ if (!TARGET_64BIT)
+ error ("code model %qs not supported in the %s bit mode",
+ "medium", "32");
+ break;
+
+ case CM_LARGE:
+ case CM_LARGE_PIC:
+ if (flag_pic)
+ ix86_cmodel = CM_LARGE_PIC;
+ if (!TARGET_64BIT)
+ error ("code model %qs not supported in the %s bit mode",
+ "large", "32");
+ break;
+
+ case CM_32:
+ if (flag_pic)
+ error ("code model %s does not support PIC mode", "32");
+ if (TARGET_64BIT)
+ error ("code model %qs not supported in the %s bit mode",
+ "32", "64");
+ break;
+
+ case CM_KERNEL:
+ if (flag_pic)
+ {
+ error ("code model %s does not support PIC mode", "kernel");
+ ix86_cmodel = CM_32;
+ }
+ if (!TARGET_64BIT)
+ error ("code model %qs not supported in the %s bit mode",
+ "kernel", "32");
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
}
else
{
@@ -3603,20 +3639,11 @@ ix86_option_override_internal (bool main_args_p)
else
ix86_cmodel = CM_32;
}
- if (ix86_asm_string != 0)
+ if (TARGET_MACHO && ix86_asm_dialect == ASM_INTEL)
{
- if (! TARGET_MACHO
- && !strcmp (ix86_asm_string, "intel"))
- ix86_asm_dialect = ASM_INTEL;
- else if (!strcmp (ix86_asm_string, "att"))
- ix86_asm_dialect = ASM_ATT;
- else
- error ("bad value (%s) for %sasm=%s %s",
- ix86_asm_string, prefix, suffix, sw);
+ error ("-masm=intel not supported in this configuration");
+ ix86_asm_dialect = ASM_ATT;
}
- if ((TARGET_64BIT == 0) != (ix86_cmodel == CM_32))
- error ("code model %qs not supported in the %s bit mode",
- ix86_cmodel_string, TARGET_64BIT ? "64" : "32");
if ((TARGET_64BIT != 0) != ((ix86_isa_flags & OPTION_MASK_ISA_64BIT) != 0))
sorry ("%i-bit mode not compiled in",
(ix86_isa_flags & OPTION_MASK_ISA_64BIT) ? 64 : 32);
@@ -3836,67 +3863,19 @@ ix86_option_override_internal (bool main_args_p)
init_machine_status = ix86_init_machine_status;
/* Validate -mregparm= value. */
- if (ix86_regparm_string)
+ if (global_options_set.x_ix86_regparm)
{
if (TARGET_64BIT)
- warning (0, "%sregparm%s is ignored in 64-bit mode", prefix, suffix);
- i = atoi (ix86_regparm_string);
- if (i < 0 || i > REGPARM_MAX)
- error ("%sregparm=%d%s is not between 0 and %d",
- prefix, i, suffix, REGPARM_MAX);
- else
- ix86_regparm = i;
- }
- if (TARGET_64BIT)
- ix86_regparm = REGPARM_MAX;
-
- /* If the user has provided any of the -malign-* options,
- warn and use that value only if -falign-* is not set.
- Remove this code in GCC 3.2 or later. */
- if (ix86_align_loops_string)
- {
- warning (0, "%salign-loops%s is obsolete, use -falign-loops%s",
- prefix, suffix, suffix);
- if (align_loops == 0)
- {
- i = atoi (ix86_align_loops_string);
- if (i < 0 || i > MAX_CODE_ALIGN)
- error ("%salign-loops=%d%s is not between 0 and %d",
- prefix, i, suffix, MAX_CODE_ALIGN);
- else
- align_loops = 1 << i;
- }
- }
-
- if (ix86_align_jumps_string)
- {
- warning (0, "%salign-jumps%s is obsolete, use -falign-jumps%s",
- prefix, suffix, suffix);
- if (align_jumps == 0)
+ warning (0, "-mregparm is ignored in 64-bit mode");
+ if (ix86_regparm > REGPARM_MAX)
{
- i = atoi (ix86_align_jumps_string);
- if (i < 0 || i > MAX_CODE_ALIGN)
- error ("%salign-loops=%d%s is not between 0 and %d",
- prefix, i, suffix, MAX_CODE_ALIGN);
- else
- align_jumps = 1 << i;
- }
- }
-
- if (ix86_align_funcs_string)
- {
- warning (0, "%salign-functions%s is obsolete, use -falign-functions%s",
- prefix, suffix, suffix);
- if (align_functions == 0)
- {
- i = atoi (ix86_align_funcs_string);
- if (i < 0 || i > MAX_CODE_ALIGN)
- error ("%salign-loops=%d%s is not between 0 and %d",
- prefix, i, suffix, MAX_CODE_ALIGN);
- else
- align_functions = 1 << i;
+ error ("-mregparm=%d is not between 0 and %d",
+ ix86_regparm, REGPARM_MAX);
+ ix86_regparm = 0;
}
}
+ if (TARGET_64BIT)
+ ix86_regparm = REGPARM_MAX;
/* Default align_* from the processor table. */
if (align_loops == 0)
@@ -3914,42 +3893,9 @@ ix86_option_override_internal (bool main_args_p)
align_functions = processor_target_table[ix86_tune].align_func;
}
- /* Validate -mbranch-cost= value, or provide default. */
- ix86_branch_cost = ix86_cost->branch_cost;
- if (ix86_branch_cost_string)
- {
- i = atoi (ix86_branch_cost_string);
- if (i < 0 || i > 5)
- error ("%sbranch-cost=%d%s is not between 0 and 5", prefix, i, suffix);
- else
- ix86_branch_cost = i;
- }
- if (ix86_section_threshold_string)
- {
- i = atoi (ix86_section_threshold_string);
- if (i < 0)
- error ("%slarge-data-threshold=%d%s is negative", prefix, i, suffix);
- else
- ix86_section_threshold = i;
- }
-
- if (ix86_tls_dialect_string)
- {
- if (strcmp (ix86_tls_dialect_string, "gnu") == 0)
- ix86_tls_dialect = TLS_DIALECT_GNU;
- else if (strcmp (ix86_tls_dialect_string, "gnu2") == 0)
- ix86_tls_dialect = TLS_DIALECT_GNU2;
- else
- error ("bad value (%s) for %stls-dialect=%s %s",
- ix86_tls_dialect_string, prefix, suffix, sw);
- }
-
- if (ix87_precision_string)
- {
- i = atoi (ix87_precision_string);
- if (i != 32 && i != 64 && i != 80)
- error ("pc%d is not valid precision setting (32, 64 or 80)", i);
- }
+ /* Provide default for -mbranch-cost= value. */
+ if (!global_options_set.x_ix86_branch_cost)
+ ix86_branch_cost = ix86_cost->branch_cost;
if (TARGET_64BIT)
{
@@ -4001,6 +3947,13 @@ ix86_option_override_internal (bool main_args_p)
if (!TARGET_80387)
target_flags |= MASK_NO_FANCY_MATH_387;
+ /* On 32bit targets, avoid moving DFmode values in
+ integer registers when optimizing for size. */
+ if (TARGET_64BIT)
+ target_flags |= TARGET_INTEGER_DFMODE_MOVES;
+ else if (optimize_size)
+ target_flags &= ~TARGET_INTEGER_DFMODE_MOVES;
+
/* Turn on MMX builtins for -msse. */
if (TARGET_SSE)
{
@@ -4015,23 +3968,24 @@ ix86_option_override_internal (bool main_args_p)
/* Validate -mpreferred-stack-boundary= value or default it to
PREFERRED_STACK_BOUNDARY_DEFAULT. */
ix86_preferred_stack_boundary = PREFERRED_STACK_BOUNDARY_DEFAULT;
- if (ix86_preferred_stack_boundary_string)
+ if (global_options_set.x_ix86_preferred_stack_boundary_arg)
{
int min = (TARGET_64BIT ? 4 : 2);
int max = (TARGET_SEH ? 4 : 12);
- i = atoi (ix86_preferred_stack_boundary_string);
- if (i < min || i > max)
+ if (ix86_preferred_stack_boundary_arg < min
+ || ix86_preferred_stack_boundary_arg > max)
{
if (min == max)
- error ("%spreferred-stack-boundary%s is not supported "
- "for this target", prefix, suffix);
+ error ("-mpreferred-stack-boundary is not supported "
+ "for this target");
else
- error ("%spreferred-stack-boundary=%d%s is not between %d and %d",
- prefix, i, suffix, min, max);
+ error ("-mpreferred-stack-boundary=%d is not between %d and %d",
+ ix86_preferred_stack_boundary_arg, min, max);
}
else
- ix86_preferred_stack_boundary = (1 << i) * BITS_PER_UNIT;
+ ix86_preferred_stack_boundary
+ = (1 << ix86_preferred_stack_boundary_arg) * BITS_PER_UNIT;
}
/* Set the default value for -mstackrealign. */
@@ -4043,15 +3997,16 @@ ix86_option_override_internal (bool main_args_p)
/* Validate -mincoming-stack-boundary= value or default it to
MIN_STACK_BOUNDARY/PREFERRED_STACK_BOUNDARY. */
ix86_incoming_stack_boundary = ix86_default_incoming_stack_boundary;
- if (ix86_incoming_stack_boundary_string)
+ if (global_options_set.x_ix86_incoming_stack_boundary_arg)
{
- i = atoi (ix86_incoming_stack_boundary_string);
- if (i < (TARGET_64BIT ? 4 : 2) || i > 12)
+ if (ix86_incoming_stack_boundary_arg < (TARGET_64BIT ? 4 : 2)
+ || ix86_incoming_stack_boundary_arg > 12)
error ("-mincoming-stack-boundary=%d is not between %d and 12",
- i, TARGET_64BIT ? 4 : 2);
+ ix86_incoming_stack_boundary_arg, TARGET_64BIT ? 4 : 2);
else
{
- ix86_user_incoming_stack_boundary = (1 << i) * BITS_PER_UNIT;
+ ix86_user_incoming_stack_boundary
+ = (1 << ix86_incoming_stack_boundary_arg) * BITS_PER_UNIT;
ix86_incoming_stack_boundary
= ix86_user_incoming_stack_boundary;
}
@@ -4062,61 +4017,44 @@ ix86_option_override_internal (bool main_args_p)
&& ! TARGET_SSE)
error ("%ssseregparm%s used without SSE enabled", prefix, suffix);
- ix86_fpmath = TARGET_FPMATH_DEFAULT;
- if (ix86_fpmath_string != 0)
+ if (global_options_set.x_ix86_fpmath)
{
- if (! strcmp (ix86_fpmath_string, "387"))
- ix86_fpmath = FPMATH_387;
- else if (! strcmp (ix86_fpmath_string, "sse"))
+ if (ix86_fpmath & FPMATH_SSE)
{
if (!TARGET_SSE)
{
warning (0, "SSE instruction set disabled, using 387 arithmetics");
ix86_fpmath = FPMATH_387;
}
- else
- ix86_fpmath = FPMATH_SSE;
- }
- else if (! strcmp (ix86_fpmath_string, "387,sse")
- || ! strcmp (ix86_fpmath_string, "387+sse")
- || ! strcmp (ix86_fpmath_string, "sse,387")
- || ! strcmp (ix86_fpmath_string, "sse+387")
- || ! strcmp (ix86_fpmath_string, "both"))
- {
- if (!TARGET_SSE)
- {
- warning (0, "SSE instruction set disabled, using 387 arithmetics");
- ix86_fpmath = FPMATH_387;
- }
- else if (!TARGET_80387)
+ else if ((ix86_fpmath & FPMATH_387) && !TARGET_80387)
{
warning (0, "387 instruction set disabled, using SSE arithmetics");
ix86_fpmath = FPMATH_SSE;
}
- else
- ix86_fpmath = (enum fpmath_unit) (FPMATH_SSE | FPMATH_387);
}
- else
- error ("bad value (%s) for %sfpmath=%s %s",
- ix86_fpmath_string, prefix, suffix, sw);
}
+ else
+ ix86_fpmath = TARGET_FPMATH_DEFAULT;
/* If the i387 is disabled, then do not return values in it. */
if (!TARGET_80387)
target_flags &= ~MASK_FLOAT_RETURNS;
/* Use external vectorized library in vectorizing intrinsics. */
- if (ix86_veclibabi_string)
- {
- if (strcmp (ix86_veclibabi_string, "svml") == 0)
+ if (global_options_set.x_ix86_veclibabi_type)
+ switch (ix86_veclibabi_type)
+ {
+ case ix86_veclibabi_type_svml:
ix86_veclib_handler = ix86_veclibabi_svml;
- else if (strcmp (ix86_veclibabi_string, "acml") == 0)
+ break;
+
+ case ix86_veclibabi_type_acml:
ix86_veclib_handler = ix86_veclibabi_acml;
- else
- error ("unknown vectorization library ABI type (%s) for "
- "%sveclibabi=%s %s", ix86_veclibabi_string,
- prefix, suffix, sw);
- }
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
if ((!USE_IX86_FRAME_POINTER
|| (x86_accumulate_outgoing_args & ix86_tune_mask))
@@ -4153,8 +4091,9 @@ ix86_option_override_internal (bool main_args_p)
}
/* For sane SSE instruction set generation we need fcomi instruction.
- It is safe to enable all CMOVE instructions. */
- if (TARGET_SSE)
+ It is safe to enable all CMOVE instructions. Also, RDRAND intrinsic
+ expands to a sequence that includes conditional move. */
+ if (TARGET_SSE || TARGET_RDRND)
TARGET_CMOVE = 1;
/* Figure out what ASM_GENERATE_INTERNAL_LABEL builds as a prefix. */
@@ -4400,7 +4339,6 @@ ix86_function_specific_save (struct cl_target_option *ptr)
ptr->arch = ix86_arch;
ptr->schedule = ix86_schedule;
ptr->tune = ix86_tune;
- ptr->fpmath = ix86_fpmath;
ptr->branch_cost = ix86_branch_cost;
ptr->tune_defaulted = ix86_tune_defaulted;
ptr->arch_specified = ix86_arch_specified;
@@ -4412,7 +4350,6 @@ ix86_function_specific_save (struct cl_target_option *ptr)
gcc_assert (ptr->arch == ix86_arch);
gcc_assert (ptr->schedule == ix86_schedule);
gcc_assert (ptr->tune == ix86_tune);
- gcc_assert (ptr->fpmath == ix86_fpmath);
gcc_assert (ptr->branch_cost == ix86_branch_cost);
}
@@ -4429,7 +4366,6 @@ ix86_function_specific_restore (struct cl_target_option *ptr)
ix86_arch = (enum processor_type) ptr->arch;
ix86_schedule = (enum attr_cpu) ptr->schedule;
ix86_tune = (enum processor_type) ptr->tune;
- ix86_fpmath = (enum fpmath_unit) ptr->fpmath;
ix86_branch_cost = ptr->branch_cost;
ix86_tune_defaulted = ptr->tune_defaulted;
ix86_arch_specified = ptr->arch_specified;
@@ -4463,7 +4399,7 @@ ix86_function_specific_print (FILE *file, int indent,
{
char *target_string
= ix86_target_string (ptr->x_ix86_isa_flags, ptr->x_target_flags,
- NULL, NULL, NULL, false);
+ NULL, NULL, ptr->x_ix86_fpmath, false);
fprintf (file, "%*sarch = %d (%s)\n",
indent, "",
@@ -4479,9 +4415,6 @@ ix86_function_specific_print (FILE *file, int indent,
? cpu_names[ptr->tune]
: "<unknown>"));
- fprintf (file, "%*sfpmath = %d%s%s\n", indent, "", ptr->fpmath,
- (ptr->fpmath & FPMATH_387) ? ", 387" : "",
- (ptr->fpmath & FPMATH_SSE) ? ", sse" : "");
fprintf (file, "%*sbranch_cost = %d\n", indent, "", ptr->branch_cost);
if (target_string)
@@ -4497,13 +4430,15 @@ ix86_function_specific_print (FILE *file, int indent,
over the list. */
static bool
-ix86_valid_target_attribute_inner_p (tree args, char *p_strings[])
+ix86_valid_target_attribute_inner_p (tree args, char *p_strings[],
+ struct gcc_options *enum_opts_set)
{
char *next_optstr;
bool ret = true;
#define IX86_ATTR_ISA(S,O) { S, sizeof (S)-1, ix86_opt_isa, O, 0 }
#define IX86_ATTR_STR(S,O) { S, sizeof (S)-1, ix86_opt_str, O, 0 }
+#define IX86_ATTR_ENUM(S,O) { S, sizeof (S)-1, ix86_opt_enum, O, 0 }
#define IX86_ATTR_YES(S,O,M) { S, sizeof (S)-1, ix86_opt_yes, O, M }
#define IX86_ATTR_NO(S,O,M) { S, sizeof (S)-1, ix86_opt_no, O, M }
@@ -4513,6 +4448,7 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[])
ix86_opt_yes,
ix86_opt_no,
ix86_opt_str,
+ ix86_opt_enum,
ix86_opt_isa
};
@@ -4549,9 +4485,11 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[])
IX86_ATTR_ISA ("rdrnd", OPT_mrdrnd),
IX86_ATTR_ISA ("f16c", OPT_mf16c),
+ /* enum options */
+ IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_),
+
/* string options */
IX86_ATTR_STR ("arch=", IX86_FUNCTION_SPECIFIC_ARCH),
- IX86_ATTR_STR ("fpmath=", IX86_FUNCTION_SPECIFIC_FPMATH),
IX86_ATTR_STR ("tune=", IX86_FUNCTION_SPECIFIC_TUNE),
/* flag options */
@@ -4592,7 +4530,8 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[])
for (; args; args = TREE_CHAIN (args))
if (TREE_VALUE (args)
- && !ix86_valid_target_attribute_inner_p (TREE_VALUE (args), p_strings))
+ && !ix86_valid_target_attribute_inner_p (TREE_VALUE (args),
+ p_strings, enum_opts_set))
ret = false;
return ret;
@@ -4648,7 +4587,9 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[])
type = attrs[i].type;
opt_len = attrs[i].len;
if (ch == attrs[i].string[0]
- && ((type != ix86_opt_str) ? len == opt_len : len > opt_len)
+ && ((type != ix86_opt_str && type != ix86_opt_enum)
+ ? len == opt_len
+ : len > opt_len)
&& memcmp (p, attrs[i].string, opt_len) == 0)
{
opt = attrs[i].opt;
@@ -4696,6 +4637,23 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[])
p_strings[opt] = xstrdup (p + opt_len);
}
+ else if (type == ix86_opt_enum)
+ {
+ bool arg_ok;
+ int value;
+
+ arg_ok = opt_enum_arg_to_value (opt, p + opt_len, &value, CL_TARGET);
+ if (arg_ok)
+ set_option (&global_options, enum_opts_set, opt, value,
+ p + opt_len, DK_UNSPECIFIED, input_location,
+ global_dc);
+ else
+ {
+ error ("attribute(target(\"%s\")) is unknown", orig_p);
+ ret = false;
+ }
+ }
+
else
gcc_unreachable ();
}
@@ -4710,17 +4668,21 @@ ix86_valid_target_attribute_tree (tree args)
{
const char *orig_arch_string = ix86_arch_string;
const char *orig_tune_string = ix86_tune_string;
- const char *orig_fpmath_string = ix86_fpmath_string;
+ enum fpmath_unit orig_fpmath_set = global_options_set.x_ix86_fpmath;
int orig_tune_defaulted = ix86_tune_defaulted;
int orig_arch_specified = ix86_arch_specified;
- char *option_strings[IX86_FUNCTION_SPECIFIC_MAX] = { NULL, NULL, NULL };
+ char *option_strings[IX86_FUNCTION_SPECIFIC_MAX] = { NULL, NULL };
tree t = NULL_TREE;
int i;
struct cl_target_option *def
= TREE_TARGET_OPTION (target_option_default_node);
+ struct gcc_options enum_opts_set;
+
+ memset (&enum_opts_set, 0, sizeof (enum_opts_set));
/* Process each of the options on the chain. */
- if (! ix86_valid_target_attribute_inner_p (args, option_strings))
+ if (! ix86_valid_target_attribute_inner_p (args, option_strings,
+ &enum_opts_set))
return NULL_TREE;
/* If the changed options are different from the default, rerun
@@ -4731,7 +4693,7 @@ ix86_valid_target_attribute_tree (tree args)
|| target_flags != def->x_target_flags
|| option_strings[IX86_FUNCTION_SPECIFIC_ARCH]
|| option_strings[IX86_FUNCTION_SPECIFIC_TUNE]
- || option_strings[IX86_FUNCTION_SPECIFIC_FPMATH])
+ || enum_opts_set.x_ix86_fpmath)
{
/* If we are using the default tune= or arch=, undo the string assigned,
and use the default. */
@@ -4746,10 +4708,13 @@ ix86_valid_target_attribute_tree (tree args)
ix86_tune_string = NULL;
/* If fpmath= is not set, and we now have sse2 on 32-bit, use it. */
- if (option_strings[IX86_FUNCTION_SPECIFIC_FPMATH])
- ix86_fpmath_string = option_strings[IX86_FUNCTION_SPECIFIC_FPMATH];
+ if (enum_opts_set.x_ix86_fpmath)
+ global_options_set.x_ix86_fpmath = (enum fpmath_unit) 1;
else if (!TARGET_64BIT && TARGET_SSE)
- ix86_fpmath_string = "sse,387";
+ {
+ ix86_fpmath = (enum fpmath_unit) (FPMATH_SSE | FPMATH_387);
+ global_options_set.x_ix86_fpmath = (enum fpmath_unit) 1;
+ }
/* Do any overrides, such as arch=xxx, or tune=xxx support. */
ix86_option_override_internal (false);
@@ -4763,7 +4728,7 @@ ix86_valid_target_attribute_tree (tree args)
ix86_arch_string = orig_arch_string;
ix86_tune_string = orig_tune_string;
- ix86_fpmath_string = orig_fpmath_string;
+ global_options_set.x_ix86_fpmath = orig_fpmath_set;
/* Free up memory allocated to hold the strings */
for (i = 0; i < IX86_FUNCTION_SPECIFIC_MAX; i++)
@@ -4861,7 +4826,7 @@ ix86_can_inline_p (tree caller, tree callee)
else if (caller_opts->tune != callee_opts->tune)
ret = false;
- else if (caller_opts->fpmath != callee_opts->fpmath)
+ else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath)
ret = false;
else if (caller_opts->branch_cost != callee_opts->branch_cost)
@@ -8643,17 +8608,17 @@ standard_sse_constant_opcode (rtx insn, rtx x)
switch (get_attr_mode (insn))
{
case MODE_V4SF:
- return TARGET_AVX ? "vxorps\t%0, %0, %0" : "xorps\t%0, %0";
+ return "%vxorps\t%0, %d0";
case MODE_V2DF:
if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return TARGET_AVX ? "vxorps\t%0, %0, %0" : "xorps\t%0, %0";
+ return "%vxorps\t%0, %d0";
else
- return TARGET_AVX ? "vxorpd\t%0, %0, %0" : "xorpd\t%0, %0";
+ return "%vxorpd\t%0, %d0";
case MODE_TI:
if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return TARGET_AVX ? "vxorps\t%0, %0, %0" : "xorps\t%0, %0";
+ return "%vxorps\t%0, %d0";
else
- return TARGET_AVX ? "vpxor\t%0, %0, %0" : "pxor\t%0, %0";
+ return "%vpxor\t%0, %d0";
case MODE_V8SF:
return "vxorps\t%x0, %x0, %x0";
case MODE_V4DF:
@@ -8670,7 +8635,7 @@ standard_sse_constant_opcode (rtx insn, rtx x)
break;
}
case 2:
- return TARGET_AVX ? "vpcmpeqd\t%0, %0, %0" : "pcmpeqd\t%0, %0";
+ return "%vpcmpeqd\t%0, %d0";
default:
break;
}
@@ -8804,6 +8769,10 @@ ix86_code_end (void)
rtx xops[2];
int regno;
+#ifdef TARGET_SOLARIS
+ solaris_code_end ();
+#endif
+
for (regno = AX_REG; regno <= SP_REG; regno++)
{
char name[32];
@@ -9064,9 +9033,10 @@ ix86_select_alt_pic_regnum (void)
return INVALID_REGNUM;
}
-/* Return 1 if we need to save REGNO. */
-static int
-ix86_save_reg (unsigned int regno, int maybe_eh_return)
+/* Return TRUE if we need to save REGNO. */
+
+static bool
+ix86_save_reg (unsigned int regno, bool maybe_eh_return)
{
if (pic_offset_table_rtx
&& regno == REAL_PIC_OFFSET_TABLE_REGNUM
@@ -9074,11 +9044,7 @@ ix86_save_reg (unsigned int regno, int maybe_eh_return)
|| crtl->profile
|| crtl->calls_eh_return
|| crtl->uses_const_pool))
- {
- if (ix86_select_alt_pic_regnum () != INVALID_REGNUM)
- return 0;
- return 1;
- }
+ return ix86_select_alt_pic_regnum () == INVALID_REGNUM;
if (crtl->calls_eh_return && maybe_eh_return)
{
@@ -9089,12 +9055,12 @@ ix86_save_reg (unsigned int regno, int maybe_eh_return)
if (test == INVALID_REGNUM)
break;
if (test == regno)
- return 1;
+ return true;
}
}
if (crtl->drap_reg && regno == REGNO (crtl->drap_reg))
- return 1;
+ return true;
return (df_regs_ever_live_p (regno)
&& !call_used_regs[regno]
@@ -10898,7 +10864,7 @@ ix86_emit_leave (void)
First register is restored from CFA - CFA_OFFSET. */
static void
ix86_emit_restore_regs_using_mov (HOST_WIDE_INT cfa_offset,
- int maybe_eh_return)
+ bool maybe_eh_return)
{
struct machine_function *m = cfun->machine;
unsigned int regno;
@@ -10937,7 +10903,7 @@ ix86_emit_restore_regs_using_mov (HOST_WIDE_INT cfa_offset,
First register is restored from CFA - CFA_OFFSET. */
static void
ix86_emit_restore_sse_regs_using_mov (HOST_WIDE_INT cfa_offset,
- int maybe_eh_return)
+ bool maybe_eh_return)
{
unsigned int regno;
@@ -11556,7 +11522,7 @@ ix86_expand_split_stack_prologue (void)
}
call_insn = ix86_expand_call (NULL_RTX, gen_rtx_MEM (QImode, fn),
GEN_INT (UNITS_PER_WORD), constm1_rtx,
- NULL_RTX, 0);
+ NULL_RTX, false);
add_function_usage_to (call_insn, call_fusage);
/* In order to make call/return prediction work right, we now need
@@ -12657,7 +12623,7 @@ legitimize_pic_address (rtx orig, rtx reg)
/* Load the thread pointer. If TO_REG is true, force it into a register. */
static rtx
-get_thread_pointer (int to_reg)
+get_thread_pointer (bool to_reg)
{
rtx tp, reg, insn;
@@ -12672,76 +12638,154 @@ get_thread_pointer (int to_reg)
return reg;
}
+/* Construct the SYMBOL_REF for the tls_get_addr function. */
+
+static GTY(()) rtx ix86_tls_symbol;
+
+static rtx
+ix86_tls_get_addr (void)
+{
+ if (!ix86_tls_symbol)
+ {
+ const char *sym
+ = ((TARGET_ANY_GNU_TLS && !TARGET_64BIT)
+ ? "___tls_get_addr" : "__tls_get_addr");
+
+ ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, sym);
+ }
+
+ return ix86_tls_symbol;
+}
+
+/* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
+
+static GTY(()) rtx ix86_tls_module_base_symbol;
+
+rtx
+ix86_tls_module_base (void)
+{
+ if (!ix86_tls_module_base_symbol)
+ {
+ ix86_tls_module_base_symbol
+ = gen_rtx_SYMBOL_REF (Pmode, "_TLS_MODULE_BASE_");
+
+ SYMBOL_REF_FLAGS (ix86_tls_module_base_symbol)
+ |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
+ }
+
+ return ix86_tls_module_base_symbol;
+}
+
/* A subroutine of ix86_legitimize_address and ix86_expand_move. FOR_MOV is
false if we expect this to be used for a memory address and true if
we expect to load the address into a register. */
static rtx
-legitimize_tls_address (rtx x, enum tls_model model, int for_mov)
+legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
{
- rtx dest, base, off, pic, tp;
+ rtx dest, base, off;
+ rtx pic = NULL_RTX, tp = NULL_RTX;
int type;
switch (model)
{
case TLS_MODEL_GLOBAL_DYNAMIC:
dest = gen_reg_rtx (Pmode);
- tp = TARGET_GNU2_TLS ? get_thread_pointer (1) : 0;
- if (TARGET_64BIT && ! TARGET_GNU2_TLS)
+ if (!TARGET_64BIT)
{
- rtx rax = gen_rtx_REG (Pmode, AX_REG), insns;
-
- start_sequence ();
- emit_call_insn (gen_tls_global_dynamic_64 (rax, x));
- insns = get_insns ();
- end_sequence ();
-
- RTL_CONST_CALL_P (insns) = 1;
- emit_libcall_block (insns, dest, rax, x);
+ if (flag_pic)
+ pic = pic_offset_table_rtx;
+ else
+ {
+ pic = gen_reg_rtx (Pmode);
+ emit_insn (gen_set_got (pic));
+ }
}
- else if (TARGET_64BIT && TARGET_GNU2_TLS)
- emit_insn (gen_tls_global_dynamic_64 (dest, x));
- else
- emit_insn (gen_tls_global_dynamic_32 (dest, x));
if (TARGET_GNU2_TLS)
{
+ if (TARGET_64BIT)
+ emit_insn (gen_tls_dynamic_gnu2_64 (dest, x));
+ else
+ emit_insn (gen_tls_dynamic_gnu2_32 (dest, x, pic));
+
+ tp = get_thread_pointer (true);
dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, tp, dest));
set_unique_reg_note (get_last_insn (), REG_EQUIV, x);
}
+ else
+ {
+ rtx caddr = ix86_tls_get_addr ();
+
+ if (TARGET_64BIT)
+ {
+ rtx rax = gen_rtx_REG (Pmode, AX_REG), insns;
+
+ start_sequence ();
+ emit_call_insn (gen_tls_global_dynamic_64 (rax, x, caddr));
+ insns = get_insns ();
+ end_sequence ();
+
+ RTL_CONST_CALL_P (insns) = 1;
+ emit_libcall_block (insns, dest, rax, x);
+ }
+ else
+ emit_insn (gen_tls_global_dynamic_32 (dest, x, pic, caddr));
+ }
break;
case TLS_MODEL_LOCAL_DYNAMIC:
base = gen_reg_rtx (Pmode);
- tp = TARGET_GNU2_TLS ? get_thread_pointer (1) : 0;
- if (TARGET_64BIT && ! TARGET_GNU2_TLS)
+ if (!TARGET_64BIT)
{
- rtx rax = gen_rtx_REG (Pmode, AX_REG), insns, note;
-
- start_sequence ();
- emit_call_insn (gen_tls_local_dynamic_base_64 (rax));
- insns = get_insns ();
- end_sequence ();
-
- note = gen_rtx_EXPR_LIST (VOIDmode, const0_rtx, NULL);
- note = gen_rtx_EXPR_LIST (VOIDmode, ix86_tls_get_addr (), note);
- RTL_CONST_CALL_P (insns) = 1;
- emit_libcall_block (insns, base, rax, note);
+ if (flag_pic)
+ pic = pic_offset_table_rtx;
+ else
+ {
+ pic = gen_reg_rtx (Pmode);
+ emit_insn (gen_set_got (pic));
+ }
}
- else if (TARGET_64BIT && TARGET_GNU2_TLS)
- emit_insn (gen_tls_local_dynamic_base_64 (base));
- else
- emit_insn (gen_tls_local_dynamic_base_32 (base));
if (TARGET_GNU2_TLS)
{
- rtx x = ix86_tls_module_base ();
+ rtx tmp = ix86_tls_module_base ();
+
+ if (TARGET_64BIT)
+ emit_insn (gen_tls_dynamic_gnu2_64 (base, tmp));
+ else
+ emit_insn (gen_tls_dynamic_gnu2_32 (base, tmp, pic));
+ tp = get_thread_pointer (true);
set_unique_reg_note (get_last_insn (), REG_EQUIV,
- gen_rtx_MINUS (Pmode, x, tp));
+ gen_rtx_MINUS (Pmode, tmp, tp));
+ }
+ else
+ {
+ rtx caddr = ix86_tls_get_addr ();
+
+ if (TARGET_64BIT)
+ {
+ rtx rax = gen_rtx_REG (Pmode, AX_REG), insns, eqv;
+
+ start_sequence ();
+ emit_call_insn (gen_tls_local_dynamic_base_64 (rax, caddr));
+ insns = get_insns ();
+ end_sequence ();
+
+ /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
+ share the LD_BASE result with other LD model accesses. */
+ eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
+ UNSPEC_TLS_LD_BASE);
+
+ RTL_CONST_CALL_P (insns) = 1;
+ emit_libcall_block (insns, base, rax, eqv);
+ }
+ else
+ emit_insn (gen_tls_local_dynamic_base_32 (base, pic, caddr));
}
off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
@@ -12755,7 +12799,6 @@ legitimize_tls_address (rtx x, enum tls_model model, int for_mov)
set_unique_reg_note (get_last_insn (), REG_EQUIV, x);
}
-
break;
case TLS_MODEL_INITIAL_EXEC:
@@ -15158,7 +15201,7 @@ emit_i387_cw_initialization (int mode)
operand may be [SDX]Fmode. */
const char *
-output_fix_trunc (rtx insn, rtx *operands, int fisttp)
+output_fix_trunc (rtx insn, rtx *operands, bool fisttp)
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
int dimode_p = GET_MODE (operands[0]) == DImode;
@@ -15223,7 +15266,7 @@ output_387_ffreep (rtx *operands ATTRIBUTE_UNUSED, int opno)
should be used. UNORDERED_P is true when fucom should be used. */
const char *
-output_fp_compare (rtx insn, rtx *operands, int eflags_p, int unordered_p)
+output_fp_compare (rtx insn, rtx *operands, bool eflags_p, bool unordered_p)
{
int stack_top_dies;
rtx cmp_op0, cmp_op1;
@@ -20797,8 +20840,8 @@ decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT expected_size, bool memset,
algs = &cost->memset[TARGET_64BIT != 0];
else
algs = &cost->memcpy[TARGET_64BIT != 0];
- if (stringop_alg != no_stringop && ALG_USABLE_P (stringop_alg))
- return stringop_alg;
+ if (ix86_stringop_alg != no_stringop && ALG_USABLE_P (ix86_stringop_alg))
+ return ix86_stringop_alg;
/* rep; movq or rep; movl is the smallest variant. */
else if (!optimize_for_speed)
{
@@ -21923,7 +21966,7 @@ construct_plt_address (rtx symbol)
rtx
ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
rtx callarg2,
- rtx pop, int sibcall)
+ rtx pop, bool sibcall)
{
rtx use = NULL, call;
@@ -22055,23 +22098,25 @@ ix86_split_call_vzeroupper (rtx insn, rtx vzeroupper)
/* Output the assembly for a call instruction. */
const char *
-ix86_output_call_insn (rtx insn, rtx call_op, int addr_op)
+ix86_output_call_insn (rtx insn, rtx call_op)
{
bool direct_p = constant_call_address_operand (call_op, Pmode);
bool seh_nop_p = false;
-
- gcc_assert (addr_op == 0 || addr_op == 1);
+ const char *xasm;
if (SIBLING_CALL_P (insn))
{
if (direct_p)
- return addr_op ? "jmp\t%P1" : "jmp\t%P0";
+ xasm = "jmp\t%P0";
/* SEH epilogue detection requires the indirect branch case
to include REX.W. */
else if (TARGET_SEH)
- return addr_op ? "rex.W jmp %A1" : "rex.W jmp %A0";
+ xasm = "rex.W jmp %A0";
else
- return addr_op ? "jmp\t%A1" : "jmp\t%A0";
+ xasm = "jmp\t%A0";
+
+ output_asm_insn (xasm, &call_op);
+ return "";
}
/* SEH unwinding can require an extra nop to be emitted in several
@@ -22105,19 +22150,16 @@ ix86_output_call_insn (rtx insn, rtx call_op, int addr_op)
}
if (direct_p)
- {
- if (seh_nop_p)
- return addr_op ? "call\t%P1\n\tnop" : "call\t%P0\n\tnop";
- else
- return addr_op ? "call\t%P1" : "call\t%P0";
- }
+ xasm = "call\t%P0";
else
- {
- if (seh_nop_p)
- return addr_op ? "call\t%A1\n\tnop" : "call\t%A0\n\tnop";
- else
- return addr_op ? "call\t%A1" : "call\t%A0";
- }
+ xasm = "call\t%A0";
+
+ output_asm_insn (xasm, &call_op);
+
+ if (seh_nop_p)
+ return "nop";
+
+ return "";
}
/* Clear stack slot assignments remembered from previous functions.
@@ -22166,43 +22208,6 @@ assign_386_stack_local (enum machine_mode mode, enum ix86_stack_slot n)
ix86_stack_locals = s;
return s->rtl;
}
-
-/* Construct the SYMBOL_REF for the tls_get_addr function. */
-
-static GTY(()) rtx ix86_tls_symbol;
-rtx
-ix86_tls_get_addr (void)
-{
-
- if (!ix86_tls_symbol)
- {
- ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode,
- (TARGET_ANY_GNU_TLS
- && !TARGET_64BIT)
- ? "___tls_get_addr"
- : "__tls_get_addr");
- }
-
- return ix86_tls_symbol;
-}
-
-/* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
-
-static GTY(()) rtx ix86_tls_module_base_symbol;
-rtx
-ix86_tls_module_base (void)
-{
-
- if (!ix86_tls_module_base_symbol)
- {
- ix86_tls_module_base_symbol = gen_rtx_SYMBOL_REF (Pmode,
- "_TLS_MODULE_BASE_");
- SYMBOL_REF_FLAGS (ix86_tls_module_base_symbol)
- |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
- }
-
- return ix86_tls_module_base_symbol;
-}
/* Calculate the length of the memory address in the instruction
encoding. Does not include the one-byte modrm, opcode, or prefix. */
@@ -22326,7 +22331,7 @@ memory_address_length (rtx addr)
/* Compute default value for "length_immediate" attribute. When SHORTFORM
is set, expect that insn have 8bit immediate alternative. */
int
-ix86_attr_length_immediate_default (rtx insn, int shortform)
+ix86_attr_length_immediate_default (rtx insn, bool shortform)
{
int len = 0;
int i;
@@ -22436,8 +22441,7 @@ ix86_attr_length_address_default (rtx insn)
2 or 3 byte VEX prefix and 1 opcode byte. */
int
-ix86_attr_length_vex_default (rtx insn, int has_0f_opcode,
- int has_vex_w)
+ix86_attr_length_vex_default (rtx insn, bool has_0f_opcode, bool has_vex_w)
{
int i;
@@ -22504,10 +22508,10 @@ ix86_issue_rate (void)
}
}
-/* A subroutine of ix86_adjust_cost -- return true iff INSN reads flags set
+/* A subroutine of ix86_adjust_cost -- return TRUE iff INSN reads flags set
by DEP_INSN and nothing set by DEP_INSN. */
-static int
+static bool
ix86_flags_dependent (rtx insn, rtx dep_insn, enum attr_type insn_type)
{
rtx set, set2;
@@ -22517,7 +22521,7 @@ ix86_flags_dependent (rtx insn, rtx dep_insn, enum attr_type insn_type)
&& insn_type != TYPE_ICMOV
&& insn_type != TYPE_FCMOV
&& insn_type != TYPE_IBR)
- return 0;
+ return false;
if ((set = single_set (dep_insn)) != 0)
{
@@ -22533,20 +22537,20 @@ ix86_flags_dependent (rtx insn, rtx dep_insn, enum attr_type insn_type)
set2 = SET_DEST (XVECEXP (PATTERN (dep_insn), 0, 0));
}
else
- return 0;
+ return false;
if (!REG_P (set) || REGNO (set) != FLAGS_REG)
- return 0;
+ return false;
/* This test is true if the dependent insn reads the flags but
not any other potentially set register. */
if (!reg_overlap_mentioned_p (set, PATTERN (insn)))
- return 0;
+ return false;
if (set2 && reg_overlap_mentioned_p (set2, PATTERN (insn)))
- return 0;
+ return false;
- return 1;
+ return true;
}
/* Return true iff USE_INSN has a memory address with operands set by
@@ -27398,7 +27402,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
&& !(ix86_builtins_isa[fcode].isa & ix86_isa_flags))
{
char *opts = ix86_target_string (ix86_builtins_isa[fcode].isa, 0, NULL,
- NULL, NULL, false);
+ NULL, (enum fpmath_unit) 0, false);
if (!opts)
error ("%qE needs unknown isa option", fndecl);
@@ -27610,6 +27614,12 @@ rdrand_step:
op0 = gen_reg_rtx (mode0);
emit_insn (GEN_FCN (icode) (op0));
+ arg0 = CALL_EXPR_ARG (exp, 0);
+ op1 = expand_normal (arg0);
+ if (!address_operand (op1, VOIDmode))
+ op1 = copy_addr_to_reg (op1);
+ emit_move_insn (gen_rtx_MEM (mode0, op1), op0);
+
op1 = gen_reg_rtx (SImode);
emit_move_insn (op1, CONST1_RTX (SImode));
@@ -27624,17 +27634,13 @@ rdrand_step:
else
op2 = gen_rtx_SUBREG (SImode, op0, 0);
+ if (target == 0)
+ target = gen_reg_rtx (SImode);
+
pat = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
const0_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, op1,
+ emit_insn (gen_rtx_SET (VOIDmode, target,
gen_rtx_IF_THEN_ELSE (SImode, pat, op2, op1)));
- emit_move_insn (target, op1);
-
- arg0 = CALL_EXPR_ARG (exp, 0);
- op1 = expand_normal (arg0);
- if (!address_operand (op1, VOIDmode))
- op1 = copy_addr_to_reg (op1);
- emit_move_insn (gen_rtx_MEM (mode0, op1), op0);
return target;
default:
@@ -28508,7 +28514,7 @@ ix86_preferred_reload_class (rtx x, reg_class_t regclass)
zero above. We only want to wind up preferring 80387 registers if
we plan on doing computation with them. */
if (TARGET_80387
- && standard_80387_constant_p (x))
+ && standard_80387_constant_p (x) > 0)
{
/* Limit class to non-sse. */
if (regclass == FLOAT_SSE_REGS)
@@ -28959,7 +28965,8 @@ ix86_register_move_cost (enum machine_mode mode, reg_class_t class1_i,
return 2;
}
-/* Return 1 if hard register REGNO can hold a value of machine-mode MODE. */
+/* Return TRUE if hard register REGNO can hold a value of machine-mode
+ MODE. */
bool
ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
@@ -28970,7 +28977,7 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
if (GET_MODE_CLASS (mode) == MODE_CC
|| GET_MODE_CLASS (mode) == MODE_RANDOM
|| GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
- return 0;
+ return false;
if (FP_REGNO_P (regno))
return VALID_FP_MODE_P (mode);
if (SSE_REGNO_P (regno))
@@ -29000,26 +29007,26 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
/* Take care for QImode values - they can be in non-QI regs,
but then they do cause partial register stalls. */
if (regno <= BX_REG || TARGET_64BIT)
- return 1;
+ return true;
if (!TARGET_PARTIAL_REG_STALL)
- return 1;
- return reload_in_progress || reload_completed;
+ return true;
+ return !can_create_pseudo_p ();
}
/* We handle both integer and floats in the general purpose registers. */
else if (VALID_INT_MODE_P (mode))
- return 1;
+ return true;
else if (VALID_FP_MODE_P (mode))
- return 1;
+ return true;
else if (VALID_DFP_MODE_P (mode))
- return 1;
+ return true;
/* Lots of MMX code casts 8 byte vector modes to DImode. If we then go
on to use that value in smaller contexts, this can easily force a
pseudo to be allocated to GENERAL_REGS. Since this is no worse than
supporting DImode, allow it. */
else if (VALID_MMX_REG_MODE_3DNOW (mode) || VALID_MMX_REG_MODE (mode))
- return 1;
+ return true;
- return 0;
+ return false;
}
/* A subroutine of ix86_modes_tieable_p. Return true if MODE is a
@@ -32148,9 +32155,10 @@ void ix86_emit_swsqrtsf (rtx res, rtx a, enum machine_mode mode,
gen_rtx_MULT (mode, e2, e3)));
}
+#ifdef TARGET_SOLARIS
/* Solaris implementation of TARGET_ASM_NAMED_SECTION. */
-static void ATTRIBUTE_UNUSED
+static void
i386_solaris_elf_named_section (const char *name, unsigned int flags,
tree decl)
{
@@ -32164,8 +32172,18 @@ i386_solaris_elf_named_section (const char *name, unsigned int flags,
flags & SECTION_WRITE ? "aw" : "a");
return;
}
+
+#ifndef USE_GAS
+ if (HAVE_COMDAT_GROUP && flags & SECTION_LINKONCE)
+ {
+ solaris_elf_asm_comdat_section (name, flags, decl);
+ return;
+ }
+#endif
+
default_elf_asm_named_section (name, flags, decl);
}
+#endif /* TARGET_SOLARIS */
/* Return the mangling of TYPE if it is an extended fundamental type. */
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 4137ecc6728..8badcbbce61 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -79,18 +79,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "config/vxworks-dummy.h"
-/* Algorithm to expand string function with. */
-enum stringop_alg
-{
- no_stringop,
- libcall,
- rep_prefix_1_byte,
- rep_prefix_4_byte,
- rep_prefix_8_byte,
- loop_1_byte,
- loop,
- unrolled_loop
-};
+#include "config/i386/i386-opts.h"
#define MAX_STRINGOP_ALGS 4
@@ -506,16 +495,6 @@ extern tree x86_mfence;
/* This is re-defined by cygming.h. */
#define TARGET_SEH 0
-/* Available call abi. */
-enum calling_abi
-{
- SYSV_ABI = 0,
- MS_ABI = 1
-};
-
-/* The abi used by target. */
-extern enum calling_abi ix86_abi;
-
/* The default abi used by target. */
#define DEFAULT_ABI SYSV_ABI
@@ -2050,50 +2029,13 @@ enum processor_type
extern enum processor_type ix86_tune;
extern enum processor_type ix86_arch;
-enum fpmath_unit
-{
- FPMATH_387 = 1,
- FPMATH_SSE = 2
-};
-
-extern enum fpmath_unit ix86_fpmath;
-
-enum tls_dialect
-{
- TLS_DIALECT_GNU,
- TLS_DIALECT_GNU2,
- TLS_DIALECT_SUN
-};
-
-extern enum tls_dialect ix86_tls_dialect;
-
-enum cmodel {
- CM_32, /* The traditional 32-bit ABI. */
- CM_SMALL, /* Assumes all code and data fits in the low 31 bits. */
- CM_KERNEL, /* Assumes all code and data fits in the high 31 bits. */
- CM_MEDIUM, /* Assumes code fits in the low 31 bits; data unlimited. */
- CM_LARGE, /* No assumptions. */
- CM_SMALL_PIC, /* Assumes code+data+got/plt fits in a 31 bit region. */
- CM_MEDIUM_PIC,/* Assumes code+got/plt fits in a 31 bit region. */
- CM_LARGE_PIC /* No assumptions. */
-};
-
-extern enum cmodel ix86_cmodel;
-
/* Size of the RED_ZONE area. */
#define RED_ZONE_SIZE 128
/* Reserved area of the red zone for temporaries. */
#define RED_ZONE_RESERVE 8
-enum asm_dialect {
- ASM_ATT,
- ASM_INTEL
-};
-
-extern enum asm_dialect ix86_asm_dialect;
extern unsigned int ix86_preferred_stack_boundary;
extern unsigned int ix86_incoming_stack_boundary;
-extern int ix86_branch_cost, ix86_section_threshold;
/* Smallest class containing REGNO. */
extern enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER];
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index b1fc57314a2..49f1ee747fc 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -414,9 +414,9 @@
(const_int 0)
(eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
imul,icmp,push,pop")
- (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
+ (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
(eq_attr "type" "imov,test")
- (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
+ (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
(eq_attr "type" "call")
(if_then_else (match_operand 0 "constant_call_address_operand" "")
(const_int 4)
@@ -524,11 +524,11 @@
(if_then_else (and (eq_attr "prefix_0f" "1")
(eq_attr "prefix_extra" "0"))
(if_then_else (eq_attr "prefix_vex_w" "1")
- (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
- (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
+ (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
+ (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
(if_then_else (eq_attr "prefix_vex_w" "1")
- (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
- (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
+ (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
+ (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
;; Set when modrm byte is used.
(define_attr "modrm" ""
@@ -1262,7 +1262,7 @@
UNSPEC_FNSTSW))]
"X87_FLOAT_MODE_P (GET_MODE (operands[1]))
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
- "* return output_fp_compare (insn, operands, 0, 0);"
+ "* return output_fp_compare (insn, operands, false, false);"
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set (attr "mode")
@@ -1309,7 +1309,7 @@
(match_operand:XF 2 "register_operand" "f"))]
UNSPEC_FNSTSW))]
"TARGET_80387"
- "* return output_fp_compare (insn, operands, 0, 0);"
+ "* return output_fp_compare (insn, operands, false, false);"
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set_attr "mode" "XF")])
@@ -1343,7 +1343,7 @@
(match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
UNSPEC_FNSTSW))]
"TARGET_80387"
- "* return output_fp_compare (insn, operands, 0, 0);"
+ "* return output_fp_compare (insn, operands, false, false);"
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set_attr "mode" "<MODE>")])
@@ -1378,7 +1378,7 @@
UNSPEC_FNSTSW))]
"X87_FLOAT_MODE_P (GET_MODE (operands[1]))
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
- "* return output_fp_compare (insn, operands, 0, 1);"
+ "* return output_fp_compare (insn, operands, false, true);"
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set (attr "mode")
@@ -1428,7 +1428,7 @@
"X87_FLOAT_MODE_P (GET_MODE (operands[1]))
&& (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
&& (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
- "* return output_fp_compare (insn, operands, 0, 0);"
+ "* return output_fp_compare (insn, operands, false, false);"
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set_attr "fp_int_src" "true")
@@ -1504,7 +1504,7 @@
"TARGET_MIX_SSE_I387
&& SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
- "* return output_fp_compare (insn, operands, 1, 0);"
+ "* return output_fp_compare (insn, operands, true, false);"
[(set_attr "type" "fcmp,ssecomi")
(set_attr "prefix" "orig,maybe_vex")
(set (attr "mode")
@@ -1533,7 +1533,7 @@
"TARGET_SSE_MATH
&& SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
- "* return output_fp_compare (insn, operands, 1, 0);"
+ "* return output_fp_compare (insn, operands, true, false);"
[(set_attr "type" "ssecomi")
(set_attr "prefix" "maybe_vex")
(set (attr "mode")
@@ -1557,7 +1557,7 @@
&& TARGET_CMOVE
&& !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
- "* return output_fp_compare (insn, operands, 1, 0);"
+ "* return output_fp_compare (insn, operands, true, false);"
[(set_attr "type" "fcmp")
(set (attr "mode")
(cond [(match_operand:SF 1 "" "")
@@ -1577,7 +1577,7 @@
"TARGET_MIX_SSE_I387
&& SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
- "* return output_fp_compare (insn, operands, 1, 1);"
+ "* return output_fp_compare (insn, operands, true, true);"
[(set_attr "type" "fcmp,ssecomi")
(set_attr "prefix" "orig,maybe_vex")
(set (attr "mode")
@@ -1606,7 +1606,7 @@
"TARGET_SSE_MATH
&& SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
- "* return output_fp_compare (insn, operands, 1, 1);"
+ "* return output_fp_compare (insn, operands, true, true);"
[(set_attr "type" "ssecomi")
(set_attr "prefix" "maybe_vex")
(set (attr "mode")
@@ -1630,7 +1630,7 @@
&& TARGET_CMOVE
&& !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
- "* return output_fp_compare (insn, operands, 1, 1);"
+ "* return output_fp_compare (insn, operands, true, true);"
[(set_attr "type" "fcmp")
(set (attr "mode")
(cond [(match_operand:SF 1 "" "")
@@ -2702,10 +2702,14 @@
[(const_int 0)]
"ix86_split_long_move (operands); DONE;")
+;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
+;; Size of pushdf using integer instructions is 2+2*memory operand size
+;; On the average, pushdf using integers can be still shorter.
+
(define_insn "*pushdf"
[(set (match_operand:DF 0 "push_operand" "=<,<,<")
- (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
- "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
+ (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
+ ""
{
/* This insn should be already split before reg-stack. */
gcc_unreachable ();
@@ -2714,23 +2718,6 @@
(set_attr "unit" "i387,*,*")
(set_attr "mode" "DF,SI,DF")])
-;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
-;; Size of pushdf using integer instructions is 2+2*memory operand size
-;; On the average, pushdf using integers can be still shorter. Allow this
-;; pattern for optimize_size too.
-
-(define_insn "*pushdf_nointeger"
- [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
- (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
- "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
-{
- /* This insn should be already split before reg-stack. */
- gcc_unreachable ();
-}
- [(set_attr "type" "multi")
- (set_attr "unit" "i387,*,*,*")
- (set_attr "mode" "DF,SI,SI,DF")])
-
;; %%% Kill this when call knows how to work this out.
(define_split
[(set (match_operand:DF 0 "push_operand" "")
@@ -2822,14 +2809,14 @@
return "%vmovaps\t{%1, %0|%0, %1}";
else
return "%vmovdqa\t{%1, %0|%0, %1}";
+
case 2:
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vxorps\t%0, %d0";
- else
- return "%vpxor\t%0, %d0";
+ return standard_sse_constant_opcode (insn, operands[1]);
+
case 3:
case 4:
return "#";
+
default:
gcc_unreachable ();
}
@@ -2862,42 +2849,14 @@
"ix86_split_long_move (operands); DONE;")
(define_insn "*movxf_internal"
- [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
- (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
- "optimize_function_for_speed_p (cfun)
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (reload_in_progress || reload_completed
- || GET_CODE (operands[1]) != CONST_DOUBLE
- || memory_operand (operands[0], XFmode))"
-{
- switch (which_alternative)
- {
- case 0:
- case 1:
- return output_387_reg_move (insn, operands);
-
- case 2:
- return standard_80387_constant_opcode (operands[1]);
-
- case 3: case 4:
- return "#";
-
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "fmov,fmov,fmov,multi,multi")
- (set_attr "mode" "XF,XF,XF,SI,SI")])
-
-;; Do not use integer registers when optimizing for size
-(define_insn "*movxf_internal_nointeger"
- [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
- (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
- "optimize_function_for_size_p (cfun)
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (reload_in_progress || reload_completed
- || standard_80387_constant_p (operands[1])
+ [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,Yx*r ,o")
+ (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
+ "!(MEM_P (operands[0]) && MEM_P (operands[1]))
+ && (!can_create_pseudo_p ()
+ || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| GET_CODE (operands[1]) != CONST_DOUBLE
+ || (optimize_function_for_size_p (cfun)
+ && standard_80387_constant_p (operands[1]) > 0)
|| memory_operand (operands[0], XFmode))"
{
switch (which_alternative)
@@ -2938,12 +2897,14 @@
(match_operand:DF 1 "general_operand"
"fm,f,G,rm,r,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
"TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (reload_in_progress || reload_completed
+ && (!can_create_pseudo_p ()
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || (!(TARGET_SSE2 && TARGET_SSE_MATH)
- && optimize_function_for_size_p (cfun)
- && standard_80387_constant_p (operands[1]))
|| GET_CODE (operands[1]) != CONST_DOUBLE
+ || (optimize_function_for_size_p (cfun)
+ && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
+ && standard_80387_constant_p (operands[1]) > 0)
+ || (TARGET_SSE2 && TARGET_SSE_MATH
+ && standard_sse_constant_p (operands[1]))))
|| memory_operand (operands[0], DFmode))"
{
switch (which_alternative)
@@ -2966,23 +2927,8 @@
return "#";
case 7:
- switch (get_attr_mode (insn))
- {
- case MODE_V4SF:
- return "%vxorps\t%0, %d0";
- case MODE_V2DF:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "%vxorps\t%0, %d0";
- else
- return "%vxorpd\t%0, %d0";
- case MODE_TI:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "%vxorps\t%0, %d0";
- else
- return "%vpxor\t%0, %d0";
- default:
- gcc_unreachable ();
- }
+ return standard_sse_constant_opcode (insn, operands[1]);
+
case 8:
case 9:
case 10:
@@ -3094,21 +3040,25 @@
]
(const_string "DF")))])
+;; Possible store forwarding (partial memory) stall in alternative 4.
(define_insn "*movdf_internal"
[(set (match_operand:DF 0 "nonimmediate_operand"
- "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
+ "=f,m,f,Yd*r ,o ,Y2*x,Y2*x,Y2*x,m ")
(match_operand:DF 1 "general_operand"
- "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
+ "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
"!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && optimize_function_for_speed_p (cfun)
- && TARGET_INTEGER_DFMODE_MOVES
- && (reload_in_progress || reload_completed
+ && (!can_create_pseudo_p ()
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || (!(TARGET_SSE2 && TARGET_SSE_MATH)
- && optimize_function_for_size_p (cfun)
- && standard_80387_constant_p (operands[1]))
|| GET_CODE (operands[1]) != CONST_DOUBLE
- || memory_operand (operands[0], DFmode))"
+ || (!TARGET_INTEGER_DFMODE_MOVES
+ && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
+ && standard_80387_constant_p (operands[1]) > 0)
+ || (TARGET_SSE2 && TARGET_SSE_MATH
+ && standard_sse_constant_p (operands[1])))
+ && !memory_operand (operands[0], DFmode))
+ || ((TARGET_INTEGER_DFMODE_MOVES
+ || !TARGET_MEMORY_MISMATCH_STALL)
+ && memory_operand (operands[0], DFmode)))"
{
switch (which_alternative)
{
@@ -3124,180 +3074,8 @@
return "#";
case 5:
- switch (get_attr_mode (insn))
- {
- case MODE_V4SF:
- return "%vxorps\t%0, %d0";
- case MODE_V2DF:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "%vxorps\t%0, %d0";
- else
- return "%vxorpd\t%0, %d0";
- case MODE_TI:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "%vxorps\t%0, %d0";
- else
- return "%vpxor\t%0, %d0";
- default:
- gcc_unreachable ();
- }
- case 6:
- case 7:
- case 8:
- switch (get_attr_mode (insn))
- {
- case MODE_V4SF:
- return "%vmovaps\t{%1, %0|%0, %1}";
- case MODE_V2DF:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "%vmovaps\t{%1, %0|%0, %1}";
- else
- return "%vmovapd\t{%1, %0|%0, %1}";
- case MODE_TI:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "%vmovaps\t{%1, %0|%0, %1}";
- else
- return "%vmovdqa\t{%1, %0|%0, %1}";
- case MODE_DI:
- return "%vmovq\t{%1, %0|%0, %1}";
- case MODE_DF:
- if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
- return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
- else
- return "%vmovsd\t{%1, %0|%0, %1}";
- case MODE_V1DF:
- if (TARGET_AVX && REG_P (operands[0]))
- return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
- else
- return "%vmovlpd\t{%1, %0|%0, %1}";
- case MODE_V2SF:
- if (TARGET_AVX && REG_P (operands[0]))
- return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
- else
- return "%vmovlps\t{%1, %0|%0, %1}";
- default:
- gcc_unreachable ();
- }
+ return standard_sse_constant_opcode (insn, operands[1]);
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
- (set (attr "prefix")
- (if_then_else (eq_attr "alternative" "0,1,2,3,4")
- (const_string "orig")
- (const_string "maybe_vex")))
- (set (attr "prefix_data16")
- (if_then_else (eq_attr "mode" "V1DF")
- (const_string "1")
- (const_string "*")))
- (set (attr "mode")
- (cond [(eq_attr "alternative" "0,1,2")
- (const_string "DF")
- (eq_attr "alternative" "3,4")
- (const_string "SI")
-
- /* For SSE1, we have many fewer alternatives. */
- (eq (symbol_ref "TARGET_SSE2") (const_int 0))
- (cond [(eq_attr "alternative" "5,6")
- (const_string "V4SF")
- ]
- (const_string "V2SF"))
-
- /* xorps is one byte shorter. */
- (eq_attr "alternative" "5")
- (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
- (const_int 0))
- (const_string "V4SF")
- (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
- (const_int 0))
- (const_string "TI")
- ]
- (const_string "V2DF"))
-
- /* For architectures resolving dependencies on
- whole SSE registers use APD move to break dependency
- chains, otherwise use short move to avoid extra work.
-
- movaps encodes one byte shorter. */
- (eq_attr "alternative" "6")
- (cond
- [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
- (const_int 0))
- (const_string "V4SF")
- (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
- (const_int 0))
- (const_string "V2DF")
- ]
- (const_string "DF"))
- /* For architectures resolving dependencies on register
- parts we may avoid extra work to zero out upper part
- of register. */
- (eq_attr "alternative" "7")
- (if_then_else
- (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
- (const_int 0))
- (const_string "V1DF")
- (const_string "DF"))
- ]
- (const_string "DF")))])
-
-;; Moving is usually shorter when only FP registers are used. This separate
-;; movdf pattern avoids the use of integer registers for FP operations
-;; when optimizing for size.
-
-(define_insn "*movdf_internal_nointeger"
- [(set (match_operand:DF 0 "nonimmediate_operand"
- "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
- (match_operand:DF 1 "general_operand"
- "fm,f,G,*roF,F*r,C ,Y2*x,mY2*x,Y2*x"))]
- "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (optimize_function_for_size_p (cfun)
- || !TARGET_INTEGER_DFMODE_MOVES)
- && (reload_in_progress || reload_completed
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || (!(TARGET_SSE2 && TARGET_SSE_MATH)
- && optimize_function_for_size_p (cfun)
- && !memory_operand (operands[0], DFmode)
- && standard_80387_constant_p (operands[1]))
- || GET_CODE (operands[1]) != CONST_DOUBLE
- || ((optimize_function_for_size_p (cfun)
- || !TARGET_MEMORY_MISMATCH_STALL
- || reload_in_progress || reload_completed)
- && memory_operand (operands[0], DFmode)))"
-{
- switch (which_alternative)
- {
- case 0:
- case 1:
- return output_387_reg_move (insn, operands);
-
- case 2:
- return standard_80387_constant_opcode (operands[1]);
-
- case 3:
- case 4:
- return "#";
-
- case 5:
- switch (get_attr_mode (insn))
- {
- case MODE_V4SF:
- return "%vxorps\t%0, %d0";
- case MODE_V2DF:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "%vxorps\t%0, %d0";
- else
- return "%vxorpd\t%0, %d0";
- case MODE_TI:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "%vxorps\t%0, %d0";
- else
- return "%vpxor\t%0, %d0";
- default:
- gcc_unreachable ();
- }
case 6:
case 7:
case 8:
@@ -3420,11 +3198,14 @@
(match_operand:SF 1 "general_operand"
"fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (reload_in_progress || reload_completed
+ && (!can_create_pseudo_p ()
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
- && standard_80387_constant_p (operands[1]))
|| GET_CODE (operands[1]) != CONST_DOUBLE
+ || (optimize_function_for_size_p (cfun)
+ && ((!TARGET_SSE_MATH
+ && standard_80387_constant_p (operands[1]) > 0)
+ || (TARGET_SSE_MATH
+ && standard_sse_constant_p (operands[1]))))
|| memory_operand (operands[0], SFmode))"
{
switch (which_alternative)
@@ -3439,11 +3220,10 @@
case 3:
case 4:
return "mov{l}\t{%1, %0|%0, %1}";
+
case 5:
- if (get_attr_mode (insn) == MODE_TI)
- return "%vpxor\t%0, %d0";
- else
- return "%vxorps\t%0, %d0";
+ return standard_sse_constant_opcode (insn, operands[1]);
+
case 6:
if (get_attr_mode (insn) == MODE_V4SF)
return "%vmovaps\t{%1, %0|%0, %1}";
@@ -3535,7 +3315,7 @@
}
else if (FP_REG_P (r))
{
- if (!standard_80387_constant_p (c))
+ if (standard_80387_constant_p (c) < 1)
FAIL;
}
else if (MMX_REG_P (r))
@@ -3567,7 +3347,7 @@
}
else if (FP_REG_P (r))
{
- if (!standard_80387_constant_p (c))
+ if (standard_80387_constant_p (c) < 1)
FAIL;
}
else if (MMX_REG_P (r))
@@ -4698,7 +4478,7 @@
&& !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
&& (TARGET_64BIT || <MODE>mode != DImode))
&& TARGET_SSE_MATH)"
- "* return output_fix_trunc (insn, operands, 1);"
+ "* return output_fix_trunc (insn, operands, true);"
[(set_attr "type" "fisttp")
(set_attr "mode" "<MODE>")])
@@ -4782,7 +4562,7 @@
"X87_FLOAT_MODE_P (GET_MODE (operands[1]))
&& !TARGET_FISTTP
&& !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fistp")
(set_attr "i387_cw" "trunc")
(set_attr "mode" "DI")])
@@ -4837,7 +4617,7 @@
"X87_FLOAT_MODE_P (GET_MODE (operands[1]))
&& !TARGET_FISTTP
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fistp")
(set_attr "i387_cw" "trunc")
(set_attr "mode" "<MODE>")])
@@ -11284,56 +11064,134 @@
;; P6 processors will jump to the address after the decrement when %esp
;; is used as a call operand, so they will execute return address as a code.
;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
-
+
+;; Register constraint for call instruction.
+(define_mode_attr c [(SI "l") (DI "r")])
+
;; Call subroutine returning no value.
-(define_expand "call_pop"
- [(parallel [(call (match_operand:QI 0 "" "")
- (match_operand:SI 1 "" ""))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 3 "" "")))])]
- "!TARGET_64BIT"
+(define_expand "call"
+ [(call (match_operand:QI 0 "" "")
+ (match_operand 1 "" ""))
+ (use (match_operand 2 "" ""))]
+ ""
+{
+ ix86_expand_call (NULL, operands[0], operands[1],
+ operands[2], NULL, false);
+ DONE;
+})
+
+(define_expand "sibcall"
+ [(call (match_operand:QI 0 "" "")
+ (match_operand 1 "" ""))
+ (use (match_operand 2 "" ""))]
+ ""
{
ix86_expand_call (NULL, operands[0], operands[1],
- operands[2], operands[3], 0);
+ operands[2], NULL, true);
DONE;
})
-(define_insn_and_split "*call_pop_0_vzeroupper"
+(define_insn_and_split "*call_vzeroupper"
+ [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
+ (match_operand 1 "" ""))
+ (unspec [(match_operand 2 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
+ [(set_attr "type" "call")])
+
+(define_insn "*call"
+ [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
+ (match_operand 1 "" ""))]
+ "!SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[0]);"
+ [(set_attr "type" "call")])
+
+(define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
[(parallel
- [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
- (match_operand:SI 1 "" ""))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 2 "immediate_operand" "")))])
- (unspec [(match_operand 3 "const_int_operand" "")]
+ [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
+ (match_operand 1 "" ""))
+ (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
+ (clobber (reg:TI XMM6_REG))
+ (clobber (reg:TI XMM7_REG))
+ (clobber (reg:TI XMM8_REG))
+ (clobber (reg:TI XMM9_REG))
+ (clobber (reg:TI XMM10_REG))
+ (clobber (reg:TI XMM11_REG))
+ (clobber (reg:TI XMM12_REG))
+ (clobber (reg:TI XMM13_REG))
+ (clobber (reg:TI XMM14_REG))
+ (clobber (reg:TI XMM15_REG))
+ (clobber (reg:DI SI_REG))
+ (clobber (reg:DI DI_REG))])
+ (unspec [(match_operand 2 "const_int_operand" "")]
UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !TARGET_64BIT"
+ "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
"#"
"&& reload_completed"
[(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
+ "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
[(set_attr "type" "call")])
-(define_insn "*call_pop_0"
- [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
- (match_operand:SI 1 "" ""))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 2 "immediate_operand" "")))]
+(define_insn "*call_rex64_ms_sysv"
+ [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
+ (match_operand 1 "" ""))
+ (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
+ (clobber (reg:TI XMM6_REG))
+ (clobber (reg:TI XMM7_REG))
+ (clobber (reg:TI XMM8_REG))
+ (clobber (reg:TI XMM9_REG))
+ (clobber (reg:TI XMM10_REG))
+ (clobber (reg:TI XMM11_REG))
+ (clobber (reg:TI XMM12_REG))
+ (clobber (reg:TI XMM13_REG))
+ (clobber (reg:TI XMM14_REG))
+ (clobber (reg:TI XMM15_REG))
+ (clobber (reg:DI SI_REG))
+ (clobber (reg:DI DI_REG))]
+ "TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[0]);"
+ [(set_attr "type" "call")])
+
+(define_insn_and_split "*sibcall_vzeroupper"
+ [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
+ (match_operand 1 "" ""))
+ (unspec [(match_operand 2 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
+ [(set_attr "type" "call")])
+
+(define_insn "*sibcall"
+ [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
+ (match_operand 1 "" ""))]
+ "SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[0]);"
+ [(set_attr "type" "call")])
+
+(define_expand "call_pop"
+ [(parallel [(call (match_operand:QI 0 "" "")
+ (match_operand:SI 1 "" ""))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 3 "" "")))])]
"!TARGET_64BIT"
{
- if (SIBLING_CALL_P (insn))
- return "jmp\t%P0";
- else
- return "call\t%P0";
-}
- [(set_attr "type" "call")])
+ ix86_expand_call (NULL, operands[0], operands[1],
+ operands[2], operands[3], false);
+ DONE;
+})
-(define_insn_and_split "*call_pop_1_vzeroupper"
+(define_insn_and_split "*call_pop_vzeroupper"
[(parallel
- [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
+ [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
(match_operand:SI 1 "" ""))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
@@ -11347,27 +11205,23 @@
"ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
[(set_attr "type" "call")])
-(define_insn "*call_pop_1"
- [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
- (match_operand:SI 1 "" ""))
+(define_insn "*call_pop"
+ [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
+ (match_operand 1 "" ""))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
(match_operand:SI 2 "immediate_operand" "i")))]
"!TARGET_64BIT && !SIBLING_CALL_P (insn)"
-{
- if (constant_call_address_operand (operands[0], Pmode))
- return "call\t%P0";
- return "call\t%A0";
-}
+ "* return ix86_output_call_insn (insn, operands[0]);"
[(set_attr "type" "call")])
-(define_insn_and_split "*sibcall_pop_1_vzeroupper"
+(define_insn_and_split "*sibcall_pop_vzeroupper"
[(parallel
- [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
- (match_operand:SI 1 "" ""))
+ [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
+ (match_operand 1 "" ""))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
- (match_operand:SI 2 "immediate_operand" "i,i")))])
+ (match_operand:SI 2 "immediate_operand" "i")))])
(unspec [(match_operand 3 "const_int_operand" "")]
UNSPEC_CALL_NEEDS_VZEROUPPER)]
"TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
@@ -11377,120 +11231,89 @@
"ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
[(set_attr "type" "call")])
-(define_insn "*sibcall_pop_1"
- [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
- (match_operand:SI 1 "" ""))
+(define_insn "*sibcall_pop"
+ [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
+ (match_operand 1 "" ""))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
- (match_operand:SI 2 "immediate_operand" "i,i")))]
+ (match_operand:SI 2 "immediate_operand" "i")))]
"!TARGET_64BIT && SIBLING_CALL_P (insn)"
- "@
- jmp\t%P0
- jmp\t%A0"
+ "* return ix86_output_call_insn (insn, operands[0]);"
[(set_attr "type" "call")])
-(define_expand "call"
- [(call (match_operand:QI 0 "" "")
- (match_operand 1 "" ""))
- (use (match_operand 2 "" ""))]
+;; Call subroutine, returning value in operand 0
+
+(define_expand "call_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "" "")
+ (match_operand 2 "" "")))
+ (use (match_operand 3 "" ""))]
""
{
- ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
+ ix86_expand_call (operands[0], operands[1], operands[2],
+ operands[3], NULL, false);
DONE;
})
-(define_expand "sibcall"
- [(call (match_operand:QI 0 "" "")
- (match_operand 1 "" ""))
- (use (match_operand 2 "" ""))]
+(define_expand "sibcall_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "" "")
+ (match_operand 2 "" "")))
+ (use (match_operand 3 "" ""))]
""
{
- ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
+ ix86_expand_call (operands[0], operands[1], operands[2],
+ operands[3], NULL, true);
DONE;
})
-(define_insn_and_split "*call_0_vzeroupper"
- [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
- (match_operand 1 "" ""))
- (unspec [(match_operand 2 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
- [(set_attr "type" "call")])
-
-(define_insn "*call_0"
- [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
- (match_operand 1 "" ""))]
- ""
- { return ix86_output_call_insn (insn, operands[0], 0); }
- [(set_attr "type" "call")])
-
-(define_insn_and_split "*call_1_vzeroupper"
- [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
- (match_operand 1 "" ""))
- (unspec [(match_operand 2 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
- [(set_attr "type" "call")])
-
-(define_insn "*call_1"
- [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
- (match_operand 1 "" ""))]
- "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
- { return ix86_output_call_insn (insn, operands[0], 0); }
- [(set_attr "type" "call")])
-
-(define_insn_and_split "*sibcall_1_vzeroupper"
- [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
- (match_operand 1 "" ""))
- (unspec [(match_operand 2 "const_int_operand" "")]
+(define_insn_and_split "*call_value_vzeroupper"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
+ (match_operand 2 "" "")))
+ (unspec [(match_operand 3 "const_int_operand" "")]
UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
+ "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
"#"
"&& reload_completed"
[(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
- [(set_attr "type" "call")])
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
+ [(set_attr "type" "callv")])
-(define_insn "*sibcall_1"
- [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
- (match_operand 1 "" ""))]
- "!TARGET_64BIT && SIBLING_CALL_P (insn)"
- { return ix86_output_call_insn (insn, operands[0], 0); }
- [(set_attr "type" "call")])
+(define_insn "*call_value"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
+ (match_operand 2 "" "")))]
+ "!SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[1]);"
+ [(set_attr "type" "callv")])
-(define_insn_and_split "*call_1_rex64_vzeroupper"
- [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
- (match_operand 1 "" ""))
- (unspec [(match_operand 2 "const_int_operand" "")]
+(define_insn_and_split "*sibcall_value_vzeroupper"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
+ (match_operand 2 "" "")))
+ (unspec [(match_operand 3 "const_int_operand" "")]
UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
- && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
+ "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
"#"
"&& reload_completed"
[(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
- [(set_attr "type" "call")])
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
+ [(set_attr "type" "callv")])
-(define_insn "*call_1_rex64"
- [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
- (match_operand 1 "" ""))]
- "TARGET_64BIT && !SIBLING_CALL_P (insn)
- && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
- { return ix86_output_call_insn (insn, operands[0], 0); }
- [(set_attr "type" "call")])
+(define_insn "*sibcall_value"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
+ (match_operand 2 "" "")))]
+ "SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[1]);"
+ [(set_attr "type" "callv")])
-(define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
+(define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
[(parallel
- [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
- (match_operand 1 "" ""))
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
+ (match_operand 2 "" "")))
(unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
(clobber (reg:TI XMM6_REG))
(clobber (reg:TI XMM7_REG))
@@ -11504,18 +11327,19 @@
(clobber (reg:TI XMM15_REG))
(clobber (reg:DI SI_REG))
(clobber (reg:DI DI_REG))])
- (unspec [(match_operand 2 "const_int_operand" "")]
+ (unspec [(match_operand 3 "const_int_operand" "")]
UNSPEC_CALL_NEEDS_VZEROUPPER)]
"TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
"#"
"&& reload_completed"
[(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
- [(set_attr "type" "call")])
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
+ [(set_attr "type" "callv")])
-(define_insn "*call_1_rex64_ms_sysv"
- [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
- (match_operand 1 "" ""))
+(define_insn "*call_value_rex64_ms_sysv"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
+ (match_operand 2 "" "")))
(unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
(clobber (reg:TI XMM6_REG))
(clobber (reg:TI XMM7_REG))
@@ -11530,48 +11354,9 @@
(clobber (reg:DI SI_REG))
(clobber (reg:DI DI_REG))]
"TARGET_64BIT && !SIBLING_CALL_P (insn)"
- { return ix86_output_call_insn (insn, operands[0], 0); }
- [(set_attr "type" "call")])
-
-(define_insn_and_split "*call_1_rex64_large_vzeroupper"
- [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
- (match_operand 1 "" ""))
- (unspec [(match_operand 2 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
- [(set_attr "type" "call")])
-
-(define_insn "*call_1_rex64_large"
- [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
- (match_operand 1 "" ""))]
- "TARGET_64BIT && !SIBLING_CALL_P (insn)"
- { return ix86_output_call_insn (insn, operands[0], 0); }
- [(set_attr "type" "call")])
-
-(define_insn_and_split "*sibcall_1_rex64_vzeroupper"
- [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
- (match_operand 1 "" ""))
- (unspec [(match_operand 2 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
- [(set_attr "type" "call")])
-
-(define_insn "*sibcall_1_rex64"
- [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
- (match_operand 1 "" ""))]
- "TARGET_64BIT && SIBLING_CALL_P (insn)"
- { return ix86_output_call_insn (insn, operands[0], 0); }
- [(set_attr "type" "call")])
+ "* return ix86_output_call_insn (insn, operands[1]);"
+ [(set_attr "type" "callv")])
-;; Call subroutine, returning value in operand 0
(define_expand "call_value_pop"
[(parallel [(set (match_operand 0 "" "")
(call (match_operand:QI 1 "" "")
@@ -11582,35 +11367,65 @@
"!TARGET_64BIT"
{
ix86_expand_call (operands[0], operands[1], operands[2],
- operands[3], operands[4], 0);
+ operands[3], operands[4], false);
DONE;
})
-(define_expand "call_value"
+(define_insn_and_split "*call_value_pop_vzeroupper"
+ [(parallel
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
+ (match_operand 2 "" "")))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 3 "immediate_operand" "i")))])
+ (unspec [(match_operand 4 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
+ [(set_attr "type" "callv")])
+
+(define_insn "*call_value_pop"
[(set (match_operand 0 "" "")
- (call (match_operand:QI 1 "" "")
- (match_operand:SI 2 "" "")))
- (use (match_operand:SI 3 "" ""))]
- ;; Operand 3 is not used on the i386.
- ""
-{
- ix86_expand_call (operands[0], operands[1], operands[2],
- operands[3], NULL, 0);
- DONE;
-})
+ (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
+ (match_operand 2 "" "")))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 3 "immediate_operand" "i")))]
+ "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[1]);"
+ [(set_attr "type" "callv")])
-(define_expand "sibcall_value"
+(define_insn_and_split "*sibcall_value_pop_vzeroupper"
+ [(parallel
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
+ (match_operand 2 "" "")))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 3 "immediate_operand" "i")))])
+ (unspec [(match_operand 4 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
+ [(set_attr "type" "callv")])
+
+(define_insn "*sibcall_value_pop"
[(set (match_operand 0 "" "")
- (call (match_operand:QI 1 "" "")
- (match_operand:SI 2 "" "")))
- (use (match_operand:SI 3 "" ""))]
- ;; Operand 3 is not used on the i386.
- ""
-{
- ix86_expand_call (operands[0], operands[1], operands[2],
- operands[3], NULL, 1);
- DONE;
-})
+ (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
+ (match_operand 2 "" "")))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 3 "immediate_operand" "i")))]
+ "!TARGET_64BIT && SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[1]);"
+ [(set_attr "type" "callv")])
;; Call subroutine returning any type.
@@ -11640,7 +11455,7 @@
: X86_64_MS_SSE_REGPARM_MAX)
: X86_32_SSE_REGPARM_MAX)
- 1),
- NULL, 0);
+ NULL, false);
for (i = 0; i < XVECLEN (operands[2], 0); i++)
{
@@ -12540,164 +12355,144 @@
(define_insn "*tls_global_dynamic_32_gnu"
[(set (match_operand:SI 0 "register_operand" "=a")
- (unspec:SI [(match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "tls_symbolic_operand" "")
- (match_operand:SI 3 "call_insn_operand" "")]
- UNSPEC_TLS_GD))
+ (unspec:SI
+ [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "tls_symbolic_operand" "")
+ (match_operand:SI 3 "constant_call_address_operand" "z")]
+ UNSPEC_TLS_GD))
(clobber (match_scratch:SI 4 "=d"))
(clobber (match_scratch:SI 5 "=c"))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && TARGET_GNU_TLS"
- "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
+{
+ output_asm_insn
+ ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
+ return "call\t%P3";
+}
[(set_attr "type" "multi")
(set_attr "length" "12")])
(define_expand "tls_global_dynamic_32"
- [(parallel [(set (match_operand:SI 0 "register_operand" "")
- (unspec:SI
- [(match_dup 2)
- (match_operand:SI 1 "tls_symbolic_operand" "")
- (match_dup 3)]
- UNSPEC_TLS_GD))
- (clobber (match_scratch:SI 4 ""))
- (clobber (match_scratch:SI 5 ""))
- (clobber (reg:CC FLAGS_REG))])]
- ""
-{
- if (flag_pic)
- operands[2] = pic_offset_table_rtx;
- else
- {
- operands[2] = gen_reg_rtx (Pmode);
- emit_insn (gen_set_got (operands[2]));
- }
- if (TARGET_GNU2_TLS)
- {
- emit_insn (gen_tls_dynamic_gnu2_32
- (operands[0], operands[1], operands[2]));
- DONE;
- }
- operands[3] = ix86_tls_get_addr ();
-})
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (unspec:SI [(match_operand:SI 2 "register_operand" "")
+ (match_operand:SI 1 "tls_symbolic_operand" "")
+ (match_operand:SI 3 "constant_call_address_operand" "")]
+ UNSPEC_TLS_GD))
+ (clobber (match_scratch:SI 4 ""))
+ (clobber (match_scratch:SI 5 ""))
+ (clobber (reg:CC FLAGS_REG))])])
(define_insn "*tls_global_dynamic_64"
[(set (match_operand:DI 0 "register_operand" "=a")
- (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
- (match_operand:DI 3 "" "")))
+ (call:DI
+ (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
+ (match_operand:DI 3 "" "")))
(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
UNSPEC_TLS_GD)]
"TARGET_64BIT"
- { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
+{
+ fputs (ASM_BYTE "0x66\n", asm_out_file);
+ output_asm_insn
+ ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
+ fputs (ASM_SHORT "0x6666\n", asm_out_file);
+ fputs ("\trex64\n", asm_out_file);
+ return "call\t%P2";
+}
[(set_attr "type" "multi")
(set_attr "length" "16")])
(define_expand "tls_global_dynamic_64"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (call:DI (mem:QI (match_dup 2)) (const_int 0)))
- (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
- UNSPEC_TLS_GD)])]
- ""
-{
- if (TARGET_GNU2_TLS)
- {
- emit_insn (gen_tls_dynamic_gnu2_64
- (operands[0], operands[1]));
- DONE;
- }
- operands[2] = ix86_tls_get_addr ();
-})
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (call:DI
+ (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
+ (const_int 0)))
+ (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
+ UNSPEC_TLS_GD)])])
(define_insn "*tls_local_dynamic_base_32_gnu"
[(set (match_operand:SI 0 "register_operand" "=a")
- (unspec:SI [(match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "call_insn_operand" "")]
- UNSPEC_TLS_LD_BASE))
+ (unspec:SI
+ [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "constant_call_address_operand" "z")]
+ UNSPEC_TLS_LD_BASE))
(clobber (match_scratch:SI 3 "=d"))
(clobber (match_scratch:SI 4 "=c"))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && TARGET_GNU_TLS"
- "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
+{
+ output_asm_insn
+ ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
+ return "call\t%P2";
+}
[(set_attr "type" "multi")
(set_attr "length" "11")])
(define_expand "tls_local_dynamic_base_32"
- [(parallel [(set (match_operand:SI 0 "register_operand" "")
- (unspec:SI [(match_dup 1) (match_dup 2)]
- UNSPEC_TLS_LD_BASE))
- (clobber (match_scratch:SI 3 ""))
- (clobber (match_scratch:SI 4 ""))
- (clobber (reg:CC FLAGS_REG))])]
- ""
-{
- if (flag_pic)
- operands[1] = pic_offset_table_rtx;
- else
- {
- operands[1] = gen_reg_rtx (Pmode);
- emit_insn (gen_set_got (operands[1]));
- }
- if (TARGET_GNU2_TLS)
- {
- emit_insn (gen_tls_dynamic_gnu2_32
- (operands[0], ix86_tls_module_base (), operands[1]));
- DONE;
- }
- operands[2] = ix86_tls_get_addr ();
-})
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (unspec:SI
+ [(match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "constant_call_address_operand" "")]
+ UNSPEC_TLS_LD_BASE))
+ (clobber (match_scratch:SI 3 ""))
+ (clobber (match_scratch:SI 4 ""))
+ (clobber (reg:CC FLAGS_REG))])])
(define_insn "*tls_local_dynamic_base_64"
[(set (match_operand:DI 0 "register_operand" "=a")
- (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
- (match_operand:DI 2 "" "")))
+ (call:DI
+ (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
+ (match_operand:DI 2 "" "")))
(unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
"TARGET_64BIT"
- "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
+{
+ output_asm_insn
+ ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
+ return "call\t%P1";
+}
[(set_attr "type" "multi")
(set_attr "length" "12")])
(define_expand "tls_local_dynamic_base_64"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (call:DI (mem:QI (match_dup 1)) (const_int 0)))
- (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
- ""
-{
- if (TARGET_GNU2_TLS)
- {
- emit_insn (gen_tls_dynamic_gnu2_64
- (operands[0], ix86_tls_module_base ()));
- DONE;
- }
- operands[1] = ix86_tls_get_addr ();
-})
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (call:DI
+ (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
+ (const_int 0)))
+ (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
;; Local dynamic of a single variable is a lose. Show combine how
;; to convert that back to global dynamic.
(define_insn_and_split "*tls_local_dynamic_32_once"
[(set (match_operand:SI 0 "register_operand" "=a")
- (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "call_insn_operand" "")]
- UNSPEC_TLS_LD_BASE)
- (const:SI (unspec:SI
- [(match_operand:SI 3 "tls_symbolic_operand" "")]
- UNSPEC_DTPOFF))))
+ (plus:SI
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "constant_call_address_operand" "z")]
+ UNSPEC_TLS_LD_BASE)
+ (const:SI (unspec:SI
+ [(match_operand:SI 3 "tls_symbolic_operand" "")]
+ UNSPEC_DTPOFF))))
(clobber (match_scratch:SI 4 "=d"))
(clobber (match_scratch:SI 5 "=c"))
(clobber (reg:CC FLAGS_REG))]
""
"#"
""
- [(parallel [(set (match_dup 0)
- (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
- UNSPEC_TLS_GD))
- (clobber (match_dup 4))
- (clobber (match_dup 5))
- (clobber (reg:CC FLAGS_REG))])])
+ [(parallel
+ [(set (match_dup 0)
+ (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
+ UNSPEC_TLS_GD))
+ (clobber (match_dup 4))
+ (clobber (match_dup 5))
+ (clobber (reg:CC FLAGS_REG))])])
;; Segment register for the thread base ptr load
(define_mode_attr tp_seg [(SI "gs") (DI "fs")])
-;; Load and add the thread base pointer from %gs:0.
+;; Load and add the thread base pointer from %<tp_seg>:0.
(define_insn "*load_tp_<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
(unspec:P [(const_int 0)] UNSPEC_TP))]
@@ -12731,7 +12526,11 @@
UNSPEC_TLS_IE_SUN))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && TARGET_SUN_TLS"
- "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
+{
+ output_asm_insn
+ ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
+ return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
+}
[(set_attr "type" "multi")])
;; GNU2 TLS patterns can be split.
@@ -13574,7 +13373,7 @@
(set (match_operand:XF 1 "register_operand" "")
(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
"find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
- && !(reload_completed || reload_in_progress)"
+ && can_create_pseudo_p ()"
[(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
(define_split
@@ -13584,7 +13383,7 @@
(set (match_operand:XF 1 "register_operand" "")
(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
"find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
- && !(reload_completed || reload_in_progress)"
+ && can_create_pseudo_p ()"
[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
(define_insn "sincos_extend<mode>xf3_i387"
@@ -13610,7 +13409,7 @@
(set (match_operand:XF 1 "register_operand" "")
(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
"find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
- && !(reload_completed || reload_in_progress)"
+ && can_create_pseudo_p ()"
[(set (match_dup 1)
(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
@@ -13622,7 +13421,7 @@
(set (match_operand:XF 1 "register_operand" "")
(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
"find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
- && !(reload_completed || reload_in_progress)"
+ && can_create_pseudo_p ()"
[(set (match_dup 0)
(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
@@ -14594,7 +14393,7 @@
UNSPEC_FIST))
(clobber (match_scratch:XF 2 "=&1f"))]
"TARGET_USE_FANCY_MATH_387"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fpspc")
(set_attr "mode" "DI")])
@@ -14653,7 +14452,7 @@
(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
UNSPEC_FIST))]
"TARGET_USE_FANCY_MATH_387"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fpspc")
(set_attr "mode" "<MODE>")])
@@ -14843,7 +14642,7 @@
(clobber (match_scratch:XF 4 "=&1f"))]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fistp")
(set_attr "i387_cw" "floor")
(set_attr "mode" "DI")])
@@ -14900,7 +14699,7 @@
(use (match_operand:HI 3 "memory_operand" "m"))]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fistp")
(set_attr "i387_cw" "floor")
(set_attr "mode" "<MODE>")])
@@ -15100,7 +14899,7 @@
(clobber (match_scratch:XF 4 "=&1f"))]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fistp")
(set_attr "i387_cw" "ceil")
(set_attr "mode" "DI")])
@@ -15157,7 +14956,7 @@
(use (match_operand:HI 3 "memory_operand" "m"))]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fistp")
(set_attr "i387_cw" "ceil")
(set_attr "mode" "<MODE>")])
@@ -17429,338 +17228,6 @@
operands[0] = dest;
})
-;; Call-value patterns last so that the wildcard operand does not
-;; disrupt insn-recog's switch tables.
-
-(define_insn_and_split "*call_value_pop_0_vzeroupper"
- [(parallel
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
- (match_operand:SI 2 "" "")))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 3 "immediate_operand" "")))])
- (unspec [(match_operand 4 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !TARGET_64BIT"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_pop_0"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
- (match_operand:SI 2 "" "")))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 3 "immediate_operand" "")))]
- "!TARGET_64BIT"
- { return ix86_output_call_insn (insn, operands[1], 1); }
- [(set_attr "type" "callv")])
-
-(define_insn_and_split "*call_value_pop_1_vzeroupper"
- [(parallel
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
- (match_operand:SI 2 "" "")))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 3 "immediate_operand" "i")))])
- (unspec [(match_operand 4 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_pop_1"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
- (match_operand:SI 2 "" "")))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 3 "immediate_operand" "i")))]
- "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
- { return ix86_output_call_insn (insn, operands[1], 1); }
- [(set_attr "type" "callv")])
-
-(define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
- [(parallel
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
- (match_operand:SI 2 "" "")))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 3 "immediate_operand" "i,i")))])
- (unspec [(match_operand 4 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
- [(set_attr "type" "callv")])
-
-(define_insn "*sibcall_value_pop_1"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
- (match_operand:SI 2 "" "")))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 3 "immediate_operand" "i,i")))]
- "!TARGET_64BIT && SIBLING_CALL_P (insn)"
- { return ix86_output_call_insn (insn, operands[1], 1); }
- [(set_attr "type" "callv")])
-
-(define_insn_and_split "*call_value_0_vzeroupper"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
- (match_operand:SI 2 "" "")))
- (unspec [(match_operand 3 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !TARGET_64BIT"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_0"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
- (match_operand:SI 2 "" "")))]
- "!TARGET_64BIT"
- { return ix86_output_call_insn (insn, operands[1], 1); }
- [(set_attr "type" "callv")])
-
-(define_insn_and_split "*call_value_0_rex64_vzeroupper"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
- (match_operand:DI 2 "const_int_operand" "")))
- (unspec [(match_operand 3 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && TARGET_64BIT"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_0_rex64"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
- (match_operand:DI 2 "const_int_operand" "")))]
- "TARGET_64BIT"
- { return ix86_output_call_insn (insn, operands[1], 1); }
- [(set_attr "type" "callv")])
-
-(define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
- [(parallel
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
- (match_operand:DI 2 "const_int_operand" "")))
- (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
- (clobber (reg:TI XMM6_REG))
- (clobber (reg:TI XMM7_REG))
- (clobber (reg:TI XMM8_REG))
- (clobber (reg:TI XMM9_REG))
- (clobber (reg:TI XMM10_REG))
- (clobber (reg:TI XMM11_REG))
- (clobber (reg:TI XMM12_REG))
- (clobber (reg:TI XMM13_REG))
- (clobber (reg:TI XMM14_REG))
- (clobber (reg:TI XMM15_REG))
- (clobber (reg:DI SI_REG))
- (clobber (reg:DI DI_REG))])
- (unspec [(match_operand 3 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_0_rex64_ms_sysv"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
- (match_operand:DI 2 "const_int_operand" "")))
- (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
- (clobber (reg:TI XMM6_REG))
- (clobber (reg:TI XMM7_REG))
- (clobber (reg:TI XMM8_REG))
- (clobber (reg:TI XMM9_REG))
- (clobber (reg:TI XMM10_REG))
- (clobber (reg:TI XMM11_REG))
- (clobber (reg:TI XMM12_REG))
- (clobber (reg:TI XMM13_REG))
- (clobber (reg:TI XMM14_REG))
- (clobber (reg:TI XMM15_REG))
- (clobber (reg:DI SI_REG))
- (clobber (reg:DI DI_REG))]
- "TARGET_64BIT && !SIBLING_CALL_P (insn)"
- { return ix86_output_call_insn (insn, operands[1], 1); }
- [(set_attr "type" "callv")])
-
-(define_insn_and_split "*call_value_1_vzeroupper"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
- (match_operand:SI 2 "" "")))
- (unspec [(match_operand 3 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_1"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
- (match_operand:SI 2 "" "")))]
- "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
- { return ix86_output_call_insn (insn, operands[1], 1); }
- [(set_attr "type" "callv")])
-
-(define_insn_and_split "*sibcall_value_1_vzeroupper"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
- (match_operand:SI 2 "" "")))
- (unspec [(match_operand 3 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
- [(set_attr "type" "callv")])
-
-(define_insn "*sibcall_value_1"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
- (match_operand:SI 2 "" "")))]
- "!TARGET_64BIT && SIBLING_CALL_P (insn)"
- { return ix86_output_call_insn (insn, operands[1], 1); }
- [(set_attr "type" "callv")])
-
-(define_insn_and_split "*call_value_1_rex64_vzeroupper"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
- (match_operand:DI 2 "" "")))
- (unspec [(match_operand 3 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
- && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_1_rex64"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
- (match_operand:DI 2 "" "")))]
- "TARGET_64BIT && !SIBLING_CALL_P (insn)
- && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
- { return ix86_output_call_insn (insn, operands[1], 1); }
- [(set_attr "type" "callv")])
-
-(define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
- [(parallel
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
- (match_operand:DI 2 "" "")))
- (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
- (clobber (reg:TI XMM6_REG))
- (clobber (reg:TI XMM7_REG))
- (clobber (reg:TI XMM8_REG))
- (clobber (reg:TI XMM9_REG))
- (clobber (reg:TI XMM10_REG))
- (clobber (reg:TI XMM11_REG))
- (clobber (reg:TI XMM12_REG))
- (clobber (reg:TI XMM13_REG))
- (clobber (reg:TI XMM14_REG))
- (clobber (reg:TI XMM15_REG))
- (clobber (reg:DI SI_REG))
- (clobber (reg:DI DI_REG))])
- (unspec [(match_operand 3 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_1_rex64_ms_sysv"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
- (match_operand:DI 2 "" "")))
- (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
- (clobber (reg:TI XMM6_REG))
- (clobber (reg:TI XMM7_REG))
- (clobber (reg:TI XMM8_REG))
- (clobber (reg:TI XMM9_REG))
- (clobber (reg:TI XMM10_REG))
- (clobber (reg:TI XMM11_REG))
- (clobber (reg:TI XMM12_REG))
- (clobber (reg:TI XMM13_REG))
- (clobber (reg:TI XMM14_REG))
- (clobber (reg:TI XMM15_REG))
- (clobber (reg:DI SI_REG))
- (clobber (reg:DI DI_REG))]
- "TARGET_64BIT && !SIBLING_CALL_P (insn)"
- { return ix86_output_call_insn (insn, operands[1], 1); }
- [(set_attr "type" "callv")])
-
-(define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
- (match_operand:DI 2 "" "")))
- (unspec [(match_operand 3 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_1_rex64_large"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
- (match_operand:DI 2 "" "")))]
- "TARGET_64BIT && !SIBLING_CALL_P (insn)"
- { return ix86_output_call_insn (insn, operands[1], 1); }
- [(set_attr "type" "callv")])
-
-(define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
- (match_operand:DI 2 "" "")))
- (unspec [(match_operand 3 "const_int_operand" "")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
- [(set_attr "type" "callv")])
-
-(define_insn "*sibcall_value_1_rex64"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
- (match_operand:DI 2 "" "")))]
- "TARGET_64BIT && SIBLING_CALL_P (insn)"
- { return ix86_output_call_insn (insn, operands[1], 1); }
- [(set_attr "type" "callv")])
-
;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
;; That, however, is usually mapped by the OS to SIGSEGV, which is often
;; caught for use by garbage collectors and the like. Using an insn that
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index f63a40629e1..21e0def1549 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -19,6 +19,9 @@
; along with GCC; see the file COPYING3. If not see
; <http://www.gnu.org/licenses/>.
+HeaderInclude
+config/i386/i386-opts.h
+
; Bit flags that specify the ISA we are compiling for.
Variable
int ix86_isa_flags = TARGET_64BIT_DEFAULT | TARGET_SUBTARGET_ISA_DEFAULT
@@ -37,10 +40,6 @@ unsigned char arch
TargetSave
unsigned char tune
-;; -mfpath=
-TargetSave
-unsigned char fpmath
-
;; CPU schedule model
TargetSave
unsigned char schedule
@@ -87,15 +86,15 @@ Target Report Mask(ALIGN_DOUBLE) Save
Align some doubles on dword boundary
malign-functions=
-Target RejectNegative Joined Var(ix86_align_funcs_string)
+Target RejectNegative Joined UInteger
Function starts are aligned to this power of 2
malign-jumps=
-Target RejectNegative Joined Var(ix86_align_jumps_string)
+Target RejectNegative Joined UInteger
Jump targets are aligned to this power of 2
malign-loops=
-Target RejectNegative Joined Var(ix86_align_loops_string)
+Target RejectNegative Joined UInteger
Loop code aligned to this power of 2
malign-stringops
@@ -107,21 +106,50 @@ Target RejectNegative Joined Var(ix86_arch_string)
Generate code for given CPU
masm=
-Target RejectNegative Joined Var(ix86_asm_string)
+Target RejectNegative Joined Enum(asm_dialect) Var(ix86_asm_dialect) Init(ASM_ATT)
Use given assembler dialect
+Enum
+Name(asm_dialect) Type(enum asm_dialect)
+Known assembler dialects (for use with the -masm-dialect= option):
+
+EnumValue
+Enum(asm_dialect) String(intel) Value(ASM_INTEL)
+
+EnumValue
+Enum(asm_dialect) String(att) Value(ASM_ATT)
+
mbranch-cost=
-Target RejectNegative Joined Var(ix86_branch_cost_string)
+Target RejectNegative Joined UInteger Var(ix86_branch_cost)
Branches are this expensive (1-5, arbitrary units)
mlarge-data-threshold=
-Target RejectNegative Joined Var(ix86_section_threshold_string)
+Target RejectNegative Joined UInteger Var(ix86_section_threshold) Init(65536)
Data greater than given threshold will go into .ldata section in x86-64 medium model
mcmodel=
-Target RejectNegative Joined Var(ix86_cmodel_string)
+Target RejectNegative Joined Enum(cmodel) Var(ix86_cmodel) Init(CM_32)
Use given x86-64 code model
+Enum
+Name(cmodel) Type(enum cmodel)
+Known code models (for use with the -mcmodel= option):
+
+EnumValue
+Enum(cmodel) String(small) Value(CM_SMALL)
+
+EnumValue
+Enum(cmodel) String(medium) Value(CM_MEDIUM)
+
+EnumValue
+Enum(cmodel) String(large) Value(CM_LARGE)
+
+EnumValue
+Enum(cmodel) String(32) Value(CM_32)
+
+EnumValue
+Enum(cmodel) String(kernel) Value(CM_KERNEL)
+
mcpu=
Target RejectNegative Joined Undocumented Alias(mtune=) Warn(%<-mcpu=%> is deprecated; use %<-mtune=%> or %<-march=%> instead)
@@ -138,9 +166,34 @@ Target Report Mask(FLOAT_RETURNS) Save
Return values of functions in FPU registers
mfpmath=
-Target RejectNegative Joined Var(ix86_fpmath_string)
+Target RejectNegative Joined Var(ix86_fpmath) Enum(fpmath_unit) Init(FPMATH_387) Save
Generate floating point mathematics using given instruction set
+Enum
+Name(fpmath_unit) Type(enum fpmath_unit)
+Valid arguments to -mfpmath=:
+
+EnumValue
+Enum(fpmath_unit) String(387) Value(FPMATH_387)
+
+EnumValue
+Enum(fpmath_unit) String(sse) Value(FPMATH_SSE)
+
+EnumValue
+Enum(fpmath_unit) String(387,sse) Value({(enum fpmath_unit) (FPMATH_SSE | FPMATH_387)})
+
+EnumValue
+Enum(fpmath_unit) String(387+sse) Value({(enum fpmath_unit) (FPMATH_SSE | FPMATH_387)})
+
+EnumValue
+Enum(fpmath_unit) String(sse,387) Value({(enum fpmath_unit) (FPMATH_SSE | FPMATH_387)})
+
+EnumValue
+Enum(fpmath_unit) String(sse+387) Value({(enum fpmath_unit) (FPMATH_SSE | FPMATH_387)})
+
+EnumValue
+Enum(fpmath_unit) String(both) Value({(enum fpmath_unit) (FPMATH_SSE | FPMATH_387)})
+
mhard-float
Target RejectNegative Mask(80387) MaskExists Save
Use hardware fp
@@ -181,16 +234,24 @@ momit-leaf-frame-pointer
Target Report Mask(OMIT_LEAF_FRAME_POINTER) Save
Omit the frame pointer in leaf functions
-mpc
-Target RejectNegative Report Joined Var(ix87_precision_string)
-Set 80387 floating-point precision (-mpc32, -mpc64, -mpc80)
+mpc32
+Target RejectNegative Report
+Set 80387 floating-point precision to 32-bit
+
+mpc64
+Target RejectNegative Report
+Set 80387 floating-point precision to 64-bit
+
+mpc80
+Target RejectNegative Report
+Set 80387 floating-point precision to 80-bit
mpreferred-stack-boundary=
-Target RejectNegative Joined Var(ix86_preferred_stack_boundary_string)
+Target RejectNegative Joined UInteger Var(ix86_preferred_stack_boundary_arg)
Attempt to keep stack aligned to this power of 2
mincoming-stack-boundary=
-Target RejectNegative Joined Var(ix86_incoming_stack_boundary_string)
+Target RejectNegative Joined UInteger Var(ix86_incoming_stack_boundary_arg)
Assume incoming stack aligned to this power of 2
mpush-args
@@ -202,7 +263,7 @@ Target RejectNegative Report InverseMask(NO_RED_ZONE, RED_ZONE) Save
Use red-zone in the x86-64 code
mregparm=
-Target RejectNegative Joined Var(ix86_regparm_string)
+Target RejectNegative Joined UInteger Var(ix86_regparm)
Number of registers used to pass integer arguments
mrtd
@@ -226,13 +287,48 @@ Target Report Mask(STACK_PROBE) Save
Enable stack probing
mstringop-strategy=
-Target RejectNegative Joined Var(ix86_stringop_string)
+Target RejectNegative Joined Enum(stringop_alg) Var(ix86_stringop_alg) Init(no_stringop)
Chose strategy to generate stringop using
+Enum
+Name(stringop_alg) Type(enum stringop_alg)
+Valid arguments to -mstringop-strategy=:
+
+EnumValue
+Enum(stringop_alg) String(rep_byte) Value(rep_prefix_1_byte)
+
+EnumValue
+Enum(stringop_alg) String(libcall) Value(libcall)
+
+EnumValue
+Enum(stringop_alg) String(rep_4byte) Value(rep_prefix_4_byte)
+
+EnumValue
+Enum(stringop_alg) String(rep_8byte) Value(rep_prefix_8_byte)
+
+EnumValue
+Enum(stringop_alg) String(byte_loop) Value(loop_1_byte)
+
+EnumValue
+Enum(stringop_alg) String(loop) Value(loop)
+
+EnumValue
+Enum(stringop_alg) String(unrolled_loop) Value(unrolled_loop)
+
mtls-dialect=
-Target RejectNegative Joined Var(ix86_tls_dialect_string)
+Target RejectNegative Joined Var(ix86_tls_dialect) Enum(tls_dialect) Init(TLS_DIALECT_GNU)
Use given thread-local storage dialect
+Enum
+Name(tls_dialect) Type(enum tls_dialect)
+Known TLS dialects (for use with the -mtls-dialect= option):
+
+EnumValue
+Enum(tls_dialect) String(gnu) Value(TLS_DIALECT_GNU)
+
+EnumValue
+Enum(tls_dialect) String(gnu2) Value(TLS_DIALECT_GNU2)
+
mtls-direct-seg-refs
Target Report Mask(TLS_DIRECT_SEG_REFS)
Use direct references against %gs when accessing tls data
@@ -242,13 +338,33 @@ Target RejectNegative Joined Var(ix86_tune_string)
Schedule code for given CPU
mabi=
-Target RejectNegative Joined Var(ix86_abi_string)
+Target RejectNegative Joined Var(ix86_abi) Enum(calling_abi) Init(SYSV_ABI)
Generate code that conforms to the given ABI
+Enum
+Name(calling_abi) Type(enum calling_abi)
+Known ABIs (for use with the -mabi= option):
+
+EnumValue
+Enum(calling_abi) String(sysv) Value(SYSV_ABI)
+
+EnumValue
+Enum(calling_abi) String(ms) Value(MS_ABI)
+
mveclibabi=
-Target RejectNegative Joined Var(ix86_veclibabi_string)
+Target RejectNegative Joined Var(ix86_veclibabi_type) Enum(ix86_veclibabi) Init(ix86_veclibabi_type_none)
Vector library ABI to use
+Enum
+Name(ix86_veclibabi) Type(enum ix86_veclibabi)
+Known vectorization library ABIs (for use with the -mveclibabi= option):
+
+EnumValue
+Enum(ix86_veclibabi) String(svml) Value(ix86_veclibabi_type_svml)
+
+EnumValue
+Enum(ix86_veclibabi) String(acml) Value(ix86_veclibabi_type_acml)
+
mvect8-ret-in-mem
Target Report Mask(VECT8_RETURNS) Save
Return 8-byte vectors in memory
diff --git a/gcc/config/i386/sol2-10.h b/gcc/config/i386/sol2-10.h
index c3decd2ef24..04a7132dc6c 100644
--- a/gcc/config/i386/sol2-10.h
+++ b/gcc/config/i386/sol2-10.h
@@ -133,6 +133,3 @@ along with GCC; see the file COPYING3. If not see
/* We do not need to search a special directory for startup files. */
#undef MD_STARTFILE_PREFIX
-
-#undef TARGET_ASM_NAMED_SECTION
-#define TARGET_ASM_NAMED_SECTION i386_solaris_elf_named_section
diff --git a/gcc/config/i386/sol2.h b/gcc/config/i386/sol2.h
index baddbb0b929..36ca62f904c 100644
--- a/gcc/config/i386/sol2.h
+++ b/gcc/config/i386/sol2.h
@@ -154,6 +154,9 @@ along with GCC; see the file COPYING3. If not see
} \
while (0)
+#undef TARGET_ASM_NAMED_SECTION
+#define TARGET_ASM_NAMED_SECTION i386_solaris_elf_named_section
+
/* We do not need NT_VERSION notes. */
#undef X86_FILE_START_VERSION_DIRECTIVE
#define X86_FILE_START_VERSION_DIRECTIVE false
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 291bffb636e..ddd66fd83b7 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -1663,7 +1663,7 @@
(match_operand:VF 3 "nonimmediate_operand" "xm,x")]
UNSPEC_FMADDSUB))]
"TARGET_FMA4"
- "vfmaddsubps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
+ "vfmaddsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -1676,7 +1676,7 @@
(match_operand:VF 3 "nonimmediate_operand" "xm,x"))]
UNSPEC_FMADDSUB))]
"TARGET_FMA4"
- "vfmsubaddps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
+ "vfmsubadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -10294,12 +10294,13 @@
"&& reload_completed"
[(const_int 0)]
{
+ rtx op0 = operands[0];
rtx op1 = operands[1];
- if (REG_P (op1))
+ if (REG_P (op0))
+ op0 = gen_rtx_REG (<ssehalfvecmode>mode, REGNO (op0));
+ else
op1 = gen_rtx_REG (<MODE>mode, REGNO (op1));
- else
- op1 = gen_lowpart (<MODE>mode, op1);
- emit_move_insn (operands[0], op1);
+ emit_move_insn (op0, op1);
DONE;
})
diff --git a/gcc/config/i386/sync.md b/gcc/config/i386/sync.md
index 22f36487579..20378d090bf 100644
--- a/gcc/config/i386/sync.md
+++ b/gcc/config/i386/sync.md
@@ -1,5 +1,5 @@
;; GCC machine description for i386 synchronization instructions.
-;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
;; Free Software Foundation, Inc.
;;
;; This file is part of GCC.
@@ -164,17 +164,74 @@
"!TARGET_64BIT && TARGET_CMPXCHG8B && flag_pic"
"xchg{l}\t%%ebx, %3\;lock{%;} cmpxchg8b\t%1\;xchg{l}\t%%ebx, %3")
+;; For operand 2 nonmemory_operand predicate is used instead of
+;; register_operand to allow combiner to better optimize atomic
+;; additions of constants.
(define_insn "sync_old_add<mode>"
[(set (match_operand:SWI 0 "register_operand" "=<r>")
(unspec_volatile:SWI
[(match_operand:SWI 1 "memory_operand" "+m")] UNSPECV_XCHG))
(set (match_dup 1)
(plus:SWI (match_dup 1)
- (match_operand:SWI 2 "register_operand" "0")))
+ (match_operand:SWI 2 "nonmemory_operand" "0")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_XADD"
"lock{%;} xadd{<imodesuffix>}\t{%0, %1|%1, %0}")
+;; This peephole2 and following insn optimize
+;; __sync_fetch_and_add (x, -N) == N into just lock {add,sub,inc,dec}
+;; followed by testing of flags instead of lock xadd and comparisons.
+(define_peephole2
+ [(set (match_operand:SWI 0 "register_operand" "")
+ (match_operand:SWI 2 "const_int_operand" ""))
+ (parallel [(set (match_dup 0)
+ (unspec_volatile:SWI
+ [(match_operand:SWI 1 "memory_operand" "")] UNSPECV_XCHG))
+ (set (match_dup 1)
+ (plus:SWI (match_dup 1)
+ (match_dup 0)))
+ (clobber (reg:CC FLAGS_REG))])
+ (set (reg:CCZ FLAGS_REG)
+ (compare:CCZ (match_dup 0)
+ (match_operand:SWI 3 "const_int_operand" "")))]
+ "peep2_reg_dead_p (3, operands[0])
+ && (unsigned HOST_WIDE_INT) INTVAL (operands[2])
+ == -(unsigned HOST_WIDE_INT) INTVAL (operands[3])
+ && !reg_overlap_mentioned_p (operands[0], operands[1])"
+ [(parallel [(set (reg:CCZ FLAGS_REG)
+ (compare:CCZ (unspec_volatile:SWI [(match_dup 1)]
+ UNSPECV_XCHG)
+ (match_dup 3)))
+ (set (match_dup 1)
+ (plus:SWI (match_dup 1)
+ (match_dup 2)))])])
+
+(define_insn "*sync_old_add_cmp<mode>"
+ [(set (reg:CCZ FLAGS_REG)
+ (compare:CCZ (unspec_volatile:SWI
+ [(match_operand:SWI 0 "memory_operand" "+m")]
+ UNSPECV_XCHG)
+ (match_operand:SWI 2 "const_int_operand" "i")))
+ (set (match_dup 0)
+ (plus:SWI (match_dup 0)
+ (match_operand:SWI 1 "const_int_operand" "i")))]
+ "(unsigned HOST_WIDE_INT) INTVAL (operands[1])
+ == -(unsigned HOST_WIDE_INT) INTVAL (operands[2])"
+{
+ if (TARGET_USE_INCDEC)
+ {
+ if (operands[1] == const1_rtx)
+ return "lock{%;} inc{<imodesuffix>}\t%0";
+ if (operands[1] == constm1_rtx)
+ return "lock{%;} dec{<imodesuffix>}\t%0";
+ }
+
+ if (x86_maybe_negate_const_int (&operands[1], <MODE>mode))
+ return "lock{%;} sub{<imodesuffix>}\t{%1, %0|%0, %1}";
+
+ return "lock{%;} add{<imodesuffix>}\t{%1, %0|%0, %1}";
+})
+
;; Recall that xchg implicitly sets LOCK#, so adding it again wastes space.
(define_insn "sync_lock_test_and_set<mode>"
[(set (match_operand:SWI 0 "register_operand" "=<r>")
diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386
index e9fa3cd8d6f..a43843351a0 100644
--- a/gcc/config/i386/t-i386
+++ b/gcc/config/i386/t-i386
@@ -24,7 +24,7 @@ i386.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(GGC_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h $(CGRAPH_H) \
$(TREE_GIMPLE_H) $(DWARF2_H) $(DF_H) tm-constrs.h $(PARAMS_H) \
i386-builtin-types.inc debug.h dwarf2out.h sbitmap.h $(FIBHEAP_H) \
- $(OPTS_H)
+ $(OPTS_H) $(DIAGNOSTIC_H)
i386-c.o: $(srcdir)/config/i386/i386-c.c \
$(srcdir)/config/i386/i386-protos.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 331f0c18dcc..f293579f5a5 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -15287,7 +15287,6 @@ mips_handle_option (struct gcc_options *opts,
location_t loc ATTRIBUTE_UNUSED)
{
size_t code = decoded->opt_index;
- const char *arg = decoded->arg;
switch (code)
{
diff --git a/gcc/config/rx/rx-protos.h b/gcc/config/rx/rx-protos.h
index 72cb199ce30..56d69316905 100644
--- a/gcc/config/rx/rx-protos.h
+++ b/gcc/config/rx/rx-protos.h
@@ -31,7 +31,7 @@ extern void rx_emit_stack_popm (rtx *, bool);
extern void rx_emit_stack_pushm (rtx *);
extern void rx_expand_epilogue (bool);
extern char * rx_gen_move_template (rtx *, bool);
-extern bool rx_legitimate_constant_p (enum machine_mode, rtx);
+extern bool rx_is_legitimate_constant (enum machine_mode, rtx);
extern bool rx_is_restricted_memory_address (rtx,
enum machine_mode);
extern bool rx_match_ccmode (rtx, enum machine_mode);
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index c8ff4393616..cedb0e073ed 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -58,7 +58,7 @@ static void rx_print_operand (FILE *, rtx, int);
#define CC_FLAG_Z (1 << 1)
#define CC_FLAG_O (1 << 2)
#define CC_FLAG_C (1 << 3)
-#define CC_FLAG_FP (1 << 4) /* fake, to differentiate CC_Fmode */
+#define CC_FLAG_FP (1 << 4) /* Fake, to differentiate CC_Fmode. */
static unsigned int flags_from_mode (enum machine_mode mode);
static unsigned int flags_from_code (enum rtx_code code);
@@ -85,7 +85,9 @@ rx_is_legitimate_address (enum machine_mode mode, rtx x,
/* Register Indirect. */
return true;
- if (GET_MODE_SIZE (mode) <= 4
+ if ((GET_MODE_SIZE (mode) == 4
+ || GET_MODE_SIZE (mode) == 2
+ || GET_MODE_SIZE (mode) == 1)
&& (GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC))
/* Pre-decrement Register Indirect or
Post-increment Register Indirect. */
@@ -125,7 +127,7 @@ rx_is_legitimate_address (enum machine_mode mode, rtx x,
case 1: factor = 1; break;
}
- if (val >= (0x10000 * factor))
+ if (val > (65535 * factor))
return false;
return (val % factor) == 0;
}
@@ -1349,7 +1351,7 @@ gen_safe_add (rtx dest, rtx src, rtx val, bool is_frame_related)
insn = emit_insn (gen_addsi3 (dest, src, val));
else
{
- /* Wrap VAL in an UNSPEC so that rx_legitimate_constant_p
+ /* Wrap VAL in an UNSPEC so that rx_is_legitimate_constant
will not reject it. */
val = gen_rtx_CONST (SImode, gen_rtx_UNSPEC (SImode, gen_rtvec (1, val), UNSPEC_CONST));
insn = emit_insn (gen_addsi3 (dest, src, val));
@@ -1928,11 +1930,14 @@ enum rx_builtin
RX_BUILTIN_max
};
+static GTY(()) tree rx_builtins[(int) RX_BUILTIN_max];
+
static void
rx_init_builtins (void)
{
#define ADD_RX_BUILTIN1(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE) \
- add_builtin_function ("__builtin_rx_" LC_NAME, \
+ rx_builtins[RX_BUILTIN_##UC_NAME] = \
+ add_builtin_function ("__builtin_rx_" LC_NAME, \
build_function_type_list (RET_TYPE##_type_node, \
ARG_TYPE##_type_node, \
NULL_TREE), \
@@ -1940,6 +1945,7 @@ rx_init_builtins (void)
BUILT_IN_MD, NULL, NULL_TREE)
#define ADD_RX_BUILTIN2(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE1, ARG_TYPE2) \
+ rx_builtins[RX_BUILTIN_##UC_NAME] = \
add_builtin_function ("__builtin_rx_" LC_NAME, \
build_function_type_list (RET_TYPE##_type_node, \
ARG_TYPE1##_type_node,\
@@ -1949,6 +1955,7 @@ rx_init_builtins (void)
BUILT_IN_MD, NULL, NULL_TREE)
#define ADD_RX_BUILTIN3(UC_NAME,LC_NAME,RET_TYPE,ARG_TYPE1,ARG_TYPE2,ARG_TYPE3) \
+ rx_builtins[RX_BUILTIN_##UC_NAME] = \
add_builtin_function ("__builtin_rx_" LC_NAME, \
build_function_type_list (RET_TYPE##_type_node, \
ARG_TYPE1##_type_node,\
@@ -1980,6 +1987,17 @@ rx_init_builtins (void)
ADD_RX_BUILTIN1 (WAIT, "wait", void, void);
}
+/* Return the RX builtin for CODE. */
+
+static tree
+rx_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
+{
+ if (code >= RX_BUILTIN_max)
+ return error_mark_node;
+
+ return rx_builtins[code];
+}
+
static rtx
rx_expand_void_builtin_1_arg (rtx arg, rtx (* gen_func)(rtx), bool reg)
{
@@ -2448,7 +2466,7 @@ rx_is_ms_bitfield_layout (const_tree record_type ATTRIBUTE_UNUSED)
operand on the RX. X is already known to satisfy CONSTANT_P. */
bool
-rx_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+rx_is_legitimate_constant (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
switch (GET_CODE (x))
{
@@ -2620,7 +2638,7 @@ rx_trampoline_init (rtx tramp, tree fndecl, rtx chain)
static int
rx_memory_move_cost (enum machine_mode mode, reg_class_t regclass, bool in)
{
- return (in ? 2 : 0) + memory_move_secondary_cost (mode, regclass, in);
+ return (in ? 2 : 0) + REGISTER_MOVE_COST (mode, regclass, regclass);
}
/* Convert a CC_MODE to the set of flags that it represents. */
@@ -2782,7 +2800,7 @@ rx_align_for_label (rtx lab, int uses_threshold)
because the delay due to the inserted NOPs would be greater than the delay
due to the misaligned branch. If uses_threshold is zero then the alignment
is always useful. */
- if (LABEL_NUSES (lab) < uses_threshold)
+ if (LABEL_P (lab) && LABEL_NUSES (lab) < uses_threshold)
return 0;
return optimize_size ? 1 : 3;
@@ -2837,7 +2855,7 @@ rx_adjust_insn_length (rtx insn, int current_length)
case CODE_FOR_smaxsi3_zero_extendhi:
case CODE_FOR_sminsi3_zero_extendhi:
case CODE_FOR_multsi3_zero_extendhi:
- case CODE_FOR_comparesi3_zero_extendqi:
+ case CODE_FOR_comparesi3_zero_extendhi:
zero = true;
factor = 2;
break;
@@ -2852,7 +2870,7 @@ rx_adjust_insn_length (rtx insn, int current_length)
case CODE_FOR_smaxsi3_sign_extendhi:
case CODE_FOR_sminsi3_sign_extendhi:
case CODE_FOR_multsi3_sign_extendhi:
- case CODE_FOR_comparesi3_zero_extendhi:
+ case CODE_FOR_comparesi3_sign_extendhi:
zero = false;
factor = 2;
break;
@@ -2867,7 +2885,7 @@ rx_adjust_insn_length (rtx insn, int current_length)
case CODE_FOR_smaxsi3_zero_extendqi:
case CODE_FOR_sminsi3_zero_extendqi:
case CODE_FOR_multsi3_zero_extendqi:
- case CODE_FOR_comparesi3_sign_extendqi:
+ case CODE_FOR_comparesi3_zero_extendqi:
zero = true;
factor = 1;
break;
@@ -2882,7 +2900,7 @@ rx_adjust_insn_length (rtx insn, int current_length)
case CODE_FOR_smaxsi3_sign_extendqi:
case CODE_FOR_sminsi3_sign_extendqi:
case CODE_FOR_multsi3_sign_extendqi:
- case CODE_FOR_comparesi3_sign_extendhi:
+ case CODE_FOR_comparesi3_sign_extendqi:
zero = false;
factor = 1;
break;
@@ -2953,6 +2971,9 @@ rx_adjust_insn_length (rtx insn, int current_length)
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS rx_init_builtins
+#undef TARGET_BUILTIN_DECL
+#define TARGET_BUILTIN_DECL rx_builtin_decl
+
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN rx_expand_builtin
@@ -3062,8 +3083,8 @@ rx_adjust_insn_length (rtx insn, int current_length)
#define TARGET_FLAGS_REGNUM CC_REG
#undef TARGET_LEGITIMATE_CONSTANT_P
-#define TARGET_LEGITIMATE_CONSTANT_P rx_legitimate_constant_p
+#define TARGET_LEGITIMATE_CONSTANT_P rx_is_legitimate_constant
struct gcc_target targetm = TARGET_INITIALIZER;
-/* #include "gt-rx.h" */
+#include "gt-rx.h"
diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h
index 1780867dcbf..67e8ce1c577 100644
--- a/gcc/config/rx/rx.h
+++ b/gcc/config/rx/rx.h
@@ -144,7 +144,7 @@
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-#define HAVE_PRE_DECCREMENT 1
+#define HAVE_PRE_DECREMENT 1
#define HAVE_POST_INCREMENT 1
#define MOVE_RATIO(SPEED) ((SPEED) ? 4 : 2)
diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md
index 824d246cb84..070f248bbdf 100644
--- a/gcc/config/rx/rx.md
+++ b/gcc/config/rx/rx.md
@@ -556,7 +556,7 @@
if (MEM_P (operand0) && MEM_P (operand1))
operands[1] = copy_to_mode_reg (<register_modes:MODE>mode, operand1);
if (CONST_INT_P (operand1)
- && ! rx_legitimate_constant_p (<register_modes:MODE>mode, operand1))
+ && ! rx_is_legitimate_constant (<register_modes:MODE>mode, operand1))
FAIL;
}
)
@@ -904,6 +904,39 @@
(set_attr "length" "3,4,5,6,7,6")]
)
+;; Peepholes to match:
+;; (set (reg A) (reg B))
+;; (set (CC) (compare:CC (reg A/reg B) (const_int 0)))
+;; and replace them with the addsi3_flags pattern, using an add
+;; of zero to copy the register and set the condition code bits.
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "register_operand"))
+ (set (reg:CC CC_REG)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ ""
+ [(parallel [(set (match_dup 0)
+ (plus:SI (match_dup 1) (const_int 0)))
+ (set (reg:CC_ZSC CC_REG)
+ (compare:CC_ZSC (plus:SI (match_dup 1) (const_int 0))
+ (const_int 0)))])]
+)
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "register_operand"))
+ (set (reg:CC CC_REG)
+ (compare:CC (match_dup 1)
+ (const_int 0)))]
+ ""
+ [(parallel [(set (match_dup 0)
+ (plus:SI (match_dup 1) (const_int 0)))
+ (set (reg:CC_ZSC CC_REG)
+ (compare:CC_ZSC (plus:SI (match_dup 1) (const_int 0))
+ (const_int 0)))])]
+)
+
(define_expand "adddi3"
[(set (match_operand:DI 0 "register_operand")
(plus:DI (match_operand:DI 1 "register_operand")
@@ -1668,6 +1701,35 @@
(extend_types:SI (match_dup 1))))]
)
+;; Convert:
+;; (set (reg1) (sign_extend (mem))
+;; (set (reg2) (zero_extend (reg1))
+;; into
+;; (set (reg2) (zero_extend (mem)))
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand")
+ (sign_extend:SI (match_operand:small_int_modes 1 "memory_operand")))
+ (set (match_operand:SI 2 "register_operand")
+ (zero_extend:SI (match_operand:small_int_modes 3 "register_operand")))]
+ "REGNO (operands[0]) == REGNO (operands[3])
+ && (REGNO (operands[0]) == REGNO (operands[2])
+ || peep2_regno_dead_p (2, REGNO (operands[0])))"
+ [(set (match_dup 2)
+ (zero_extend:SI (match_dup 1)))]
+)
+
+;; Remove the redundant sign extension from:
+;; (set (reg) (extend (mem)))
+;; (set (reg) (extend (reg)))
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand")
+ (extend_types:SI (match_operand:small_int_modes 1 "memory_operand")))
+ (set (match_dup 0)
+ (extend_types:SI (match_operand:small_int_modes 2 "register_operand")))]
+ "REGNO (operands[0]) == REGNO (operands[2])"
+ [(set (match_dup 0) (extend_types:SI (match_dup 1)))]
+)
+
(define_insn "comparesi3_<extend_types:code><small_int_modes:mode>"
[(set (reg:CC CC_REG)
(compare:CC (match_operand:SI 0 "register_operand" "=r")
@@ -1769,7 +1831,7 @@
)
(define_insn "*bitset_in_memory"
- [(set (match_operand:QI 0 "memory_operand" "+Q")
+ [(set (match_operand:QI 0 "rx_restricted_mem_operand" "+Q")
(ior:QI (ashift:QI (const_int 1)
(match_operand:QI 1 "nonmemory_operand" "ri"))
(match_dup 0)))]
@@ -1790,7 +1852,7 @@
)
(define_insn "*bitinvert_in_memory"
- [(set (match_operand:QI 0 "memory_operand" "+Q")
+ [(set (match_operand:QI 0 "rx_restricted_mem_operand" "+Q")
(xor:QI (ashift:QI (const_int 1)
(match_operand:QI 1 "nonmemory_operand" "ri"))
(match_dup 0)))]
@@ -1813,7 +1875,7 @@
)
(define_insn "*bitclr_in_memory"
- [(set (match_operand:QI 0 "memory_operand" "+Q")
+ [(set (match_operand:QI 0 "rx_restricted_mem_operand" "+Q")
(and:QI (not:QI
(ashift:QI
(const_int 1)
diff --git a/gcc/config/sol2-protos.h b/gcc/config/sol2-protos.h
index 800629aaba1..25753ff610e 100644
--- a/gcc/config/sol2-protos.h
+++ b/gcc/config/sol2-protos.h
@@ -22,3 +22,5 @@ extern void solaris_insert_attributes (tree, tree *);
extern void solaris_register_pragmas (void);
extern void solaris_output_init_fini (FILE *, tree);
extern void solaris_assemble_visibility (tree, int);
+extern void solaris_elf_asm_comdat_section (const char *, unsigned int, tree);
+extern void solaris_code_end (void);
diff --git a/gcc/config/sol2.c b/gcc/config/sol2.c
index decde2fea29..7fed184e14d 100644
--- a/gcc/config/sol2.c
+++ b/gcc/config/sol2.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h"
#include "diagnostic-core.h"
#include "ggc.h"
+#include "hashtab.h"
tree solaris_pending_aligns, solaris_pending_inits, solaris_pending_finis;
@@ -106,14 +107,14 @@ solaris_output_init_fini (FILE *file, tree decl)
{
if (lookup_attribute ("init", DECL_ATTRIBUTES (decl)))
{
- fprintf (file, PUSHSECTION_FORMAT, ".init");
+ fprintf (file, "\t.pushsection\t" SECTION_NAME_FORMAT "\n", ".init");
ASM_OUTPUT_CALL (file, decl);
fprintf (file, "\t.popsection\n");
}
if (lookup_attribute ("fini", DECL_ATTRIBUTES (decl)))
{
- fprintf (file, PUSHSECTION_FORMAT, ".fini");
+ fprintf (file, "\t.pushsection\t" SECTION_NAME_FORMAT "\n", ".fini");
ASM_OUTPUT_CALL (file, decl);
fprintf (file, "\t.popsection\n");
}
@@ -155,3 +156,129 @@ solaris_assemble_visibility (tree decl ATTRIBUTE_UNUSED,
"in this configuration; ignored");
#endif
}
+
+/* Hash table of group signature symbols. */
+
+static htab_t solaris_comdat_htab;
+
+/* Group section information entry stored in solaris_comdat_htab. */
+
+typedef struct comdat_entry
+{
+ const char *name;
+ unsigned int flags;
+ tree decl;
+ const char *sig;
+} comdat_entry;
+
+/* Helper routines for maintaining solaris_comdat_htab. */
+
+static hashval_t
+comdat_hash (const void *p)
+{
+ const comdat_entry *entry = (const comdat_entry *) p;
+
+ return htab_hash_string (entry->sig);
+}
+
+static int
+comdat_eq (const void *p1, const void *p2)
+{
+ const comdat_entry *entry1 = (const comdat_entry *) p1;
+ const comdat_entry *entry2 = (const comdat_entry *) p2;
+
+ return strcmp (entry1->sig, entry2->sig) == 0;
+}
+
+/* Output assembly to switch to COMDAT group section NAME with attributes
+ FLAGS and group signature symbol DECL, using Sun as syntax. */
+
+void
+solaris_elf_asm_comdat_section (const char *name, unsigned int flags, tree decl)
+{
+ const char *signature;
+ char *section;
+ comdat_entry entry, **slot;
+
+ if (TREE_CODE (decl) == IDENTIFIER_NODE)
+ signature = IDENTIFIER_POINTER (decl);
+ else
+ signature = IDENTIFIER_POINTER (DECL_COMDAT_GROUP (decl));
+
+ /* Sun as requires group sections to be fragmented, i.e. to have names of
+ the form <section>%<fragment>. Strictly speaking this is only
+ necessary to support cc -xF, but is enforced globally in violation of
+ the ELF gABI. We keep the section names generated by GCC (generally
+ of the form .text.<signature>) and append %<signature> to pacify as,
+ despite the redundancy. */
+ section = concat (name, "%", signature, NULL);
+
+ /* Clear SECTION_LINKONCE flag so targetm.asm_out.named_section only
+ emits this as a regular section. Emit section before .group
+ directive since Sun as treats undeclared sections as @progbits,
+ which conflicts with .bss* sections which are @nobits. */
+ targetm.asm_out.named_section (section, flags & ~SECTION_LINKONCE, decl);
+
+ /* Sun as separates declaration of a group section and of the group
+ itself, using the .group directive and the #comdat flag. */
+ fprintf (asm_out_file, "\t.group\t%s," SECTION_NAME_FORMAT ",#comdat\n",
+ signature, section);
+
+ /* Unlike GNU as, group signature symbols need to be defined explicitly
+ for Sun as. With a few exceptions, this is already the case. To
+ identify the missing ones without changing the affected frontents,
+ remember the signature symbols and emit those not marked
+ TREE_SYMBOL_REFERENCED in solaris_code_end. */
+ if (solaris_comdat_htab == NULL)
+ solaris_comdat_htab = htab_create_alloc (37, comdat_hash, comdat_eq, NULL,
+ xcalloc, free);
+
+ entry.sig = signature;
+ slot = (comdat_entry **) htab_find_slot (solaris_comdat_htab, &entry, INSERT);
+
+ if (*slot == NULL)
+ {
+ *slot = XCNEW (comdat_entry);
+ /* Remember fragmented section name. */
+ (*slot)->name = section;
+ /* Emit as regular section, .group declaration has already been done. */
+ (*slot)->flags = flags & ~SECTION_LINKONCE;
+ (*slot)->decl = decl;
+ (*slot)->sig = signature;
+ }
+}
+
+/* Define unreferenced COMDAT group signature symbol corresponding to SLOT. */
+
+static int
+solaris_define_comdat_signature (void **slot, void *aux ATTRIBUTE_UNUSED)
+{
+ comdat_entry *entry = *(comdat_entry **) slot;
+ tree decl = entry->decl;
+
+ if (TREE_CODE (decl) != IDENTIFIER_NODE)
+ decl = DECL_COMDAT_GROUP (decl);
+
+ if (!TREE_SYMBOL_REFERENCED (decl))
+ {
+ /* Switch to group section, otherwise Sun as complains
+ `Group Id symbol defined outside of group'. */
+ switch_to_section (get_section (entry->name, entry->flags, entry->decl));
+
+ ASM_OUTPUT_LABEL (asm_out_file, entry->sig);
+ }
+
+ /* Continue with scan. */
+ return 1;
+}
+
+/* Emit unreferenced COMDAT group signature symbols for Sun as. */
+
+void
+solaris_code_end (void)
+{
+ if (solaris_comdat_htab == NULL)
+ return;
+
+ htab_traverse (solaris_comdat_htab, solaris_define_comdat_signature, NULL);
+}
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
index 7e42ddb6a4b..f3394fda74d 100644
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -19,6 +19,9 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+/* We are compiling for Solaris 2 now. */
+#define TARGET_SOLARIS 1
+
/* We use stabs-in-elf for debugging, because that is what the native
toolchain uses. */
#undef PREFERRED_DEBUGGING_TYPE
@@ -257,9 +260,8 @@ __enable_execute_stack (void *addr) \
{ "init", 0, 0, true, false, false, NULL, false }, \
{ "fini", 0, 0, true, false, false, NULL, false }
-/* Solaris/x86 as and gas support the common ELF .section/.pushsection
- syntax. */
-#define PUSHSECTION_FORMAT "\t.pushsection\t%s\n"
+/* Solaris/x86 as and gas support unquoted section names. */
+#define SECTION_NAME_FORMAT "%s"
/* This is how to declare the size of a function. For Solaris, we output
any .init or .fini entries here. */
diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h
index 73355ca8c45..a53b82a8e95 100644
--- a/gcc/config/sparc/sol2.h
+++ b/gcc/config/sparc/sol2.h
@@ -188,9 +188,16 @@ along with GCC; see the file COPYING3. If not see
#undef TARGET_ASM_NAMED_SECTION
#define TARGET_ASM_NAMED_SECTION sparc_solaris_elf_asm_named_section
-/* And SPARC non-standard pushsection syntax. */
-#undef PUSHSECTION_FORMAT
-#define PUSHSECTION_FORMAT "\t.pushsection\t\"%s\"\n"
+/* Emit COMDAT group signature symbols for Sun as. */
+#undef TARGET_ASM_CODE_END
+#define TARGET_ASM_CODE_END solaris_code_end
+
+/* Solaris/SPARC as requires doublequoted section names. While gas
+ supports that, too, we prefer the standard variant. */
+#ifndef USE_GAS
+#undef SECTION_NAME_FORMAT
+#define SECTION_NAME_FORMAT "\"%s\""
+#endif
/* Static stack checking is supported by means of probes. */
#define STACK_CHECK_STATIC_BUILTIN 1
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index a3bab331910..10b35f250e9 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -3110,8 +3110,16 @@ legitimate_pic_operand_p (rtx x)
return true;
}
-/* Return nonzero if ADDR is a valid memory address.
- STRICT specifies whether strict register checking applies. */
+#define RTX_OK_FOR_OFFSET_P(X) \
+ (CONST_INT_P (X) && INTVAL (X) >= -0x1000 && INTVAL (X) < 0x1000 - 8)
+
+#define RTX_OK_FOR_OLO10_P(X) \
+ (CONST_INT_P (X) && INTVAL (X) >= -0x1000 && INTVAL (X) < 0xc00 - 8)
+
+/* Handle the TARGET_LEGITIMATE_ADDRESS_P target hook.
+
+ On SPARC, the actual legitimate addresses must be REG+REG or REG+SMALLINT
+ ordinarily. This changes a bit when generating PIC. */
static bool
sparc_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict)
@@ -3706,7 +3714,7 @@ sparc_mode_dependent_address_p (const_rtx addr)
rtx op0 = XEXP (addr, 0);
rtx op1 = XEXP (addr, 1);
if (op0 == pic_offset_table_rtx
- && SYMBOLIC_CONST (op1))
+ && symbolic_operand (op1, VOIDmode))
return true;
}
@@ -8529,12 +8537,19 @@ sparc_profile_hook (int labelno)
}
}
+#ifdef TARGET_SOLARIS
/* Solaris implementation of TARGET_ASM_NAMED_SECTION. */
static void
sparc_solaris_elf_asm_named_section (const char *name, unsigned int flags,
tree decl ATTRIBUTE_UNUSED)
{
+ if (HAVE_COMDAT_GROUP && flags & SECTION_LINKONCE)
+ {
+ solaris_elf_asm_comdat_section (name, flags, decl);
+ return;
+ }
+
fprintf (asm_out_file, "\t.section\t\"%s\"", name);
if (!(flags & SECTION_DEBUG))
@@ -8550,6 +8565,7 @@ sparc_solaris_elf_asm_named_section (const char *name, unsigned int flags,
fputc ('\n', asm_out_file);
}
+#endif /* TARGET_SOLARIS */
/* We do not allow indirect calls to be optimized into sibling calls.
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 7039fb048b0..ad354e89eca 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1538,41 +1538,6 @@ do { \
addresses which require two reload registers. */
#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X)
-
-/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
- and check its validity for a certain class.
- We have two alternate definitions for each of them.
- The usual definition accepts all pseudo regs; the other rejects
- them unless they have been allocated suitable hard regs.
- The symbol REG_OK_STRICT causes the latter definition to be used.
-
- Most source files want to accept pseudo regs in the hope that
- they will get allocated to the class that the insn wants them to be in.
- Source files for reload pass need to be strict.
- After reload, it makes no difference, since pseudo regs have
- been eliminated by then. */
-
-#ifndef REG_OK_STRICT
-
-/* Nonzero if X is a hard reg that can be used as an index
- or if it is a pseudo reg. */
-#define REG_OK_FOR_INDEX_P(X) \
- (REGNO (X) < 32 \
- || REGNO (X) == FRAME_POINTER_REGNUM \
- || REGNO (X) >= FIRST_PSEUDO_REGISTER)
-
-/* Nonzero if X is a hard reg that can be used as a base reg
- or if it is a pseudo reg. */
-#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_INDEX_P (X)
-
-#else
-
-/* Nonzero if X is a hard reg that can be used as an index. */
-#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
-/* Nonzero if X is a hard reg that can be used as a base reg. */
-#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
-
-#endif
/* Should gcc use [%reg+%lo(xx)+offset] addresses? */
@@ -1582,31 +1547,6 @@ do { \
#define USE_AS_OFFSETABLE_LO10 0
#endif
-/* On SPARC, the actual legitimate addresses must be REG+REG or REG+SMALLINT
- ordinarily. This changes a bit when generating PIC. The details are
- in sparc.c's implementation of TARGET_LEGITIMATE_ADDRESS_P. */
-
-#define SYMBOLIC_CONST(X) symbolic_operand (X, VOIDmode)
-
-#define RTX_OK_FOR_BASE_P(X) \
- ((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \
- || (GET_CODE (X) == SUBREG \
- && GET_CODE (SUBREG_REG (X)) == REG \
- && REG_OK_FOR_BASE_P (SUBREG_REG (X))))
-
-#define RTX_OK_FOR_INDEX_P(X) \
- ((GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X)) \
- || (GET_CODE (X) == SUBREG \
- && GET_CODE (SUBREG_REG (X)) == REG \
- && REG_OK_FOR_INDEX_P (SUBREG_REG (X))))
-
-#define RTX_OK_FOR_OFFSET_P(X) \
- (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0x1000 - 8)
-
-#define RTX_OK_FOR_OLO10_P(X) \
- (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0xc00 - 8)
-
-
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
macro is used in only one place: `find_reloads_address' in reload.c. */
diff --git a/gcc/config/t-sol2 b/gcc/config/t-sol2
index 6a76bf1bad8..1604b9e499f 100644
--- a/gcc/config/t-sol2
+++ b/gcc/config/t-sol2
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2008, 2009, 2010 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
@@ -25,7 +25,7 @@ sol2-c.o: $(srcdir)/config/sol2-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
# Solaris-specific attributes
sol2.o: $(srcdir)/config/sol2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- tree.h output.h $(TM_H) $(TM_P_H) $(GGC_H)
+ tree.h output.h $(TM_H) $(TARGET_H) $(TM_P_H) $(GGC_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/sol2.c