aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorH.J. Lu <hongjiu.lu@intel.com>2010-10-30 13:17:15 +0000
committerH.J. Lu <hjl@gcc.gnu.org>2010-10-30 06:17:15 -0700
commit3127848955bbdaa2fca1b4984b3d78b42d1a36e1 (patch)
treeb0af389ca8d4064e80270e11f499ff0d1002bb4d /gcc
parent46a88c12210a5677435efa706e424a4e37ab4646 (diff)
downloadgcc-3127848955bbdaa2fca1b4984b3d78b42d1a36e1.zip
gcc-3127848955bbdaa2fca1b4984b3d78b42d1a36e1.tar.gz
gcc-3127848955bbdaa2fca1b4984b3d78b42d1a36e1.tar.bz2
Align long double parameters on stack to 4byte in 32bit.
2010-10-30 H.J. Lu <hongjiu.lu@intel.com> PR target/46195 * config/i386/i386.c (contains_aligned_value_p): Renamed to ... (ix86_compat_aligned_value_p): This. (ix86_old_function_arg_boundary): Renamed to ... (ix86_compat_function_arg_boundary): This. Updated. (ix86_contains_aligned_value_p): New. (ix86_function_arg_boundary): Align long double parameters on stack to 4byte in 32bit. From-SVN: r166088
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/i386/i386.c95
2 files changed, 94 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 22ded87..00bb74f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2010-10-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/46195
+ * config/i386/i386.c (contains_aligned_value_p): Renamed to ...
+ (ix86_compat_aligned_value_p): This.
+ (ix86_old_function_arg_boundary): Renamed to ...
+ (ix86_compat_function_arg_boundary): This. Updated.
+ (ix86_contains_aligned_value_p): New.
+ (ix86_function_arg_boundary): Align long double parameters on
+ stack to 4byte in 32bit.
+
2010-10-30 Nicola Pero <nicola.pero@meta-innovation.com>
Implemented Objective-C 2.0 @property, @synthesize and @dynamic.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index f2bd705..4cd3f07 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -6952,10 +6952,12 @@ ix86_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
return 0;
}
-/* Return true when TYPE should be 128bit aligned for 32bit argument passing
- ABI. */
+/* Return true when TYPE should be 128bit aligned for 32bit argument
+ passing ABI. XXX: This function is obsolete and is only used for
+ checking psABI compatibility with previous versions of GCC. */
+
static bool
-contains_aligned_value_p (const_tree type)
+ix86_compat_aligned_value_p (const_tree type)
{
enum machine_mode mode = TYPE_MODE (type);
if (((TARGET_SSE && SSE_REG_MODE_P (mode))
@@ -6982,7 +6984,7 @@ contains_aligned_value_p (const_tree type)
for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
{
if (TREE_CODE (field) == FIELD_DECL
- && contains_aligned_value_p (TREE_TYPE (field)))
+ && ix86_compat_aligned_value_p (TREE_TYPE (field)))
return true;
}
break;
@@ -6990,7 +6992,7 @@ contains_aligned_value_p (const_tree type)
case ARRAY_TYPE:
/* Just for use if some languages passes arrays by value. */
- if (contains_aligned_value_p (TREE_TYPE (type)))
+ if (ix86_compat_aligned_value_p (TREE_TYPE (type)))
return true;
break;
@@ -7001,9 +7003,13 @@ contains_aligned_value_p (const_tree type)
return false;
}
+/* Return the alignment boundary for MODE and TYPE with alignment ALIGN.
+ XXX: This function is obsolete and is only used for checking psABI
+ compatibility with previous versions of GCC. */
+
static int
-ix86_old_function_arg_boundary (enum machine_mode mode, const_tree type,
- int align)
+ix86_compat_function_arg_boundary (enum machine_mode mode,
+ const_tree type, int align)
{
/* In 32bit, only _Decimal128 and __float128 are aligned to their
natural boundaries. */
@@ -7023,7 +7029,7 @@ ix86_old_function_arg_boundary (enum machine_mode mode, const_tree type,
}
else
{
- if (!contains_aligned_value_p (type))
+ if (!ix86_compat_aligned_value_p (type))
align = PARM_BOUNDARY;
}
}
@@ -7032,6 +7038,59 @@ ix86_old_function_arg_boundary (enum machine_mode mode, const_tree type,
return align;
}
+/* Return true when TYPE should be 128bit aligned for 32bit argument
+ passing ABI. */
+
+static bool
+ix86_contains_aligned_value_p (const_tree type)
+{
+ enum machine_mode mode = TYPE_MODE (type);
+
+ if (mode == XFmode || mode == XCmode)
+ return false;
+
+ if (TYPE_ALIGN (type) < 128)
+ return false;
+
+ if (AGGREGATE_TYPE_P (type))
+ {
+ /* Walk the aggregates recursively. */
+ switch (TREE_CODE (type))
+ {
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ {
+ tree field;
+
+ /* Walk all the structure fields. */
+ for (field = TYPE_FIELDS (type);
+ field;
+ field = DECL_CHAIN (field))
+ {
+ if (TREE_CODE (field) == FIELD_DECL
+ && ix86_contains_aligned_value_p (TREE_TYPE (field)))
+ return true;
+ }
+ break;
+ }
+
+ case ARRAY_TYPE:
+ /* Just for use if some languages passes arrays by value. */
+ if (ix86_contains_aligned_value_p (TREE_TYPE (type)))
+ return true;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+ else
+ return TYPE_ALIGN (type) >= 128;
+
+ return false;
+}
+
/* Gives the alignment boundary, in bits, of an argument with the
specified mode and type. */
@@ -7055,13 +7114,25 @@ ix86_function_arg_boundary (enum machine_mode mode, const_tree type)
static bool warned;
int saved_align = align;
- if (!TARGET_64BIT && align < 128)
- align = PARM_BOUNDARY;
+ if (!TARGET_64BIT)
+ {
+ /* i386 ABI defines XFmode arguments to be 4 byte aligned. */
+ if (!type)
+ {
+ if (mode == XFmode || mode == XCmode)
+ align = PARM_BOUNDARY;
+ }
+ else if (!ix86_contains_aligned_value_p (type))
+ align = PARM_BOUNDARY;
+
+ if (align < 128)
+ align = PARM_BOUNDARY;
+ }
if (warn_psabi
&& !warned
- && align != ix86_old_function_arg_boundary (mode, type,
- saved_align))
+ && align != ix86_compat_function_arg_boundary (mode, type,
+ saved_align))
{
warned = true;
inform (input_location,