summaryrefslogtreecommitdiff
path: root/debian/patches/illumos-strict-calling-conventions.diff
blob: 342f91f3744d3dd451f966b3d6a3376eb96045f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
From: Richard Lowe <richlowe@richlowe.net>
Date: Sat, 27 Oct 2012 02:44:09 +0100
Subject: [PATCH] Implement -fstrict-calling-conventions

Stock GCC is overly willing to violate the ABI when calling local functions,
such that it passes arguments in registers on i386.  This hampers debugging
with anything other than a fully-aware DWARF debugger, and is generally not
something we desire.

Implement a flag which disables this behaviour, enabled by default.  The flag is
global, though only effective on i386, to more easily allow its globalization
later which, given the odds, is likely to be necessary.

See http://wiki.illumos.org/display/illumos/GCC+Modifications

Index: gcc-48/src/gcc/common.opt
===================================================================
--- gcc-48.orig/src/gcc/common.opt	2014-04-18 19:51:49.854293922 +0400
+++ gcc-48/src/gcc/common.opt	2014-04-19 13:25:33.566648986 +0400
@@ -1930,6 +1930,10 @@
 Common Report Var(flag_strict_aliasing) Optimization
 Assume strict aliasing rules apply
 
+fstrict-calling-conventions
+Common Report Var(flag_strict_calling_conventions) Init(1)
+Use strict ABI calling conventions even for static functions
+
 fstrict-overflow
 Common Report Var(flag_strict_overflow)
 Treat signed overflow as undefined
Index: gcc-48/src/gcc/config/i386/i386.c
===================================================================
--- gcc-48.orig/src/gcc/config/i386/i386.c	2014-04-18 19:39:46.504594693 +0400
+++ gcc-48/src/gcc/config/i386/i386.c	2014-04-19 13:28:34.056953493 +0400
@@ -5176,6 +5176,7 @@
   /* Use register calling convention for local functions when possible.  */
   if (decl
       && TREE_CODE (decl) == FUNCTION_DECL
+      && (TARGET_64BIT || !flag_strict_calling_conventions)
       /* Caller and callee must agree on the calling convention, so
 	 checking here just optimize means that with
 	 __attribute__((optimize (...))) caller could use regparm convention
@@ -5258,8 +5259,9 @@
 
   /* For local functions, pass up to SSE_REGPARM_MAX SFmode
      (and DFmode for SSE2) arguments in SSE registers.  */
-  if (decl && TARGET_SSE_MATH && optimize
-      && !(profile_flag && !flag_fentry))
+  if (decl && TARGET_SSE_MATH && optimize &&
+      (TARGET_64BIT || !flag_strict_calling_conventions) &&
+      !(profile_flag && !flag_fentry))
     {
       /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified.  */
       struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE(decl));
Index: gcc-48/src/gcc/doc/invoke.texi
===================================================================
--- gcc-48.orig/src/gcc/doc/invoke.texi	2014-04-18 19:51:49.889319972 +0400
+++ gcc-48/src/gcc/doc/invoke.texi	2014-04-19 13:25:33.904408477 +0400
@@ -8034,6 +8034,12 @@
 The @option{-fstrict-aliasing} option is enabled at levels
 @option{-O2}, @option{-O3}, @option{-Os}.
 
+@item -fstrict-calling-conventions
+@opindex fstrict-calling-conventions
+Use strict ABI calling conventions even with local functions.
+This disable certain optimizations that may cause GCC to call local
+functions in a manner other than that described by the ABI.
+
 @item -fstrict-overflow
 @opindex fstrict-overflow
 Allow the compiler to assume strict signed overflow rules, depending
Index: gcc-48/src/gcc/testsuite/gcc.target/i386/local.c
===================================================================
--- gcc-48.orig/src/gcc/testsuite/gcc.target/i386/local.c	2012-02-27 23:18:23.000000000 +0400
+++ gcc-48/src/gcc/testsuite/gcc.target/i386/local.c	2014-04-19 13:25:33.941693684 +0400
@@ -1,5 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -funit-at-a-time" } */
+/* { dg-options "-O2 -funit-at-a-time -fno-strict-calling-conventions" { target ilp32 } } */
+/* { dg-options "-O2 -funit-at-a-time" { target lp64 } } */
 /* { dg-final { scan-assembler "magic\[^\\n\]*eax" { target ia32 } } } */
 /* { dg-final { scan-assembler "magic\[^\\n\]*(edi|ecx)" { target { ! { ia32 } } } } } */
 
Index: gcc-48/src/gcc/testsuite/gcc.target/i386/strict-cc.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc-48/src/gcc/testsuite/gcc.target/i386/strict-cc.c	2014-04-19 13:25:33.944559397 +0400
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { ilp32 } } } */
+/* { dg-options "-O2 -funit-at-a-time -fstrict-calling-conventions"  } */
+/* { dg-final { scan-assembler "pushl.*\\\$1" } } */
+/* { dg-final { scan-assembler "pushl.*\\\$2" } } */
+/* { dg-final { scan-assembler "pushl.*\\\$3" } } */
+/* { dg-final { scan-assembler "pushl.*\\\$4" } } */
+/* { dg-final { scan-assembler "pushl.*\\\$5" } } */
+
+#include <stdio.h>
+
+/* Verify that local calling convention is not used if strict conventions.  */
+static t(int, int, int, int, int) __attribute__ ((noinline));
+
+m()
+{
+    t(1, 2, 3, 4, 5);
+}
+
+static t(int a, int b, int c, int d, int e)
+{
+    printf("%d\n", a, b, c, d, e);
+}