diff mbox series

Introduce vxworks7r2 support for ppc and ppc64

Message ID 0F50294D-060F-48EF-BACB-677C0BF59575@adacore.com
State New
Headers show
Series Introduce vxworks7r2 support for ppc and ppc64 | expand

Commit Message

Olivier Hainque Oct. 20, 2020, 10:10 a.m. UTC
Hello,

This change introduces support for the most recent versions
of VxWorks on PowerPC targets, for both 32 and 64 bit thanks
to a bi-arch setup.

The system compilers are essentially configured as Linux
toolchains with only a few specificities and we replicate
that model here.

The most visible specificities are the use of secureplt by
default, the pre-definition of some macros that the system
headers still rely on (_VX_CPU and _VX_CPU_FAMILY, for example),
and of course some variations related to the so VxWorks typical
kernel vs RTP mode distinction.

In addition to the introduction of config.gcc and libgcc
configuration chunks, much inspired by the linux ones, the
change

- Reworks rs6000/vxworks.h file to feature bits common to the
  Vx6 and Vx7 port then a separate section for each, where the
  Vx7 part is very short as we rely on the Linux definitions
  for most things.

- Adjusts the CPU macro predefinitions in CPP_SPEC to resort to
  "_VX_CPU" instead of "CPU" for Vx7, to better match the more recent
  system headers expectations,

- Adds a cpu definition case for e6500.

- Changes to the use SUB3TARGET_OVERRIDE_OPTIONS instead of
  SUBSUBTARGET_OVERRIDE_OPTIONS for specifics, so we don't override
  the Linux's version of the latter for vx7.


We have been using this for a while in gcc-9 production toolchains
with Ada, C & C++ support.

I have also verified that I could

- build and pass quite a few tests with a gcc-10 based ongoing port
  (an in-house testsuite for cross configurations and Ada acats for
  both kernel and RTP setups), for both VxWorks 6.9 and 7.2

- build a VxWorks 6.9 and 7.2 compiler with mainline sources, as well
  as a Ada+C VxWorks 653 compiler with only a couple of minor configuration
  self-spec presets (-DVTHREADS -D_WRS_VXWORKS_MAJOR=5).

The base ports were initially developed by Doug Rupp, then reworked a
bit to fit with other ongoing work in the VxWorks area.

Olivier


2020-10-20  Douglas Rupp  <rupp@adacore.com>
            Olivier Hainque  <hainque@adacore.com>

gcc/
	* config.gcc (powerpc*-wrs-vxworks7r*): New case.
	* config/rs6000/vxworks.h: Rework to handle VxWorks7. Refactor as
	common bits + vx6 vs vx7 ones. For the latter, rely essentially on
	Linux configuration and adjust CPU to _VX_CPU in CPP_SPEC. Add case
	for e6500. Use SUB3TARGET_OVERRIDE_OPTIONS for specifics so we don't
	override the Linux's version of the latter for vx7.

libgcc/
	* config.host (powerpc*-wrs-vxworks7*): New case.
	* configure.ac: Handle powerpc*-*-vxworks7* as powerpc*-*-linux*
	for ppc-fp_type.
	* configure: Regenerate.

Comments

Segher Boessenkool Oct. 20, 2020, 8:06 p.m. UTC | #1
Hi!

On Tue, Oct 20, 2020 at 12:10:59PM +0200, Olivier Hainque wrote:
> This change introduces support for the most recent versions
> of VxWorks on PowerPC targets, for both 32 and 64 bit thanks
> to a bi-arch setup.
> 
> The system compilers are essentially configured as Linux
> toolchains with only a few specificities and we replicate
> that model here.

> +powerpc*-wrs-vxworks7r*)
> +
> +	# Wind River 7 post SR0600 is mostly like Linux so we setup
> +	# out config in a very similar fashion and adjust to a few
> +	# specificities.

"our config"?

> -   analogous changes here too.  */
> +/* The port comes in two very different flavors at this stage:
> +
> +   - For 653 (AE) and regular versions prior to VxWorks 7, the port
> +     comes with its own set of definitions, matching a system compiler
> +     configured this way as well as the corresponding run-time
> +     environment.  This is essentially an eabi system, so changes to
> +     eabi.h should usually be reflected here.
> +
> +   - Starting with VxWorks 7 (post SR600), the system environment
> +     was made extremely similar to GNU/Linux and this toolchain is
> +     builtin on top of the corresponding header files.  */

"built on top"?

> +/****************************
> + * Common definitions first *
> + ****************************/

We don't use such decorated comments in GCC.  But it is your header file
of course :-)

I don't see anything wrong with the actual code itself, fwiw :-)


Segher
Olivier Hainque Oct. 21, 2020, 10:30 a.m. UTC | #2
Hi Segher!

> On 20 Oct 2020, at 22:06, Segher Boessenkool <segher@kernel.crashing.org> wrote:
> 
>> +	# Wind River 7 post SR0600 is mostly like Linux so we setup
>> +	# out config in a very similar fashion and adjust to a few
>> +	# specificities.
> 
> "our config"?
> 
>> +   - Starting with VxWorks 7 (post SR600), the system environment
>> +     was made extremely similar to GNU/Linux and this toolchain is
>> +     builtin on top of the corresponding header files.  */
> 
> "built on top"?

Indeed.

>> +/****************************
>> + * Common definitions first *
>> + ****************************/
> 
> We don't use such decorated comments in GCC.  But it is your header file
> of course :-)

Hmm, I’d really like to keep some visible separation for the
sections because it’s pretty dense overall and I think hard to
read without some high level hints about the general organization.

There are (a few, agreed :) instances of sectioning in other
sources, tree-core.h or tree-vectorizer.h for example, with a
different style though. I think I’ll adjust to one of these.

> I don't see anything wrong with the actual code itself, fwiw :-)

Great, feedback appreciated, thanks!

Next in line specific to rs6000 are a couple of suggestions
for updates in the testsuite (wrt fpic and dfp).

Regards,

Olivier
diff mbox series

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index b79c544c9fa4..2cc121ac3686 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2976,6 +2976,27 @@  powerpc*-*-linux*)
 		tm_file="rs6000/secureplt.h ${tm_file}"
 	fi
 	;;
+powerpc*-wrs-vxworks7r*)
+
+	# Wind River 7 post SR0600 is mostly like Linux so we setup
+	# out config in a very similar fashion and adjust to a few
+	# specificities.
+
+	# The system compiler is configured with secureplt by default.
+	tm_file="${tm_file} rs6000/secureplt.h"
+
+	tm_file="${tm_file} elfos.h gnu-user.h linux.h freebsd-spec.h"
+	tm_file="${tm_file} rs6000/sysv4.h rs6000/biarch64.h rs6000/default64.h rs6000/linux64.h"
+	tm_file="${tm_file} vx-common.h vxworks.h rs6000/vxworks.h"
+
+	extra_options="${extra_options} rs6000/sysv4.opt linux.opt rs6000/linux64.opt"
+
+	tmake_file="${tmake_file} t-linux rs6000/t-linux64 rs6000/t-fprules rs6000/t-ppccomm"
+	tmake_file="${tmake_file} rs6000/t-vxworks"
+
+	tm_defines="$tm_defines DEFAULT_LIBC=LIBC_GLIBC"
+	extra_objs="$extra_objs linux.o rs6000-linux.o"
+	;;
 powerpc-wrs-vxworks*)
 	tm_file="${tm_file} elfos.h gnu-user.h freebsd-spec.h rs6000/sysv4.h"
 	tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-ppccomm rs6000/t-vxworks"
diff --git a/gcc/config/rs6000/vxworks.h b/gcc/config/rs6000/vxworks.h
index 60e1ef42390f..ed324a9b94b8 100644
--- a/gcc/config/rs6000/vxworks.h
+++ b/gcc/config/rs6000/vxworks.h
@@ -18,10 +18,21 @@  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/>.  */
 
-/* Note to future editors: VxWorks is mostly an EABI target.  We do
-   not use rs6000/eabi.h because we would have to override most of
-   it anyway.  However, if you change that file, consider making
-   analogous changes here too.  */
+/* The port comes in two very different flavors at this stage:
+
+   - For 653 (AE) and regular versions prior to VxWorks 7, the port
+     comes with its own set of definitions, matching a system compiler
+     configured this way as well as the corresponding run-time
+     environment.  This is essentially an eabi system, so changes to
+     eabi.h should usually be reflected here.
+
+   - Starting with VxWorks 7 (post SR600), the system environment
+     was made extremely similar to GNU/Linux and this toolchain is
+     builtin on top of the corresponding header files.  */
+
+/****************************
+ * Common definitions first *
+ ****************************/
 
 /* CPP predefined macros.  */
 
@@ -86,97 +97,89 @@  along with GCC; see the file COPYING3.  If not see
     }		\
   while (0)
 
-/* vx6 library path.  */
-#if !TARGET_VXWORKS7
-#undef  STARTFILE_PREFIX_SPEC
-#define STARTFILE_PREFIX_SPEC						\
- "%{mrtp:%{!shared:%:getenv(WIND_BASE /target/lib/usr/lib/ppc/PPC32/common)}}"
+/* Specific CPU macro definitions expected by the system headers,
+   inferred from -mcpu requests by the user.  Different versions of
+   VxWorks expect different forms of macros, such as
+
+   -D_VX_CPU=_VX_PPC403 on Vx7 and some variants of Vx6,
+   -DCPU=PPC403 on all Vx6 and earlier.  */
+
+#if TARGET_VXWORKS7
+#define VX_CPU_PREFIX "_VX_"
+#else
+#define VX_CPU_PREFIX ""
 #endif
 
-/* Only big endian PPC is supported by VxWorks.  */
-#undef BYTES_BIG_ENDIAN
-#define BYTES_BIG_ENDIAN 1
-#undef WORDS_BIG_ENDIAN
-#define WORDS_BIG_ENDIAN 1
+#define VX_CPUDEF(CPUID) \
+  ":-D" VX_CPU_PREFIX "CPU=" VX_CPU_PREFIX #CPUID
 
-/* We have to kill off the entire specs set created by rs6000/sysv4.h
-   and substitute our own set.  The top level vxworks.h has done some
-   of this for us.  */
+#define VX_MCPU(CPU,CPUID) \
+  "mcpu=" #CPU VX_CPUDEF(CPUID)
 
-#undef SUBTARGET_EXTRA_SPECS
 #undef CPP_SPEC
-#undef CC1_SPEC
-#undef ASM_SPEC
-
-#define SUBTARGET_EXTRA_SPECS /* none needed */
+#define CPP_SPEC			\
+  "%{!D" VX_CPU_PREFIX "CPU=*:%{"	\
+  VX_MCPU(403, PPC403)   ";"		\
+  VX_MCPU(405, PPC405)   ";"		\
+  VX_MCPU(440, PPC440)   ";"		\
+  VX_MCPU(464, PPC464)   ";"		\
+  VX_MCPU(476, PPC476)   ";"		\
+  VX_MCPU(603, PPC603)   ";"		\
+  VX_MCPU(604, PPC604)   ";"		\
+  VX_MCPU(860, PPC860)   ";"		\
+  VX_MCPU(e6500, E6500)  ";"		\
+  VX_MCPU(8540, PPC85XX) ";"		\
+  VX_MCPU(8548, PPC85XX) ";"		\
+  VX_CPUDEF(PPC604)			\
+  "}}"					\
+  VXWORKS_ADDITIONAL_CPP_SPEC
 
 /* FIXME: The only reason we allow no -mcpu switch at all is because
-   config-ml.in insists on a "." multilib. */
-#define CPP_SPEC \
-"%{!DCPU=*:		  \
-   %{mcpu=403 : -DCPU=PPC403  ; \
-     mcpu=405 : -DCPU=PPC405  ; \
-     mcpu=440 : -DCPU=PPC440  ; \
-     mcpu=464 : -DCPU=PPC464  ; \
-     mcpu=476 : -DCPU=PPC476  ; \
-     mcpu=603 : -DCPU=PPC603  ; \
-     mcpu=604 : -DCPU=PPC604  ; \
-     mcpu=860 : -DCPU=PPC860  ; \
-     mcpu=8540: -DCPU=PPC85XX ; \
-     mcpu=8548: -DCPU=PPC85XX ; \
-              : -DCPU=PPC604  }}" \
-VXWORKS_ADDITIONAL_CPP_SPEC
-
-#define CC1_SPEC						\
-"%{G*} %{mno-sdata:-msdata=none} %{msdata:-msdata=default}	\
- %{mlittle|mlittle-endian:-mstrict-align}"
-
-#define ASM_SPEC \
-"%(asm_cpu) \
- %{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \
- %{mrelocatable} %{mrelocatable-lib} %{" FPIC_SPEC ":-K PIC} -mbig"
+   config-ml.in insists on a "." multilib.  */
 
 #undef  LIB_SPEC
 #define LIB_SPEC VXWORKS_LIB_SPEC
 
-/* For RTPs, leverage linker relaxation.  This helps programs referring
-   to, typically, kernel services too far away for short calls.  This is more
-   precise than -mlongcall and can be overriden with -Wl,--no-relax.  */
-#define VXWORKS_RELAX_LINK_SPEC "%{mrtp:--relax}"
-
-#undef  LINK_SPEC
-#define LINK_SPEC VXWORKS_LINK_SPEC " " VXWORKS_RELAX_LINK_SPEC
-
 #undef  STARTFILE_SPEC
 #define STARTFILE_SPEC VXWORKS_STARTFILE_SPEC
+
 #undef  ENDFILE_SPEC
 #define ENDFILE_SPEC VXWORKS_ENDFILE_SPEC
 
 /* There is no default multilib.  */
 #undef MULTILIB_DEFAULTS
 
-#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_EABI | MASK_STRICT_ALIGN)
+/* No _mcount profiling on VxWorks.  */
+#undef FUNCTION_PROFILER
+#define FUNCTION_PROFILER(FILE,LABELNO) VXWORKS_FUNCTION_PROFILER(FILE,LABELNO)
 
-#undef PROCESSOR_DEFAULT
-#define PROCESSOR_DEFAULT PROCESSOR_PPC604
+/* Initialize library function table.  */
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS rs6000_vxworks_init_libfuncs
 
 /* Nor sdata, for kernel mode.  We use this in
    SUBSUBTARGET_INITIALIZE_OPTIONS, after rs6000_rtp has been initialized.  */
 #undef SDATA_DEFAULT_SIZE
 #define SDATA_DEFAULT_SIZE (TARGET_VXWORKS_RTP ? 8 : 0)
 
-/* Enforce 16-byte alignment for the stack pointer, to permit general
-   compliance with e.g. Altivec instructions requirements.  Make sure
-   this isn't overruled by the EABI constraints.  */
+#undef SUB3TARGET_OVERRIDE_OPTIONS
+#define SUB3TARGET_OVERRIDE_OPTIONS           \
+  do {                                          \
+  if (!global_options_set.x_g_switch_value)     \
+    g_switch_value = SDATA_DEFAULT_SIZE;        \
+  VXWORKS_OVERRIDE_OPTIONS;                     \
+  } while (0)
 
-#undef  STACK_BOUNDARY
-#define STACK_BOUNDARY (16*BITS_PER_UNIT)
+/* Leverage linker relaxation for RTPs.  This helps 32bit programs
+   referring to kernel services too far away for short calls, is more
+   precise than -mlongcall and can be overriden with -Wl,--no-relax.  */
+#define VXWORKS_RELAX_LINK_SPEC "%{mrtp:--relax}"
 
-#undef  PREFERRED_STACK_BOUNDARY
-#define PREFERRED_STACK_BOUNDARY STACK_BOUNDARY
+/******************************
+ * pre-VxWorks7 configuration *
+ ******************************/
 
-#undef  ABI_STACK_BOUNDARY
+#if !TARGET_VXWORKS7
 
 #undef RS6000_STARTING_FRAME_OFFSET
 #define RS6000_STARTING_FRAME_OFFSET					\
@@ -189,21 +192,84 @@  VXWORKS_ADDITIONAL_CPP_SPEC
    RS6000_ALIGN (crtl->outgoing_args_size.to_constant ()		\
 		 + STACK_POINTER_OFFSET, 16)
 
-#undef SUBSUBTARGET_OVERRIDE_OPTIONS
-#define SUBSUBTARGET_OVERRIDE_OPTIONS		\
-  do {						\
-  if (!global_options_set.x_g_switch_value)	\
-    g_switch_value = SDATA_DEFAULT_SIZE;	\
-  VXWORKS_OVERRIDE_OPTIONS;			\
-  } while (0)
+/* Enforce 16-byte alignment for the stack pointer, to permit general
+   compliance with e.g. Altivec instructions requirements.  Make sure
+   this isn't overruled by the EABI constraints.  */
 
-/* No _mcount profiling on VxWorks.  */
-#undef FUNCTION_PROFILER
-#define FUNCTION_PROFILER(FILE,LABELNO) VXWORKS_FUNCTION_PROFILER(FILE,LABELNO)
+#undef  STACK_BOUNDARY
+#define STACK_BOUNDARY (16*BITS_PER_UNIT)
+
+#undef  PREFERRED_STACK_BOUNDARY
+#define PREFERRED_STACK_BOUNDARY STACK_BOUNDARY
+
+#undef  ABI_STACK_BOUNDARY
+
+#undef  STARTFILE_PREFIX_SPEC
+#define STARTFILE_PREFIX_SPEC						\
+ "%{mrtp:%{!shared:%:getenv(WIND_BASE /target/lib/usr/lib/ppc/PPC32/common)}}"
+
+/* For aggregates passing, use the same, consistent ABI as Linux.  */
+#define AGGREGATE_PADDING_FIXED 0
+#define AGGREGATES_PAD_UPWARD_ALWAYS 0
+
+#undef ASM_SPEC
+#define ASM_SPEC \
+"%(asm_cpu) \
+ %{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \
+ %{mrelocatable} %{mrelocatable-lib} %{" FPIC_SPEC ":-K PIC} -mbig"
+
+#undef CC1_SPEC
+#define CC1_SPEC VXWORKS_CC1_SPEC " \
+  %{G*} %{mno-sdata:-msdata=none} %{msdata:-msdata=default}      \
+ %{mlittle|mlittle-endian:-mstrict-align}"
+
+#undef  LINK_SPEC
+#define LINK_SPEC VXWORKS_LINK_SPEC " " VXWORKS_RELAX_LINK_SPEC
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (MASK_EABI | MASK_STRICT_ALIGN)
+
+#undef PROCESSOR_DEFAULT
+#define PROCESSOR_DEFAULT PROCESSOR_PPC604
+
+/* Only big endian PPC is supported by VxWorks.  */
+#undef BYTES_BIG_ENDIAN
+#define BYTES_BIG_ENDIAN 1
+
+#undef WORDS_BIG_ENDIAN
+#define WORDS_BIG_ENDIAN 1
+
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS /* none needed */
+
+#else /* post VxWorks 7 (SR600) configurations  */
+
+/* VxWorks does not use local symbols for the function entry point.  */
+#undef DOT_SYMBOLS
+#define DOT_SYMBOLS 0
+
+#undef LINK_OS_VXWORKS_SPEC
+#define LINK_OS_VXWORKS_SPEC \
+  " %{!mrtp:-r} %{mrtp:-q -static} %{!Xbind-lazy:-z now}"
+
+#undef LINK_OS_EXTRA_SPEC32
+#define LINK_OS_EXTRA_SPEC32 LINK_OS_VXWORKS_SPEC " " VXWORKS_RELAX_LINK_SPEC
+
+#undef LINK_OS_EXTRA_SPEC64
+#define LINK_OS_EXTRA_SPEC64 LINK_OS_VXWORKS_SPEC
+
+/* linux64.h enables this, not supported in vxWorks.  */
+#undef TARGET_FLOAT128_ENABLE_TYPE
+#define TARGET_FLOAT128_ENABLE_TYPE 0
+
+#endif
+
+/* The stack pointer need not be moved while checking the stack.  */
+#undef STACK_CHECK_MOVING_SP
 
 /* Define this to be nonzero if static stack checking is supported.  */
 #define STACK_CHECK_STATIC_BUILTIN 1
 
-/* This platform supports the probing method of stack checking (RTP mode).
-   8K is reserved in the stack to propagate exceptions in case of overflow.  */
-#define STACK_CHECK_PROTECT 8192
+/* Room needed to allow exception propagation, from what experiments
+   and low level observations taught us ...  */
+#define STACK_CHECK_PROTECT (TARGET_64BIT ? 16 * 1024 : 12 * 1024)
diff --git a/libgcc/config.host b/libgcc/config.host
index dbb378f6756c..fd8e55e92e1a 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -1226,6 +1226,23 @@  powerpc*-*-linux*)
 	extra_parts="$extra_parts ecrti.o ecrtn.o ncrti.o ncrtn.o"
 	md_unwind_header=rs6000/linux-unwind.h
 	;;
+powerpc*-wrs-vxworks7*)
+        tmake_file="$tmake_file rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff rs6000/t-linux t-dfprules config/rs6000/t-ppc64-fp t-slibgcc-libgcc"
+        case $ppc_fp_type in
+        64)
+                ;;
+        hard)
+                tmake_file="${tmake_file} t-hardfp-sfdf"
+                ;;
+        soft)
+                tmake_file="${tmake_file} t-softfp-sfdf t-softfp"
+                ;;
+        *)
+                echo "Unknown ppc_fp_type $ppc_fp_type" 1>&2
+                exit 1
+                ;;
+        esac
+        ;;
 powerpc-wrs-vxworks*)
 	tmake_file="$tmake_file rs6000/t-ppccomm rs6000/t-savresfgpr t-fdpbit"
 	extra_parts="$extra_parts crtbegin.o crtend.o"
diff --git a/libgcc/configure b/libgcc/configure
index 284e4db0cddf..78fc22a5784e 100755
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -5164,11 +5164,11 @@  fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibc_version_major.$glibc_version_minor" >&5
 $as_echo "$glibc_version_major.$glibc_version_minor" >&6; }
 
-# Determine floating-point type for powerpc*-*-linux*.
+# Determine floating-point type for powerpc*-*-linux* or vxworks7*.
 # Single-precision-only FPRs are not a supported configuration for
 # this target, so are not allowed for in this test.
 case ${host} in
-powerpc*-*-linux*)
+powerpc*-*-linux* | powerpc*-*-vxworks7*)
   cat > conftest.c <<EOF
 #ifdef __powerpc64__
 ppc_fp_type=64
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index ef0d79975e16..ed50c0e9b494 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -383,11 +383,11 @@  AC_COMPUTE_INT([glibc_version_minor], [__GLIBC_MINOR__],
 				      [glibc_version_minor=0])])
 AC_MSG_RESULT([$glibc_version_major.$glibc_version_minor])
 
-# Determine floating-point type for powerpc*-*-linux*.
+# Determine floating-point type for powerpc*-*-linux* or vxworks7*.
 # Single-precision-only FPRs are not a supported configuration for
 # this target, so are not allowed for in this test.
 case ${host} in
-powerpc*-*-linux*)
+powerpc*-*-linux* | powerpc*-*-vxworks7*)
   cat > conftest.c <<EOF
 #ifdef __powerpc64__
 ppc_fp_type=64