libc/picolibc: Support 'long long' and 'minimal' printf variants

Picolibc's 'minimal' printf mode reduces functionality and size even more
than the 'integer' mode. Use this where memory is at a premium and where
the application knows that it does not require exact printf semantics.

1.8.5 adds two more printf variants, 'long long' and 'minimal'. The 'long
long' variant is the same as the 'integer' variant but with long long
support enabled. The 'minimal' variant reduces functionality and size even
more than the 'integer' mode. Applications can use this where memory is at
a premium and where the application does not require exact printf
semantics.

With these two added variants, the SDK has enough options so that all of
the cbprintf modes can be supported with the pre-compiled bits:

 1. CBPRINTF_NANO - picolibc's 'minimal' variant
 2. CBPRINTF_REDUCED_INTEGRAL - picolibc's 'integer' variant
 3. CBPRINTF_FULL_INTEGRAL - picolibc's 'long long' variant
 4. CBPRINTF_FB_SUPPORT - picolibc's 'double' variant

This patch makes the cbprintf Kconfig values drive the default picolibc
variant, disables picolibc variants not capable of supporting the required
cbprintf level, but allows applications to select more functionality in
picolibc than cbprintf requires.

Note that this depends on the SDK including picolibc 1.8.5. Without that,
selecting the 'minimal' or 'long long' variant in Zephyr will end up with
the default variant from picolibc, which is the full version with floating
point support. When using the module things will work as specified.

Signed-off-by: Keith Packard <keithp@keithp.com>
diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig
index c9678ad..8b71808 100644
--- a/lib/libc/Kconfig
+++ b/lib/libc/Kconfig
@@ -12,7 +12,6 @@
 
 config REQUIRES_FLOAT_PRINTF
 	bool "Requires floating point support in printf"
-	select PICOLIBC_IO_FLOAT if PICOLIBC
 	select CBPRINTF_FP_SUPPORT if MINIMAL_LIBC
 	select NEWLIB_LIBC_FLOAT_PRINTF if NEWLIB_LIBC
 	help
diff --git a/lib/libc/picolibc/CMakeLists.txt b/lib/libc/picolibc/CMakeLists.txt
index 3bbe812..232e4ba 100644
--- a/lib/libc/picolibc/CMakeLists.txt
+++ b/lib/libc/picolibc/CMakeLists.txt
@@ -17,6 +17,12 @@
   if(CONFIG_PICOLIBC_IO_FLOAT)
     zephyr_compile_definitions(PICOLIBC_DOUBLE_PRINTF_SCANF)
     zephyr_link_libraries(-DPICOLIBC_DOUBLE_PRINTF_SCANF)
+  elseif(CONFIG_PICOLIBC_IO_MINIMAL)
+    zephyr_compile_definitions(PICOLIBC_MINIMAL_PRINTF_SCANF)
+    zephyr_link_libraries(-DPICOLIBC_MINIMAL_PRINTF_SCANF)
+  elseif(CONFIG_PICOLIBC_IO_LONG_LONG)
+    zephyr_compile_definitions(PICOLIBC_LONG_LONG_PRINTF_SCANF)
+    zephyr_link_libraries(-DPICOLIBC_LONG_LONG_PRINTF_SCANF)
   else()
     zephyr_compile_definitions(PICOLIBC_INTEGER_PRINTF_SCANF)
     zephyr_link_libraries(-DPICOLIBC_INTEGER_PRINTF_SCANF)
diff --git a/lib/libc/picolibc/Kconfig b/lib/libc/picolibc/Kconfig
index 6adc9fd..fa6ae7e 100644
--- a/lib/libc/picolibc/Kconfig
+++ b/lib/libc/picolibc/Kconfig
@@ -31,16 +31,42 @@
 	  If set to -2, then the value of COMMON_LIBC_MALLOC_ARENA_SIZE
 	  will be used.
 
-config PICOLIBC_IO_LONG_LONG
-	bool "support for long long in integer-only printf/scanf"
+choice PICOLIBC_IO_LEVEL
+	prompt "Picolibc printf/scanf level"
+	default PICOLIBC_IO_MINIMAL if CBPRINTF_NANO
+	default PICOLIBC_IO_LONG_LONG if CBPRINTF_FULL_INTEGRAL
+	default PICOLIBC_IO_INTEGER
 	help
-	  Includes support for long long in integer-only printf/scanf. long long
-	  types are always supported in the floating-point versions.
+	  Selects the level of printf and scanf support
 
 config PICOLIBC_IO_FLOAT
-	bool "support for floating point values in printf/scanf"
+	bool "full support for integer/floating point values in printf/scanf"
 	help
-	  Include floating point support in printf/scanf functions.
+	  Include full floating point and integer support in printf/scanf
+	  functions.
+
+config PICOLIBC_IO_LONG_LONG
+	bool "full support for integer values, including long long, in printf/scanf"
+	depends on !REQUIRES_FLOAT_PRINTF && (!CBPRINTF_FP_SUPPORT || CBPRINTF_NANO)
+	help
+	  Includes full integer with long long, but no floating
+	  point in printf/scanf.
+
+config PICOLIBC_IO_INTEGER
+	bool "full support for integer values, other than long long, in printf/scanf"
+	depends on !REQUIRES_FLOAT_PRINTF && ((!CBPRINTF_FP_SUPPORT && !CBPRINTF_FULL_INTEGRAL) || CBPRINTF_NANO)
+	help
+	  Include full integer other than long long, but no floating point
+	  in printf/scanf.
+
+config PICOLIBC_IO_MINIMAL
+	bool "limited support for integer values in printf/scanf"
+	depends on !REQUIRES_FLOAT_PRINTF && CBPRINTF_NANO
+	help
+	  Include limited integer and no floating point support in
+	  printf/scanf.
+
+endchoice
 
 if PICOLIBC_USE_MODULE
 
@@ -101,17 +127,18 @@
 	bool "support C99 format additions in printf/scanf"
 	default y
 	help
-	  Includes support for hex floats (in floating-point version) and j, z,
-	  t size modifiers.
+	  Includes C99 printf and scanf support for j, z, t size
+	  modifiers. C99 support is always included in the floating-point
+	  variant
 
 config PICOLIBC_IO_POS_ARGS
 	bool "Support POSIX positional args (e.g. %$1d) in printf/scanf"
 	default y
-	depends on !PICOLIBC_IO_FLOAT
+	depends on !PICOLIBC_IO_MINIMAL
 	help
-	  Includes support for positional args (e.g. $1) in integer-only printf
-	  and scanf. Positional args are always supported in the floating-point
-	  versions.
+	  Includes support for positional args (e.g. $1) in integer-only
+	  printf and scanf. Positional args are always supported in the
+	  floating-point variant.
 
 config PICOLIBC_IO_FLOAT_EXACT
 	bool "support for exact float/string conversion"
@@ -121,6 +148,21 @@
 	  This ensures that printf values with enough digits can be
 	  fed to scanf and generate exactly the same binary value.
 
+config PICOLIBC_IO_SMALL_ULTOA
+	bool "avoid soft division in printf"
+	default y
+	help
+	  Replaces division and modulus by 10 with shifts and adds when
+	  doing binary to decimal conversion in printf for 64-bit
+	  values on 32-bit targets.
+
+config PICOLIBC_IO_MINIMAL_LONG_LONG
+	bool "Include long long support in minimal printf"
+	depends on PICOLIBC_IO_MINIMAL
+	default y if CBPRINTF_FULL_INTEGRAL
+	help
+	  Include long long support in the minimal picolibc printf code
+
 config PICOLIBC_LOCALE_INFO
 	bool "support locales in libc functions"
 	help
diff --git a/lib/os/Kconfig.cbprintf b/lib/os/Kconfig.cbprintf
index 777cd7d..54ba8cc 100644
--- a/lib/os/Kconfig.cbprintf
+++ b/lib/os/Kconfig.cbprintf
@@ -31,7 +31,7 @@
 # 01: 0% / 0 B (01 / 00)
 config CBPRINTF_FULL_INTEGRAL
 	bool "Convert the full range of integer values"
-	select PICOLIBC_IO_LONG_LONG if PICOLIBC && !CBPRINTF_NANO
+	select PICOLIBC_IO_MINIMAL_LONG_LONG if PICOLIBC_IO_MINIMAL && PICOLIBC_USE_MODULE
 	help
 	  Build cbprintf with buffers sized to support converting the full
 	  range of all integral and pointer values.
@@ -67,7 +67,6 @@
 	bool "Floating point formatting in cbprintf"
 	default y if FPU
 	depends on CBPRINTF_COMPLETE
-	select PICOLIBC_IO_FLOAT if PICOLIBC
 	help
 	  Build the cbprintf utility function with support for floating
 	  point format specifiers.  Selecting this increases stack size