diff --git a/newlib/libc/string/local.h b/newlib/libc/string/local.h
index 012a30d16..79436ab69 100644
--- a/newlib/libc/string/local.h
+++ b/newlib/libc/string/local.h
@@ -1,5 +1,6 @@
 #include <_ansi.h>
 #include <../ctype/local.h>
+#include <stdint.h>
 
 /* internal function to compute width of wide char. */
 int __wcwidth (wint_t);
@@ -17,11 +18,24 @@ int __wcwidth (wint_t);
 # define __inhibit_loop_to_libcall
 #endif
 
+#ifdef __INTPTR_TYPE__
+  #define INTPTRTYPE intptr_t
+#else
+  /* Fallback, just in case there is no intptr_t on a target... */
+  #if __SIZEOF_POINTER__ > __SIZEOF_SHORT__
+    /* 32-bit targets; the default */
+	#define INTPTRTYPE long
+  #else
+    /* 16-bit targets; we silently assume sizeof(short)==2 and sizeof(long)==4 */
+	#define INTPTRTYPE short
+  #endif
+#endif
+
 /* Nonzero if X is not aligned on a "long" boundary.
  * This macro is used to skip a few bytes to find an aligned pointer.
  * It's better to keep it as is even if _HAVE_HW_MISALIGNED_ACCESS is enabled,
  * to avoid small performance penalties (if they are not zero).  */
-#define UNALIGNED_X(X) ((long)(X) & (sizeof (long) - 1))
+#define UNALIGNED_X(X) ((long)(INTPTRTYPE)(X) & (sizeof (long) - 1))
 
 #ifdef _HAVE_HW_MISALIGNED_ACCESS
 /* Hardware performs unaligned operations with little
@@ -30,7 +44,8 @@ int __wcwidth (wint_t);
 #else /* _HAVE_HW_MISALIGNED_ACCESS */
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED_X_Y(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((long)(INTPTRTYPE)X & (sizeof (long) - 1)) | \
+   ((long)(INTPTRTYPE)Y & (sizeof (long) - 1)))
 #endif /* _HAVE_HW_MISALIGNED_ACCESS */
 
 /* How many bytes are copied each iteration of the word copy loop.  */
