Index: libc/pmstring/strstr_PF.S
===================================================================
--- libc/pmstring/strstr_PF.S	(revision 2404)
+++ libc/pmstring/strstr_PF.S	(working copy)
@@ -113,10 +113,12 @@
 
 	clr	ret_b0
 	clr	ret_b1
+	LPM_R0_ZPLUS_FINI s2_b2
 	ret
 
 .L_match_P:
 	sbiw	ret_b0, 1
+	LPM_R0_ZPLUS_INIT s2_b2
 	ret
 
 .L_strstr_end_P:
Index: libc/pmstring/strcasecmp_PF.S
===================================================================
--- libc/pmstring/strcasecmp_PF.S	(revision 2404)
+++ libc/pmstring/strcasecmp_PF.S	(working copy)
@@ -101,6 +101,7 @@
 ; ret_hi = SREG.C ? 0xFF : 0
 
 	sbc	ret_b1, ret_b1
+	LPM_R0_ZPLUS_FINI s2_b2
 	ret
 
 .L_strcasecmp_PF_end:
Index: libc/pmstring/strlen_PF.S
===================================================================
--- libc/pmstring/strlen_PF.S	(revision 2404)
+++ libc/pmstring/strlen_PF.S	(working copy)
@@ -77,6 +77,7 @@
 	add	src_b0, ZL
 	adc	src_b1, ZH
 	X_movw	src_b2, src_b0	; size_t is 16 bits
+	LPM_R0_ZPLUS_FINI src_b2
 	ret
 
 .L_strlen_PF_end:
Index: libc/pmstring/strncasecmp_PF.S
===================================================================
--- libc/pmstring/strncasecmp_PF.S	(revision 2404)
+++ libc/pmstring/strncasecmp_PF.S	(working copy)
@@ -112,6 +112,7 @@
 ; ret_hi = SREG.C ? 0xFF : 0
 
 	sbc	ret_b1, ret_b1
+	LPM_R0_ZPLUS_FINI s2_b2
 	ret
 
 .L_strncasecmp_PF_end:
Index: libc/pmstring/strcpy_PF.S
===================================================================
--- libc/pmstring/strcpy_PF.S	(revision 2404)
+++ libc/pmstring/strcpy_PF.S	(working copy)
@@ -75,7 +75,7 @@
 	st	X+, r0
 	tst	r0
 	brne	.L_strcpy_PF_loop
-
+	LPM_R0_ZPLUS_FINI src_b2
 ; return dest (unchanged)
 
 	ret
Index: libc/pmstring/strnlen_PF.S
===================================================================
--- libc/pmstring/strnlen_PF.S	(revision 2404)
+++ libc/pmstring/strnlen_PF.S	(working copy)
@@ -88,6 +88,7 @@
 	com	src_b1
 	add	src_b0, ZL
 	adc	src_b1, ZH
+	LPM_R0_ZPLUS_FINI src_b2
 	X_movw	src_b2, src_b0		; size_t is 16 bits
 	ret
 
Index: libc/pmstring/memcpy_PF.S
===================================================================
--- libc/pmstring/memcpy_PF.S	(revision 2404)
+++ libc/pmstring/memcpy_PF.S	(working copy)
@@ -109,7 +109,7 @@
 #endif
 
 	brcc	.L_memcpy_PF_loop
-
+	LPM_R0_ZPLUS_FINI src_b2
 ; return dest (unchanged)
 
 	ret
Index: libc/pmstring/strcat_PF.S
===================================================================
--- libc/pmstring/strcat_PF.S	(revision 2404)
+++ libc/pmstring/strcat_PF.S	(working copy)
@@ -84,7 +84,7 @@
 	st	X+, r0
 	tst	r0
 	brne	.L_strcat_PF_loop
-
+	LPM_R0_ZPLUS_FINI src_b2
 ; return dest (unchanged)
 
 	ret
Index: libc/pmstring/strlcpy_PF.S
===================================================================
--- libc/pmstring/strlcpy_PF.S	(revision 2404)
+++ libc/pmstring/strlcpy_PF.S	(working copy)
@@ -100,6 +100,7 @@
 	sbc	ZH, src_b1		; Z points past \0
 	sbiw	ZL, 1
 	X_movw	rWord_b0, ZL
+	LPM_R0_ZPLUS_FINI src_b2
 	ret
 
 .L_strlcpy_PF_end:
Index: libc/pmstring/strncpy_PF.S
===================================================================
--- libc/pmstring/strncpy_PF.S	(revision 2404)
+++ libc/pmstring/strncpy_PF.S	(working copy)
@@ -104,6 +104,7 @@
 	brcc	.L_strncpy_PF_clr_loop
 
 .L_strncpy_PF_done:
+	LPM_R0_ZPLUS_FINI src_b2
 ; return dest (unchanged)
 
 	ret
Index: libc/pmstring/strcmp_PF.S
===================================================================
--- libc/pmstring/strcmp_PF.S	(revision 2404)
+++ libc/pmstring/strcmp_PF.S	(working copy)
@@ -86,6 +86,7 @@
 ; ret_hi = SREG.C ? 0xFF : 0
 
 	sbc	ret_b1, ret_b1
+	LPM_R0_ZPLUS_FINI s2_b2
 	ret
 
 .L_strcmp_PF_end:
Index: libc/pmstring/strlcat_PF.S
===================================================================
--- libc/pmstring/strlcat_PF.S	(revision 2404)
+++ libc/pmstring/strlcat_PF.S	(working copy)
@@ -144,6 +144,7 @@
 	adc	rWord_b1, ZH
 	sub	rWord_b0, src_b0
 	sbc	rWord_b1, src_b1	; return(dlen + (Z - src))
+	LPM_R0_ZPLUS_FINI src_b2
 	pop	src_b2
 	ret
 
Index: libc/pmstring/strncat_PF.S
===================================================================
--- libc/pmstring/strncat_PF.S	(revision 2404)
+++ libc/pmstring/strncat_PF.S	(working copy)
@@ -91,7 +91,7 @@
 	tst	r0
 	st	X+, r0
 	brne	.L_strncat_PF_loop
-
+	LPM_R0_ZPLUS_FINI src_b2
 ; return dest (unchanged)
 
 	ret
@@ -99,7 +99,7 @@
 .L_strncat_PF_done:
 
 	st	X, __zero_reg__
-
+	LPM_R0_ZPLUS_FINI src_b2
 ; return dest (unchanged)
 
 	ret
Index: libc/pmstring/memcmp_PF.S
===================================================================
--- libc/pmstring/memcmp_PF.S	(revision 2404)
+++ libc/pmstring/memcmp_PF.S	(working copy)
@@ -99,6 +99,7 @@
   sub   ret_b0, ret_b0
 3:
   sbc   ret_b1, ret_b1
+  LPM_R0_ZPLUS_FINI s2_b2
   ret
 
   .size _U(memcmp_PF), . - _U(memcmp_PF)
Index: libc/pmstring/strncmp_PF.S
===================================================================
--- libc/pmstring/strncmp_PF.S	(revision 2404)
+++ libc/pmstring/strncmp_PF.S	(working copy)
@@ -96,6 +96,7 @@
 ; ret_hi = SREG.C ? 0xFF : 0
 
 	sbc	ret_b1, ret_b1
+	LPM_R0_ZPLUS_FINI s2_b2
 	ret
 
 .L_strncmp_PF_end:
Index: common/macros.inc
===================================================================
--- common/macros.inc	(revision 2404)
+++ common/macros.inc	(working copy)
@@ -334,7 +334,10 @@
    LPM_R0_ZPLUS_NEXT is used inside the loop to load a byte from
    the program memory at [RAMPZ:]Z to R0, and increment [RAMPZ:]Z.
 
-   The argument in both macros is a register that contains the
+   LPM_R0_ZPLUS_FINI is used after the loop to restore RAMPZ if
+   both ELPM and RAMPD are present.
+
+   The argument in above macros is a register that contains the
    high byte (bits 23-16) of the address, bits 15-0 should be in
    the Z (r31:r30) register.  It can be any register except for:
    r0, r1 (__zero_reg__ - assumed to always contain 0), r30, r31.
@@ -343,7 +346,13 @@
 	.macro	LPM_R0_ZPLUS_INIT hhi
 #if __AVR_ENHANCED__
   #if __AVR_HAVE_ELPM__
-	out	AVR_RAMPZ_ADDR, \hhi
+    #if __AVR_HAVE_RAMPD__
+      in r0, AVR_RAMPZ_ADDR
+      out AVR_RAMPZ_ADDR, \hhi
+      mov \hhi, r0
+    #else
+      out AVR_RAMPZ_ADDR, \hhi
+    #endif
   #endif
 #endif
 	.endm
@@ -371,3 +380,14 @@
   #endif
 #endif
 	.endm
+
+	.macro LPM_R0_ZPLUS_FINI hhi
+#if __AVR_ENHANCED__
+  #if __AVR_HAVE_ELPM__
+    #if __AVR_HAVE_RAMPD__
+      out AVR_RAMPZ_ADDR, \hhi
+    #endif
+  #endif
+#endif
+	.endm
+
