Merge "Remove __INTRODUCED_IN_ architecture macros."
diff --git a/libc/Android.bp b/libc/Android.bp
index ecabb06..1e2458a 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -932,6 +932,21 @@
                 "arch-riscv64/bionic/setjmp.S",
                 "arch-riscv64/bionic/syscall.S",
                 "arch-riscv64/bionic/vfork.S",
+
+                "arch-riscv64/string/memchr_vext.S",
+                "arch-riscv64/string/memcmp_vext.S",
+                "arch-riscv64/string/memcpy_vext.S",
+                "arch-riscv64/string/memmove_vext.S",
+                "arch-riscv64/string/memset_vext.S",
+                "arch-riscv64/string/strcat_vext.S",
+                "arch-riscv64/string/strchr_vext.S",
+                "arch-riscv64/string/strcmp_vext.S",
+                "arch-riscv64/string/strcpy_vext.S",
+                "arch-riscv64/string/strlen_vext.S",
+                "arch-riscv64/string/strncat_vext.S",
+                "arch-riscv64/string/strncmp_vext.S",
+                "arch-riscv64/string/strncpy_vext.S",
+                "arch-riscv64/string/strnlen_vext.S",
             ],
         },
 
@@ -1541,6 +1556,9 @@
         arm64: {
             srcs: ["arch-arm64/static_function_dispatch.S"],
         },
+        riscv64: {
+            srcs: ["arch-riscv64/static_function_dispatch.S"]
+        },
     },
 }
 
@@ -1569,6 +1587,9 @@
         arm64: {
             srcs: ["arch-arm64/dynamic_function_dispatch.cpp"],
         },
+        riscv64: {
+            srcs: ["arch-riscv64/dynamic_function_dispatch.cpp"]
+        },
     },
 }
 
diff --git a/libc/NOTICE b/libc/NOTICE
index 4d3a108..441e79c 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -4540,6 +4540,34 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 2023 SiFive, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the company may not be used to endorse or promote
+   products derived from this software without specific prior written
+   permission.
+
+THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
 Copyright (c)1999 Citrus Project,
 All rights reserved.
 
diff --git a/libc/arch-riscv64/dynamic_function_dispatch.cpp b/libc/arch-riscv64/dynamic_function_dispatch.cpp
new file mode 100644
index 0000000..0925c5f
--- /dev/null
+++ b/libc/arch-riscv64/dynamic_function_dispatch.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <private/bionic_ifuncs.h>
+#include <stddef.h>
+#include <sys/auxv.h>
+
+#if defined(__riscv_v)
+extern "C" {
+
+typedef void* memchr_func(const void*, int, size_t);
+DEFINE_IFUNC_FOR(memchr) {
+  RETURN_FUNC(memchr_func, memchr_vext);
+}
+
+typedef int memcmp_func(const void*, const void*, size_t);
+DEFINE_IFUNC_FOR(memcmp) {
+  RETURN_FUNC(memcmp_func, memcmp_vext);
+}
+
+typedef void* memcpy_func(void*, const void*, size_t);
+DEFINE_IFUNC_FOR(memcpy) {
+  RETURN_FUNC(memcpy_func, memcpy_vext);
+}
+
+typedef void* memmove_func(void*, const void*, size_t);
+DEFINE_IFUNC_FOR(memmove) {
+  RETURN_FUNC(memmove_func, memmove_vext);
+}
+
+typedef void* memset_func(void*, int, size_t);
+DEFINE_IFUNC_FOR(memset) {
+  RETURN_FUNC(memset_func, memset_vext);
+}
+
+typedef char* strcat_func(char*, const char*);
+DEFINE_IFUNC_FOR(strcat) {
+  RETURN_FUNC(strcat_func, strcat_vext);
+}
+
+typedef char* strchr_func(const char*, int);
+DEFINE_IFUNC_FOR(strchr) {
+  RETURN_FUNC(strchr_func, strchr_vext);
+}
+
+typedef int strcmp_func(const char*, const char*);
+DEFINE_IFUNC_FOR(strcmp) {
+  RETURN_FUNC(strcmp_func, strcmp_vext);
+}
+
+typedef char* strcpy_func(char*, const char*);
+DEFINE_IFUNC_FOR(strcpy) {
+  RETURN_FUNC(strcpy_func, strcpy_vext);
+}
+
+typedef size_t strlen_func(const char*);
+DEFINE_IFUNC_FOR(strlen) {
+  RETURN_FUNC(strlen_func, strlen_vext);
+}
+
+typedef char* strncat_func(char*, const char*, size_t);
+DEFINE_IFUNC_FOR(strncat) {
+  RETURN_FUNC(strncat_func, strncat_vext);
+}
+
+typedef int strncmp_func(const char*, const char*, size_t);
+DEFINE_IFUNC_FOR(strncmp) {
+  RETURN_FUNC(strncmp_func, strncmp_vext);
+}
+
+typedef char* strncpy_func(char*, const char*, size_t);
+DEFINE_IFUNC_FOR(strncpy) {
+  RETURN_FUNC(strncpy_func, strncpy_vext);
+}
+
+typedef size_t strnlen_func(const char*, size_t);
+DEFINE_IFUNC_FOR(strnlen) {
+  RETURN_FUNC(strnlen_func, strnlen_vext);
+}
+
+}  // extern "C"
+#endif
diff --git a/libc/arch-riscv64/static_function_dispatch.S b/libc/arch-riscv64/static_function_dispatch.S
new file mode 100644
index 0000000..3bf0275
--- /dev/null
+++ b/libc/arch-riscv64/static_function_dispatch.S
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <private/bionic_asm.h>
+
+#define FUNCTION_DELEGATE(name, impl) \
+ENTRY(name); \
+    j impl; \
+END(name)
+
+#if defined(__riscv_v)
+
+FUNCTION_DELEGATE(memchr, memchr_vext)
+FUNCTION_DELEGATE(memcmp, memcmp_vext)
+FUNCTION_DELEGATE(memcpy, memcpy_vext)
+FUNCTION_DELEGATE(memmove, memmove_vext)
+FUNCTION_DELEGATE(memset, memset_vext)
+FUNCTION_DELEGATE(strcat, strcat_vext)
+FUNCTION_DELEGATE(strchr, strchr_vext)
+FUNCTION_DELEGATE(strcmp, strcmp_vext)
+FUNCTION_DELEGATE(strcpy, strcpy_vext)
+FUNCTION_DELEGATE(strlen, strlen_vext)
+FUNCTION_DELEGATE(strncat, strncat_vext)
+FUNCTION_DELEGATE(strncmp, strncmp_vext)
+FUNCTION_DELEGATE(strncpy, strncpy_vext)
+FUNCTION_DELEGATE(strnlen, strnlen_vext)
+
+#endif
+
+NOTE_GNU_PROPERTY()
diff --git a/libc/arch-riscv64/string/memchr_vext.S b/libc/arch-riscv64/string/memchr_vext.S
new file mode 100644
index 0000000..3761265
--- /dev/null
+++ b/libc/arch-riscv64/string/memchr_vext.S
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define iResult a0
+
+#define pSrc a0
+#define iValue a1
+#define iNum a2
+
+#define iVL a3
+#define iTemp a4
+
+#define ELEM_LMUL_SETTING m8
+#define vData v0
+#define vMask v8
+
+ENTRY(memchr_vext)
+
+L(loop):
+    vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
+
+    vle8ff.v vData, (pSrc)
+    vmseq.vx vMask, vData, iValue
+    vfirst.m iTemp, vMask
+
+    # skip the loop if we find the matched value.
+    bgez iTemp, L(found)
+
+    csrr iVL, vl
+    sub iNum, iNum, iVL
+    add pSrc, pSrc, iVL
+
+    bnez iNum, L(loop)
+
+    li iResult, 0
+    ret
+
+L(found):
+    add iResult, pSrc, iTemp
+    ret
+
+END(memchr_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/memcmp_vext.S b/libc/arch-riscv64/string/memcmp_vext.S
new file mode 100644
index 0000000..d8e7a06
--- /dev/null
+++ b/libc/arch-riscv64/string/memcmp_vext.S
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define iResult a0
+
+#define pSrc1 a0
+#define pSrc2 a1
+#define iNum a2
+
+#define iVL a3
+#define iTemp a4
+#define iTemp1 a5
+#define iTemp2 a6
+
+#define ELEM_LMUL_SETTING m8
+#define vData1 v0
+#define vData2 v8
+#define vMask v16
+
+ENTRY(memcmp_vext)
+
+L(loop):
+    vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
+
+    vle8.v vData1, (pSrc1)
+    vle8.v vData2, (pSrc2)
+
+    vmsne.vv vMask, vData1, vData2
+    sub iNum, iNum, iVL
+    vfirst.m iTemp, vMask
+
+    /* skip the loop if we find the different
+       value between pSrc1 and pSrc2.  */
+    bgez iTemp, L(found)
+
+    add pSrc1, pSrc1, iVL
+    add pSrc2, pSrc2, iVL
+
+    bnez iNum, L(loop)
+
+    li iResult, 0
+    ret
+
+L(found):
+    add pSrc1, pSrc1, iTemp
+    add pSrc2, pSrc2, iTemp
+    lbu iTemp1, 0(pSrc1)
+    lbu iTemp2, 0(pSrc2)
+    sub iResult, iTemp1, iTemp2
+    ret
+
+END(memcmp_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/memcpy_vext.S b/libc/arch-riscv64/string/memcpy_vext.S
new file mode 100644
index 0000000..100f538
--- /dev/null
+++ b/libc/arch-riscv64/string/memcpy_vext.S
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pDst a0
+#define pSrc a1
+#define iNum a2
+
+#define iVL a3
+#define pDstPtr a4
+
+#define ELEM_LMUL_SETTING m8
+#define vData v0
+
+ENTRY(memcpy_vext)
+
+    mv pDstPtr, pDst
+
+L(loop):
+    vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
+
+    vle8.v vData, (pSrc)
+    sub iNum, iNum, iVL
+    add pSrc, pSrc, iVL
+    vse8.v vData, (pDstPtr)
+    add pDstPtr, pDstPtr, iVL
+
+    bnez iNum, L(loop)
+
+    ret
+
+END(memcpy_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/memmove_vext.S b/libc/arch-riscv64/string/memmove_vext.S
new file mode 100644
index 0000000..722ffd1
--- /dev/null
+++ b/libc/arch-riscv64/string/memmove_vext.S
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pDst a0
+#define pSrc a1
+#define iNum a2
+
+#define iVL a3
+#define pDstPtr a4
+#define pSrcBackwardPtr a5
+#define pDstBackwardPtr a6
+
+#define ELEM_LMUL_SETTING m8
+#define vData v0
+
+ENTRY(memmove_vext)
+
+    mv pDstPtr, pDst
+
+    bgeu pSrc, pDst, L(forward_copy_loop)
+    add pSrcBackwardPtr, pSrc, iNum
+    add pDstBackwardPtr, pDst, iNum
+    bltu pDst, pSrcBackwardPtr, L(backward_copy_loop)
+
+L(forward_copy_loop):
+    vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
+
+    vle8.v vData, (pSrc)
+    sub iNum, iNum, iVL
+    add pSrc, pSrc, iVL
+    vse8.v vData, (pDstPtr)
+    add pDstPtr, pDstPtr, iVL
+
+    bnez iNum, L(forward_copy_loop)
+    ret
+
+L(backward_copy_loop):
+    vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
+
+    sub pSrcBackwardPtr, pSrcBackwardPtr, iVL
+    vle8.v vData, (pSrcBackwardPtr)
+    sub iNum, iNum, iVL
+    sub pDstBackwardPtr, pDstBackwardPtr, iVL
+    vse8.v vData, (pDstBackwardPtr)
+    bnez iNum, L(backward_copy_loop)
+    ret
+
+END(memmove_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/memset_vext.S b/libc/arch-riscv64/string/memset_vext.S
new file mode 100644
index 0000000..ef8387d
--- /dev/null
+++ b/libc/arch-riscv64/string/memset_vext.S
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pDst a0
+#define iValue a1
+#define iNum a2
+
+#define iVL a3
+#define iTemp a4
+#define pDstPtr a5
+
+#define ELEM_LMUL_SETTING m8
+#define vData v0
+
+ENTRY(memset_vext)
+
+    mv pDstPtr, pDst
+
+    vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
+    vmv.v.x vData, iValue
+
+L(loop):
+    vse8.v vData, (pDstPtr)
+    sub iNum, iNum, iVL
+    add pDstPtr, pDstPtr, iVL
+    vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
+    bnez iNum, L(loop)
+
+    ret
+
+END(memset_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strcat_vext.S b/libc/arch-riscv64/string/strcat_vext.S
new file mode 100644
index 0000000..790c07a
--- /dev/null
+++ b/libc/arch-riscv64/string/strcat_vext.S
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pDst a0
+#define pSrc a1
+#define pDstPtr a2
+
+#define iVL a3
+#define iCurrentVL a4
+#define iActiveElemPos a5
+
+#define ELEM_LMUL_SETTING m1
+#define vMask1 v0
+#define vMask2 v1
+#define vStr1 v8
+#define vStr2 v16
+
+ENTRY(strcat_vext)
+
+    mv pDstPtr, pDst
+
+    // the strlen of dst
+L(strlen_loop):
+    vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
+
+    vle8ff.v vStr1, (pDstPtr)
+    // find the '\0'
+    vmseq.vx vMask1, vStr1, zero
+    csrr iCurrentVL, vl
+    vfirst.m iActiveElemPos, vMask1
+    add pDstPtr, pDstPtr, iCurrentVL
+    bltz iActiveElemPos, L(strlen_loop)
+
+    sub pDstPtr, pDstPtr, iCurrentVL
+    add pDstPtr, pDstPtr, iActiveElemPos
+
+    // copy pSrc to pDstPtr
+L(strcpy_loop):
+    vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
+
+    vle8ff.v vStr1, (pSrc)
+    vmseq.vx vMask2, vStr1, zero
+    csrr iCurrentVL, vl
+    vfirst.m iActiveElemPos, vMask2
+    vmsif.m vMask1, vMask2
+    add pSrc, pSrc, iCurrentVL
+    vse8.v vStr1, (pDstPtr), vMask1.t
+    add pDstPtr, pDstPtr, iCurrentVL
+    bltz iActiveElemPos, L(strcpy_loop)
+
+    ret
+
+END(strcat_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strchr_vext.S b/libc/arch-riscv64/string/strchr_vext.S
new file mode 100644
index 0000000..89828ea
--- /dev/null
+++ b/libc/arch-riscv64/string/strchr_vext.S
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pStr a0
+#define iCh a1
+#define iEndOffset a2
+#define iChOffset a3
+#define iTemp1 a4
+#define iTemp2 a5
+#define iCurrentVL a6
+#define iVL t0
+
+#define ELEM_LMUL_SETTING m1
+#define vStr v0
+#define vMaskEnd v8
+#define vMaskCh v9
+
+ENTRY(strchr_vext)
+
+L(strchr_loop):
+    vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
+    vle8ff.v vStr, (pStr)
+    vmseq.vi vMaskEnd, vStr, 0
+    vmseq.vx vMaskCh, vStr, iCh
+    vfirst.m iEndOffset, vMaskEnd /* first occurrence of \0 */
+    vfirst.m iChOffset, vMaskCh /* first occurrence of ch */
+    sltz iTemp1, iChOffset
+    sltu iTemp2, iEndOffset, iChOffset
+    or iTemp1, iTemp1, iTemp2
+    beqz iTemp1, L(found_ch) /* Found ch, not preceded by \0? */
+    csrr iCurrentVL, vl
+    add pStr, pStr, iCurrentVL
+    bltz iEndOffset, L(strchr_loop) /* Didn't find \0? */
+    li pStr, 0
+    ret
+L(found_ch):
+    add pStr, pStr, iChOffset
+    ret
+
+END(strchr_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strcmp_vext.S b/libc/arch-riscv64/string/strcmp_vext.S
new file mode 100644
index 0000000..d6ad96e
--- /dev/null
+++ b/libc/arch-riscv64/string/strcmp_vext.S
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define iResult a0
+
+#define pStr1 a0
+#define pStr2 a1
+
+#define iVL a2
+#define iTemp1 a3
+#define iTemp2 a4
+#define iLMUL1 a5
+#define iLMUL2 a6
+#define iLMUL4 a7
+
+#define iLMUL t0
+
+#define vStr1 v0
+#define vStr2 v8
+#define vMask1 v16
+#define vMask2 v17
+
+ENTRY(strcmp_vext)
+
+    # increase the lmul using the following sequences:
+    # 1/2, 1/2, 1, 2, 4, 4, 4, ...
+
+    # lmul=1/2
+    vsetvli iVL, zero, e8, mf2, ta, ma
+
+    vle8ff.v vStr1, (pStr1)
+     # check if vStr1[i] == 0
+    vmseq.vx vMask1, vStr1, zero
+
+    vle8ff.v vStr2, (pStr2)
+    # check if vStr1[i] != vStr2[i]
+    vmsne.vv vMask2, vStr1, vStr2
+
+    # find the index x for vStr1[x]==0
+    vfirst.m iTemp1, vMask1
+    # find the index x for vStr1[x]!=vStr2[x]
+    vfirst.m iTemp2, vMask2
+
+    bgez iTemp1, L(check1)
+    bgez iTemp2, L(check2)
+
+    # get the current vl updated by vle8ff.
+    csrr iVL, vl
+    add pStr1, pStr1, iVL
+    add pStr2, pStr2, iVL
+
+    vsetvli iVL, zero, e8, mf2, ta, ma
+    addi iLMUL1, zero, 1
+    addi iLMUL, zero, 1
+    j L(loop)
+L(m1):
+    vsetvli iVL, zero, e8, m1, ta, ma
+    addi iLMUL2, zero, 2
+    addi iLMUL, zero, 2
+    j L(loop)
+L(m2):
+    vsetvli iVL, zero, e8, m2, ta, ma
+    addi iLMUL4, zero, 4
+    addi iLMUL, zero, 4
+    j L(loop)
+L(m4):
+    vsetvli iVL, zero, e8, m4, ta, ma
+
+L(loop):
+    vle8ff.v vStr1, (pStr1)
+    vmseq.vx vMask1, vStr1, zero
+
+    vle8ff.v vStr2, (pStr2)
+    vmsne.vv vMask2, vStr1, vStr2
+
+    vfirst.m iTemp1, vMask1
+    vfirst.m iTemp2, vMask2
+
+    bgez iTemp1, L(check1)
+    bgez iTemp2, L(check2)
+
+    csrr iVL, vl
+    add pStr1, pStr1, iVL
+    add pStr2, pStr2, iVL
+
+    beq iLMUL, iLMUL1, L(m1)
+    beq iLMUL, iLMUL2, L(m2)
+    beq iLMUL, iLMUL4, L(m4)
+    j L(loop)
+
+    // iTemp1>=0
+L(check1):
+    bltz iTemp2, 1f
+    blt iTemp2, iTemp1, L(check2)
+1:
+    // iTemp2<0
+    // iTemp2>=0 && iTemp1<iTemp2
+    add pStr1, pStr1, iTemp1
+    add pStr2, pStr2, iTemp1
+    lbu iTemp1, 0(pStr1)
+    lbu iTemp2, 0(pStr2)
+    sub iResult, iTemp1, iTemp2
+    ret
+
+    // iTemp1<0
+    // iTemp2>=0
+L(check2):
+    add pStr1, pStr1, iTemp2
+    add pStr2, pStr2, iTemp2
+    lbu iTemp1, 0(pStr1)
+    lbu iTemp2, 0(pStr2)
+    sub iResult, iTemp1, iTemp2
+    ret
+
+END(strcmp_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strcpy_vext.S b/libc/arch-riscv64/string/strcpy_vext.S
new file mode 100644
index 0000000..9c11f7d
--- /dev/null
+++ b/libc/arch-riscv64/string/strcpy_vext.S
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pDst a0
+#define pSrc a1
+#define pDstPtr a2
+
+#define iVL a3
+#define iCurrentVL a4
+#define iActiveElemPos a5
+
+#define ELEM_LMUL_SETTING m1
+#define vMask1 v0
+#define vMask2 v1
+#define vStr1 v8
+#define vStr2 v16
+
+ENTRY(strcpy_vext)
+
+    mv pDstPtr, pDst
+
+    // copy pSrc to pDstPtr
+L(strcpy_loop):
+    vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
+    vle8ff.v vStr1, (pSrc)
+    vmseq.vx vMask2, vStr1, zero
+    csrr iCurrentVL, vl
+    vfirst.m iActiveElemPos, vMask2
+    vmsif.m vMask1, vMask2
+    add pSrc, pSrc, iCurrentVL
+    vse8.v vStr1, (pDstPtr), vMask1.t
+    add pDstPtr, pDstPtr, iCurrentVL
+    bltz iActiveElemPos, L(strcpy_loop)
+
+    ret
+
+END(strcpy_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strlen_vext.S b/libc/arch-riscv64/string/strlen_vext.S
new file mode 100644
index 0000000..393af58
--- /dev/null
+++ b/libc/arch-riscv64/string/strlen_vext.S
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define iResult a0
+#define pStr a0
+#define pCopyStr a1
+#define iVL a2
+#define iCurrentVL a2
+#define iEndOffset a3
+
+#define ELEM_LMUL_SETTING m2
+#define vStr v0
+#define vMaskEnd v2
+
+ENTRY(strlen_vext)
+
+    mv pCopyStr, pStr
+L(loop):
+    vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
+    vle8ff.v vStr, (pCopyStr)
+    csrr iCurrentVL, vl
+    vmseq.vi vMaskEnd, vStr, 0
+    vfirst.m iEndOffset, vMaskEnd
+    add pCopyStr, pCopyStr, iCurrentVL
+    bltz iEndOffset, L(loop)
+
+    add pStr, pStr, iCurrentVL
+    add pCopyStr, pCopyStr, iEndOffset
+    sub iResult, pCopyStr, iResult
+
+    ret
+
+END(strlen)
+
+#endif
diff --git a/libc/arch-riscv64/string/strncat_vext.S b/libc/arch-riscv64/string/strncat_vext.S
new file mode 100644
index 0000000..e9da434
--- /dev/null
+++ b/libc/arch-riscv64/string/strncat_vext.S
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pDst a0
+#define pSrc a1
+#define iLength a2
+#define pDstPtr a3
+
+#define iVL a4
+#define iCurrentVL a5
+#define iActiveElemPos a6
+
+#define ELEM_LMUL_SETTING m1
+#define vMask1 v0
+#define vMask2 v1
+#define vStr1 v8
+#define vStr2 v16
+
+ENTRY(strncat_vext)
+
+    mv pDstPtr, pDst
+
+    // the strlen of dst
+L(strlen_loop):
+    vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
+
+    vle8ff.v vStr1, (pDstPtr)
+    // find the '\0'
+    vmseq.vx vMask1, vStr1, zero
+    csrr iCurrentVL, vl
+    vfirst.m iActiveElemPos, vMask1
+    add pDstPtr, pDstPtr, iCurrentVL
+    bltz iActiveElemPos, L(strlen_loop)
+
+    sub pDstPtr, pDstPtr, iCurrentVL
+    add pDstPtr, pDstPtr, iActiveElemPos
+
+    // copy pSrc to pDstPtr
+L(strcpy_loop):
+    vsetvli iVL, iLength, e8, ELEM_LMUL_SETTING, ta, ma
+
+    vle8ff.v vStr1, (pSrc)
+    vmseq.vx vMask2, vStr1, zero
+    csrr iCurrentVL, vl
+    vfirst.m iActiveElemPos, vMask2
+    vmsif.m vMask1, vMask2
+    add pSrc, pSrc, iCurrentVL
+    sub iLength, iLength, iCurrentVL
+    vse8.v vStr1, (pDstPtr), vMask1.t
+    add pDstPtr, pDstPtr, iCurrentVL
+    beqz iLength, L(fill_zero)
+    bltz iActiveElemPos, L(strcpy_loop)
+
+    ret
+
+L(fill_zero):
+    bgez iActiveElemPos, L(fill_zero_end)
+    sb zero, (pDstPtr)
+
+L(fill_zero_end):
+    ret
+
+END(strncat_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strncmp_vext.S b/libc/arch-riscv64/string/strncmp_vext.S
new file mode 100644
index 0000000..88f0f3e
--- /dev/null
+++ b/libc/arch-riscv64/string/strncmp_vext.S
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define iResult a0
+
+#define pStr1 a0
+#define pStr2 a1
+#define iLength a2
+
+#define iVL a3
+#define iTemp1 a4
+#define iTemp2 a5
+
+#define ELEM_LMUL_SETTING m1
+#define vStr1 v0
+#define vStr2 v4
+#define vMask1 v8
+#define vMask2 v9
+
+ENTRY(strncmp_vext)
+
+    beqz iLength, L(zero_length)
+
+L(loop):
+    vsetvli iVL, iLength, e8, ELEM_LMUL_SETTING, ta, ma
+
+    vle8ff.v vStr1, (pStr1)
+     # vStr1[i] == 0
+    vmseq.vx vMask1, vStr1, zero
+
+    vle8ff.v vStr2, (pStr2)
+    # vStr1[i] != vStr2[i]
+    vmsne.vv vMask2, vStr1, vStr2
+
+    csrr iVL, vl
+
+    # r = mask1 | mask2
+    # We could use vfirst.m to get the first zero char or the
+    # first different char between str1 and str2.
+    vmor.mm vMask1, vMask1, vMask2
+
+    sub iLength, iLength, iVL
+
+    vfirst.m iTemp1, vMask1
+
+    bgez iTemp1, L(end_loop)
+
+    add pStr1, pStr1, iVL
+    add pStr2, pStr2, iVL
+    bnez iLength, L(loop)
+L(end_loop):
+
+    add pStr1, pStr1, iTemp1
+    add pStr2, pStr2, iTemp1
+    lbu iTemp1, 0(pStr1)
+    lbu iTemp2, 0(pStr2)
+
+    sub iResult, iTemp1, iTemp2
+    ret
+
+L(zero_length):
+    li iResult, 0
+    ret
+
+END(strncmp_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strncpy_vext.S b/libc/arch-riscv64/string/strncpy_vext.S
new file mode 100644
index 0000000..1aedaf9
--- /dev/null
+++ b/libc/arch-riscv64/string/strncpy_vext.S
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pDst a0
+#define pSrc a1
+#define iLength a2
+#define pDstPtr a3
+
+#define iVL a4
+#define iCurrentVL a5
+#define iActiveElemPos a6
+
+#define ELEM_LMUL_SETTING m1
+#define vMask1 v0
+#define vMask2 v1
+#define ZERO_FILL_ELEM_LMUL_SETTING m8
+#define vStr1 v8
+#define vStr2 v16
+
+ENTRY(strncpy_vext)
+
+    mv pDstPtr, pDst
+
+    // copy pSrc to pDstPtr
+L(strcpy_loop):
+    vsetvli iVL, iLength, e8, ELEM_LMUL_SETTING, ta, ma
+    vle8ff.v vStr1, (pSrc)
+    vmseq.vx vMask2, vStr1, zero
+    csrr iCurrentVL, vl
+    vfirst.m iActiveElemPos, vMask2
+    vmsif.m vMask1, vMask2
+    add pSrc, pSrc, iCurrentVL
+    sub iLength, iLength, iCurrentVL
+    vse8.v vStr1, (pDstPtr), vMask1.t
+    add pDstPtr, pDstPtr, iCurrentVL
+    bgez iActiveElemPos, L(fill_zero)
+    bnez iLength, L(strcpy_loop)
+    ret
+
+    # fill the tail zero.
+L(fill_zero):
+    sub iVL, iCurrentVL, iActiveElemPos
+    add iLength, iLength, iVL
+    bnez iLength, 1f
+    ret
+1:
+    sub pDstPtr, pDstPtr, iVL
+    vsetvli zero, iLength, e8, ZERO_FILL_ELEM_LMUL_SETTING, ta, ma
+    vmv.v.x vStr2, zero
+
+L(fill_zero_loop):
+    vsetvli iVL, iLength, e8, ZERO_FILL_ELEM_LMUL_SETTING, ta, ma
+    vse8.v vStr2, (pDstPtr)
+    sub iLength, iLength, iVL
+    add pDstPtr, pDstPtr, iVL
+    bnez iLength, L(fill_zero_loop)
+
+    ret
+
+END(strncpy_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strnlen_vext.S b/libc/arch-riscv64/string/strnlen_vext.S
new file mode 100644
index 0000000..f546689
--- /dev/null
+++ b/libc/arch-riscv64/string/strnlen_vext.S
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pStr a0
+#define pCopyStr a2
+#define iRetValue a0
+#define iMaxlen a1
+#define iCurrentVL a3
+#define iEndOffset a4
+
+#define ELEM_LMUL_SETTING m1
+#define vStr v0
+#define vMaskEnd v8
+
+ENTRY(strnlen_vext)
+
+    mv pCopyStr, pStr
+    mv iRetValue, iMaxlen
+L(strnlen_loop):
+    beqz iMaxlen, L(end_strnlen_loop)
+    vsetvli zero, iMaxlen, e8, ELEM_LMUL_SETTING, ta, ma
+    vle8ff.v vStr, (pCopyStr)
+    vmseq.vi vMaskEnd, vStr, 0
+    vfirst.m iEndOffset, vMaskEnd /* first occurrence of \0 */
+    csrr iCurrentVL, vl
+    add pCopyStr, pCopyStr, iCurrentVL
+    sub iMaxlen, iMaxlen, iCurrentVL
+    bltz iEndOffset, L(strnlen_loop)
+    add iMaxlen, iMaxlen, iCurrentVL
+    sub iRetValue, iRetValue, iMaxlen
+    add iRetValue, iRetValue, iEndOffset
+L(end_strnlen_loop):
+    ret
+
+END(strnlen_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/sys/asm.h b/libc/arch-riscv64/string/sys/asm.h
new file mode 100644
index 0000000..cc76dc5
--- /dev/null
+++ b/libc/arch-riscv64/string/sys/asm.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_ASM_H
+#define _SYS_ASM_H
+
+#undef LEAF
+#define LEAF(symbol)       \
+  .globl symbol;           \
+  .align 2;                \
+  .type symbol, @function; \
+  symbol:                  \
+  .cfi_startproc;
+
+#undef END
+#define END(function) \
+  .cfi_endproc;       \
+  .size function, .- function
+
+#define ENTRY(name) LEAF(name)
+
+#define L(label) .L##label
+
+#endif /* _SYS_ASM_H */
diff --git a/libc/bionic/strtold.cpp b/libc/bionic/strtold.cpp
index 6b673e6..c55dd61 100644
--- a/libc/bionic/strtold.cpp
+++ b/libc/bionic/strtold.cpp
@@ -26,8 +26,6 @@
  * SUCH DAMAGE.
  */
 
-#define __BIONIC_LP32_USE_LONG_DOUBLE
-
 #include <float.h>
 #include <stdlib.h>
 
diff --git a/libc/bionic/wcstod.cpp b/libc/bionic/wcstod.cpp
index 75a59f5..c82d788 100644
--- a/libc/bionic/wcstod.cpp
+++ b/libc/bionic/wcstod.cpp
@@ -26,8 +26,6 @@
  * SUCH DAMAGE.
  */
 
-#define __BIONIC_LP32_USE_LONG_DOUBLE
-
 #include <wchar.h>
 
 #include <stdlib.h>
diff --git a/libc/include/bits/fortify/fcntl.h b/libc/include/bits/fortify/fcntl.h
index 1f6ebad..ce600ff 100644
--- a/libc/include/bits/fortify/fcntl.h
+++ b/libc/include/bits/fortify/fcntl.h
@@ -30,13 +30,13 @@
 #error "Never include this file directly; instead, include <fcntl.h>"
 #endif
 
-int __open_2(const char*, int) __INTRODUCED_IN(17);
-int __openat_2(int, const char*, int) __INTRODUCED_IN(17);
+int __open_2(const char* _Nonnull, int) __INTRODUCED_IN(17);
+int __openat_2(int, const char* _Nonnull, int) __INTRODUCED_IN(17);
 /*
  * These are the easiest way to call the real open even in clang FORTIFY.
  */
-int __open_real(const char*, int, ...) __RENAME(open);
-int __openat_real(int, const char*, int, ...) __RENAME(openat);
+int __open_real(const char* _Nonnull, int, ...) __RENAME(open);
+int __openat_real(int, const char* _Nonnull, int, ...) __RENAME(openat);
 
 #if defined(__BIONIC_FORTIFY)
 #define __open_too_many_args_error "too many arguments"
@@ -46,7 +46,7 @@
 #define __open_modes_useful(flags) (((flags) & O_CREAT) || ((flags) & O_TMPFILE) == O_TMPFILE)
 
 __BIONIC_ERROR_FUNCTION_VISIBILITY
-int open(const char* pathname, int flags, mode_t modes, ...) __overloadable
+int open(const char* _Nonnull pathname, int flags, mode_t modes, ...) __overloadable
         __errorattr(__open_too_many_args_error);
 
 /*
@@ -56,7 +56,7 @@
  * open(const char *, int, ...).
  */
 __BIONIC_FORTIFY_INLINE
-int open(const char* const __pass_object_size pathname, int flags)
+int open(const char* _Nonnull const __pass_object_size pathname, int flags)
         __overloadable
         __clang_error_if(__open_modes_useful(flags), "'open' " __open_too_few_args_error) {
 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
@@ -67,7 +67,7 @@
 }
 
 __BIONIC_FORTIFY_INLINE
-int open(const char* const __pass_object_size pathname, int flags, mode_t modes)
+int open(const char* _Nonnull const __pass_object_size pathname, int flags, mode_t modes)
         __overloadable
         __clang_warning_if(!__open_modes_useful(flags) && modes,
                            "'open' " __open_useless_modes_warning) {
@@ -75,12 +75,12 @@
 }
 
 __BIONIC_ERROR_FUNCTION_VISIBILITY
-int openat(int dirfd, const char* pathname, int flags, mode_t modes, ...)
+int openat(int dirfd, const char* _Nonnull pathname, int flags, mode_t modes, ...)
         __overloadable
         __errorattr(__open_too_many_args_error);
 
 __BIONIC_FORTIFY_INLINE
-int openat(int dirfd, const char* const __pass_object_size pathname, int flags)
+int openat(int dirfd, const char* _Nonnull const __pass_object_size pathname, int flags)
         __overloadable
         __clang_error_if(__open_modes_useful(flags), "'openat' " __open_too_few_args_error) {
 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
@@ -91,7 +91,7 @@
 }
 
 __BIONIC_FORTIFY_INLINE
-int openat(int dirfd, const char* const __pass_object_size pathname, int flags, mode_t modes)
+int openat(int dirfd, const char* _Nonnull const __pass_object_size pathname, int flags, mode_t modes)
         __overloadable
         __clang_warning_if(!__open_modes_useful(flags) && modes,
                            "'openat' " __open_useless_modes_warning) {
@@ -101,18 +101,18 @@
 /* Note that open == open64, so we reuse those bits in the open64 variants below.  */
 
 __BIONIC_ERROR_FUNCTION_VISIBILITY
-int open64(const char* pathname, int flags, mode_t modes, ...) __overloadable
+int open64(const char* _Nonnull pathname, int flags, mode_t modes, ...) __overloadable
         __errorattr(__open_too_many_args_error);
 
 __BIONIC_FORTIFY_INLINE
-int open64(const char* const __pass_object_size pathname, int flags)
+int open64(const char* _Nonnull const __pass_object_size pathname, int flags)
         __overloadable
         __clang_error_if(__open_modes_useful(flags), "'open64' " __open_too_few_args_error) {
     return open(pathname, flags);
 }
 
 __BIONIC_FORTIFY_INLINE
-int open64(const char* const __pass_object_size pathname, int flags, mode_t modes)
+int open64(const char* _Nonnull const __pass_object_size pathname, int flags, mode_t modes)
         __overloadable
         __clang_warning_if(!__open_modes_useful(flags) && modes,
                            "'open64' " __open_useless_modes_warning) {
@@ -120,19 +120,19 @@
 }
 
 __BIONIC_ERROR_FUNCTION_VISIBILITY
-int openat64(int dirfd, const char* pathname, int flags, mode_t modes, ...)
+int openat64(int dirfd, const char* _Nonnull pathname, int flags, mode_t modes, ...)
         __overloadable
         __errorattr(__open_too_many_args_error);
 
 __BIONIC_FORTIFY_INLINE
-int openat64(int dirfd, const char* const __pass_object_size pathname, int flags)
+int openat64(int dirfd, const char* _Nonnull const __pass_object_size pathname, int flags)
         __overloadable
         __clang_error_if(__open_modes_useful(flags), "'openat64' " __open_too_few_args_error) {
     return openat(dirfd, pathname, flags);
 }
 
 __BIONIC_FORTIFY_INLINE
-int openat64(int dirfd, const char* const __pass_object_size pathname, int flags, mode_t modes)
+int openat64(int dirfd, const char* _Nonnull const __pass_object_size pathname, int flags, mode_t modes)
         __overloadable
         __clang_warning_if(!__open_modes_useful(flags) && modes,
                            "'openat64' " __open_useless_modes_warning) {
diff --git a/libc/include/bits/fortify/poll.h b/libc/include/bits/fortify/poll.h
index 0b5cd4b..f2e27d7 100644
--- a/libc/include/bits/fortify/poll.h
+++ b/libc/include/bits/fortify/poll.h
@@ -30,9 +30,9 @@
 #error "Never include this file directly; instead, include <poll.h>"
 #endif
 
-int __poll_chk(struct pollfd*, nfds_t, int, size_t) __INTRODUCED_IN(23);
-int __ppoll_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*, size_t) __INTRODUCED_IN(23);
-int __ppoll64_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset64_t*, size_t) __INTRODUCED_IN(28);
+int __poll_chk(struct pollfd* _Nullable, nfds_t, int, size_t) __INTRODUCED_IN(23);
+int __ppoll_chk(struct pollfd* _Nullable, nfds_t, const struct timespec* _Nullable, const sigset_t* _Nullable, size_t) __INTRODUCED_IN(23);
+int __ppoll64_chk(struct pollfd* _Nullable, nfds_t, const struct timespec* _Nullable, const sigset64_t* _Nullable, size_t) __INTRODUCED_IN(28);
 
 #if defined(__BIONIC_FORTIFY)
 #define __bos_fd_count_trivially_safe(bos_val, fds, fd_count)              \
@@ -40,7 +40,7 @@
                                (fd_count) <= __BIONIC_CAST(static_cast, nfds_t, -1) / sizeof(*fds))
 
 __BIONIC_FORTIFY_INLINE
-int poll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, int timeout)
+int poll(struct pollfd* _Nullable const fds __pass_object_size, nfds_t fd_count, int timeout)
     __overloadable
     __clang_error_if(__bos_unevaluated_lt(__bos(fds), sizeof(*fds) * fd_count),
                      "in call to 'poll', fd_count is larger than the given buffer") {
@@ -55,7 +55,7 @@
 }
 
 __BIONIC_FORTIFY_INLINE
-int ppoll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, const struct timespec* timeout, const sigset_t* mask)
+int ppoll(struct pollfd* _Nullable const fds __pass_object_size, nfds_t fd_count, const struct timespec* _Nullable timeout, const sigset_t* _Nullable mask)
     __overloadable
     __clang_error_if(__bos_unevaluated_lt(__bos(fds), sizeof(*fds) * fd_count),
                      "in call to 'ppoll', fd_count is larger than the given buffer") {
@@ -71,7 +71,7 @@
 
 #if __ANDROID_API__ >= 28
 __BIONIC_FORTIFY_INLINE
-int ppoll64(struct pollfd* const fds __pass_object_size, nfds_t fd_count, const struct timespec* timeout, const sigset64_t* mask)
+int ppoll64(struct pollfd* _Nullable const fds __pass_object_size, nfds_t fd_count, const struct timespec* _Nullable timeout, const sigset64_t* _Nullable mask)
     __overloadable
     __clang_error_if(__bos_unevaluated_lt(__bos(fds), sizeof(*fds) * fd_count),
                      "in call to 'ppoll64', fd_count is larger than the given buffer") {
diff --git a/libc/include/bits/fortify/stdlib.h b/libc/include/bits/fortify/stdlib.h
index 623be58..b84dae4 100644
--- a/libc/include/bits/fortify/stdlib.h
+++ b/libc/include/bits/fortify/stdlib.h
@@ -35,7 +35,7 @@
 /* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */
 #define __PATH_MAX 4096
 
-char* realpath(const char* path, char* resolved)
+char* _Nullable realpath(const char* _Nonnull path, char* _Nullable resolved)
         __clang_error_if(!path, "'realpath': NULL path is never correct; flipped arguments?")
         __clang_error_if(__bos_unevaluated_lt(__bos(resolved), __PATH_MAX),
                          "'realpath' output parameter must be NULL or a pointer to a buffer "
diff --git a/libc/include/bits/threads_inlines.h b/libc/include/bits/threads_inlines.h
index 17de4a1..5878e0a 100644
--- a/libc/include/bits/threads_inlines.h
+++ b/libc/include/bits/threads_inlines.h
@@ -48,46 +48,46 @@
   }
 }
 
-__BIONIC_THREADS_INLINE void call_once(once_flag* __flag,
-                                       void (*__function)(void)) {
+__BIONIC_THREADS_INLINE void call_once(once_flag* _Nonnull __flag,
+                                       void (* _Nonnull __function)(void)) {
   pthread_once(__flag, __function);
 }
 
 
 
-__BIONIC_THREADS_INLINE int cnd_broadcast(cnd_t* __cnd) {
+__BIONIC_THREADS_INLINE int cnd_broadcast(cnd_t* _Nonnull __cnd) {
   return __bionic_thrd_error(pthread_cond_broadcast(__cnd));
 }
 
-__BIONIC_THREADS_INLINE void cnd_destroy(cnd_t* __cnd) {
+__BIONIC_THREADS_INLINE void cnd_destroy(cnd_t* _Nonnull __cnd) {
   pthread_cond_destroy(__cnd);
 }
 
-__BIONIC_THREADS_INLINE int cnd_init(cnd_t* __cnd) {
+__BIONIC_THREADS_INLINE int cnd_init(cnd_t* _Nonnull __cnd) {
   return __bionic_thrd_error(pthread_cond_init(__cnd, NULL));
 }
 
-__BIONIC_THREADS_INLINE int cnd_signal(cnd_t* __cnd) {
+__BIONIC_THREADS_INLINE int cnd_signal(cnd_t* _Nonnull __cnd) {
   return __bionic_thrd_error(pthread_cond_signal(__cnd));
 }
 
-__BIONIC_THREADS_INLINE int cnd_timedwait(cnd_t* __cnd,
-                                          mtx_t* __mtx,
-                                          const struct timespec* __timeout) {
+__BIONIC_THREADS_INLINE int cnd_timedwait(cnd_t* _Nonnull __cnd,
+                                          mtx_t* _Nonnull __mtx,
+                                          const struct timespec* _Nullable __timeout) {
   return __bionic_thrd_error(pthread_cond_timedwait(__cnd, __mtx, __timeout));
 }
 
-__BIONIC_THREADS_INLINE int cnd_wait(cnd_t* __cnd, mtx_t* __mtx) {
+__BIONIC_THREADS_INLINE int cnd_wait(cnd_t* _Nonnull __cnd, mtx_t* _Nonnull __mtx) {
   return __bionic_thrd_error(pthread_cond_wait(__cnd, __mtx));
 }
 
 
 
-__BIONIC_THREADS_INLINE void mtx_destroy(mtx_t* __mtx) {
+__BIONIC_THREADS_INLINE void mtx_destroy(mtx_t* _Nonnull __mtx) {
   pthread_mutex_destroy(__mtx);
 }
 
-__BIONIC_THREADS_INLINE int mtx_init(mtx_t* __mtx, int __type) {
+__BIONIC_THREADS_INLINE int mtx_init(mtx_t* _Nonnull __mtx, int __type) {
   int __pthread_type = (__type & mtx_recursive) ? PTHREAD_MUTEX_RECURSIVE
                                                 : PTHREAD_MUTEX_NORMAL;
   __type &= ~mtx_recursive;
@@ -99,31 +99,32 @@
   return __bionic_thrd_error(pthread_mutex_init(__mtx, &__attr));
 }
 
-__BIONIC_THREADS_INLINE int mtx_lock(mtx_t* __mtx) {
+__BIONIC_THREADS_INLINE int mtx_lock(mtx_t* _Nonnull __mtx) {
   return __bionic_thrd_error(pthread_mutex_lock(__mtx));
 }
 
-__BIONIC_THREADS_INLINE int mtx_timedlock(mtx_t* __mtx,
-                                          const struct timespec* __timeout) {
+__BIONIC_THREADS_INLINE int mtx_timedlock(mtx_t* _Nonnull __mtx,
+                                          const struct timespec* _Nullable __timeout) {
   return __bionic_thrd_error(pthread_mutex_timedlock(__mtx, __timeout));
 }
 
-__BIONIC_THREADS_INLINE int mtx_trylock(mtx_t* __mtx) {
+__BIONIC_THREADS_INLINE int mtx_trylock(mtx_t* _Nonnull __mtx) {
   return __bionic_thrd_error(pthread_mutex_trylock(__mtx));
 }
 
-__BIONIC_THREADS_INLINE int mtx_unlock(mtx_t* __mtx) {
+__BIONIC_THREADS_INLINE int mtx_unlock(mtx_t* _Nonnull __mtx) {
   return __bionic_thrd_error(pthread_mutex_unlock(__mtx));
 }
 
-
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnullability-completeness"
 struct __bionic_thrd_data {
   thrd_start_t __func;
   void* __arg;
 };
+#pragma clang diagnostic pop
 
-static inline void* __bionic_thrd_trampoline(void* __arg) {
+static inline void* _Nonnull __bionic_thrd_trampoline(void* _Nonnull __arg) {
   struct __bionic_thrd_data __data =
       *__BIONIC_CAST(static_cast, struct __bionic_thrd_data*, __arg);
   free(__arg);
@@ -132,9 +133,9 @@
                        __BIONIC_CAST(static_cast, uintptr_t, __result));
 }
 
-__BIONIC_THREADS_INLINE int thrd_create(thrd_t* __thrd,
-                                        thrd_start_t __func,
-                                        void* __arg) {
+__BIONIC_THREADS_INLINE int thrd_create(thrd_t* _Nonnull __thrd,
+                                        thrd_start_t _Nonnull __func,
+                                        void* _Nullable __arg) {
   struct __bionic_thrd_data* __pthread_arg =
       __BIONIC_CAST(static_cast, struct __bionic_thrd_data*,
                     malloc(sizeof(struct __bionic_thrd_data)));
@@ -164,7 +165,7 @@
                              __BIONIC_CAST(static_cast, uintptr_t, __result)));
 }
 
-__BIONIC_THREADS_INLINE int thrd_join(thrd_t __thrd, int* __result) {
+__BIONIC_THREADS_INLINE int thrd_join(thrd_t __thrd, int* _Nullable __result) {
   void* __pthread_result;
   if (pthread_join(__thrd, &__pthread_result) != 0) return thrd_error;
   if (__result) {
@@ -173,8 +174,8 @@
   return thrd_success;
 }
 
-__BIONIC_THREADS_INLINE int thrd_sleep(const struct timespec* __duration,
-                                       struct timespec* __remaining) {
+__BIONIC_THREADS_INLINE int thrd_sleep(const struct timespec* _Nonnull __duration,
+                                       struct timespec* _Nullable __remaining) {
   int __rc = nanosleep(__duration, __remaining);
   if (__rc == 0) return 0;
   return (errno == EINTR) ? -1 : -2;
@@ -186,7 +187,7 @@
 
 
 
-__BIONIC_THREADS_INLINE int tss_create(tss_t* __key, tss_dtor_t __dtor) {
+__BIONIC_THREADS_INLINE int tss_create(tss_t* _Nonnull __key, tss_dtor_t _Nullable __dtor) {
   return __bionic_thrd_error(pthread_key_create(__key, __dtor));
 }
 
@@ -194,11 +195,11 @@
   pthread_key_delete(__key);
 }
 
-__BIONIC_THREADS_INLINE void* tss_get(tss_t __key) {
+__BIONIC_THREADS_INLINE void* _Nullable tss_get(tss_t __key) {
   return pthread_getspecific(__key);
 }
 
-__BIONIC_THREADS_INLINE int tss_set(tss_t __key, void* __value) {
+__BIONIC_THREADS_INLINE int tss_set(tss_t __key, void* _Nonnull __value) {
   return __bionic_thrd_error(pthread_setspecific(__key, __value));
 }
 
diff --git a/libc/include/complex.h b/libc/include/complex.h
index 50da330..6bbeda3 100644
--- a/libc/include/complex.h
+++ b/libc/include/complex.h
@@ -55,99 +55,99 @@
 /* 7.3.5.1 The cacos functions */
 double complex cacos(double complex __z) __INTRODUCED_IN(23);
 float complex cacosf(float complex __z) __INTRODUCED_IN(23);
-long double complex cacosl(long double complex __z) __RENAME_LDBL(cacos, 23, 26);
+long double complex cacosl(long double complex __z) __INTRODUCED_IN(26);
 /* 7.3.5.2 The casin functions */
 double complex casin(double complex __z) __INTRODUCED_IN(23);
 float complex casinf(float complex __z) __INTRODUCED_IN(23);
-long double complex casinl(long double complex __z) __RENAME_LDBL(casin, 23, 26);
+long double complex casinl(long double complex __z) __INTRODUCED_IN(26);
 /* 7.3.5.1 The catan functions */
 double complex catan(double complex __z) __INTRODUCED_IN(23);
 float complex catanf(float complex __z) __INTRODUCED_IN(23);
-long double complex catanl(long double complex __z) __RENAME_LDBL(catan, 23, 26);
+long double complex catanl(long double complex __z) __INTRODUCED_IN(26);
 /* 7.3.5.1 The ccos functions */
 double complex ccos(double complex __z) __INTRODUCED_IN(23);
 float complex ccosf(float complex __z) __INTRODUCED_IN(23);
-long double complex ccosl(long double complex __z) __RENAME_LDBL(ccos, 23, 26);
+long double complex ccosl(long double complex __z) __INTRODUCED_IN(26);
 /* 7.3.5.1 The csin functions */
 double complex csin(double complex __z) __INTRODUCED_IN(23);
 float complex csinf(float complex __z) __INTRODUCED_IN(23);
-long double complex csinl(long double complex __z) __RENAME_LDBL(csin, 23, 26);
+long double complex csinl(long double complex __z) __INTRODUCED_IN(26);
 /* 7.3.5.1 The ctan functions */
 double complex ctan(double complex __z) __INTRODUCED_IN(23);
 float complex ctanf(float complex __z) __INTRODUCED_IN(23);
-long double complex ctanl(long double complex __z) __RENAME_LDBL(ctan, 23, 26);
+long double complex ctanl(long double complex __z) __INTRODUCED_IN(26);
 
 /* 7.3.6 Hyperbolic functions */
 /* 7.3.6.1 The cacosh functions */
 double complex cacosh(double complex __z) __INTRODUCED_IN(23);
 float complex cacoshf(float complex __z) __INTRODUCED_IN(23);
-long double complex cacoshl(long double complex __z) __RENAME_LDBL(cacosh, 23, 26);
+long double complex cacoshl(long double complex __z) __INTRODUCED_IN(26);
 /* 7.3.6.2 The casinh functions */
 double complex casinh(double complex __z) __INTRODUCED_IN(23);
 float complex casinhf(float complex __z) __INTRODUCED_IN(23);
-long double complex casinhl(long double complex __z) __RENAME_LDBL(casinh, 23, 26);
+long double complex casinhl(long double complex __z) __INTRODUCED_IN(26);
 /* 7.3.6.3 The catanh functions */
 double complex catanh(double complex __z) __INTRODUCED_IN(23);
 float complex catanhf(float complex __z) __INTRODUCED_IN(23);
-long double complex catanhl(long double complex __z) __RENAME_LDBL(catanh, 23, 26);
+long double complex catanhl(long double complex __z) __INTRODUCED_IN(26);
 /* 7.3.6.4 The ccosh functions */
 double complex ccosh(double complex __z) __INTRODUCED_IN(23);
 float complex ccoshf(float complex __z) __INTRODUCED_IN(23);
-long double complex ccoshl(long double complex __z) __RENAME_LDBL(ccosh, 23, 26);
+long double complex ccoshl(long double complex __z) __INTRODUCED_IN(26);
 /* 7.3.6.5 The csinh functions */
 double complex csinh(double complex __z) __INTRODUCED_IN(23);
 float complex csinhf(float complex __z) __INTRODUCED_IN(23);
-long double complex csinhl(long double complex __z) __RENAME_LDBL(csinh, 23, 26);
+long double complex csinhl(long double complex __z) __INTRODUCED_IN(26);
 /* 7.3.6.6 The ctanh functions */
 double complex ctanh(double complex __z) __INTRODUCED_IN(23);
 float complex ctanhf(float complex __z) __INTRODUCED_IN(23);
-long double complex ctanhl(long double complex __z) __RENAME_LDBL(ctanh, 23, 26);
+long double complex ctanhl(long double complex __z) __INTRODUCED_IN(26);
 
 /* 7.3.7 Exponential and logarithmic functions */
 /* 7.3.7.1 The cexp functions */
 double complex cexp(double complex __z) __INTRODUCED_IN(23);
 float complex cexpf(float complex __z) __INTRODUCED_IN(23);
-long double complex cexpl(long double complex __z) __RENAME_LDBL(cexp, 23, 26);
+long double complex cexpl(long double complex __z) __INTRODUCED_IN(26);
 /* 7.3.7.2 The clog functions */
 double complex clog(double complex __z) __INTRODUCED_IN(26);
 float complex clogf(float complex __z) __INTRODUCED_IN(26);
-long double complex clogl(long double complex __z) __RENAME_LDBL(clog, 26, 26);
+long double complex clogl(long double complex __z) __INTRODUCED_IN(26);
 
 /* 7.3.8 Power and absolute-value functions */
 /* 7.3.8.1 The cabs functions */
 double cabs(double complex __z) __INTRODUCED_IN(23);
 float cabsf(float complex __z) __INTRODUCED_IN(23);
-long double cabsl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23) /*__RENAME_LDBL(cabs)*/;
+long double cabsl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23);
 /* 7.3.8.2 The cpow functions */
 double complex cpow(double complex __x, double complex __z) __INTRODUCED_IN(26);
 float complex cpowf(float complex __x, float complex __z) __INTRODUCED_IN(26);
-long double complex cpowl(long double complex __x, long double complex __z) __RENAME_LDBL(cpow, 26, 26);
+long double complex cpowl(long double complex __x, long double complex __z) __INTRODUCED_IN(26);
 /* 7.3.8.3 The csqrt functions */
 double complex csqrt(double complex __z) __INTRODUCED_IN(23);
 float complex csqrtf(float complex __z) __INTRODUCED_IN(23);
-long double complex csqrtl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23) /*__RENAME_LDBL(csqrt)*/;
+long double complex csqrtl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23);
 
 /* 7.3.9 Manipulation functions */
 /* 7.3.9.1 The carg functions */
 double carg(double complex __z) __INTRODUCED_IN(23);
 float cargf(float complex __z) __INTRODUCED_IN(23);
-long double cargl(long double complex __z) __RENAME_LDBL(carg, 23, 23);
+long double cargl(long double complex __z) __INTRODUCED_IN(23);
 /* 7.3.9.2 The cimag functions */
 double cimag(double complex __z) __INTRODUCED_IN(23);
 float cimagf(float complex __z) __INTRODUCED_IN(23);
-long double cimagl(long double complex __z) __RENAME_LDBL(cimag, 23, 23);
+long double cimagl(long double complex __z) __INTRODUCED_IN(23);
 /* 7.3.9.3 The conj functions */
 double complex conj(double complex __z) __INTRODUCED_IN(23);
 float complex conjf(float complex __z) __INTRODUCED_IN(23);
-long double complex conjl(long double complex __z) __RENAME_LDBL(conj, 23, 23);
+long double complex conjl(long double complex __z) __INTRODUCED_IN(23);
 /* 7.3.9.4 The cproj functions */
 double complex cproj(double complex __z) __INTRODUCED_IN(23);
 float complex cprojf(float complex __z) __INTRODUCED_IN(23);
-long double complex cprojl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23) /*__RENAME_LDBL(cproj)*/;
+long double complex cprojl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23);
 /* 7.3.9.5 The creal functions */
 double creal(double complex __z) __INTRODUCED_IN(23);
 float crealf(float complex __z) __INTRODUCED_IN(23);
-long double creall(long double complex __z) __RENAME_LDBL(creal, 23, 23);
+long double creall(long double complex __z) __INTRODUCED_IN(23);
 
 __END_DECLS
 
diff --git a/libc/include/ftw.h b/libc/include/ftw.h
index c5fa4de..ee154f0 100644
--- a/libc/include/ftw.h
+++ b/libc/include/ftw.h
@@ -57,8 +57,8 @@
 __BEGIN_DECLS
 int ftw(const char* _Nonnull __dir_path, int (* _Nonnull __callback)(const char* _Nonnull, const struct stat* _Nonnull, int), int __max_fd_count) __INTRODUCED_IN(17);
 int nftw(const char* _Nonnull __dir_path, int (* _Nonnull __callback)(const char* _Nonnull, const struct stat* _Nonnull, int, struct FTW* _Nonnull), int __max_fd_count, int __flags) __INTRODUCED_IN(17);
-int ftw64(const char* _Nonnull __dir_path, int (* _Nonnull __callback)(const char* _Nonnull, const struct stat64* _Nonnull, int), int __max_fd_count) __RENAME_STAT64(ftw, 17, 21);
-int nftw64(const char* _Nonnull __dir_path, int (* _Nonnull __callback)(const char* _Nonnull, const struct stat64* _Nonnull, int, struct FTW* _Nonnull), int __max_fd_count, int __flags) __RENAME_STAT64(nftw, 17, 21);
+int ftw64(const char* _Nonnull __dir_path, int (* _Nonnull __callback)(const char* _Nonnull, const struct stat64* _Nonnull, int), int __max_fd_count) __INTRODUCED_IN(21);
+int nftw64(const char* _Nonnull __dir_path, int (* _Nonnull __callback)(const char* _Nonnull, const struct stat64* _Nonnull, int, struct FTW* _Nonnull), int __max_fd_count, int __flags) __INTRODUCED_IN(21);
 __END_DECLS
 
 #endif
diff --git a/libc/include/math.h b/libc/include/math.h
index d3b4a33..0572238 100644
--- a/libc/include/math.h
+++ b/libc/include/math.h
@@ -75,231 +75,231 @@
 
 double acos(double __x);
 float acosf(float __x);
-long double acosl(long double __x) __RENAME_LDBL(acos, 3, 21);
+long double acosl(long double __x);
 
 double asin(double __x);
 float asinf(float __x);
-long double asinl(long double __x) __RENAME_LDBL(asin, 3, 21);
+long double asinl(long double __x);
 
 double atan(double __x);
 float atanf(float __x);
-long double atanl(long double __x) __RENAME_LDBL(atan, 3, 21);
+long double atanl(long double __x);
 
 double atan2(double __y, double __x);
 float atan2f(float __y, float __x);
-long double atan2l(long double __y, long double __x) __RENAME_LDBL(atan2, 3, 21);
+long double atan2l(long double __y, long double __x);
 
 double cos(double __x);
 float cosf(float __x);
-long double cosl(long double __x) __RENAME_LDBL(cos, 3, 21);
+long double cosl(long double __x);
 
 double sin(double __x);
 float sinf(float __x);
-long double sinl(long double __x) __RENAME_LDBL(sin, 3, 21);
+long double sinl(long double __x);
 
 double tan(double __x);
 float tanf(float __x);
-long double tanl(long double __x) __RENAME_LDBL(tan, 3, 21);
+long double tanl(long double __x);
 
 double acosh(double __x);
 float acoshf(float __x);
-long double acoshl(long double __x) __RENAME_LDBL(acosh, 3, 21);
+long double acoshl(long double __x);
 
 double asinh(double __x);
 float asinhf(float __x);
-long double asinhl(long double __x) __RENAME_LDBL(asinh, 3, 21);
+long double asinhl(long double __x);
 
 double atanh(double __x);
 float atanhf(float __x);
-long double atanhl(long double __x) __RENAME_LDBL(atanh, 3, 21);
+long double atanhl(long double __x);
 
 double cosh(double __x);
 float coshf(float __x);
-long double coshl(long double __x) __RENAME_LDBL(cosh, 3, 21);
+long double coshl(long double __x);
 
 double sinh(double __x);
 float sinhf(float __x);
-long double sinhl(long double __x) __RENAME_LDBL(sinh, 3, 21);
+long double sinhl(long double __x);
 
 double tanh(double __x);
 float tanhf(float __x);
-long double tanhl(long double __x) __RENAME_LDBL(tanh, 3, 21);
+long double tanhl(long double __x);
 
 double exp(double __x);
 float expf(float __x);
-long double expl(long double __x) __RENAME_LDBL(exp, 3, 21);
+long double expl(long double __x);
 
 double exp2(double __x);
 float exp2f(float __x);
-long double exp2l(long double __x) __RENAME_LDBL(exp2, 3, 21);
+long double exp2l(long double __x);
 
 double expm1(double __x);
 float expm1f(float __x);
-long double expm1l(long double __x) __RENAME_LDBL(expm1, 3, 21);
+long double expm1l(long double __x);
 
 double frexp(double __x, int* _Nonnull __exponent);
 float frexpf(float __x, int* _Nonnull __exponent);
-long double frexpl(long double __x, int* _Nonnull __exponent) __RENAME_LDBL(frexp, 3, 21);
+long double frexpl(long double __x, int* _Nonnull __exponent);
 
 int ilogb(double __x) __attribute_const__;
 int ilogbf(float __x) __attribute_const__;
-int ilogbl(long double __x) __RENAME_LDBL(ilogb, 3, 3) __attribute_const__;
+int ilogbl(long double __x) __attribute_const__;
 
 double ldexp(double __x, int __exponent);
 float ldexpf(float __x, int __exponent);
-long double ldexpl(long double __x, int __exponent) __RENAME_LDBL(ldexp, 3, 3);
+long double ldexpl(long double __x, int __exponent);
 
 double log(double __x);
 float logf(float __x);
-long double logl(long double __x) __RENAME_LDBL(log, 3, 21);
+long double logl(long double __x);
 
 double log10(double __x);
 float log10f(float __x);
-long double log10l(long double __x) __RENAME_LDBL(log10, 3, 21);
+long double log10l(long double __x);
 
 double log1p(double __x);
 float log1pf(float __x);
-long double log1pl(long double __x) __RENAME_LDBL(log1p, 3, 21);
+long double log1pl(long double __x);
 
 double log2(double __x) __INTRODUCED_IN(18);
 float log2f(float __x) __INTRODUCED_IN(18);
-long double log2l(long double __x) __RENAME_LDBL(log2, 18, 18);
+long double log2l(long double __x);
 
 double logb(double __x);
 float logbf(float __x);
-long double logbl(long double __x) __RENAME_LDBL(logb, 3, 18);
+long double logbl(long double __x);
 
 double modf(double __x, double* _Nonnull __integral_part);
 float modff(float __x, float* _Nonnull __integral_part);
-long double modfl(long double __x, long double* _Nonnull __integral_part) __RENAME_LDBL(modf, 3, 21);
+long double modfl(long double __x, long double* _Nonnull __integral_part);
 
 double scalbn(double __x, int __exponent);
 float scalbnf(float __x, int __exponent);
-long double scalbnl(long double __x, int __exponent) __RENAME_LDBL(scalbn, 3, 3);
+long double scalbnl(long double __x, int __exponent);
 
 double scalbln(double __x, long __exponent);
 float scalblnf(float __x, long __exponent);
-long double scalblnl(long double __x, long __exponent) __RENAME_LDBL(scalbln, 9, 18);
+long double scalblnl(long double __x, long __exponent);
 
 double cbrt(double __x);
 float cbrtf(float __x);
-long double cbrtl(long double __x) __RENAME_LDBL(cbrt, 3, 21);
+long double cbrtl(long double __x);
 
 double fabs(double __x) __attribute_const__;
 float fabsf(float __x) __attribute_const__;
-long double fabsl(long double __x) __RENAME_LDBL(fabs, 3, 3) __attribute_const__;
+long double fabsl(long double __x) __attribute_const__;
 
 double hypot(double __x, double __y);
 float hypotf(float __x, float __y);
-long double hypotl(long double __x, long double __y) __RENAME_LDBL(hypot, 3, 21);
+long double hypotl(long double __x, long double __y);
 
 double pow(double __x, double __y);
 float powf(float __x, float __y);
-long double powl(long double __x, long double __y) __RENAME_LDBL(pow, 3, 21);
+long double powl(long double __x, long double __y);
 
 double sqrt(double __x);
 float sqrtf(float __x);
-long double sqrtl(long double __x) __RENAME_LDBL(sqrt, 3, 21);
+long double sqrtl(long double __x);
 
 double erf(double __x);
 float erff(float __x);
-long double erfl(long double __x) __RENAME_LDBL(erf, 3, 21);
+long double erfl(long double __x);
 
 double erfc(double __x);
 float erfcf(float __x);
-long double erfcl(long double __x) __RENAME_LDBL(erfc, 3, 21);
+long double erfcl(long double __x);
 
 double lgamma(double __x);
 float lgammaf(float __x);
-long double lgammal(long double __x) __RENAME_LDBL(lgamma, 3, 21);
+long double lgammal(long double __x);
 
 double tgamma(double __x);
 float tgammaf(float __x);
-long double tgammal(long double __x) __RENAME_LDBL(tgamma, 3, 21);
+long double tgammal(long double __x);
 
 double ceil(double __x);
 float ceilf(float __x);
-long double ceill(long double __x) __RENAME_LDBL(ceil, 3, 3);
+long double ceill(long double __x);
 
 double floor(double __x);
 float floorf(float __x);
-long double floorl(long double __x) __RENAME_LDBL(floor, 3, 3);
+long double floorl(long double __x);
 
 double nearbyint(double __x);
 float nearbyintf(float __x);
-long double nearbyintl(long double __x) __RENAME_LDBL(nearbyint, 3, 21);
+long double nearbyintl(long double __x);
 
 double rint(double __x);
 float rintf(float __x);
-long double rintl(long double __x) __RENAME_LDBL(rint, 3, 21);
+long double rintl(long double __x);
 
 long lrint(double __x);
 long lrintf(float __x);
-long lrintl(long double __x) __RENAME_LDBL(lrint, 3, 21);
+long lrintl(long double __x);
 
 long long llrint(double __x);
 long long llrintf(float __x);
-long long llrintl(long double __x) __RENAME_LDBL(llrint, 3, 21);
+long long llrintl(long double __x);
 
 double round(double __x);
 float roundf(float __x);
-long double roundl(long double __x) __RENAME_LDBL(roundl, 3, 3);
+long double roundl(long double __x);
 
 long lround(double __x);
 long lroundf(float __x);
-long lroundl(long double __x) __RENAME_LDBL(lround, 3, 3);
+long lroundl(long double __x);
 
 long long llround(double __x);
 long long llroundf(float __x);
-long long llroundl(long double __x) __RENAME_LDBL(llround, 3, 3);
+long long llroundl(long double __x);
 
 double trunc(double __x);
 float truncf(float __x);
-long double truncl(long double __x) __RENAME_LDBL(trunc, 3, 3);
+long double truncl(long double __x);
 
 double fmod(double __x, double __y);
 float fmodf(float __x, float __y);
-long double fmodl(long double __x, long double __y) __RENAME_LDBL(fmod, 3, 21);
+long double fmodl(long double __x, long double __y);
 
 double remainder(double __x, double __y);
 float remainderf(float __x, float __y);
-long double remainderl(long double __x, long double __y) __RENAME_LDBL(remainder, 3, 21);
+long double remainderl(long double __x, long double __y);
 
 double remquo(double __x, double __y, int* _Nonnull __quotient_bits);
 float remquof(float __x, float __y, int* _Nonnull __quotient_bits);
-long double remquol(long double __x, long double __y, int* _Nonnull __quotient_bits) __RENAME_LDBL(remquo, 3, 21);
+long double remquol(long double __x, long double __y, int* _Nonnull __quotient_bits);
 
 double copysign(double __value, double __sign) __attribute_const__;
 float copysignf(float __value, float __sign) __attribute_const__;
-long double copysignl(long double __value, long double __sign) __RENAME_LDBL(copysign, 3, 3) __attribute_const__;
+long double copysignl(long double __value, long double __sign) __attribute_const__;
 
 double nan(const char* _Nonnull __kind) __attribute_const__;
 float nanf(const char* _Nonnull __kind) __attribute_const__;
-long double nanl(const char* _Nonnull __kind) __RENAME_LDBL(nan, 13, 13) __attribute_const__;
+long double nanl(const char* _Nonnull __kind) __attribute_const__;
 
 double nextafter(double __x, double __y);
 float nextafterf(float __x, float __y);
-long double nextafterl(long double __x, long double __y) __RENAME_LDBL_NO_GUARD_FOR_NDK(nextafter, 3, 21);
+long double nextafterl(long double __x, long double __y);
 
 double nexttoward(double __x, long double __y);
 float nexttowardf(float __x, long double __y);
-long double nexttowardl(long double __x, long double __y) __RENAME_LDBL_NO_GUARD_FOR_NDK(nexttoward, 18, 18);
+long double nexttowardl(long double __x, long double __y);
 
 double fdim(double __x, double __y);
 float fdimf(float __x, float __y);
-long double fdiml(long double __x, long double __y) __RENAME_LDBL(fdim, 3, 3);
+long double fdiml(long double __x, long double __y);
 
 double fmax(double __x, double __y) __attribute_const__;
 float fmaxf(float __x, float __y) __attribute_const__;
-long double fmaxl(long double __x, long double __y) __RENAME_LDBL(fmax, 3, 3) __attribute_const__;
+long double fmaxl(long double __x, long double __y) __attribute_const__;
 
 double fmin(double __x, double __y) __attribute_const__;
 float fminf(float __x, float __y) __attribute_const__;
-long double fminl(long double __x, long double __y) __RENAME_LDBL(fmin, 3, 3) __attribute_const__;
+long double fminl(long double __x, long double __y) __attribute_const__;
 
 double fma(double __x, double __y, double __z);
 float fmaf(float __x, float __y, float __z);
-long double fmal(long double __x, long double __y, long double __z) __RENAME_LDBL_NO_GUARD_FOR_NDK(fma, 3, 21);
+long double fmal(long double __x, long double __y, long double __z);
 
 #define isgreater(x, y) __builtin_isgreater((x), (y))
 #define isgreaterequal(x, y) __builtin_isgreaterequal((x), (y))
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 2bcb870..ee4b12a 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -78,7 +78,7 @@
 void* _Nullable aligned_alloc(size_t __alignment, size_t __size) __INTRODUCED_IN(28);
 
 double strtod(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr);
-long double strtold(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr) __RENAME_LDBL(strtod, 3, 21);
+long double strtold(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr) __INTRODUCED_IN(21);
 
 unsigned long strtoul_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(26);
 
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 484757e..4154e62 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -201,39 +201,6 @@
 #  define __RENAME_IF_FILE_OFFSET64(func)
 #endif
 
-/*
- * For LP32, `long double` == `double`. Historically many `long double` functions were incorrect
- * on x86, missing on most architectures, and even if they are present and correct, linking to
- * them just bloats your ELF file by adding extra relocations. The __BIONIC_LP32_USE_LONG_DOUBLE
- * macro lets us test the headers both ways (and adds an escape valve).
- *
- * Note that some functions have their __RENAME_LDBL commented out as a sign that although we could
- * use __RENAME_LDBL it would actually cause the function to be introduced later because the
- * `long double` variant appeared before the `double` variant.
- *
- * The _NO_GUARD_FOR_NDK variants keep the __VERSIONER_NO_GUARD behavior working for the NDK. This
- * allows libc++ to refer to these functions in inlines without needing to guard them, needed since
- * libc++ doesn't currently guard these calls. There's no risk to the apps though because using
- * those APIs will still cause a link error.
- */
-#if defined(__LP64__) || defined(__BIONIC_LP32_USE_LONG_DOUBLE)
-#define __RENAME_LDBL(rewrite,rewrite_api_level,regular_api_level) __INTRODUCED_IN(regular_api_level)
-#define __RENAME_LDBL_NO_GUARD_FOR_NDK(rewrite,rewrite_api_level,regular_api_level) __INTRODUCED_IN_NO_GUARD_FOR_NDK(regular_api_level)
-#else
-#define __RENAME_LDBL(rewrite,rewrite_api_level,regular_api_level) __RENAME(rewrite) __INTRODUCED_IN(rewrite_api_level)
-#define __RENAME_LDBL_NO_GUARD_FOR_NDK(rewrite,rewrite_api_level,regular_api_level) __RENAME(rewrite) __INTRODUCED_IN_NO_GUARD_FOR_NDK(rewrite_api_level)
-#endif
-
-/*
- * On all architectures, `struct stat` == `struct stat64`, but LP32 didn't gain the *64 functions
- * until API level 21.
- */
-#if defined(__LP64__) || defined(__BIONIC_LP32_USE_STAT64)
-#define __RENAME_STAT64(rewrite,rewrite_api_level,regular_api_level) __INTRODUCED_IN(regular_api_level)
-#else
-#define __RENAME_STAT64(rewrite,rewrite_api_level,regular_api_level) __RENAME(rewrite) __INTRODUCED_IN(rewrite_api_level)
-#endif
-
 /* glibc compatibility. */
 #if defined(__LP64__)
 #define __WORDSIZE 64
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index 54621b7..f773ff6 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -141,13 +141,13 @@
 int mkdir(const char* _Nonnull __path, mode_t __mode);
 
 int fstat(int __fd, struct stat* _Nonnull __buf);
-int fstat64(int __fd, struct stat64* _Nonnull __buf) __RENAME_STAT64(fstat, 3, 21);
+int fstat64(int __fd, struct stat64* _Nonnull __buf) __INTRODUCED_IN(21);
 int fstatat(int __dir_fd, const char* _Nonnull __path, struct stat* _Nonnull __buf, int __flags);
-int fstatat64(int __dir_fd, const char* _Nonnull __path, struct stat64* _Nonnull __buf, int __flags) __RENAME_STAT64(fstatat, 3, 21);
+int fstatat64(int __dir_fd, const char* _Nonnull __path, struct stat64* _Nonnull __buf, int __flags) __INTRODUCED_IN(21);
 int lstat(const char* _Nonnull __path, struct stat* _Nonnull __buf);
-int lstat64(const char* _Nonnull __path, struct stat64* _Nonnull __buf) __RENAME_STAT64(lstat, 3, 21);
+int lstat64(const char* _Nonnull __path, struct stat64* _Nonnull __buf) __INTRODUCED_IN(21);
 int stat(const char* _Nonnull __path, struct stat* _Nonnull __buf);
-int stat64(const char* _Nonnull __path, struct stat64* _Nonnull __buf) __RENAME_STAT64(stat, 3, 21);
+int stat64(const char* _Nonnull __path, struct stat64* _Nonnull __buf) __INTRODUCED_IN(21);
 
 int mknod(const char* _Nonnull __path, mode_t __mode, dev_t __dev);
 mode_t umask(mode_t __mask);
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index 39f9374..cd09a19 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -102,7 +102,7 @@
 long wcstol(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base);
 long wcstol_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(28);
 long long wcstoll(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base) __INTRODUCED_IN(21);
-long double wcstold(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr) __RENAME_LDBL(wcstod, 3, 21);
+long double wcstold(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr) __INTRODUCED_IN(21);
 unsigned long wcstoul(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base);
 unsigned long wcstoul_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(28);
 unsigned long long wcstoull(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base) __INTRODUCED_IN(21);
diff --git a/libc/stdio/scanf_common.h b/libc/stdio/scanf_common.h
new file mode 100644
index 0000000..8132e90
--- /dev/null
+++ b/libc/stdio/scanf_common.h
@@ -0,0 +1,115 @@
+/*	$OpenBSD: vfscanf.c,v 1.31 2014/03/19 05:17:01 guenther Exp $ */
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <wctype.h>
+#include "local.h"
+
+#include <platform/bionic/macros.h>
+#include <private/bionic_fortify.h>
+#include <private/bionic_mbstate.h>
+
+#define BUF 513 /* Maximum length of numeric string. */
+
+// Flags used during conversion.
+// Size/type:
+#define LONG 0x00001        // l: long or double
+#define LONGDBL 0x00002     // L: long double
+#define SHORT 0x00004       // h: short
+#define SHORTSHORT 0x00008  // hh: 8 bit integer
+#define LLONG 0x00010       // ll: long long (+ deprecated q: quad)
+#define POINTER 0x00020     // p: void* (as hex)
+#define SIZEINT 0x00040     // z: (signed) size_t
+#define MAXINT 0x00080      // j: intmax_t
+#define PTRINT 0x00100      // t: ptrdiff_t
+#define NOSKIP 0x00200      // [ or c: do not skip blanks
+// Modifiers:
+#define SUPPRESS 0x00400  // *: suppress assignment
+#define UNSIGNED 0x00800  // %[oupxX] conversions
+#define ALLOCATE 0x01000  // m: allocate a char*
+// Internal use during integer parsing:
+#define SIGNOK 0x02000    // +/- is (still) legal
+#define HAVESIGN 0x04000  // Sign detected
+#define NDIGITS 0x08000   // No digits detected
+#define PFXOK 0x10000     // "0x" prefix is (still) legal
+#define PFBOK 0x20000     // "0b" prefix is (still) legal
+#define NZDIGITS 0x40000  // No zero digits detected
+
+// Conversion types.
+#define CT_CHAR 0    // %c conversion
+#define CT_CCL 1     // %[...] conversion
+#define CT_STRING 2  // %s conversion
+#define CT_INT 3     // Integer: strtoimax/strtoumax
+#define CT_FLOAT 4   // Float: strtod
+
+#define to_digit(c) static_cast<int>((c) - '0')
+#define is_digit(c) ((unsigned)to_digit(c) <= 9)
+
+// Append a digit to a value and check for overflow.
+#define APPEND_DIGIT(val, dig)               \
+  do {                                       \
+    if ((val) > INT_MAX / 10)                \
+      errno = ENOMEM;                        \
+    else {                                   \
+      (val) *= 10;                           \
+      if ((val) > INT_MAX - to_digit((dig))) \
+        errno = ENOMEM;                      \
+      else                                   \
+        (val) += to_digit((dig));            \
+    }                                        \
+  } while (0)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-function"
+// Trasnlate a fixed size integer argument for the %w/%wf format to a
+// flag representation. Supported sizes are 8, 16, 32, and 64 so far.
+// See details in bionic/libc/include/stdint.h
+static int w_to_flag(int size, bool fast) {
+  static constexpr int fast_size = sizeof(void*) == 8 ? LLONG : 0;
+  if (size == 8) return SHORTSHORT;
+  if (size == 16) return fast ? fast_size : SHORT;
+  if (size == 32) return fast ? fast_size : 0;
+  if (size == 64) return LLONG;
+  __fortify_fatal("%%w%s%d is unsupported", fast ? "f" : "", size);
+}
+
+#pragma clang diagnostic pop
\ No newline at end of file
diff --git a/libc/stdio/vfscanf.cpp b/libc/stdio/vfscanf.cpp
index dfd001d..65f54a5 100644
--- a/libc/stdio/vfscanf.cpp
+++ b/libc/stdio/vfscanf.cpp
@@ -31,53 +31,7 @@
  * SUCH DAMAGE.
  */
 
-#include <ctype.h>
-#include <inttypes.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/param.h>
-#include <wctype.h>
-#include "local.h"
-
-#include <private/bionic_fortify.h>
-#include <platform/bionic/macros.h>
-#include <private/bionic_mbstate.h>
-
-#define BUF 513 /* Maximum length of numeric string. */
-
-// Flags used during conversion.
-// Size/type:
-#define LONG       0x00001 // l: long or double
-#define LONGDBL    0x00002 // L: long double
-#define SHORT      0x00004 // h: short
-#define SHORTSHORT 0x00008 // hh: 8 bit integer
-#define LLONG      0x00010 // ll: long long (+ deprecated q: quad)
-#define POINTER    0x00020 // p: void* (as hex)
-#define SIZEINT    0x00040 // z: (signed) size_t
-#define MAXINT     0x00080 // j: intmax_t
-#define PTRINT     0x00100 // t: ptrdiff_t
-#define NOSKIP     0x00200 // [ or c: do not skip blanks
-// Modifiers:
-#define SUPPRESS   0x00400 // *: suppress assignment
-#define UNSIGNED   0x00800 // %[oupxX] conversions
-#define ALLOCATE   0x01000 // m: allocate a char*
-// Internal use during integer parsing:
-#define SIGNOK     0x02000 // +/- is (still) legal
-#define HAVESIGN   0x04000 // Sign detected
-#define NDIGITS    0x08000 // No digits detected
-#define PFXOK      0x10000 // "0x" prefix is (still) legal
-#define PFBOK      0x20000 // "0b" prefix is (still) legal
-#define NZDIGITS   0x40000 // No zero digits detected
-
-// Conversion types.
-#define CT_CHAR 0   // %c conversion
-#define CT_CCL 1    // %[...] conversion
-#define CT_STRING 2 // %s conversion
-#define CT_INT 3    // Integer: strtoimax/strtoumax
-#define CT_FLOAT 4  // Float: strtod
+#include "scanf_common.h"
 
 static const unsigned char* __sccl(char*, const unsigned char*);
 
@@ -122,6 +76,7 @@
      */
 again:
     c = *fmt++;
+reswitch:
     switch (c) {
       case '%':
 literal:
@@ -220,6 +175,18 @@
         base = 10;
         break;
 
+      case 'w': {
+        int size = 0;
+        bool fast = false;
+        c = *fmt++;
+        while (is_digit(c)) {
+          APPEND_DIGIT(size, c);
+          c = *fmt++;
+        }
+        flags |= w_to_flag(size, fast);
+        goto reswitch;
+      }
+
       case 'X':
       case 'x':
         flags |= PFXOK; /* enable 0x prefixing */
diff --git a/libc/stdio/vfwscanf.cpp b/libc/stdio/vfwscanf.cpp
index 5f21acd..14b1754 100644
--- a/libc/stdio/vfwscanf.cpp
+++ b/libc/stdio/vfwscanf.cpp
@@ -31,62 +31,7 @@
  * SUCH DAMAGE.
  */
 
-#include <inttypes.h>
-#include <limits.h>
-#include <locale.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wctype.h>
-#include "local.h"
-
-#include <platform/bionic/macros.h>
-
-#define BUF 513 /* Maximum length of numeric string. */
-
-/*
- * Flags used during conversion.
- */
-#define LONG 0x00001       /* l: long or double */
-#define LONGDBL 0x00002    /* L: long double */
-#define SHORT 0x00004      /* h: short */
-#define SHORTSHORT 0x00008 /* hh: 8 bit integer */
-#define LLONG 0x00010      /* ll: long long (+ deprecated q: quad) */
-#define POINTER 0x00020    /* p: void * (as hex) */
-#define SIZEINT 0x00040    /* z: (signed) size_t */
-#define MAXINT 0x00080     /* j: intmax_t */
-#define PTRINT 0x00100     /* t: ptrdiff_t */
-#define NOSKIP 0x00200     /* [ or c: do not skip blanks */
-#define SUPPRESS 0x00400   /* *: suppress assignment */
-#define UNSIGNED 0x00800   /* %[oupxX] conversions */
-
-/*
- * The following are used in numeric conversions only:
- * SIGNOK, HAVESIGN, NDIGITS, DPTOK, and EXPOK are for floating point;
- * SIGNOK, HAVESIGN, NDIGITS, PFXOK, and NZDIGITS are for integral.
- */
-#define SIGNOK   0x01000  /* +/- is (still) legal */
-#define HAVESIGN 0x02000 /* sign detected */
-#define NDIGITS  0x04000 /* no digits detected */
-
-#define DPTOK    0x08000 /* (float) decimal point is still legal */
-#define EXPOK    0x10000 /* (float) exponent (e+3, etc) still legal */
-
-#define PFBOK    0x20000 /* 0x prefix is (still) legal */
-#define PFXOK    0x40000 /* 0x prefix is (still) legal */
-#define NZDIGITS 0x80000 /* no zero digits detected */
-
-/*
- * Conversion types.
- */
-#define CT_CHAR 0   /* %c conversion */
-#define CT_CCL 1    /* %[...] conversion */
-#define CT_STRING 2 /* %s conversion */
-#define CT_INT 3    /* integer, i.e., strtoimax or strtoumax */
-#define CT_FLOAT 4  /* floating, i.e., strtod */
-
+#include "scanf_common.h"
 // An interpretive version of __sccl from vfscanf.c --- a table of all wchar_t values would
 // be a little too expensive, and some kind of compressed version isn't worth the trouble.
 static inline bool in_ccl(wchar_t wc, const wchar_t* ccl) {
@@ -176,6 +121,7 @@
      */
   again:
     c = *fmt++;
+  reswitch:
     switch (c) {
       case '%':
       literal:
@@ -273,6 +219,18 @@
         base = 10;
         break;
 
+      case 'w': {
+        int size = 0;
+        bool fast = false;
+        c = *fmt++;
+        while (is_digit(c)) {
+          APPEND_DIGIT(size, c);
+          c = *fmt++;
+        }
+        flags |= w_to_flag(size, fast);
+        goto reswitch;
+      }
+
       case 'X':
       case 'x':
         flags |= PFXOK; /* enable 0x prefixing */
diff --git a/libm/Android.bp b/libm/Android.bp
index 13fbf9a..079fd9a 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -400,7 +400,6 @@
     ],
 
     cflags: [
-        "-D__BIONIC_LP32_USE_LONG_DOUBLE",
         "-D_BSD_SOURCE",
         "-DFLT_EVAL_METHOD=0",
         "-include freebsd-compat.h",
diff --git a/tests/Android.bp b/tests/Android.bp
index 281e29d..36a3a37 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -386,7 +386,6 @@
         "bug_26110743_test.cpp",
         "byteswap_test.cpp",
         "complex_test.cpp",
-        "complex_force_long_double_test.cpp",
         "ctype_test.cpp",
         "dirent_test.cpp",
         "elf_test.cpp",
@@ -423,7 +422,6 @@
         "malloc_iterate_test.cpp",
         "malloc_test.cpp",
         "math_test.cpp",
-        "math_force_long_double_test.cpp",
         "membarrier_test.cpp",
         "memtag_stack_test.cpp",
         "mntent_test.cpp",
diff --git a/tests/complex_force_long_double_test.cpp b/tests/complex_force_long_double_test.cpp
deleted file mode 100644
index 2ea7bd4..0000000
--- a/tests/complex_force_long_double_test.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-#define __BIONIC_LP32_USE_LONG_DOUBLE
-#include "complex_test.cpp"
diff --git a/tests/complex_test.cpp b/tests/complex_test.cpp
index f015b2c..d27861a 100644
--- a/tests/complex_test.cpp
+++ b/tests/complex_test.cpp
@@ -14,12 +14,6 @@
  * limitations under the License.
  */
 
-#if defined(__BIONIC_LP32_USE_LONG_DOUBLE)
-#define COMPLEX_TEST complex_h_force_long_double
-#else
-#define COMPLEX_TEST complex_h
-#endif
-
 // This file is compiled against both glibc and bionic, and our complex.h
 // depends on bionic-specific macros, so hack around that.
 #include <sys/cdefs.h>
@@ -27,7 +21,6 @@
 #define __INTRODUCED_IN(x)
 #define __INTRODUCED_IN_32(x)
 #define __INTRODUCED_IN_64(x)
-#define __RENAME_LDBL(a,b,c)
 #endif
 
 // libc++ actively gets in the way of including <complex.h> from C++, so we
@@ -62,259 +55,259 @@
 #include <gtest/gtest.h>
 #pragma pop_macro("I")
 
-TEST(COMPLEX_TEST, cabs) {
+TEST(complex_h, cabs) {
   ASSERT_EQ(0.0, cabs(0));
 }
 
-TEST(COMPLEX_TEST, cabsf) {
+TEST(complex_h, cabsf) {
   ASSERT_EQ(0.0, cabsf(0));
 }
 
-TEST(COMPLEX_TEST, cabsl) {
+TEST(complex_h, cabsl) {
   ASSERT_EQ(0.0, cabsl(0));
 }
 
-TEST(COMPLEX_TEST, cacos) {
+TEST(complex_h, cacos) {
   ASSERT_EQ(M_PI_2, cacos(0.0));
 }
 
-TEST(COMPLEX_TEST, cacosf) {
+TEST(complex_h, cacosf) {
   ASSERT_EQ(static_cast<float>(M_PI_2), cacosf(0.0));
 }
 
-TEST(COMPLEX_TEST, cacosl) {
+TEST(complex_h, cacosl) {
   ASSERT_EQ(M_PI_2l, cacosl(0.0));
 }
 
-TEST(COMPLEX_TEST, cacosh) {
+TEST(complex_h, cacosh) {
   ASSERT_EQ(0.0, cacosh(1.0));
 }
 
-TEST(COMPLEX_TEST, cacoshl) {
+TEST(complex_h, cacoshl) {
   ASSERT_EQ(0.0, cacoshl(1.0));
 }
 
-TEST(COMPLEX_TEST, cacoshf) {
+TEST(complex_h, cacoshf) {
   ASSERT_EQ(0.0, cacoshf(1.0));
 }
 
-TEST(COMPLEX_TEST, carg) {
+TEST(complex_h, carg) {
   ASSERT_EQ(0.0, carg(0));
 }
 
-TEST(COMPLEX_TEST, cargf) {
+TEST(complex_h, cargf) {
   ASSERT_EQ(0.0, cargf(0));
 }
 
-TEST(COMPLEX_TEST, cargl) {
+TEST(complex_h, cargl) {
   ASSERT_EQ(0.0, cargl(0));
 }
 
-TEST(COMPLEX_TEST, casin) {
+TEST(complex_h, casin) {
   ASSERT_EQ(0.0, casin(0));
 }
 
-TEST(COMPLEX_TEST, casinf) {
+TEST(complex_h, casinf) {
   ASSERT_EQ(0.0, casinf(0));
 }
 
-TEST(COMPLEX_TEST, casinl) {
+TEST(complex_h, casinl) {
   ASSERT_EQ(0.0, casinl(0));
 }
 
-TEST(COMPLEX_TEST, casinh) {
+TEST(complex_h, casinh) {
   ASSERT_EQ(0.0, casinh(0));
 }
 
-TEST(COMPLEX_TEST, casinhf) {
+TEST(complex_h, casinhf) {
   ASSERT_EQ(0.0, casinhf(0));
 }
 
-TEST(COMPLEX_TEST, casinhl) {
+TEST(complex_h, casinhl) {
   ASSERT_EQ(0.0, casinhl(0));
 }
 
-TEST(COMPLEX_TEST, catan) {
+TEST(complex_h, catan) {
   ASSERT_EQ(0.0, catan(0));
 }
 
-TEST(COMPLEX_TEST, catanf) {
+TEST(complex_h, catanf) {
   ASSERT_EQ(0.0, catanf(0));
 }
 
-TEST(COMPLEX_TEST, catanl) {
+TEST(complex_h, catanl) {
   ASSERT_EQ(0.0, catanl(0));
 }
 
-TEST(COMPLEX_TEST, catanh) {
+TEST(complex_h, catanh) {
   ASSERT_EQ(0.0, catanh(0));
 }
 
-TEST(COMPLEX_TEST, catanhf) {
+TEST(complex_h, catanhf) {
   ASSERT_EQ(0.0, catanhf(0));
 }
 
-TEST(COMPLEX_TEST, catanhl) {
+TEST(complex_h, catanhl) {
   ASSERT_EQ(0.0, catanhl(0));
 }
 
-TEST(COMPLEX_TEST, ccos) {
+TEST(complex_h, ccos) {
   ASSERT_EQ(1.0, ccos(0));
 }
 
-TEST(COMPLEX_TEST, ccosf) {
+TEST(complex_h, ccosf) {
   ASSERT_EQ(1.0, ccosf(0));
 }
 
-TEST(COMPLEX_TEST, ccosl) {
+TEST(complex_h, ccosl) {
   ASSERT_EQ(1.0, ccosl(0));
 }
 
-TEST(COMPLEX_TEST, ccosh) {
+TEST(complex_h, ccosh) {
   ASSERT_EQ(1.0, ccosh(0));
 }
 
-TEST(COMPLEX_TEST, ccoshf) {
+TEST(complex_h, ccoshf) {
   ASSERT_EQ(1.0, ccoshf(0));
 }
 
-TEST(COMPLEX_TEST, ccoshl) {
+TEST(complex_h, ccoshl) {
   ASSERT_EQ(1.0, ccoshl(0));
 }
 
-TEST(COMPLEX_TEST, cexp) {
+TEST(complex_h, cexp) {
   ASSERT_EQ(1.0, cexp(0));
 }
 
-TEST(COMPLEX_TEST, cexpf) {
+TEST(complex_h, cexpf) {
   ASSERT_EQ(1.0, cexpf(0));
 }
 
-TEST(COMPLEX_TEST, cexpl) {
+TEST(complex_h, cexpl) {
   ASSERT_EQ(1.0, cexpl(0));
 }
 
-TEST(COMPLEX_TEST, cimag) {
+TEST(complex_h, cimag) {
   ASSERT_EQ(0.0, cimag(0));
 }
 
-TEST(COMPLEX_TEST, cimagf) {
+TEST(complex_h, cimagf) {
   ASSERT_EQ(0.0f, cimagf(0));
 }
 
-TEST(COMPLEX_TEST, cimagl) {
+TEST(complex_h, cimagl) {
   ASSERT_EQ(0.0, cimagl(0));
 }
 
-TEST(COMPLEX_TEST, clog) {
+TEST(complex_h, clog) {
   ASSERT_EQ(0.0, clog(1.0));
 }
 
-TEST(COMPLEX_TEST, clogf) {
+TEST(complex_h, clogf) {
   ASSERT_EQ(0.0f, clogf(1.0f));
 }
 
-TEST(COMPLEX_TEST, clogl) {
+TEST(complex_h, clogl) {
   ASSERT_EQ(0.0L, clogl(1.0L));
 }
 
-TEST(COMPLEX_TEST, conj) {
+TEST(complex_h, conj) {
   ASSERT_EQ(0.0, conj(0));
 }
 
-TEST(COMPLEX_TEST, conjf) {
+TEST(complex_h, conjf) {
   ASSERT_EQ(0.0f, conjf(0));
 }
 
-TEST(COMPLEX_TEST, conjl) {
+TEST(complex_h, conjl) {
   ASSERT_EQ(0.0, conjl(0));
 }
 
-TEST(COMPLEX_TEST, cpow) {
+TEST(complex_h, cpow) {
   ASSERT_EQ(8.0, cpow(2.0, 3.0));
 }
 
-TEST(COMPLEX_TEST, cpowf) {
+TEST(complex_h, cpowf) {
   ASSERT_EQ(8.0f, cpowf(2.0f, 3.0f));
 }
 
-TEST(COMPLEX_TEST, cpowl) {
+TEST(complex_h, cpowl) {
   ASSERT_EQ(8.0L, cpowl(2.0L, 3.0L));
 }
 
-TEST(COMPLEX_TEST, cproj) {
+TEST(complex_h, cproj) {
   ASSERT_EQ(0.0, cproj(0));
 }
 
-TEST(COMPLEX_TEST, cprojf) {
+TEST(complex_h, cprojf) {
   ASSERT_EQ(0.0f, cprojf(0));
 }
 
-TEST(COMPLEX_TEST, cprojl) {
+TEST(complex_h, cprojl) {
   ASSERT_EQ(0.0, cprojl(0));
 }
 
-TEST(COMPLEX_TEST, creal) {
+TEST(complex_h, creal) {
   ASSERT_EQ(2.0, creal(2.0 + 3.0I));
 }
 
-TEST(COMPLEX_TEST, crealf) {
+TEST(complex_h, crealf) {
   ASSERT_EQ(2.0f, crealf(2.0f + 3.0fI));
 }
 
-TEST(COMPLEX_TEST, creall) {
+TEST(complex_h, creall) {
   ASSERT_EQ(2.0, creall(2.0L + 3.0LI));
 }
 
-TEST(COMPLEX_TEST, csin) {
+TEST(complex_h, csin) {
   ASSERT_EQ(0.0, csin(0));
 }
 
-TEST(COMPLEX_TEST, csinf) {
+TEST(complex_h, csinf) {
   ASSERT_EQ(0.0, csinf(0));
 }
 
-TEST(COMPLEX_TEST, csinl) {
+TEST(complex_h, csinl) {
   ASSERT_EQ(0.0, csinl(0));
 }
 
-TEST(COMPLEX_TEST, csinh) {
+TEST(complex_h, csinh) {
   ASSERT_EQ(0.0, csinh(0));
 }
 
-TEST(COMPLEX_TEST, csinhf) {
+TEST(complex_h, csinhf) {
   ASSERT_EQ(0.0, csinhf(0));
 }
 
-TEST(COMPLEX_TEST, csinhl) {
+TEST(complex_h, csinhl) {
   ASSERT_EQ(0.0, csinhl(0));
 }
 
-TEST(COMPLEX_TEST, csqrt) {
+TEST(complex_h, csqrt) {
   ASSERT_EQ(0.0, csqrt(0));
 }
 
-TEST(COMPLEX_TEST, csqrtf) {
+TEST(complex_h, csqrtf) {
   ASSERT_EQ(0.0f, csqrtf(0));
 }
 
-TEST(COMPLEX_TEST, csqrtl) {
+TEST(complex_h, csqrtl) {
   ASSERT_EQ(0.0, csqrtl(0));
 }
 
-TEST(COMPLEX_TEST, ctan) {
+TEST(complex_h, ctan) {
   ASSERT_EQ(0.0, ctan(0));
 }
 
-TEST(COMPLEX_TEST, ctanf) {
+TEST(complex_h, ctanf) {
   ASSERT_EQ(0.0, ctanf(0));
 }
 
-TEST(COMPLEX_TEST, ctanl) {
+TEST(complex_h, ctanl) {
   ASSERT_EQ(0.0, ctanl(0));
 }
 
-TEST(COMPLEX_TEST, ctanh) {
+TEST(complex_h, ctanh) {
   ASSERT_EQ(0.0, ctanh(0));
 
   double complex z;
@@ -335,7 +328,7 @@
   ASSERT_TRUE(isnan(cimag(z)));
 }
 
-TEST(COMPLEX_TEST, ctanhf) {
+TEST(complex_h, ctanhf) {
   ASSERT_EQ(0.0f, ctanhf(0.0f));
 
   float complex z;
@@ -356,7 +349,7 @@
   ASSERT_TRUE(isnan(cimagf(z)));
 }
 
-TEST(COMPLEX_TEST, ctanhl) {
+TEST(complex_h, ctanhl) {
   ASSERT_EQ(0.0L, ctanhl(0.0L));
 
   long double complex z;
diff --git a/tests/math_force_long_double_test.cpp b/tests/math_force_long_double_test.cpp
deleted file mode 100644
index 432182b..0000000
--- a/tests/math_force_long_double_test.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-#define __BIONIC_LP32_USE_LONG_DOUBLE
-#include "math_test.cpp"
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index 60872f3..493f3af 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -48,12 +48,6 @@
 }
 }
 
-#if defined(__BIONIC_LP32_USE_LONG_DOUBLE)
-#define MATH_TEST math_h_force_long_double
-#else
-#define MATH_TEST math_h
-#endif
-
 #include "math_data_test.h"
 
 #include <gtest/gtest.h>
@@ -103,7 +97,7 @@
   return u.e;
 }
 
-TEST(MATH_TEST, fpclassify) {
+TEST(math_h, fpclassify) {
   ASSERT_EQ(FP_INFINITE, fpclassify(INFINITY));
   ASSERT_EQ(FP_INFINITE, fpclassify(HUGE_VALF));
   ASSERT_EQ(FP_INFINITE, fpclassify(-HUGE_VALF));
@@ -129,7 +123,7 @@
   ASSERT_EQ(FP_ZERO, fpclassify(0.0L));
 }
 
-TEST(MATH_TEST, isfinite) {
+TEST(math_h, isfinite) {
   ASSERT_TRUE(test_capture_isfinite(123.0f));
   ASSERT_TRUE(test_capture_isfinite(123.0));
   ASSERT_TRUE(test_capture_isfinite(123.0L));
@@ -141,7 +135,7 @@
   ASSERT_FALSE(test_capture_isfinite(-HUGE_VALL));
 }
 
-TEST(MATH_TEST, isinf) {
+TEST(math_h, isinf) {
   ASSERT_FALSE(test_capture_isinf(123.0f));
   ASSERT_FALSE(test_capture_isinf(123.0));
   ASSERT_FALSE(test_capture_isinf(123.0L));
@@ -153,7 +147,7 @@
   ASSERT_TRUE(test_capture_isinf(-HUGE_VALL));
 }
 
-TEST(MATH_TEST, isnan) {
+TEST(math_h, isnan) {
   ASSERT_FALSE(test_capture_isnan(123.0f));
   ASSERT_FALSE(test_capture_isnan(123.0));
   ASSERT_FALSE(test_capture_isnan(123.0L));
@@ -162,7 +156,7 @@
   ASSERT_TRUE(test_capture_isnan(nanl("")));
 }
 
-TEST(MATH_TEST, isnormal) {
+TEST(math_h, isnormal) {
   ASSERT_TRUE(isnormal(123.0f));
   ASSERT_TRUE(isnormal(123.0));
   ASSERT_TRUE(isnormal(123.0L));
@@ -172,7 +166,7 @@
 }
 
 // TODO: isgreater, isgreaterequals, isless, islessequal, islessgreater, isunordered
-TEST(MATH_TEST, signbit) {
+TEST(math_h, signbit) {
   ASSERT_EQ(0, test_capture_signbit(0.0f));
   ASSERT_EQ(0, test_capture_signbit(0.0));
   ASSERT_EQ(0, test_capture_signbit(0.0L));
@@ -192,7 +186,7 @@
 extern "C" int __fpclassifyf(float);
 extern "C" int __fpclassifyl(long double);
 
-TEST(MATH_TEST, __fpclassify) {
+TEST(math_h, __fpclassify) {
   ASSERT_EQ(FP_INFINITE, __fpclassify(HUGE_VAL));
   ASSERT_EQ(FP_INFINITE, __fpclassify(-HUGE_VAL));
   ASSERT_EQ(FP_NAN, __fpclassify(nan("")));
@@ -201,7 +195,7 @@
   ASSERT_EQ(FP_ZERO, __fpclassify(0.0));
 }
 
-TEST(MATH_TEST, __fpclassifyd) {
+TEST(math_h, __fpclassifyd) {
 #if defined(__GLIBC__) || defined(ANDROID_HOST_MUSL)
 #define __fpclassifyd __fpclassify
 #endif
@@ -213,7 +207,7 @@
   ASSERT_EQ(FP_ZERO, __fpclassifyd(0.0));
 }
 
-TEST(MATH_TEST, __fpclassifyf) {
+TEST(math_h, __fpclassifyf) {
   ASSERT_EQ(FP_INFINITE, __fpclassifyf(HUGE_VALF));
   ASSERT_EQ(FP_INFINITE, __fpclassifyf(-HUGE_VALF));
   ASSERT_EQ(FP_NAN, __fpclassifyf(nanf("")));
@@ -222,7 +216,7 @@
   ASSERT_EQ(FP_ZERO, __fpclassifyf(0.0f));
 }
 
-TEST(MATH_TEST, __fpclassifyl) {
+TEST(math_h, __fpclassifyl) {
   EXPECT_EQ(FP_INFINITE, __fpclassifyl(HUGE_VALL));
   EXPECT_EQ(FP_INFINITE, __fpclassifyl(-HUGE_VALL));
   EXPECT_EQ(FP_NAN, __fpclassifyl(nanl("")));
@@ -231,7 +225,7 @@
   EXPECT_EQ(FP_ZERO, __fpclassifyl(0.0L));
 }
 
-TEST(MATH_TEST, finitef) {
+TEST(math_h, finitef) {
   ASSERT_TRUE(finitef(123.0f));
   ASSERT_FALSE(finitef(HUGE_VALF));
   ASSERT_FALSE(finitef(-HUGE_VALF));
@@ -244,7 +238,7 @@
 extern "C" int __isfinitel(long double);
 extern "C" int isfinitel(long double);
 
-TEST(MATH_TEST, __isfinite) {
+TEST(math_h, __isfinite) {
 #if defined(__GLIBC__)
 #define __isfinite __finite
 #elif defined(ANDROID_HOST_MUSL)
@@ -255,7 +249,7 @@
   ASSERT_FALSE(__isfinite(-HUGE_VAL));
 }
 
-TEST(MATH_TEST, __isfinitef) {
+TEST(math_h, __isfinitef) {
 #if defined(__GLIBC__)
 #define __isfinitef __finitef
 #elif defined(ANDROID_HOST_MUSL)
@@ -266,7 +260,7 @@
   ASSERT_FALSE(__isfinitef(-HUGE_VALF));
 }
 
-TEST(MATH_TEST, isfinitef) {
+TEST(math_h, isfinitef) {
 #if defined(__GLIBC__)
 #define isfinitef __finitef
 #elif defined(ANDROID_HOST_MUSL)
@@ -277,7 +271,7 @@
   ASSERT_FALSE(isfinitef(-HUGE_VALF));
 }
 
-TEST(MATH_TEST, __isfinitel) {
+TEST(math_h, __isfinitel) {
 #if defined(__GLIBC__)
 #define __isfinitel __finitel
 #elif defined(ANDROID_HOST_MUSL)
@@ -288,7 +282,7 @@
   ASSERT_FALSE(__isfinitel(-HUGE_VALL));
 }
 
-TEST(MATH_TEST, isfinitel) {
+TEST(math_h, isfinitel) {
 #if defined(__GLIBC__)
 #define isfinitel __finitel
 #elif defined(ANDROID_HOST_MUSL)
@@ -299,13 +293,13 @@
   ASSERT_FALSE(isfinitel(-HUGE_VALL));
 }
 
-TEST(MATH_TEST, finite) {
+TEST(math_h, finite) {
   ASSERT_TRUE(finite(123.0));
   ASSERT_FALSE(finite(HUGE_VAL));
   ASSERT_FALSE(finite(-HUGE_VAL));
 }
 
-TEST(MATH_TEST, isinf_function) {
+TEST(math_h, isinf_function) {
   // The isinf macro deals with all three types; the isinf function is for doubles.
   ASSERT_FALSE((isinf)(123.0));
   ASSERT_TRUE((isinf)(HUGE_VAL));
@@ -319,7 +313,7 @@
 extern "C" int __isinfl(long double);
 extern "C" int isinfl(long double);
 
-TEST(MATH_TEST, __isinf) {
+TEST(math_h, __isinf) {
 #if defined(ANDROID_HOST_MUSL)
 #define __isinf isinf
 #endif
@@ -328,7 +322,7 @@
   ASSERT_TRUE(__isinf(-HUGE_VAL));
 }
 
-TEST(MATH_TEST, __isinff) {
+TEST(math_h, __isinff) {
 #if defined(ANDROID_HOST_MUSL)
 #define __isinff isinf
 #endif
@@ -337,7 +331,7 @@
   ASSERT_TRUE(__isinff(-HUGE_VALF));
 }
 
-TEST(MATH_TEST, isinff) {
+TEST(math_h, isinff) {
 #if defined(ANDROID_HOST_MUSL)
 #define isinff isinf
 #endif
@@ -346,7 +340,7 @@
   ASSERT_TRUE(isinff(-HUGE_VALF));
 }
 
-TEST(MATH_TEST, __isinfl) {
+TEST(math_h, __isinfl) {
 #if defined(ANDROID_HOST_MUSL)
 #define __isinfl isinf
 #endif
@@ -355,7 +349,7 @@
   ASSERT_TRUE(__isinfl(-HUGE_VALL));
 }
 
-TEST(MATH_TEST, isinfl) {
+TEST(math_h, isinfl) {
 #if defined(ANDROID_HOST_MUSL)
 #define isinfl isinf
 #endif
@@ -364,7 +358,7 @@
   ASSERT_TRUE(isinfl(-HUGE_VALL));
 }
 
-TEST(MATH_TEST, isnan_function) {
+TEST(math_h, isnan_function) {
   // The isnan macro deals with all three types; the isnan function is for doubles.
   ASSERT_FALSE((isnan)(123.0));
   ASSERT_TRUE((isnan)(nan("")));
@@ -377,7 +371,7 @@
 extern "C" int __isnanl(long double);
 extern "C" int isnanl(long double);
 
-TEST(MATH_TEST, __isnan) {
+TEST(math_h, __isnan) {
 #if defined(ANDROID_HOST_MUSL)
 #define __isnan isnan
 #endif
@@ -385,7 +379,7 @@
   ASSERT_TRUE(__isnan(nan("")));
 }
 
-TEST(MATH_TEST, __isnanf) {
+TEST(math_h, __isnanf) {
 #if defined(ANDROID_HOST_MUSL)
 #define __isnanf isnan
 #endif
@@ -393,7 +387,7 @@
   ASSERT_TRUE(__isnanf(nanf("")));
 }
 
-TEST(MATH_TEST, isnanf) {
+TEST(math_h, isnanf) {
 #if defined(ANDROID_HOST_MUSL)
 #define isnanf isnan
 #endif
@@ -401,7 +395,7 @@
   ASSERT_TRUE(isnanf(nanf("")));
 }
 
-TEST(MATH_TEST, __isnanl) {
+TEST(math_h, __isnanl) {
 #if defined(ANDROID_HOST_MUSL)
 #define __isnanl isnan
 #endif
@@ -409,7 +403,7 @@
   ASSERT_TRUE(__isnanl(nanl("")));
 }
 
-TEST(MATH_TEST, isnanl) {
+TEST(math_h, isnanl) {
 #if defined(ANDROID_HOST_MUSL)
 #define isnanl isnan
 #endif
@@ -424,7 +418,7 @@
 extern "C" int __isnormall(long double);
 extern "C" int isnormall(long double);
 
-TEST(MATH_TEST, __isnormal) {
+TEST(math_h, __isnormal) {
 #if defined(__BIONIC__)
   ASSERT_TRUE(__isnormal(123.0));
   ASSERT_FALSE(__isnormal(double_subnormal()));
@@ -433,7 +427,7 @@
 #endif // __BIONIC__
 }
 
-TEST(MATH_TEST, __isnormalf) {
+TEST(math_h, __isnormalf) {
 #if defined(__BIONIC__)
   ASSERT_TRUE(__isnormalf(123.0f));
   ASSERT_FALSE(__isnormalf(float_subnormal()));
@@ -442,7 +436,7 @@
 #endif // __BIONIC__
 }
 
-TEST(MATH_TEST, isnormalf) {
+TEST(math_h, isnormalf) {
 #if defined(__BIONIC__)
   ASSERT_TRUE(isnormalf(123.0f));
   ASSERT_FALSE(isnormalf(float_subnormal()));
@@ -451,7 +445,7 @@
 #endif // __BIONIC__
 }
 
-TEST(MATH_TEST, __isnormall) {
+TEST(math_h, __isnormall) {
 #if defined(__BIONIC__)
   ASSERT_TRUE(__isnormall(123.0L));
   ASSERT_FALSE(__isnormall(ldouble_subnormal()));
@@ -460,7 +454,7 @@
 #endif // __BIONIC__
 }
 
-TEST(MATH_TEST, isnormall) {
+TEST(math_h, isnormall) {
 #if defined(__BIONIC__)
   ASSERT_TRUE(isnormall(123.0L));
   ASSERT_FALSE(isnormall(ldouble_subnormal()));
@@ -474,370 +468,370 @@
 extern "C" int __signbitf(float);
 extern "C" int __signbitl(long double);
 
-TEST(MATH_TEST, __signbit) {
+TEST(math_h, __signbit) {
   ASSERT_EQ(0, __signbit(0.0));
   ASSERT_EQ(0, __signbit(1.0));
   ASSERT_NE(0, __signbit(-1.0));
 }
 
-TEST(MATH_TEST, __signbitf) {
+TEST(math_h, __signbitf) {
   ASSERT_EQ(0, __signbitf(0.0f));
   ASSERT_EQ(0, __signbitf(1.0f));
   ASSERT_NE(0, __signbitf(-1.0f));
 }
 
-TEST(MATH_TEST, __signbitl) {
+TEST(math_h, __signbitl) {
   ASSERT_EQ(0L, __signbitl(0.0L));
   ASSERT_EQ(0L, __signbitl(1.0L));
   ASSERT_NE(0L, __signbitl(-1.0L));
 }
 
-TEST(MATH_TEST, acos) {
+TEST(math_h, acos) {
   ASSERT_DOUBLE_EQ(M_PI/2.0, acos(0.0));
 }
 
-TEST(MATH_TEST, acosf) {
+TEST(math_h, acosf) {
   ASSERT_FLOAT_EQ(static_cast<float>(M_PI)/2.0f, acosf(0.0f));
 }
 
-TEST(MATH_TEST, acosl) {
+TEST(math_h, acosl) {
   ASSERT_DOUBLE_EQ(M_PI/2.0L, acosl(0.0L));
 }
 
-TEST(MATH_TEST, asin) {
+TEST(math_h, asin) {
   ASSERT_DOUBLE_EQ(0.0, asin(0.0));
 }
 
-TEST(MATH_TEST, asinf) {
+TEST(math_h, asinf) {
   ASSERT_FLOAT_EQ(0.0f, asinf(0.0f));
 }
 
-TEST(MATH_TEST, asinl) {
+TEST(math_h, asinl) {
   ASSERT_DOUBLE_EQ(0.0L, asinl(0.0L));
 }
 
-TEST(MATH_TEST, atan) {
+TEST(math_h, atan) {
   ASSERT_DOUBLE_EQ(0.0, atan(0.0));
 }
 
-TEST(MATH_TEST, atanf) {
+TEST(math_h, atanf) {
   ASSERT_FLOAT_EQ(0.0f, atanf(0.0f));
 }
 
-TEST(MATH_TEST, atanl) {
+TEST(math_h, atanl) {
   ASSERT_DOUBLE_EQ(0.0L, atanl(0.0L));
 }
 
-TEST(MATH_TEST, atan2) {
+TEST(math_h, atan2) {
   ASSERT_DOUBLE_EQ(0.0, atan2(0.0, 0.0));
 }
 
-TEST(MATH_TEST, atan2f) {
+TEST(math_h, atan2f) {
   ASSERT_FLOAT_EQ(0.0f, atan2f(0.0f, 0.0f));
 }
 
-TEST(MATH_TEST, atan2l) {
+TEST(math_h, atan2l) {
   ASSERT_DOUBLE_EQ(0.0L, atan2l(0.0L, 0.0L));
 }
 
-TEST(MATH_TEST, cos) {
+TEST(math_h, cos) {
   ASSERT_DOUBLE_EQ(1.0, cos(0.0));
 }
 
-TEST(MATH_TEST, cosf) {
+TEST(math_h, cosf) {
   ASSERT_FLOAT_EQ(1.0f, cosf(0.0f));
 }
 
-TEST(MATH_TEST, cosl) {
+TEST(math_h, cosl) {
   ASSERT_DOUBLE_EQ(1.0L, cosl(0.0L));
 }
 
-TEST(MATH_TEST, sin) {
+TEST(math_h, sin) {
   ASSERT_DOUBLE_EQ(0.0, sin(0.0));
 }
 
-TEST(MATH_TEST, sinf) {
+TEST(math_h, sinf) {
   ASSERT_FLOAT_EQ(0.0f, sinf(0.0f));
 }
 
-TEST(MATH_TEST, sinl) {
+TEST(math_h, sinl) {
   ASSERT_DOUBLE_EQ(0.0L, sinl(0.0L));
 }
 
-TEST(MATH_TEST, sincos) {
+TEST(math_h, sincos) {
   double s, c;
   sincos(0.0, &s, &c);
   ASSERT_DOUBLE_EQ(0.0, s);
   ASSERT_DOUBLE_EQ(1.0, c);
 }
 
-TEST(MATH_TEST, sincosf) {
+TEST(math_h, sincosf) {
   float s, c;
   sincosf(0.0f, &s, &c);
   ASSERT_FLOAT_EQ(0.0f, s);
   ASSERT_FLOAT_EQ(1.0f, c);
 }
 
-TEST(MATH_TEST, sincosl) {
+TEST(math_h, sincosl) {
   long double s, c;
   sincosl(0.0L, &s, &c);
   ASSERT_DOUBLE_EQ(0.0L, s);
   ASSERT_DOUBLE_EQ(1.0L, c);
 }
 
-TEST(MATH_TEST, tan) {
+TEST(math_h, tan) {
   ASSERT_DOUBLE_EQ(0.0, tan(0.0));
 }
 
-TEST(MATH_TEST, tanf) {
+TEST(math_h, tanf) {
   ASSERT_FLOAT_EQ(0.0f, tanf(0.0f));
 }
 
-TEST(MATH_TEST, tanl) {
+TEST(math_h, tanl) {
   ASSERT_DOUBLE_EQ(0.0L, tanl(0.0L));
 }
 
-TEST(MATH_TEST, acosh) {
+TEST(math_h, acosh) {
   ASSERT_DOUBLE_EQ(0.0, acosh(1.0));
 }
 
-TEST(MATH_TEST, acoshf) {
+TEST(math_h, acoshf) {
   ASSERT_FLOAT_EQ(0.0f, acoshf(1.0f));
 }
 
-TEST(MATH_TEST, acoshl) {
+TEST(math_h, acoshl) {
   ASSERT_DOUBLE_EQ(0.0L, acoshl(1.0L));
 }
 
-TEST(MATH_TEST, asinh) {
+TEST(math_h, asinh) {
   ASSERT_DOUBLE_EQ(0.0, asinh(0.0));
 }
 
-TEST(MATH_TEST, asinhf) {
+TEST(math_h, asinhf) {
   ASSERT_FLOAT_EQ(0.0f, asinhf(0.0f));
 }
 
-TEST(MATH_TEST, asinhl) {
+TEST(math_h, asinhl) {
   ASSERT_DOUBLE_EQ(0.0L, asinhl(0.0L));
 }
 
-TEST(MATH_TEST, atanh) {
+TEST(math_h, atanh) {
   ASSERT_DOUBLE_EQ(0.0, atanh(0.0));
 }
 
-TEST(MATH_TEST, atanhf) {
+TEST(math_h, atanhf) {
   ASSERT_FLOAT_EQ(0.0f, atanhf(0.0f));
 }
 
-TEST(MATH_TEST, atanhl) {
+TEST(math_h, atanhl) {
   ASSERT_DOUBLE_EQ(0.0L, atanhl(0.0L));
 }
 
-TEST(MATH_TEST, cosh) {
+TEST(math_h, cosh) {
   ASSERT_DOUBLE_EQ(1.0, cosh(0.0));
 }
 
-TEST(MATH_TEST, coshf) {
+TEST(math_h, coshf) {
   ASSERT_FLOAT_EQ(1.0f, coshf(0.0f));
 }
 
-TEST(MATH_TEST, coshl) {
+TEST(math_h, coshl) {
   ASSERT_DOUBLE_EQ(1.0L, coshl(0.0L));
 }
 
-TEST(MATH_TEST, sinh) {
+TEST(math_h, sinh) {
   ASSERT_DOUBLE_EQ(0.0, sinh(0.0));
 }
 
-TEST(MATH_TEST, sinhf) {
+TEST(math_h, sinhf) {
   ASSERT_FLOAT_EQ(0.0f, sinhf(0.0f));
 }
 
-TEST(MATH_TEST, sinhl) {
+TEST(math_h, sinhl) {
   ASSERT_DOUBLE_EQ(0.0L, sinhl(0.0L));
 }
 
-TEST(MATH_TEST, tanh) {
+TEST(math_h, tanh) {
   ASSERT_DOUBLE_EQ(0.0, tanh(0.0));
 }
 
-TEST(MATH_TEST, tanhf) {
+TEST(math_h, tanhf) {
   ASSERT_FLOAT_EQ(0.0f, tanhf(0.0f));
 }
 
-TEST(MATH_TEST, tanhl) {
+TEST(math_h, tanhl) {
   ASSERT_DOUBLE_EQ(0.0L, tanhl(0.0L));
 }
 
-TEST(MATH_TEST, log) {
+TEST(math_h, log) {
   ASSERT_DOUBLE_EQ(1.0, log(M_E));
 }
 
-TEST(MATH_TEST, logf) {
+TEST(math_h, logf) {
   ASSERT_FLOAT_EQ(1.0f, logf(static_cast<float>(M_E)));
 }
 
-TEST(MATH_TEST, logl) {
+TEST(math_h, logl) {
   ASSERT_DOUBLE_EQ(1.0L, logl(M_E));
 }
 
-TEST(MATH_TEST, log2) {
+TEST(math_h, log2) {
   ASSERT_DOUBLE_EQ(12.0, log2(4096.0));
 }
 
-TEST(MATH_TEST, log2f) {
+TEST(math_h, log2f) {
   ASSERT_FLOAT_EQ(12.0f, log2f(4096.0f));
 }
 
-TEST(MATH_TEST, log2l) {
+TEST(math_h, log2l) {
   ASSERT_DOUBLE_EQ(12.0L, log2l(4096.0L));
 }
 
-TEST(MATH_TEST, log10) {
+TEST(math_h, log10) {
   ASSERT_DOUBLE_EQ(3.0, log10(1000.0));
 }
 
-TEST(MATH_TEST, log10f) {
+TEST(math_h, log10f) {
   ASSERT_FLOAT_EQ(3.0f, log10f(1000.0f));
 }
 
-TEST(MATH_TEST, log10l) {
+TEST(math_h, log10l) {
   ASSERT_DOUBLE_EQ(3.0L, log10l(1000.0L));
 }
 
-TEST(MATH_TEST, cbrt) {
+TEST(math_h, cbrt) {
   ASSERT_DOUBLE_EQ(3.0, cbrt(27.0));
 }
 
-TEST(MATH_TEST, cbrtf) {
+TEST(math_h, cbrtf) {
   ASSERT_FLOAT_EQ(3.0f, cbrtf(27.0f));
 }
 
-TEST(MATH_TEST, cbrtl) {
+TEST(math_h, cbrtl) {
   ASSERT_DOUBLE_EQ(3.0L, cbrtl(27.0L));
 }
 
-TEST(MATH_TEST, sqrt) {
+TEST(math_h, sqrt) {
   ASSERT_DOUBLE_EQ(2.0, sqrt(4.0));
 }
 
-TEST(MATH_TEST, sqrtf) {
+TEST(math_h, sqrtf) {
   ASSERT_FLOAT_EQ(2.0f, sqrtf(4.0f));
 }
 
-TEST(MATH_TEST, sqrtl) {
+TEST(math_h, sqrtl) {
   ASSERT_DOUBLE_EQ(2.0L, sqrtl(4.0L));
 }
 
-TEST(MATH_TEST, exp) {
+TEST(math_h, exp) {
   ASSERT_DOUBLE_EQ(1.0, exp(0.0));
   ASSERT_DOUBLE_EQ(M_E, exp(1.0));
 }
 
-TEST(MATH_TEST, expf) {
+TEST(math_h, expf) {
   ASSERT_FLOAT_EQ(1.0f, expf(0.0f));
   ASSERT_FLOAT_EQ(static_cast<float>(M_E), expf(1.0f));
 }
 
-TEST(MATH_TEST, expl) {
+TEST(math_h, expl) {
   ASSERT_DOUBLE_EQ(1.0L, expl(0.0L));
   ASSERT_DOUBLE_EQ(M_E, expl(1.0L));
 }
 
-TEST(MATH_TEST, exp2) {
+TEST(math_h, exp2) {
   ASSERT_DOUBLE_EQ(8.0, exp2(3.0));
 }
 
-TEST(MATH_TEST, exp2f) {
+TEST(math_h, exp2f) {
   ASSERT_FLOAT_EQ(8.0f, exp2f(3.0f));
 }
 
-TEST(MATH_TEST, exp2l) {
+TEST(math_h, exp2l) {
   ASSERT_DOUBLE_EQ(8.0L, exp2l(3.0L));
 }
 
-TEST(MATH_TEST, expm1) {
+TEST(math_h, expm1) {
   ASSERT_DOUBLE_EQ(M_E - 1.0, expm1(1.0));
 }
 
-TEST(MATH_TEST, expm1f) {
+TEST(math_h, expm1f) {
   ASSERT_FLOAT_EQ(static_cast<float>(M_E) - 1.0f, expm1f(1.0f));
 }
 
-TEST(MATH_TEST, expm1l) {
+TEST(math_h, expm1l) {
   ASSERT_DOUBLE_EQ(M_E - 1.0L, expm1l(1.0L));
 }
 
-TEST(MATH_TEST, pow) {
+TEST(math_h, pow) {
   ASSERT_TRUE(isnan(pow(nan(""), 3.0)));
   ASSERT_DOUBLE_EQ(1.0, (pow(1.0, nan(""))));
   ASSERT_TRUE(isnan(pow(2.0, nan(""))));
   ASSERT_DOUBLE_EQ(8.0, pow(2.0, 3.0));
 }
 
-TEST(MATH_TEST, powf) {
+TEST(math_h, powf) {
   ASSERT_TRUE(isnanf(powf(nanf(""), 3.0f)));
   ASSERT_FLOAT_EQ(1.0f, (powf(1.0f, nanf(""))));
   ASSERT_TRUE(isnanf(powf(2.0f, nanf(""))));
   ASSERT_FLOAT_EQ(8.0f, powf(2.0f, 3.0f));
 }
 
-TEST(MATH_TEST, powl) {
+TEST(math_h, powl) {
   ASSERT_TRUE(__isnanl(powl(nanl(""), 3.0L)));
   ASSERT_DOUBLE_EQ(1.0L, (powl(1.0L, nanl(""))));
   ASSERT_TRUE(__isnanl(powl(2.0L, nanl(""))));
   ASSERT_DOUBLE_EQ(8.0L, powl(2.0L, 3.0L));
 }
 
-TEST(MATH_TEST, ceil) {
+TEST(math_h, ceil) {
   ASSERT_DOUBLE_EQ(1.0, ceil(0.9));
 }
 
-TEST(MATH_TEST, ceilf) {
+TEST(math_h, ceilf) {
   ASSERT_FLOAT_EQ(1.0f, ceilf(0.9f));
 }
 
-TEST(MATH_TEST, ceill) {
+TEST(math_h, ceill) {
   ASSERT_DOUBLE_EQ(1.0L, ceill(0.9L));
 }
 
-TEST(MATH_TEST, floor) {
+TEST(math_h, floor) {
   ASSERT_DOUBLE_EQ(1.0, floor(1.1));
 }
 
-TEST(MATH_TEST, floorf) {
+TEST(math_h, floorf) {
   ASSERT_FLOAT_EQ(1.0f, floorf(1.1f));
 }
 
-TEST(MATH_TEST, floorl) {
+TEST(math_h, floorl) {
   ASSERT_DOUBLE_EQ(1.0L, floorl(1.1L));
 }
 
-TEST(MATH_TEST, fabs) {
+TEST(math_h, fabs) {
   ASSERT_DOUBLE_EQ(1.0, fabs(-1.0));
 }
 
-TEST(MATH_TEST, fabsf) {
+TEST(math_h, fabsf) {
   ASSERT_FLOAT_EQ(1.0f, fabsf(-1.0f));
 }
 
-TEST(MATH_TEST, fabsl) {
+TEST(math_h, fabsl) {
   ASSERT_DOUBLE_EQ(1.0L, fabsl(-1.0L));
 }
 
-TEST(MATH_TEST, ldexp) {
+TEST(math_h, ldexp) {
   ASSERT_DOUBLE_EQ(16.0, ldexp(2.0, 3.0));
 }
 
-TEST(MATH_TEST, ldexpf) {
+TEST(math_h, ldexpf) {
   ASSERT_FLOAT_EQ(16.0f, ldexpf(2.0f, 3.0f));
 }
 
-TEST(MATH_TEST, ldexpl) {
+TEST(math_h, ldexpl) {
   ASSERT_DOUBLE_EQ(16.0L, ldexpl(2.0L, 3.0));
 }
 
-TEST(MATH_TEST, fmod) {
+TEST(math_h, fmod) {
   ASSERT_DOUBLE_EQ(2.0, fmod(12.0, 10.0));
 
   // If x is an infinity, NaN is returned.
@@ -852,7 +846,7 @@
   ASSERT_TRUE(isnan(fmod(3.0, 0.0)));
 }
 
-TEST(MATH_TEST, fmodf) {
+TEST(math_h, fmodf) {
   ASSERT_FLOAT_EQ(2.0f, fmodf(12.0f, 10.0f));
 
   // If x is an infinity, NaN is returned.
@@ -867,7 +861,7 @@
   ASSERT_TRUE(isnanf(fmodf(3.0f, 0.0f)));
 }
 
-TEST(MATH_TEST, fmodl) {
+TEST(math_h, fmodl) {
   ASSERT_DOUBLE_EQ(2.0L, fmodl(12.0L, 10.0L));
 
   // If x is an infinity, NaN is returned.
@@ -882,7 +876,7 @@
   ASSERT_TRUE(isnanl(fmodl(3.0L, 0.0L)));
 }
 
-TEST(MATH_TEST, remainder) {
+TEST(math_h, remainder) {
   ASSERT_DOUBLE_EQ(2.0, remainder(12.0, 10.0));
 
   // If x or y is a NaN, NaN is returned.
@@ -897,7 +891,7 @@
   ASSERT_TRUE(isnan(remainder(12.0, 0.0)));
 }
 
-TEST(MATH_TEST, remainderf) {
+TEST(math_h, remainderf) {
   ASSERT_FLOAT_EQ(2.0f, remainderf(12.0f, 10.0f));
 
   // If x or y is a NaN, NaN is returned.
@@ -912,7 +906,7 @@
   ASSERT_TRUE(isnanf(remainderf(12.0f, 0.0f)));
 }
 
-TEST(MATH_TEST, remainderl) {
+TEST(math_h, remainderl) {
   ASSERT_DOUBLE_EQ(2.0L, remainderl(12.0L, 10.0L));
 
   // If x or y is a NaN, NaN is returned.
@@ -927,63 +921,63 @@
   ASSERT_TRUE(isnanl(remainderl(12.0L, 0.0L)));
 }
 
-TEST(MATH_TEST, drem) {
+TEST(math_h, drem) {
   ASSERT_DOUBLE_EQ(2.0, drem(12.0, 10.0));
 }
 
-TEST(MATH_TEST, dremf) {
+TEST(math_h, dremf) {
   ASSERT_FLOAT_EQ(2.0f, dremf(12.0f, 10.0f));
 }
 
-TEST(MATH_TEST, fmax) {
+TEST(math_h, fmax) {
   ASSERT_DOUBLE_EQ(12.0, fmax(12.0, 10.0));
   ASSERT_DOUBLE_EQ(12.0, fmax(12.0, nan("")));
   ASSERT_DOUBLE_EQ(12.0, fmax(nan(""), 12.0));
 }
 
-TEST(MATH_TEST, fmaxf) {
+TEST(math_h, fmaxf) {
   ASSERT_FLOAT_EQ(12.0f, fmaxf(12.0f, 10.0f));
   ASSERT_FLOAT_EQ(12.0f, fmaxf(12.0f, nanf("")));
   ASSERT_FLOAT_EQ(12.0f, fmaxf(nanf(""), 12.0f));
 }
 
-TEST(MATH_TEST, fmaxl) {
+TEST(math_h, fmaxl) {
   ASSERT_DOUBLE_EQ(12.0L, fmaxl(12.0L, 10.0L));
   ASSERT_DOUBLE_EQ(12.0L, fmaxl(12.0L, nanl("")));
   ASSERT_DOUBLE_EQ(12.0L, fmaxl(nanl(""), 12.0L));
 }
 
-TEST(MATH_TEST, fmin) {
+TEST(math_h, fmin) {
   ASSERT_DOUBLE_EQ(10.0, fmin(12.0, 10.0));
   ASSERT_DOUBLE_EQ(12.0, fmin(12.0, nan("")));
   ASSERT_DOUBLE_EQ(12.0, fmin(nan(""), 12.0));
 }
 
-TEST(MATH_TEST, fminf) {
+TEST(math_h, fminf) {
   ASSERT_FLOAT_EQ(10.0f, fminf(12.0f, 10.0f));
   ASSERT_FLOAT_EQ(12.0f, fminf(12.0f, nanf("")));
   ASSERT_FLOAT_EQ(12.0f, fminf(nanf(""), 12.0f));
 }
 
-TEST(MATH_TEST, fminl) {
+TEST(math_h, fminl) {
   ASSERT_DOUBLE_EQ(10.0L, fminl(12.0L, 10.0L));
   ASSERT_DOUBLE_EQ(12.0L, fminl(12.0L, nanl("")));
   ASSERT_DOUBLE_EQ(12.0L, fminl(nanl(""), 12.0L));
 }
 
-TEST(MATH_TEST, fma) {
+TEST(math_h, fma) {
   ASSERT_DOUBLE_EQ(10.0, fma(2.0, 3.0, 4.0));
 }
 
-TEST(MATH_TEST, fmaf) {
+TEST(math_h, fmaf) {
   ASSERT_FLOAT_EQ(10.0f, fmaf(2.0f, 3.0f, 4.0f));
 }
 
-TEST(MATH_TEST, fmal) {
+TEST(math_h, fmal) {
   ASSERT_DOUBLE_EQ(10.0L, fmal(2.0L, 3.0L, 4.0L));
 }
 
-TEST(MATH_TEST, hypot) {
+TEST(math_h, hypot) {
   ASSERT_DOUBLE_EQ(5.0, hypot(3.0, 4.0));
 
   // If x or y is an infinity, returns positive infinity.
@@ -997,7 +991,7 @@
   ASSERT_TRUE(isnan(hypot(nan(""), 4.0)));
 }
 
-TEST(MATH_TEST, hypotf) {
+TEST(math_h, hypotf) {
   ASSERT_FLOAT_EQ(5.0f, hypotf(3.0f, 4.0f));
 
   // If x or y is an infinity, returns positive infinity.
@@ -1011,7 +1005,7 @@
   ASSERT_TRUE(isnanf(hypotf(nanf(""), 4.0f)));
 }
 
-TEST(MATH_TEST, hypotl) {
+TEST(math_h, hypotl) {
   ASSERT_DOUBLE_EQ(5.0L, hypotl(3.0L, 4.0L));
 
   // If x or y is an infinity, returns positive infinity.
@@ -1025,31 +1019,31 @@
   ASSERT_TRUE(isnanl(hypotl(nanl(""), 4.0L)));
 }
 
-TEST(MATH_TEST, erf) {
+TEST(math_h, erf) {
   ASSERT_DOUBLE_EQ(0.84270079294971489, erf(1.0));
 }
 
-TEST(MATH_TEST, erff) {
+TEST(math_h, erff) {
   ASSERT_FLOAT_EQ(0.84270078f, erff(1.0f));
 }
 
-TEST(MATH_TEST, erfl) {
+TEST(math_h, erfl) {
   ASSERT_DOUBLE_EQ(0.84270079294971489L, erfl(1.0L));
 }
 
-TEST(MATH_TEST, erfc) {
+TEST(math_h, erfc) {
   ASSERT_DOUBLE_EQ(0.15729920705028513, erfc(1.0));
 }
 
-TEST(MATH_TEST, erfcf) {
+TEST(math_h, erfcf) {
   ASSERT_FLOAT_EQ(0.15729921f, erfcf(1.0f));
 }
 
-TEST(MATH_TEST, erfcl) {
+TEST(math_h, erfcl) {
   ASSERT_DOUBLE_EQ(0.15729920705028513L, erfcl(1.0L));
 }
 
-TEST(MATH_TEST, lrint) {
+TEST(math_h, lrint) {
   auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
 
   fesetround(FE_UPWARD); // lrint/lrintf/lrintl obey the rounding mode.
@@ -1071,7 +1065,7 @@
   EXPECT_EQ(1234L, llrintl(1234.01L));
 }
 
-TEST(MATH_TEST, rint) {
+TEST(math_h, rint) {
   auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
 
   fesetround(FE_UPWARD); // rint/rintf/rintl obey the rounding mode.
@@ -1099,7 +1093,7 @@
   ASSERT_EQ(1234.0, rintl(1234.01L));
 }
 
-TEST(MATH_TEST, nearbyint) {
+TEST(math_h, nearbyint) {
   auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_UPWARD); // nearbyint/nearbyintf/nearbyintl obey the rounding mode.
   feclearexcept(FE_ALL_EXCEPT); // nearbyint/nearbyintf/nearbyintl don't set the FE_INEXACT flag.
@@ -1126,7 +1120,7 @@
   ASSERT_EQ(1234.0, nearbyintl(1234.01L));
 }
 
-TEST(MATH_TEST, lround) {
+TEST(math_h, lround) {
   auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_UPWARD); // lround ignores the rounding mode.
   ASSERT_EQ(1234, lround(1234.01));
@@ -1134,7 +1128,7 @@
   ASSERT_EQ(1234, lroundl(1234.01L));
 }
 
-TEST(MATH_TEST, llround) {
+TEST(math_h, llround) {
   auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_UPWARD); // llround ignores the rounding mode.
   ASSERT_EQ(1234L, llround(1234.01));
@@ -1142,7 +1136,7 @@
   ASSERT_EQ(1234L, llroundl(1234.01L));
 }
 
-TEST(MATH_TEST, ilogb) {
+TEST(math_h, ilogb) {
   ASSERT_EQ(FP_ILOGB0, ilogb(0.0));
   ASSERT_EQ(FP_ILOGBNAN, ilogb(nan("")));
   ASSERT_EQ(INT_MAX, ilogb(HUGE_VAL));
@@ -1151,7 +1145,7 @@
   ASSERT_EQ(3, ilogb(10.0));
 }
 
-TEST(MATH_TEST, ilogbf) {
+TEST(math_h, ilogbf) {
   ASSERT_EQ(FP_ILOGB0, ilogbf(0.0f));
   ASSERT_EQ(FP_ILOGBNAN, ilogbf(nanf("")));
   ASSERT_EQ(INT_MAX, ilogbf(HUGE_VALF));
@@ -1160,7 +1154,7 @@
   ASSERT_EQ(3, ilogbf(10.0f));
 }
 
-TEST(MATH_TEST, ilogbl) {
+TEST(math_h, ilogbl) {
   ASSERT_EQ(FP_ILOGB0, ilogbl(0.0L));
   ASSERT_EQ(FP_ILOGBNAN, ilogbl(nanl("")));
   ASSERT_EQ(INT_MAX, ilogbl(HUGE_VALL));
@@ -1169,7 +1163,7 @@
   ASSERT_EQ(3L, ilogbl(10.0L));
 }
 
-TEST(MATH_TEST, logb) {
+TEST(math_h, logb) {
   ASSERT_EQ(-HUGE_VAL, logb(0.0));
   ASSERT_TRUE(isnan(logb(nan(""))));
   ASSERT_TRUE(isinf(logb(HUGE_VAL)));
@@ -1178,7 +1172,7 @@
   ASSERT_EQ(3.0, logb(10.0));
 }
 
-TEST(MATH_TEST, logbf) {
+TEST(math_h, logbf) {
   ASSERT_EQ(-HUGE_VALF, logbf(0.0f));
   ASSERT_TRUE(isnanf(logbf(nanf(""))));
   ASSERT_TRUE(isinff(logbf(HUGE_VALF)));
@@ -1187,7 +1181,7 @@
   ASSERT_EQ(3.0f, logbf(10.0f));
 }
 
-TEST(MATH_TEST, logbl) {
+TEST(math_h, logbl) {
   ASSERT_EQ(-HUGE_VAL, logbl(0.0L));
   ASSERT_TRUE(isnan(logbl(nanl(""))));
   ASSERT_TRUE(isinf(logbl(HUGE_VALL)));
@@ -1196,7 +1190,7 @@
   ASSERT_EQ(3.0L, logbl(10.0L));
 }
 
-TEST(MATH_TEST, log1p) {
+TEST(math_h, log1p) {
   ASSERT_EQ(-HUGE_VAL, log1p(-1.0));
   ASSERT_TRUE(isnan(log1p(nan(""))));
   ASSERT_TRUE(isinf(log1p(HUGE_VAL)));
@@ -1204,7 +1198,7 @@
   ASSERT_DOUBLE_EQ(1.0, log1p(M_E - 1.0));
 }
 
-TEST(MATH_TEST, log1pf) {
+TEST(math_h, log1pf) {
   ASSERT_EQ(-HUGE_VALF, log1pf(-1.0f));
   ASSERT_TRUE(isnanf(log1pf(nanf(""))));
   ASSERT_TRUE(isinff(log1pf(HUGE_VALF)));
@@ -1212,7 +1206,7 @@
   ASSERT_FLOAT_EQ(1.0f, log1pf(static_cast<float>(M_E) - 1.0f));
 }
 
-TEST(MATH_TEST, log1pl) {
+TEST(math_h, log1pl) {
   ASSERT_EQ(-HUGE_VALL, log1pl(-1.0L));
   ASSERT_TRUE(isnanl(log1pl(nanl(""))));
   ASSERT_TRUE(isinfl(log1pl(HUGE_VALL)));
@@ -1220,25 +1214,25 @@
   ASSERT_DOUBLE_EQ(1.0L, log1pl(M_E - 1.0L));
 }
 
-TEST(MATH_TEST, fdim) {
+TEST(math_h, fdim) {
   ASSERT_DOUBLE_EQ(0.0, fdim(1.0, 1.0));
   ASSERT_DOUBLE_EQ(1.0, fdim(2.0, 1.0));
   ASSERT_DOUBLE_EQ(0.0, fdim(1.0, 2.0));
 }
 
-TEST(MATH_TEST, fdimf) {
+TEST(math_h, fdimf) {
   ASSERT_FLOAT_EQ(0.0f, fdimf(1.0f, 1.0f));
   ASSERT_FLOAT_EQ(1.0f, fdimf(2.0f, 1.0f));
   ASSERT_FLOAT_EQ(0.0f, fdimf(1.0f, 2.0f));
 }
 
-TEST(MATH_TEST, fdiml) {
+TEST(math_h, fdiml) {
   ASSERT_DOUBLE_EQ(0.0L, fdiml(1.0L, 1.0L));
   ASSERT_DOUBLE_EQ(1.0L, fdiml(2.0L, 1.0L));
   ASSERT_DOUBLE_EQ(0.0L, fdiml(1.0L, 2.0L));
 }
 
-TEST(MATH_TEST, round) {
+TEST(math_h, round) {
   auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_TOWARDZERO); // round ignores the rounding mode and always rounds away from zero.
   ASSERT_DOUBLE_EQ(1.0, round(0.5));
@@ -1250,7 +1244,7 @@
   ASSERT_DOUBLE_EQ(-HUGE_VAL, round(-HUGE_VAL));
 }
 
-TEST(MATH_TEST, roundf) {
+TEST(math_h, roundf) {
   auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_TOWARDZERO); // roundf ignores the rounding mode and always rounds away from zero.
   ASSERT_FLOAT_EQ(1.0f, roundf(0.5f));
@@ -1262,7 +1256,7 @@
   ASSERT_FLOAT_EQ(-HUGE_VALF, roundf(-HUGE_VALF));
 }
 
-TEST(MATH_TEST, roundl) {
+TEST(math_h, roundl) {
   auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_TOWARDZERO); // roundl ignores the rounding mode and always rounds away from zero.
   ASSERT_DOUBLE_EQ(1.0L, roundl(0.5L));
@@ -1274,7 +1268,7 @@
   ASSERT_DOUBLE_EQ(-HUGE_VALL, roundl(-HUGE_VALL));
 }
 
-TEST(MATH_TEST, trunc) {
+TEST(math_h, trunc) {
   auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_UPWARD); // trunc ignores the rounding mode and always rounds toward zero.
   ASSERT_DOUBLE_EQ(1.0, trunc(1.5));
@@ -1286,7 +1280,7 @@
   ASSERT_DOUBLE_EQ(-HUGE_VAL, trunc(-HUGE_VAL));
 }
 
-TEST(MATH_TEST, truncf) {
+TEST(math_h, truncf) {
   auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_UPWARD); // truncf ignores the rounding mode and always rounds toward zero.
   ASSERT_FLOAT_EQ(1.0f, truncf(1.5f));
@@ -1298,7 +1292,7 @@
   ASSERT_FLOAT_EQ(-HUGE_VALF, truncf(-HUGE_VALF));
 }
 
-TEST(MATH_TEST, truncl) {
+TEST(math_h, truncl) {
   auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_UPWARD); // truncl ignores the rounding mode and always rounds toward zero.
   ASSERT_DOUBLE_EQ(1.0L, truncl(1.5L));
@@ -1310,19 +1304,19 @@
   ASSERT_DOUBLE_EQ(-HUGE_VALL, truncl(-HUGE_VALL));
 }
 
-TEST(MATH_TEST, nextafter) {
+TEST(math_h, nextafter) {
   ASSERT_DOUBLE_EQ(0.0, nextafter(0.0, 0.0));
   ASSERT_DOUBLE_EQ(4.9406564584124654e-324, nextafter(0.0, 1.0));
   ASSERT_DOUBLE_EQ(-4.9406564584124654e-324, nextafter(0.0, -1.0));
 }
 
-TEST(MATH_TEST, nextafterf) {
+TEST(math_h, nextafterf) {
   ASSERT_FLOAT_EQ(0.0f, nextafterf(0.0f, 0.0f));
   ASSERT_FLOAT_EQ(1.4012985e-45f, nextafterf(0.0f, 1.0f));
   ASSERT_FLOAT_EQ(-1.4012985e-45f, nextafterf(0.0f, -1.0f));
 }
 
-TEST(MATH_TEST, nextafterl) {
+TEST(math_h, nextafterl) {
   ASSERT_DOUBLE_EQ(0.0L, nextafterl(0.0L, 0.0L));
   // Use a runtime value to accomodate the case when
   // sizeof(double) == sizeof(long double)
@@ -1331,19 +1325,19 @@
   ASSERT_DOUBLE_EQ(-smallest_positive, nextafterl(0.0L, -1.0L));
 }
 
-TEST(MATH_TEST, nexttoward) {
+TEST(math_h, nexttoward) {
   ASSERT_DOUBLE_EQ(0.0, nexttoward(0.0, 0.0L));
   ASSERT_DOUBLE_EQ(4.9406564584124654e-324, nexttoward(0.0, 1.0L));
   ASSERT_DOUBLE_EQ(-4.9406564584124654e-324, nexttoward(0.0, -1.0L));
 }
 
-TEST(MATH_TEST, nexttowardf) {
+TEST(math_h, nexttowardf) {
   ASSERT_FLOAT_EQ(0.0f, nexttowardf(0.0f, 0.0L));
   ASSERT_FLOAT_EQ(1.4012985e-45f, nexttowardf(0.0f, 1.0L));
   ASSERT_FLOAT_EQ(-1.4012985e-45f, nexttowardf(0.0f, -1.0L));
 }
 
-TEST(MATH_TEST, nexttowardl) {
+TEST(math_h, nexttowardl) {
   ASSERT_DOUBLE_EQ(0.0L, nexttowardl(0.0L, 0.0L));
   // Use a runtime value to accomodate the case when
   // sizeof(double) == sizeof(long double)
@@ -1352,40 +1346,40 @@
   ASSERT_DOUBLE_EQ(-smallest_positive, nexttowardl(0.0L, -1.0L));
 }
 
-TEST(MATH_TEST, copysign) {
+TEST(math_h, copysign) {
   ASSERT_DOUBLE_EQ(0.0, copysign(0.0, 1.0));
   ASSERT_DOUBLE_EQ(-0.0, copysign(0.0, -1.0));
   ASSERT_DOUBLE_EQ(2.0, copysign(2.0, 1.0));
   ASSERT_DOUBLE_EQ(-2.0, copysign(2.0, -1.0));
 }
 
-TEST(MATH_TEST, copysignf) {
+TEST(math_h, copysignf) {
   ASSERT_FLOAT_EQ(0.0f, copysignf(0.0f, 1.0f));
   ASSERT_FLOAT_EQ(-0.0f, copysignf(0.0f, -1.0f));
   ASSERT_FLOAT_EQ(2.0f, copysignf(2.0f, 1.0f));
   ASSERT_FLOAT_EQ(-2.0f, copysignf(2.0f, -1.0f));
 }
 
-TEST(MATH_TEST, copysignl) {
+TEST(math_h, copysignl) {
   ASSERT_DOUBLE_EQ(0.0L, copysignl(0.0L, 1.0L));
   ASSERT_DOUBLE_EQ(-0.0L, copysignl(0.0L, -1.0L));
   ASSERT_DOUBLE_EQ(2.0L, copysignl(2.0L, 1.0L));
   ASSERT_DOUBLE_EQ(-2.0L, copysignl(2.0L, -1.0L));
 }
 
-TEST(MATH_TEST, significand) {
+TEST(math_h, significand) {
   ASSERT_DOUBLE_EQ(0.0, significand(0.0));
   ASSERT_DOUBLE_EQ(1.2, significand(1.2));
   ASSERT_DOUBLE_EQ(1.53125, significand(12.25));
 }
 
-TEST(MATH_TEST, significandf) {
+TEST(math_h, significandf) {
   ASSERT_FLOAT_EQ(0.0f, significandf(0.0f));
   ASSERT_FLOAT_EQ(1.2f, significandf(1.2f));
   ASSERT_FLOAT_EQ(1.53125f, significandf(12.25f));
 }
 
-TEST(MATH_TEST, significandl) {
+TEST(math_h, significandl) {
 #if !defined(ANDROID_HOST_MUSL)
   ASSERT_DOUBLE_EQ(0.0L, significandl(0.0L));
   ASSERT_DOUBLE_EQ(1.2L, significandl(1.2L));
@@ -1395,40 +1389,39 @@
 #endif
 }
 
-
-TEST(MATH_TEST, scalb) {
+TEST(math_h, scalb) {
   ASSERT_DOUBLE_EQ(12.0, scalb(3.0, 2.0));
 }
 
-TEST(MATH_TEST, scalbf) {
+TEST(math_h, scalbf) {
   ASSERT_FLOAT_EQ(12.0f, scalbf(3.0f, 2.0f));
 }
 
-TEST(MATH_TEST, scalbln) {
+TEST(math_h, scalbln) {
   ASSERT_DOUBLE_EQ(12.0, scalbln(3.0, 2L));
 }
 
-TEST(MATH_TEST, scalblnf) {
+TEST(math_h, scalblnf) {
   ASSERT_FLOAT_EQ(12.0f, scalblnf(3.0f, 2L));
 }
 
-TEST(MATH_TEST, scalblnl) {
+TEST(math_h, scalblnl) {
   ASSERT_DOUBLE_EQ(12.0L, scalblnl(3.0L, 2L));
 }
 
-TEST(MATH_TEST, scalbn) {
+TEST(math_h, scalbn) {
   ASSERT_DOUBLE_EQ(12.0, scalbn(3.0, 2));
 }
 
-TEST(MATH_TEST, scalbnf) {
+TEST(math_h, scalbnf) {
   ASSERT_FLOAT_EQ(12.0f, scalbnf(3.0f, 2));
 }
 
-TEST(MATH_TEST, scalbnl) {
+TEST(math_h, scalbnl) {
   ASSERT_DOUBLE_EQ(12.0L, scalbnl(3.0L, 2));
 }
 
-TEST(MATH_TEST, gamma) {
+TEST(math_h, gamma) {
 #if !defined(ANDROID_HOST_MUSL)
   ASSERT_DOUBLE_EQ(log(24.0), gamma(5.0));
 #else
@@ -1436,7 +1429,7 @@
 #endif
 }
 
-TEST(MATH_TEST, gammaf) {
+TEST(math_h, gammaf) {
 #if !defined(ANDROID_HOST_MUSL)
   ASSERT_FLOAT_EQ(logf(24.0f), gammaf(5.0f));
 #else
@@ -1444,7 +1437,7 @@
 #endif
 }
 
-TEST(MATH_TEST, gamma_r) {
+TEST(math_h, gamma_r) {
 #if defined(__BIONIC__)
   int sign;
   ASSERT_DOUBLE_EQ(log(24.0), gamma_r(5.0, &sign));
@@ -1454,7 +1447,7 @@
 #endif // __BIONIC__
 }
 
-TEST(MATH_TEST, gammaf_r) {
+TEST(math_h, gammaf_r) {
 #if defined(__BIONIC__)
   int sign;
   ASSERT_FLOAT_EQ(logf(24.0f), gammaf_r(5.0f, &sign));
@@ -1464,25 +1457,25 @@
 #endif // __BIONIC__
 }
 
-TEST(MATH_TEST, lgamma) {
+TEST(math_h, lgamma) {
   ASSERT_DOUBLE_EQ(log(24.0), lgamma(5.0));
 }
 
-TEST(MATH_TEST, lgammaf) {
+TEST(math_h, lgammaf) {
   ASSERT_FLOAT_EQ(logf(24.0f), lgammaf(5.0f));
 }
 
-TEST(MATH_TEST, lgammal) {
+TEST(math_h, lgammal) {
   ASSERT_DOUBLE_EQ(logl(24.0L), lgammal(5.0L));
 }
 
-TEST(MATH_TEST, lgamma_r) {
+TEST(math_h, lgamma_r) {
   int sign;
   ASSERT_DOUBLE_EQ(log(24.0), lgamma_r(5.0, &sign));
   ASSERT_EQ(1, sign);
 }
 
-TEST(MATH_TEST, lgamma_r_17471883) {
+TEST(math_h, lgamma_r_17471883) {
   int sign;
 
   sign = 0;
@@ -1493,13 +1486,13 @@
   ASSERT_EQ(-1, sign);
 }
 
-TEST(MATH_TEST, lgammaf_r) {
+TEST(math_h, lgammaf_r) {
   int sign;
   ASSERT_FLOAT_EQ(logf(24.0f), lgammaf_r(5.0f, &sign));
   ASSERT_EQ(1, sign);
 }
 
-TEST(MATH_TEST, lgammaf_r_17471883) {
+TEST(math_h, lgammaf_r_17471883) {
   int sign;
 
   sign = 0;
@@ -1510,13 +1503,13 @@
   ASSERT_EQ(-1, sign);
 }
 
-TEST(MATH_TEST, lgammal_r) {
+TEST(math_h, lgammal_r) {
   int sign;
   ASSERT_DOUBLE_EQ(log(24.0L), lgamma_r(5.0L, &sign));
   ASSERT_EQ(1, sign);
 }
 
-TEST(MATH_TEST, lgammal_r_17471883) {
+TEST(math_h, lgammal_r_17471883) {
   int sign;
 
   sign = 0;
@@ -1527,142 +1520,142 @@
   ASSERT_EQ(-1, sign);
 }
 
-TEST(MATH_TEST, tgamma_NaN) {
+TEST(math_h, tgamma_NaN) {
   ASSERT_TRUE(isnan(tgamma(nan(""))));
   ASSERT_TRUE(isnanf(tgammaf(nanf(""))));
   ASSERT_TRUE(isnanl(tgammal(nanl(""))));
 }
 
-TEST(MATH_TEST, tgamma_inf) {
+TEST(math_h, tgamma_inf) {
   ASSERT_TRUE(isinf(tgamma(HUGE_VAL)));
   ASSERT_TRUE(isinff(tgammaf(HUGE_VALF)));
   ASSERT_TRUE(isinfl(tgammal(HUGE_VALL)));
 }
 
-TEST(MATH_TEST, tgamma_negative) {
+TEST(math_h, tgamma_negative) {
   ASSERT_TRUE(isnan(tgamma(-1.0)));
   ASSERT_TRUE(isnanf(tgammaf(-1.0f)));
   ASSERT_TRUE(isnanl(tgammal(-1.0L)));
 }
 
-TEST(MATH_TEST, tgamma) {
+TEST(math_h, tgamma) {
   ASSERT_DOUBLE_EQ(24.0, tgamma(5.0));
   ASSERT_DOUBLE_EQ(120.0, tgamma(6.0));
   ASSERT_TRUE(isinf(tgamma(172.0)));
 }
 
-TEST(MATH_TEST, tgammaf) {
+TEST(math_h, tgammaf) {
   ASSERT_FLOAT_EQ(24.0f, tgammaf(5.0f));
   ASSERT_FLOAT_EQ(120.0f, tgammaf(6.0f));
   ASSERT_TRUE(isinff(tgammaf(172.0f)));
 }
 
-TEST(MATH_TEST, tgammal) {
+TEST(math_h, tgammal) {
   ASSERT_DOUBLE_EQ(24.0L, tgammal(5.0L));
   ASSERT_DOUBLE_EQ(120.0L, tgammal(6.0L));
   ASSERT_TRUE(isinf(tgammal(172.0L)));
 }
 
-TEST(MATH_TEST, j0) {
+TEST(math_h, j0) {
   ASSERT_DOUBLE_EQ(1.0, j0(0.0));
   ASSERT_DOUBLE_EQ(0.76519768655796661, j0(1.0));
 }
 
-TEST(MATH_TEST, j0f) {
+TEST(math_h, j0f) {
   ASSERT_FLOAT_EQ(1.0f, j0f(0.0f));
   ASSERT_FLOAT_EQ(0.76519769f, j0f(1.0f));
 }
 
-TEST(MATH_TEST, j1) {
+TEST(math_h, j1) {
   ASSERT_DOUBLE_EQ(0.0, j1(0.0));
   ASSERT_DOUBLE_EQ(0.44005058574493355, j1(1.0));
 }
 
-TEST(MATH_TEST, j1f) {
+TEST(math_h, j1f) {
   ASSERT_FLOAT_EQ(0.0f, j1f(0.0f));
   ASSERT_FLOAT_EQ(0.44005057f, j1f(1.0f));
 }
 
-TEST(MATH_TEST, jn) {
+TEST(math_h, jn) {
   ASSERT_DOUBLE_EQ(0.0, jn(4, 0.0));
   ASSERT_DOUBLE_EQ(0.0024766389641099553, jn(4, 1.0));
 }
 
-TEST(MATH_TEST, jnf) {
+TEST(math_h, jnf) {
   ASSERT_FLOAT_EQ(0.0f, jnf(4, 0.0f));
   ASSERT_FLOAT_EQ(0.0024766389f, jnf(4, 1.0f));
 }
 
-TEST(MATH_TEST, y0) {
+TEST(math_h, y0) {
   ASSERT_DOUBLE_EQ(-HUGE_VAL, y0(0.0));
   ASSERT_DOUBLE_EQ(0.08825696421567697, y0(1.0));
 }
 
-TEST(MATH_TEST, y0f) {
+TEST(math_h, y0f) {
   ASSERT_FLOAT_EQ(-HUGE_VALF, y0f(0.0f));
   ASSERT_FLOAT_EQ(0.088256963f, y0f(1.0f));
 }
 
-TEST(MATH_TEST, y1) {
+TEST(math_h, y1) {
   ASSERT_DOUBLE_EQ(-HUGE_VAL, y1(0.0));
   ASSERT_DOUBLE_EQ(-0.78121282130028868, y1(1.0));
 }
 
-TEST(MATH_TEST, y1f) {
+TEST(math_h, y1f) {
   ASSERT_FLOAT_EQ(-HUGE_VALF, y1f(0.0f));
   ASSERT_FLOAT_EQ(-0.78121281f, y1f(1.0f));
 }
 
-TEST(MATH_TEST, yn) {
+TEST(math_h, yn) {
   ASSERT_DOUBLE_EQ(-HUGE_VAL, yn(4, 0.0));
   ASSERT_DOUBLE_EQ(-33.278423028972114, yn(4, 1.0));
 }
 
-TEST(MATH_TEST, ynf) {
+TEST(math_h, ynf) {
   ASSERT_FLOAT_EQ(-HUGE_VALF, ynf(4, 0.0f));
   ASSERT_FLOAT_EQ(-33.278423f, ynf(4, 1.0f));
 }
 
-TEST(MATH_TEST, frexp) {
+TEST(math_h, frexp) {
   int exp;
   double dr = frexp(1024.0, &exp);
   ASSERT_DOUBLE_EQ(1024.0, scalbn(dr, exp));
 }
 
-TEST(MATH_TEST, frexpf) {
+TEST(math_h, frexpf) {
   int exp;
   float fr = frexpf(1024.0f, &exp);
   ASSERT_FLOAT_EQ(1024.0f, scalbnf(fr, exp));
 }
 
-TEST(MATH_TEST, frexpl) {
+TEST(math_h, frexpl) {
   int exp;
   long double ldr = frexpl(1024.0L, &exp);
   ASSERT_DOUBLE_EQ(1024.0L, scalbnl(ldr, exp));
 }
 
-TEST(MATH_TEST, modf) {
+TEST(math_h, modf) {
   double di;
   double df = modf(123.75, &di);
   ASSERT_DOUBLE_EQ(123.0, di);
   ASSERT_DOUBLE_EQ(0.75, df);
 }
 
-TEST(MATH_TEST, modff) {
+TEST(math_h, modff) {
   float fi;
   float ff = modff(123.75f, &fi);
   ASSERT_FLOAT_EQ(123.0f, fi);
   ASSERT_FLOAT_EQ(0.75f, ff);
 }
 
-TEST(MATH_TEST, modfl) {
+TEST(math_h, modfl) {
   long double ldi;
   long double ldf = modfl(123.75L, &ldi);
   ASSERT_DOUBLE_EQ(123.0L, ldi);
   ASSERT_DOUBLE_EQ(0.75L, ldf);
 }
 
-TEST(MATH_TEST, remquo) {
+TEST(math_h, remquo) {
   int q;
   double d = remquo(13.0, 4.0, &q);
   ASSERT_EQ(3, q);
@@ -1680,7 +1673,7 @@
   ASSERT_TRUE(isnan(remquo(12.0, 0.0, &q)));
 }
 
-TEST(MATH_TEST, remquof) {
+TEST(math_h, remquof) {
   int q;
   float f = remquof(13.0f, 4.0f, &q);
   ASSERT_EQ(3, q);
@@ -1698,7 +1691,7 @@
   ASSERT_TRUE(isnanf(remquof(12.0f, 0.0f, &q)));
 }
 
-TEST(MATH_TEST, remquol) {
+TEST(math_h, remquol) {
   int q;
   long double ld = remquol(13.0L, 4.0L, &q);
   ASSERT_DOUBLE_EQ(3L, q);
@@ -1717,13 +1710,13 @@
 }
 
 // https://code.google.com/p/android/issues/detail?id=6697
-TEST(MATH_TEST, frexpf_public_bug_6697) {
+TEST(math_h, frexpf_public_bug_6697) {
   int exp;
   float fr = frexpf(14.1f, &exp);
   ASSERT_FLOAT_EQ(14.1f, scalbnf(fr, exp));
 }
 
-TEST(MATH_TEST, exp2_STRICT_ALIGN_OpenBSD_bug) {
+TEST(math_h, exp2_STRICT_ALIGN_OpenBSD_bug) {
   // OpenBSD/x86's libm had a bug here, but it was already fixed in FreeBSD:
   // http://svnweb.FreeBSD.org/base/head/lib/msun/src/math_private.h?revision=240827&view=markup
   ASSERT_DOUBLE_EQ(5.0, exp2(log2(5)));
@@ -1731,7 +1724,7 @@
   ASSERT_DOUBLE_EQ(5.0L, exp2l(log2l(5)));
 }
 
-TEST(MATH_TEST, nextafterl_OpenBSD_bug) {
+TEST(math_h, nextafterl_OpenBSD_bug) {
   // OpenBSD/x86's libm had a bug here.
   ASSERT_TRUE(nextafter(1.0, 0.0) - 1.0 < 0.0);
   ASSERT_TRUE(nextafterf(1.0f, 0.0f) - 1.0f < 0.0f);
@@ -1739,511 +1732,511 @@
 }
 
 #include "math_data/acos_intel_data.h"
-TEST(MATH_TEST, acos_intel) {
+TEST(math_h, acos_intel) {
   DoMathDataTest<1>(g_acos_intel_data, acos);
 }
 
 #include "math_data/acosf_intel_data.h"
-TEST(MATH_TEST, acosf_intel) {
+TEST(math_h, acosf_intel) {
   DoMathDataTest<1>(g_acosf_intel_data, acosf);
 }
 
 #include "math_data/acosh_intel_data.h"
-TEST(MATH_TEST, acosh_intel) {
+TEST(math_h, acosh_intel) {
   DoMathDataTest<2>(g_acosh_intel_data, acosh);
 }
 
 #include "math_data/acoshf_intel_data.h"
-TEST(MATH_TEST, acoshf_intel) {
+TEST(math_h, acoshf_intel) {
   DoMathDataTest<2>(g_acoshf_intel_data, acoshf);
 }
 
 #include "math_data/asin_intel_data.h"
-TEST(MATH_TEST, asin_intel) {
+TEST(math_h, asin_intel) {
   DoMathDataTest<1>(g_asin_intel_data, asin);
 }
 
 #include "math_data/asinf_intel_data.h"
-TEST(MATH_TEST, asinf_intel) {
+TEST(math_h, asinf_intel) {
   DoMathDataTest<1>(g_asinf_intel_data, asinf);
 }
 
 #include "math_data/asinh_intel_data.h"
-TEST(MATH_TEST, asinh_intel) {
+TEST(math_h, asinh_intel) {
   DoMathDataTest<2>(g_asinh_intel_data, asinh);
 }
 
 #include "math_data/asinhf_intel_data.h"
-TEST(MATH_TEST, asinhf_intel) {
+TEST(math_h, asinhf_intel) {
   DoMathDataTest<2>(g_asinhf_intel_data, asinhf);
 }
 
 #include "math_data/atan2_intel_data.h"
-TEST(MATH_TEST, atan2_intel) {
+TEST(math_h, atan2_intel) {
   DoMathDataTest<2>(g_atan2_intel_data, atan2);
 }
 
 #include "math_data/atan2f_intel_data.h"
-TEST(MATH_TEST, atan2f_intel) {
+TEST(math_h, atan2f_intel) {
   DoMathDataTest<2>(g_atan2f_intel_data, atan2f);
 }
 
 #include "math_data/atan_intel_data.h"
-TEST(MATH_TEST, atan_intel) {
+TEST(math_h, atan_intel) {
   DoMathDataTest<1>(g_atan_intel_data, atan);
 }
 
 #include "math_data/atanf_intel_data.h"
-TEST(MATH_TEST, atanf_intel) {
+TEST(math_h, atanf_intel) {
   DoMathDataTest<1>(g_atanf_intel_data, atanf);
 }
 
 #include "math_data/atanh_intel_data.h"
-TEST(MATH_TEST, atanh_intel) {
+TEST(math_h, atanh_intel) {
   DoMathDataTest<2>(g_atanh_intel_data, atanh);
 }
 
 #include "math_data/atanhf_intel_data.h"
-TEST(MATH_TEST, atanhf_intel) {
+TEST(math_h, atanhf_intel) {
   DoMathDataTest<2>(g_atanhf_intel_data, atanhf);
 }
 
 #include "math_data/cbrt_intel_data.h"
-TEST(MATH_TEST, cbrt_intel) {
+TEST(math_h, cbrt_intel) {
   DoMathDataTest<1>(g_cbrt_intel_data, cbrt);
 }
 
 #include "math_data/cbrtf_intel_data.h"
-TEST(MATH_TEST, cbrtf_intel) {
+TEST(math_h, cbrtf_intel) {
   DoMathDataTest<1>(g_cbrtf_intel_data, cbrtf);
 }
 
 #include "math_data/ceil_intel_data.h"
-TEST(MATH_TEST, ceil_intel) {
+TEST(math_h, ceil_intel) {
   DoMathDataTest<1>(g_ceil_intel_data, ceil);
 }
 
 #include "math_data/ceilf_intel_data.h"
-TEST(MATH_TEST, ceilf_intel) {
+TEST(math_h, ceilf_intel) {
   DoMathDataTest<1>(g_ceilf_intel_data, ceilf);
 }
 
 #include "math_data/copysign_intel_data.h"
-TEST(MATH_TEST, copysign_intel) {
+TEST(math_h, copysign_intel) {
   DoMathDataTest<1>(g_copysign_intel_data, copysign);
 }
 
 #include "math_data/copysignf_intel_data.h"
-TEST(MATH_TEST, copysignf_intel) {
+TEST(math_h, copysignf_intel) {
   DoMathDataTest<1>(g_copysignf_intel_data, copysignf);
 }
 
 #include "math_data/cos_intel_data.h"
-TEST(MATH_TEST, cos_intel) {
+TEST(math_h, cos_intel) {
   DoMathDataTest<1>(g_cos_intel_data, cos);
 }
 
 #include "math_data/cosf_intel_data.h"
-TEST(MATH_TEST, cosf_intel) {
+TEST(math_h, cosf_intel) {
   DoMathDataTest<1>(g_cosf_intel_data, cosf);
 }
 
 #include "math_data/cosh_intel_data.h"
-TEST(MATH_TEST, cosh_intel) {
+TEST(math_h, cosh_intel) {
   DoMathDataTest<2>(g_cosh_intel_data, cosh);
 }
 
 #include "math_data/coshf_intel_data.h"
-TEST(MATH_TEST, coshf_intel) {
+TEST(math_h, coshf_intel) {
   DoMathDataTest<2>(g_coshf_intel_data, coshf);
 }
 
 #include "math_data/exp_intel_data.h"
-TEST(MATH_TEST, exp_intel) {
+TEST(math_h, exp_intel) {
   DoMathDataTest<1>(g_exp_intel_data, exp);
 }
 
 #include "math_data/expf_intel_data.h"
-TEST(MATH_TEST, expf_intel) {
+TEST(math_h, expf_intel) {
   DoMathDataTest<1>(g_expf_intel_data, expf);
 }
 
 #include "math_data/exp2_intel_data.h"
-TEST(MATH_TEST, exp2_intel) {
+TEST(math_h, exp2_intel) {
   DoMathDataTest<1>(g_exp2_intel_data, exp2);
 }
 
 #include "math_data/exp2f_intel_data.h"
-TEST(MATH_TEST, exp2f_intel) {
+TEST(math_h, exp2f_intel) {
   DoMathDataTest<1>(g_exp2f_intel_data, exp2f);
 }
 
 #include "math_data/expm1_intel_data.h"
-TEST(MATH_TEST, expm1_intel) {
+TEST(math_h, expm1_intel) {
   DoMathDataTest<1>(g_expm1_intel_data, expm1);
 }
 
 #include "math_data/expm1f_intel_data.h"
-TEST(MATH_TEST, expm1f_intel) {
+TEST(math_h, expm1f_intel) {
   DoMathDataTest<1>(g_expm1f_intel_data, expm1f);
 }
 
 #include "math_data/fabs_intel_data.h"
-TEST(MATH_TEST, fabs_intel) {
+TEST(math_h, fabs_intel) {
   DoMathDataTest<1>(g_fabs_intel_data, fabs);
 }
 
 #include "math_data/fabsf_intel_data.h"
-TEST(MATH_TEST, fabsf_intel) {
+TEST(math_h, fabsf_intel) {
   DoMathDataTest<1>(g_fabsf_intel_data, fabsf);
 }
 
 #include "math_data/fdim_intel_data.h"
-TEST(MATH_TEST, fdim_intel) {
+TEST(math_h, fdim_intel) {
   DoMathDataTest<1>(g_fdim_intel_data, fdim);
 }
 
 #include "math_data/fdimf_intel_data.h"
-TEST(MATH_TEST, fdimf_intel) {
+TEST(math_h, fdimf_intel) {
   DoMathDataTest<1>(g_fdimf_intel_data, fdimf);
 }
 
 #include "math_data/floor_intel_data.h"
-TEST(MATH_TEST, floor_intel) {
+TEST(math_h, floor_intel) {
   DoMathDataTest<1>(g_floor_intel_data, floor);
 }
 
 #include "math_data/floorf_intel_data.h"
-TEST(MATH_TEST, floorf_intel) {
+TEST(math_h, floorf_intel) {
   DoMathDataTest<1>(g_floorf_intel_data, floorf);
 }
 
 #include "math_data/fma_intel_data.h"
-TEST(MATH_TEST, fma_intel) {
+TEST(math_h, fma_intel) {
   DoMathDataTest<1>(g_fma_intel_data, fma);
 }
 
 #include "math_data/fmaf_intel_data.h"
-TEST(MATH_TEST, fmaf_intel) {
+TEST(math_h, fmaf_intel) {
   DoMathDataTest<1>(g_fmaf_intel_data, fmaf);
 }
 
 #include "math_data/fmax_intel_data.h"
-TEST(MATH_TEST, fmax_intel) {
+TEST(math_h, fmax_intel) {
   DoMathDataTest<1>(g_fmax_intel_data, fmax);
 }
 
 #include "math_data/fmaxf_intel_data.h"
-TEST(MATH_TEST, fmaxf_intel) {
+TEST(math_h, fmaxf_intel) {
   DoMathDataTest<1>(g_fmaxf_intel_data, fmaxf);
 }
 
 #include "math_data/fmin_intel_data.h"
-TEST(MATH_TEST, fmin_intel) {
+TEST(math_h, fmin_intel) {
   DoMathDataTest<1>(g_fmin_intel_data, fmin);
 }
 
 #include "math_data/fminf_intel_data.h"
-TEST(MATH_TEST, fminf_intel) {
+TEST(math_h, fminf_intel) {
   DoMathDataTest<1>(g_fminf_intel_data, fminf);
 }
 
 #include "math_data/fmod_intel_data.h"
-TEST(MATH_TEST, fmod_intel) {
+TEST(math_h, fmod_intel) {
   DoMathDataTest<1>(g_fmod_intel_data, fmod);
 }
 
 #include "math_data/fmodf_intel_data.h"
-TEST(MATH_TEST, fmodf_intel) {
+TEST(math_h, fmodf_intel) {
   DoMathDataTest<1>(g_fmodf_intel_data, fmodf);
 }
 
 #include "math_data/frexp_intel_data.h"
-TEST(MATH_TEST, frexp_intel) {
+TEST(math_h, frexp_intel) {
   DoMathDataTest<1>(g_frexp_intel_data, frexp);
 }
 
 #include "math_data/frexpf_intel_data.h"
-TEST(MATH_TEST, frexpf_intel) {
+TEST(math_h, frexpf_intel) {
   DoMathDataTest<1>(g_frexpf_intel_data, frexpf);
 }
 
 #include "math_data/hypot_intel_data.h"
-TEST(MATH_TEST, hypot_intel) {
+TEST(math_h, hypot_intel) {
   DoMathDataTest<1>(g_hypot_intel_data, hypot);
 }
 
 #include "math_data/hypotf_intel_data.h"
-TEST(MATH_TEST, hypotf_intel) {
+TEST(math_h, hypotf_intel) {
   DoMathDataTest<1>(g_hypotf_intel_data, hypotf);
 }
 
 #include "math_data/ilogb_intel_data.h"
-TEST(MATH_TEST, ilogb_intel) {
+TEST(math_h, ilogb_intel) {
   DoMathDataTest<1>(g_ilogb_intel_data, ilogb);
 }
 
 #include "math_data/ilogbf_intel_data.h"
-TEST(MATH_TEST, ilogbf_intel) {
+TEST(math_h, ilogbf_intel) {
   DoMathDataTest<1>(g_ilogbf_intel_data, ilogbf);
 }
 
 #include "math_data/ldexp_intel_data.h"
-TEST(MATH_TEST, ldexp_intel) {
+TEST(math_h, ldexp_intel) {
   DoMathDataTest<1>(g_ldexp_intel_data, ldexp);
 }
 
 #include "math_data/ldexpf_intel_data.h"
-TEST(MATH_TEST, ldexpf_intel) {
+TEST(math_h, ldexpf_intel) {
   DoMathDataTest<1>(g_ldexpf_intel_data, ldexpf);
 }
 
 #include "math_data/llrint_intel_data.h"
-TEST(MATH_TEST, llrint_intel) {
+TEST(math_h, llrint_intel) {
   DoMathDataTest<1>(g_llrint_intel_data, llrint);
 }
 
 #include "math_data/llrintf_intel_data.h"
-TEST(MATH_TEST, llrintf_intel) {
+TEST(math_h, llrintf_intel) {
   DoMathDataTest<1>(g_llrintf_intel_data, llrintf);
 }
 
 #include "math_data/log_intel_data.h"
-TEST(MATH_TEST, log_intel) {
+TEST(math_h, log_intel) {
   DoMathDataTest<1>(g_log_intel_data, log);
 }
 
 #include "math_data/logf_intel_data.h"
-TEST(MATH_TEST, logf_intel) {
+TEST(math_h, logf_intel) {
   DoMathDataTest<1>(g_logf_intel_data, logf);
 }
 
 #include "math_data/log10_intel_data.h"
-TEST(MATH_TEST, log10_intel) {
+TEST(math_h, log10_intel) {
   DoMathDataTest<1>(g_log10_intel_data, log10);
 }
 
 #include "math_data/log10f_intel_data.h"
-TEST(MATH_TEST, log10f_intel) {
+TEST(math_h, log10f_intel) {
   DoMathDataTest<1>(g_log10f_intel_data, log10f);
 }
 
 #include "math_data/log1p_intel_data.h"
-TEST(MATH_TEST, log1p_intel) {
+TEST(math_h, log1p_intel) {
   DoMathDataTest<1>(g_log1p_intel_data, log1p);
 }
 
 #include "math_data/log1pf_intel_data.h"
-TEST(MATH_TEST, log1pf_intel) {
+TEST(math_h, log1pf_intel) {
   DoMathDataTest<1>(g_log1pf_intel_data, log1pf);
 }
 
 #include "math_data/log2_intel_data.h"
-TEST(MATH_TEST, log2_intel) {
+TEST(math_h, log2_intel) {
   DoMathDataTest<1>(g_log2_intel_data, log2);
 }
 
 #include "math_data/log2f_intel_data.h"
-TEST(MATH_TEST, log2f_intel) {
+TEST(math_h, log2f_intel) {
   DoMathDataTest<1>(g_log2f_intel_data, log2f);
 }
 
 #include "math_data/logb_intel_data.h"
-TEST(MATH_TEST, logb_intel) {
+TEST(math_h, logb_intel) {
   DoMathDataTest<1>(g_logb_intel_data, logb);
 }
 
 #include "math_data/logbf_intel_data.h"
-TEST(MATH_TEST, logbf_intel) {
+TEST(math_h, logbf_intel) {
   DoMathDataTest<1>(g_logbf_intel_data, logbf);
 }
 
 #include "math_data/lrint_intel_data.h"
-TEST(MATH_TEST, lrint_intel) {
+TEST(math_h, lrint_intel) {
   DoMathDataTest<1>(g_lrint_intel_data, lrint);
 }
 
 #include "math_data/lrintf_intel_data.h"
-TEST(MATH_TEST, lrintf_intel) {
+TEST(math_h, lrintf_intel) {
   DoMathDataTest<1>(g_lrintf_intel_data, lrintf);
 }
 
 #include "math_data/modf_intel_data.h"
-TEST(MATH_TEST, modf_intel) {
+TEST(math_h, modf_intel) {
   DoMathDataTest<1>(g_modf_intel_data, modf);
 }
 
 #include "math_data/modff_intel_data.h"
-TEST(MATH_TEST, modff_intel) {
+TEST(math_h, modff_intel) {
   DoMathDataTest<1>(g_modff_intel_data, modff);
 }
 
 #include "math_data/nearbyint_intel_data.h"
-TEST(MATH_TEST, nearbyint_intel) {
+TEST(math_h, nearbyint_intel) {
   DoMathDataTest<1>(g_nearbyint_intel_data, nearbyint);
 }
 
 #include "math_data/nearbyintf_intel_data.h"
-TEST(MATH_TEST, nearbyintf_intel) {
+TEST(math_h, nearbyintf_intel) {
   DoMathDataTest<1>(g_nearbyintf_intel_data, nearbyintf);
 }
 
 #include "math_data/nextafter_intel_data.h"
-TEST(MATH_TEST, nextafter_intel) {
+TEST(math_h, nextafter_intel) {
   DoMathDataTest<1>(g_nextafter_intel_data, nextafter);
 }
 
 #include "math_data/nextafterf_intel_data.h"
-TEST(MATH_TEST, nextafterf_intel) {
+TEST(math_h, nextafterf_intel) {
   DoMathDataTest<1>(g_nextafterf_intel_data, nextafterf);
 }
 
 #include "math_data/pow_intel_data.h"
-TEST(MATH_TEST, pow_intel) {
+TEST(math_h, pow_intel) {
   DoMathDataTest<1>(g_pow_intel_data, pow);
 }
 
 #include "math_data/powf_intel_data.h"
-TEST(MATH_TEST, powf_intel) {
+TEST(math_h, powf_intel) {
   DoMathDataTest<1>(g_powf_intel_data, powf);
 }
 
 #include "math_data/remainder_intel_data.h"
-TEST(MATH_TEST, remainder_intel) {
+TEST(math_h, remainder_intel) {
   DoMathDataTest<1>(g_remainder_intel_data, remainder);
 }
 
 #include "math_data/remainderf_intel_data.h"
-TEST(MATH_TEST, remainderf_intel) {
+TEST(math_h, remainderf_intel) {
   DoMathDataTest<1>(g_remainderf_intel_data, remainderf);
 }
 
 #include "math_data/remquo_intel_data.h"
-TEST(MATH_TEST, remquo_intel) {
+TEST(math_h, remquo_intel) {
   DoMathDataTest<1>(g_remquo_intel_data, remquo);
 }
 
 #include "math_data/remquof_intel_data.h"
-TEST(MATH_TEST, remquof_intel) {
+TEST(math_h, remquof_intel) {
   DoMathDataTest<1>(g_remquof_intel_data, remquof);
 }
 
 #include "math_data/rint_intel_data.h"
-TEST(MATH_TEST, rint_intel) {
+TEST(math_h, rint_intel) {
   DoMathDataTest<1>(g_rint_intel_data, rint);
 }
 
 #include "math_data/rintf_intel_data.h"
-TEST(MATH_TEST, rintf_intel) {
+TEST(math_h, rintf_intel) {
   DoMathDataTest<1>(g_rintf_intel_data, rintf);
 }
 
 #include "math_data/round_intel_data.h"
-TEST(MATH_TEST, round_intel) {
+TEST(math_h, round_intel) {
   DoMathDataTest<1>(g_round_intel_data, round);
 }
 
 #include "math_data/roundf_intel_data.h"
-TEST(MATH_TEST, roundf_intel) {
+TEST(math_h, roundf_intel) {
   DoMathDataTest<1>(g_roundf_intel_data, roundf);
 }
 
 #include "math_data/scalb_intel_data.h"
-TEST(MATH_TEST, scalb_intel) {
+TEST(math_h, scalb_intel) {
   DoMathDataTest<1>(g_scalb_intel_data, scalb);
 }
 
 #include "math_data/scalbf_intel_data.h"
-TEST(MATH_TEST, scalbf_intel) {
+TEST(math_h, scalbf_intel) {
   DoMathDataTest<1>(g_scalbf_intel_data, scalbf);
 }
 
 #include "math_data/scalbn_intel_data.h"
-TEST(MATH_TEST, scalbn_intel) {
+TEST(math_h, scalbn_intel) {
   DoMathDataTest<1>(g_scalbn_intel_data, scalbn);
 }
 
 #include "math_data/scalbnf_intel_data.h"
-TEST(MATH_TEST, scalbnf_intel) {
+TEST(math_h, scalbnf_intel) {
   DoMathDataTest<1>(g_scalbnf_intel_data, scalbnf);
 }
 
 #include "math_data/significand_intel_data.h"
-TEST(MATH_TEST, significand_intel) {
+TEST(math_h, significand_intel) {
   DoMathDataTest<1>(g_significand_intel_data, significand);
 }
 
 #include "math_data/significandf_intel_data.h"
-TEST(MATH_TEST, significandf_intel) {
+TEST(math_h, significandf_intel) {
   DoMathDataTest<1>(g_significandf_intel_data, significandf);
 }
 
 #include "math_data/sin_intel_data.h"
-TEST(MATH_TEST, sin_intel) {
+TEST(math_h, sin_intel) {
   DoMathDataTest<1>(g_sin_intel_data, sin);
 }
 
 #include "math_data/sinf_intel_data.h"
-TEST(MATH_TEST, sinf_intel) {
+TEST(math_h, sinf_intel) {
   DoMathDataTest<1>(g_sinf_intel_data, sinf);
 }
 
 #include "math_data/sinh_intel_data.h"
-TEST(MATH_TEST, sinh_intel) {
+TEST(math_h, sinh_intel) {
   DoMathDataTest<2>(g_sinh_intel_data, sinh);
 }
 
 #include "math_data/sinhf_intel_data.h"
-TEST(MATH_TEST, sinhf_intel) {
+TEST(math_h, sinhf_intel) {
   DoMathDataTest<2>(g_sinhf_intel_data, sinhf);
 }
 
 #include "math_data/sincos_intel_data.h"
-TEST(MATH_TEST, sincos_intel) {
+TEST(math_h, sincos_intel) {
   DoMathDataTest<1>(g_sincos_intel_data, sincos);
 }
 
 #include "math_data/sincosf_intel_data.h"
-TEST(MATH_TEST, sincosf_intel) {
+TEST(math_h, sincosf_intel) {
   DoMathDataTest<1>(g_sincosf_intel_data, sincosf);
 }
 
 #include "math_data/sqrt_intel_data.h"
-TEST(MATH_TEST, sqrt_intel) {
+TEST(math_h, sqrt_intel) {
   DoMathDataTest<1>(g_sqrt_intel_data, sqrt);
 }
 
 #include "math_data/sqrtf_intel_data.h"
-TEST(MATH_TEST, sqrtf_intel) {
+TEST(math_h, sqrtf_intel) {
   DoMathDataTest<1>(g_sqrtf_intel_data, sqrtf);
 }
 
 #include "math_data/tan_intel_data.h"
-TEST(MATH_TEST, tan_intel) {
+TEST(math_h, tan_intel) {
   DoMathDataTest<1>(g_tan_intel_data, tan);
 }
 
 #include "math_data/tanf_intel_data.h"
-TEST(MATH_TEST, tanf_intel) {
+TEST(math_h, tanf_intel) {
   DoMathDataTest<1>(g_tanf_intel_data, tanf);
 }
 
 #include "math_data/tanh_intel_data.h"
-TEST(MATH_TEST, tanh_intel) {
+TEST(math_h, tanh_intel) {
   DoMathDataTest<2>(g_tanh_intel_data, tanh);
 }
 
 #include "math_data/tanhf_intel_data.h"
-TEST(MATH_TEST, tanhf_intel) {
+TEST(math_h, tanhf_intel) {
   DoMathDataTest<2>(g_tanhf_intel_data, tanhf);
 }
 
 #include "math_data/trunc_intel_data.h"
-TEST(MATH_TEST, trunc_intel) {
+TEST(math_h, trunc_intel) {
   DoMathDataTest<1>(g_trunc_intel_data, trunc);
 }
 
 #include "math_data/truncf_intel_data.h"
-TEST(MATH_TEST, truncf_intel) {
+TEST(math_h, truncf_intel) {
   DoMathDataTest<1>(g_truncf_intel_data, truncf);
 }
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index b85edfb..c20597b 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -3486,3 +3486,141 @@
   GTEST_SKIP() << "no %w in glibc";
 #endif
 }
+
+TEST(STDIO_TEST, sscanf_w_base) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+  int8_t a;
+  EXPECT_EQ(1, sscanf("<0b101>", "<%w8b>", &a));
+  EXPECT_EQ(0b101, a);
+  int8_t b1;
+  EXPECT_EQ(1, sscanf("<0xFF>", "<%w8i>", &b1));
+  EXPECT_EQ(-1, b1);
+  int8_t b2;
+  EXPECT_EQ(1, sscanf("<0x1FF>", "<%w8i>", &b2));
+  EXPECT_EQ(-1, b2);
+  int16_t c1;
+  EXPECT_EQ(1, sscanf("<0xFFFF>", "<%w16i>", &c1));
+  EXPECT_EQ(-1, c1);
+  uint16_t c2;
+  EXPECT_EQ(1, sscanf("<64>", "<%w16d>", &c2));
+  EXPECT_EQ(64, c2);
+  int32_t d;
+  EXPECT_EQ(1, sscanf("<021>", "<%w32o>", &d));
+  EXPECT_EQ(021, d);
+  uint32_t e;
+  EXPECT_EQ(1, sscanf("<-1>", "<%w32u>", &e));
+  EXPECT_EQ(4294967295, e);
+  int64_t f;
+  EXPECT_EQ(1, sscanf("<0x3b>", "<%w64x>", &f));
+  EXPECT_EQ(0x3b, f);
+  EXPECT_EQ(1, sscanf("<0x3b>", "<%w64X>", &f));
+  EXPECT_EQ(0x3B, f);
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, sscanf_w_combination) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+  uint32_t a;
+  int64_t b;
+  char c;
+
+  EXPECT_EQ(3, sscanf("<0b10101010101010101010101010101010 0x3333333344444444 1>",
+                      "<%w32b %w64x %c>", &a, &b, &c));
+  EXPECT_EQ(0xaaaaaaaa, a);
+  EXPECT_EQ(0x3333333344444444, b);
+  EXPECT_EQ('1', c);
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, sscanf_invalid_w_width) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+  int32_t a;
+  EXPECT_DEATH(sscanf("<100>", "<%w20d>", &a), "%w20 is unsupported");
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swscanf_w_base) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+  int8_t a;
+  EXPECT_EQ(1, swscanf(L"<0b101>", L"<%w8b>", &a));
+  EXPECT_EQ(0b101, a);
+  int8_t b1;
+  EXPECT_EQ(1, swscanf(L"<0xFF>", L"<%w8i>", &b1));
+  EXPECT_EQ(-1, b1);
+  int8_t b2;
+  EXPECT_EQ(1, swscanf(L"<0x1FF>", L"<%w8i>", &b2));
+  EXPECT_EQ(-1, b2);
+  int16_t c1;
+  EXPECT_EQ(1, swscanf(L"<0xFFFF>", L"<%w16i>", &c1));
+  EXPECT_EQ(-1, c1);
+  uint16_t c2;
+  EXPECT_EQ(1, swscanf(L"<64>", L"<%w16d>", &c2));
+  EXPECT_EQ(64, c2);
+  int32_t d;
+  EXPECT_EQ(1, swscanf(L"<021>", L"<%w32o>", &d));
+  EXPECT_EQ(021, d);
+  uint32_t e;
+  EXPECT_EQ(1, swscanf(L"<-1>", L"<%w32u>", &e));
+  EXPECT_EQ(4294967295, e);
+  int64_t f;
+  EXPECT_EQ(1, swscanf(L"<0x3b>", L"<%w64x>", &f));
+  EXPECT_EQ(0x3b, f);
+  EXPECT_EQ(1, swscanf(L"<0x3b>", L"<%w64X>", &f));
+  EXPECT_EQ(0x3B, f);
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swscanf_w_combination) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+  uint32_t a;
+  int64_t b;
+  char c;
+
+  EXPECT_EQ(3, swscanf(L"<0b10101010101010101010101010101010 0x3333333344444444 1>",
+                       L"<%w32b %w64x %c>", &a, &b, &c));
+  EXPECT_EQ(0xaaaaaaaa, a);
+  EXPECT_EQ(0x3333333344444444, b);
+  EXPECT_EQ('1', c);
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swscanf_invalid_w_width) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+  int32_t a;
+  EXPECT_DEATH(swscanf(L"<100>", L"<%w20d>", &a), "%w20 is unsupported");
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "no %w in glibc";
+#endif
+}
\ No newline at end of file