[MSP430] Add -mtiny-printf option to support reduced code size printf and puts

Message ID 20191024215637.762778d7@jozef-kubuntu
State New
Headers show
Series
  • [MSP430] Add -mtiny-printf option to support reduced code size printf and puts
Related show

Commit Message

Jozef Lawrynowicz Oct. 24, 2019, 8:56 p.m.
I added support for reduced code size printf and puts functions to Newlib for
MSP430 a while ago [1]. By removing support for reentrancy, streams and
buffering we can greatly reduce code size, which is always often a limitation
when using printf on microcontrollers.

This patch adds an interface to enable these reduced code size implementations
from GCC by using the -mtiny-printf option. The tiny printf and puts
implementations require GCC to be configured with
--enable-newlib-nano-formatted-io, so there are some modifications to configure
scripts to support the checking of that.

-mtiny-printf is merely an alias for passing "--wrap printf --wrap puts" to the
linker.
This will replace references to "printf" and "puts" in user
code with "__wrap_printf" and "__wrap_puts" respectively.
If there is no implementation of these __wrap* functions in user code,
these "tiny" printf and puts implementations will be linked into the
final executable.

The wrapping mechanism is supposed to be invisible to the user since even if
they are unaware of the "tiny" implementation, and implement their own 
__wrap_printf and __wrap_puts, their own implementation will be automatically
chosen over the "tiny" printf and puts from the library.

Successfully regtested on trunk by comparing results with -mtiny-printf with a
set of testresults without the option.
The new test "gcc.target/msp430/tiny-printf.c" verifies the option behaves as
expected when GCC is configured with and without
--enable-newlib-nano-formatted-io.

Ok to apply?

[1]
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=commit;h=1e6c561d48f

Comments

Jeff Law Nov. 1, 2019, 10:02 p.m. | #1
On 10/24/19 2:56 PM, Jozef Lawrynowicz wrote:
> I added support for reduced code size printf and puts functions to Newlib for

> MSP430 a while ago [1]. By removing support for reentrancy, streams and

> buffering we can greatly reduce code size, which is always often a limitation

> when using printf on microcontrollers.

> 

> This patch adds an interface to enable these reduced code size implementations

> from GCC by using the -mtiny-printf option. The tiny printf and puts

> implementations require GCC to be configured with

> --enable-newlib-nano-formatted-io, so there are some modifications to configure

> scripts to support the checking of that.

> 

> -mtiny-printf is merely an alias for passing "--wrap printf --wrap puts" to the

> linker.

> This will replace references to "printf" and "puts" in user

> code with "__wrap_printf" and "__wrap_puts" respectively.

> If there is no implementation of these __wrap* functions in user code,

> these "tiny" printf and puts implementations will be linked into the

> final executable.

> 

> The wrapping mechanism is supposed to be invisible to the user since even if

> they are unaware of the "tiny" implementation, and implement their own 

> __wrap_printf and __wrap_puts, their own implementation will be automatically

> chosen over the "tiny" printf and puts from the library.

> 

> Successfully regtested on trunk by comparing results with -mtiny-printf with a

> set of testresults without the option.

> The new test "gcc.target/msp430/tiny-printf.c" verifies the option behaves as

> expected when GCC is configured with and without

> --enable-newlib-nano-formatted-io.

> 

> Ok to apply?

> 

> [1]

> https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=commit;h=1e6c561d48f

> 

> 

> 0001-MSP430-Add-mtiny-printf-option.patch

> 

> From 4d4e2b6bb92317b2b4db1d99c3f43a167a1e3288 Mon Sep 17 00:00:00 2001

> From: Jozef Lawrynowicz <jozef.l@mittosystems.com>

> Date: Thu, 24 Oct 2019 13:30:21 +0100

> Subject: [PATCH] MSP430: Add -mtiny-printf option

> 

> gcc/ChangeLog:

> 

> 2019-10-24  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

> 

> 	* config.in: Regenerate.

> 	* config/msp430/msp430.c (msp430_option_override): Emit an error if

> 	-mtiny-printf is used without GCC being configured with

> 	--enable-newlib-nano-formatted-io.

> 	* config/msp430/msp430.h (LINK_SPEC): Pass 

> 	"--wrap puts --wrap printf" when -mtiny-printf is used.

> 	* config/msp430/msp430.opt: Document -mtiny-printf.

> 	* configure: Regenerate.

> 	* configure.ac: Enable --enable-newlib-nano-formatted-io flag.

> 	Define HAVE_NEWLIB_NANO_FORMATTED_IO if

> 	--enable-newlib-nano-formatted-io is passed.

> 	* doc/invoke.texi: Document -mtiny-printf.

OK
jeff

Patch

From 4d4e2b6bb92317b2b4db1d99c3f43a167a1e3288 Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <jozef.l@mittosystems.com>
Date: Thu, 24 Oct 2019 13:30:21 +0100
Subject: [PATCH] MSP430: Add -mtiny-printf option

gcc/ChangeLog:

2019-10-24  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

	* config.in: Regenerate.
	* config/msp430/msp430.c (msp430_option_override): Emit an error if
	-mtiny-printf is used without GCC being configured with
	--enable-newlib-nano-formatted-io.
	* config/msp430/msp430.h (LINK_SPEC): Pass 
	"--wrap puts --wrap printf" when -mtiny-printf is used.
	* config/msp430/msp430.opt: Document -mtiny-printf.
	* configure: Regenerate.
	* configure.ac: Enable --enable-newlib-nano-formatted-io flag.
	Define HAVE_NEWLIB_NANO_FORMATTED_IO if
	--enable-newlib-nano-formatted-io is passed.
	* doc/invoke.texi: Document -mtiny-printf.

gcc/testsuite/ChangeLog:

2019-10-24  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

	* gcc.target/msp430/tiny-printf.c: New test.

---
 gcc/config.in                                 |  7 ++++++
 gcc/config/msp430/msp430.c                    |  6 +++++
 gcc/config/msp430/msp430.h                    |  1 +
 gcc/config/msp430/msp430.opt                  |  4 +++
 gcc/configure                                 | 25 +++++++++++++++++--
 gcc/configure.ac                              | 16 ++++++++++++
 gcc/doc/invoke.texi                           | 15 ++++++++++-
 gcc/testsuite/gcc.target/msp430/tiny-printf.c |  3 +++
 8 files changed, 74 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/msp430/tiny-printf.c

diff --git a/gcc/config.in b/gcc/config.in
index 9b54a4715db..7925d892cce 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -1675,6 +1675,13 @@ 
 #endif
 
 
+/* Define if GCC has been configured with --enable-newlib-nano-formatted-io.
+   */
+#ifndef USED_FOR_TARGET
+#undef HAVE_NEWLIB_NANO_FORMATTED_IO
+#endif
+
+
 /* Define to 1 if you have the `nl_langinfo' function. */
 #ifndef USED_FOR_TARGET
 #undef HAVE_NL_LANGINFO
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index 31029395c3d..dbbff4a6863 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -284,6 +284,12 @@  msp430_option_override (void)
      possible to build newlib with -Os enabled.  Until now...  */
   if (TARGET_OPT_SPACE && optimize < 3)
     optimize_size = 1;
+
+#ifndef HAVE_NEWLIB_NANO_FORMATTED_IO
+  if (TARGET_TINY_PRINTF)
+    error ("GCC must be configured with %<--enable-newlib-nano-formatted-io%> "
+	   "to use %<-mtiny-printf%>");
+#endif
 }
 
 #undef  TARGET_SCALAR_MODE_SUPPORTED_P
diff --git a/gcc/config/msp430/msp430.h b/gcc/config/msp430/msp430.h
index 73afe2e2d16..4a89f03a35e 100644
--- a/gcc/config/msp430/msp430.h
+++ b/gcc/config/msp430/msp430.h
@@ -75,6 +75,7 @@  extern bool msp430x;
     "msp430_propagate_region_opt(%* %{muse-lower-region-prefix})} " \
   "%{mdata-region=*:--data-region=%:" \
     "msp430_propagate_region_opt(%* %{muse-lower-region-prefix})} " \
+  "%{mtiny-printf:--wrap puts --wrap printf} "
 
 #define DRIVER_SELF_SPECS \
   " %{!mlarge:%{mcode-region=*:%{mdata-region=*:%e-mcode-region and "	\
diff --git a/gcc/config/msp430/msp430.opt b/gcc/config/msp430/msp430.opt
index 2db2906ca11..b451174c3d1 100644
--- a/gcc/config/msp430/msp430.opt
+++ b/gcc/config/msp430/msp430.opt
@@ -2,6 +2,10 @@  msim
 Target
 Use simulator runtime.
 
+mtiny-printf
+Target Report Mask(TINY_PRINTF)
+Use a lightweight configuration of printf and puts to reduce code size. For single-threaded applications, not requiring reentrant I/O only. Requires Newlib Nano IO.
+
 masm-hex
 Target Mask(ASM_HEX)
 Force assembly output to always use hex constants.
diff --git a/gcc/configure b/gcc/configure
index 9de9ef85f24..29e3074dc48 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -988,6 +988,7 @@  with_plugin_ld
 enable_gnu_indirect_function
 enable_initfini_array
 enable_comdat
+enable_newlib_nano_formatted_io
 enable_standard_branch_protection
 enable_fix_cortex_a53_835769
 enable_fix_cortex_a53_843419
@@ -1716,6 +1717,8 @@  Optional Features:
                           glibc systems
   --enable-initfini-array	use .init_array/.fini_array sections
   --enable-comdat         enable COMDAT group support
+  --enable-newlib-nano-formatted-io
+                          Use nano version formatted IO
 
   --enable-standard-branch-protection
                           enable Branch Target Identification Mechanism and
@@ -18851,7 +18854,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 18854 "configure"
+#line 18857 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -18957,7 +18960,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 18960 "configure"
+#line 18963 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -24477,6 +24480,19 @@  $as_echo "#define HAVE_GAS_DISCRIMINATOR 1" >>confdefs.h
 fi
 
 
+# Catch the newlib flag of the same name so we can gate GCC features on it.
+# Check whether --enable-newlib-nano-formatted-io was given.
+if test "${enable_newlib_nano_formatted_io+set}" = set; then :
+  enableval=$enable_newlib_nano_formatted_io; case "${enableval}" in
+  yes|no)
+    ;;
+  *)
+    as_fn_error $? "unknown newlib-nano-formatted-io setting $enableval" "$LINENO" 5
+    ;;
+esac
+fi
+
+
 # Thread-local storage - the check is heavily parameterized.
 conftest_s=
 tls_first_major=
@@ -27867,6 +27883,11 @@  $as_echo "#define HAVE_AS_MSPABI_ATTRIBUTE 1" >>confdefs.h
 
 fi
 
+    if test x$enable_newlib_nano_formatted_io = xyes; then
+
+$as_echo "#define HAVE_NEWLIB_NANO_FORMATTED_IO 1" >>confdefs.h
+
+      fi
     ;;
     riscv*-*-*)
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .attribute support" >&5
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 62f4b2651cc..9a7e95ea504 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -3336,6 +3336,18 @@  gcc_GAS_CHECK_FEATURE([line table discriminator support],
 [AC_DEFINE(HAVE_GAS_DISCRIMINATOR, 1,
   [Define if your assembler supports the .loc discriminator sub-directive.])])
 
+# Catch the newlib flag of the same name so we can gate GCC features on it.
+AC_ARG_ENABLE(newlib-nano-formatted-io,
+[AS_HELP_STRING([--enable-newlib-nano-formatted-io], [Use nano version
+ formatted IO])],
+[case "${enableval}" in
+  yes|no)
+    ;;
+  *)
+    AC_MSG_ERROR([unknown newlib-nano-formatted-io setting $enableval])
+    ;;
+esac], [])
+
 # Thread-local storage - the check is heavily parameterized.
 conftest_s=
 tls_first_major=
@@ -4976,6 +4988,10 @@  pointers into PC-relative form.])
       [.mspabi_attribute 4,1],,
       [AC_DEFINE(HAVE_AS_MSPABI_ATTRIBUTE, 1,
 	  [Define if your assembler supports .mspabi_attribute.])])
+    if test x$enable_newlib_nano_formatted_io = xyes; then
+      AC_DEFINE(HAVE_NEWLIB_NANO_FORMATTED_IO, 1, [Define if GCC has been
+configured with --enable-newlib-nano-formatted-io.])
+      fi
     ;;
     riscv*-*-*)
     gcc_GAS_CHECK_FEATURE([.attribute support],
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 1407d019d14..6e55738322f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1009,7 +1009,7 @@  Objective-C and Objective-C++ Dialects}.
 -mwarn-mcu @gol
 -mcode-region=  -mdata-region= @gol
 -msilicon-errata=  -msilicon-errata-warn= @gol
--mhwmult=  -minrt}
+-mhwmult=  -minrt  -mtiny-printf}
 
 @emph{NDS32 Options}
 @gccoptlist{-mbig-endian  -mlittle-endian @gol
@@ -23267,6 +23267,19 @@  initializers or constructors.  This is intended for memory-constrained
 devices.  The compiler includes special symbols in some objects
 that tell the linker and runtime which code fragments are required.
 
+@item -mtiny-printf
+@opindex mtiny-printf
+Enable reduced code size @code{printf} and @code{puts} library functions.
+The @samp{tiny} implementations of these functions are not reentrant, so
+must be used with caution in multi-threaded applications.
+
+Support for streams has been removed and the string to be printed will
+always be sent to stdout via the @code{write} syscall.  The string is not
+buffered before it is sent to write.
+
+This option requires Newlib Nano IO, so GCC must be configured with
+@samp{--enable-newlib-nano-formatted-io}.
+
 @item -mcode-region=
 @itemx -mdata-region=
 @opindex mcode-region
diff --git a/gcc/testsuite/gcc.target/msp430/tiny-printf.c b/gcc/testsuite/gcc.target/msp430/tiny-printf.c
new file mode 100644
index 00000000000..55ef5f76ca4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/tiny-printf.c
@@ -0,0 +1,3 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mtiny-printf" } */
+/* { dg-error "GCC must be configured with --enable-newlib-nano-formatted-io to use -mtiny-printf" "" { target { ! newlib_nano_io } } 0 } */
-- 
2.17.1