This is the mail archive of the newlib-cvs@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[newlib-cygwin/cygwin-2.0] For the RX port, avoid using string instructions when __RX_DISALLOW_STRING_INSNS__ is defined.


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=cd0d45913525ef09f0494a2f0c8e3d6fe8fface2

commit cd0d45913525ef09f0494a2f0c8e3d6fe8fface2
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Apr 9 09:20:00 2015 +0100

    For the RX port, avoid using string instructions when __RX_DISALLOW_STRING_INSNS__ is defined.
    
    	* rx/crt0.S (_start): If string instructions are not allowed,
    	avoid using SMOVF.
    
    	* libc/machine/rx/memchr.S: Add non-string insn using version.
    	* libc/machine/rx/memcpy.S: Likewise.
    	* libc/machine/rx/memmove.S: Likewise.
    	* libc/machine/rx/mempcpy.S: Likewise.
    	* libc/machine/rx/strcat.S: Likewise.
    	* libc/machine/rx/strcmp.S: Likewise.
    	* libc/machine/rx/strcpy.S: Likewise.
    	* libc/machine/rx/strlen.S: Likewise.
    	* libc/machine/rx/strncat.S: Likewise.
    	* libc/machine/rx/strncmp.S: Likewise.
    	* libc/machine/rx/strncpy.S: Likewise.

Diff:
---
 include/elf/rx.h                 |  5 +++++
 libgloss/ChangeLog               |  5 +++++
 libgloss/rx/crt0.S               | 13 +++++++++++++
 newlib/ChangeLog                 | 14 ++++++++++++++
 newlib/libc/machine/rx/memchr.S  | 19 +++++++++++++++++++
 newlib/libc/machine/rx/memcpy.S  | 21 +++++++++++++++++++++
 newlib/libc/machine/rx/memmove.S | 37 +++++++++++++++++++++++++++++++++++++
 newlib/libc/machine/rx/mempcpy.S | 17 +++++++++++++++++
 newlib/libc/machine/rx/memset.S  |  3 +++
 newlib/libc/machine/rx/strcat.S  | 19 +++++++++++++++++++
 newlib/libc/machine/rx/strcmp.S  | 18 ++++++++++++++++++
 newlib/libc/machine/rx/strcpy.S  | 14 ++++++++++++++
 newlib/libc/machine/rx/strlen.S  | 13 +++++++++++++
 newlib/libc/machine/rx/strncat.S | 23 +++++++++++++++++++++++
 newlib/libc/machine/rx/strncmp.S | 28 ++++++++++++++++++++++++++++
 newlib/libc/machine/rx/strncpy.S | 23 +++++++++++++++++++++++
 16 files changed, 272 insertions(+)

diff --git a/include/elf/rx.h b/include/elf/rx.h
index 8398085..c17128c 100644
--- a/include/elf/rx.h
+++ b/include/elf/rx.h
@@ -120,6 +120,11 @@ END_RELOC_NUMBERS (R_RX_max)
 #define E_FLAG_RX_PID			(1 << 2) /* Unofficial - DJ */
 #define E_FLAG_RX_ABI			(1 << 3) /* Binary passes stacked arguments using natural alignment.  Unofficial - NC.  */
 
+#define E_FLAG_RX_SINSNS_SET		(1 << 6) /* Set if bit-5 is significant.  */
+#define E_FLAG_RX_SINSNS_YES		(1 << 7) /* Set if string instructions are used in the binary.  */
+#define E_FLAG_RX_SINSNS_NO		0        /* Bit-5 if this binary must not be linked with a string instruction using binary.  */
+#define E_FLAG_RX_SINSNS_MASK		(3 << 6) /* Mask of bits used to determine string instruction use.  */
+
 /* These define the addend field of R_RX_RH_RELAX relocations.  */
 #define	RX_RELAXA_IMM6	0x00000010	/* Imm8/16/24/32 at bit offset 6.  */
 #define	RX_RELAXA_IMM12	0x00000020	/* Imm8/16/24/32 at bit offset 12.  */
diff --git a/libgloss/ChangeLog b/libgloss/ChangeLog
index fc3674e..37cb4a5 100644
--- a/libgloss/ChangeLog
+++ b/libgloss/ChangeLog
@@ -1,3 +1,8 @@
+2015-04-09  Nick Clifton  <nickc@redhat.com>
+
+	* rx/crt0.S (_start): If string instructions are not allowed,
+	avoid using SMOVF.
+
 2015-04-08  Nick Clifton  <nickc@redhat.com>
 
 	* rx/rx.ld: Add .note and DWARF3 sections.
diff --git a/libgloss/rx/crt0.S b/libgloss/rx/crt0.S
index 2227423..6d7089d 100644
--- a/libgloss/rx/crt0.S
+++ b/libgloss/rx/crt0.S
@@ -40,11 +40,24 @@ _start:
 	mov	#__stack, r0
 	mvtc	#__vectors, intb
 
+	/* Copy the .data section from ROM into RAM.  */
 	mov	#__datastart, r1
 	mov	#__romdatastart, r2
 	mov	#__romdatacopysize, r3
+#ifdef __RX_DISALLOW_STRING_INSNS__
+	cmp	#0, r3
+	beq	2f
+
+1:	mov.b	[r2+], r5
+	mov.b	r5, [r1+]
+	sub	#1, r3
+	bne	1b
+2:	
+#else
 	smovf
+#endif
 
+	/* Initialise the contents of the .bss section.  */
 	mov	#__bssstart, r1
 	mov	#0, r2
 	mov	#__bsssize, r3
diff --git a/newlib/ChangeLog b/newlib/ChangeLog
index 470978d..bca1277 100644
--- a/newlib/ChangeLog
+++ b/newlib/ChangeLog
@@ -1,3 +1,17 @@
+2015-04-09  Nick Clifton  <nickc@redhat.com>
+
+	* libc/machine/rx/memchr.S: Add non-string insn using version.
+	* libc/machine/rx/memcpy.S: Likewise.
+	* libc/machine/rx/memmove.S: Likewise.
+	* libc/machine/rx/mempcpy.S: Likewise.
+	* libc/machine/rx/strcat.S: Likewise.
+	* libc/machine/rx/strcmp.S: Likewise.
+	* libc/machine/rx/strcpy.S: Likewise.
+	* libc/machine/rx/strlen.S: Likewise.
+	* libc/machine/rx/strncat.S: Likewise.
+	* libc/machine/rx/strncmp.S: Likewise.
+	* libc/machine/rx/strncpy.S: Likewise.
+
 2015-04-01  Corinna Vinschen  <vinschen@redhat.com>
 
 	* libc/include/stdint.h: Throughout add parens around MIN/MAX values.
diff --git a/newlib/libc/machine/rx/memchr.S b/newlib/libc/machine/rx/memchr.S
index 937753c..cdc97c8 100644
--- a/newlib/libc/machine/rx/memchr.S
+++ b/newlib/libc/machine/rx/memchr.S
@@ -5,9 +5,28 @@
 	.global  _memchr
 	.type	 _memchr,@function
 _memchr:
+	;; R1: string pointer
+	;; R2: byte sought
+	;; R3: max number to scan
+#ifdef __RX_DISALLOW_STRING_INSNS__
+	mov.b	r2, r2		; The mov.b below sign extends as it loads, so make sure that r2 is sign-extended as well.
+2:	cmp	#0, r3
+	beq	1f
+	sub	#1, r3
+	mov.b	[r1+], r5
+	cmp	r5, r2
+	bne	2b
+
+	sub	#1, r1		; We have found a match, bit now R1 points to the byte after the match.
+1:	rts
+#else
 	cmp	#0, r3		; If r3 is 0 suntil.b will do nothing and not set any flags...
 	stz     #1, r1		; ...so store 1 into r1.  It will be decremented by the SUB later.
 	suntil.b    		; Search until *r1 == r2 or r3 bytes have been examined.
 	stnz	#1, r1		; If no match was found return NULL.
 	sub	#1, r1		; suntil.b leaves r1 pointing at the address *after* the match.
 	rts
+#endif
+
+	.size _memchr, . - _memchr
+	
diff --git a/newlib/libc/machine/rx/memcpy.S b/newlib/libc/machine/rx/memcpy.S
index 3e0d500..eb671c0 100644
--- a/newlib/libc/machine/rx/memcpy.S
+++ b/newlib/libc/machine/rx/memcpy.S
@@ -4,7 +4,28 @@
 	.global  _memcpy
 	.type	 _memcpy,@function
 _memcpy:
+#ifdef __RX_DISALLOW_STRING_INSNS__
+	/* Do not use the string instructions - they might prefetch
+	   bytes from outside of valid memory.  This is particularly
+	   dangerous in I/O space.  */
+
+	;; FIXME: It would be more space efficient to just branch to _memmove...
+	
+	cmp	 #0, r3	      	; If the count is zero, do nothing
+	beq	 1f
+	
+	mov	 r1, r14	; Save a copy of DEST
+
+2:	mov.b	 [r2+], r5
+	mov.b	 r5, [r14+]
+	sub	 #1, r3
+	bne	 2b
+	
+1:	rts
+#else
 	mov	r1, r4		; Save a copy of DEST
 	smovf	    		; Copy R2 (source) to R1 (dest).  Stop after R3 bytes.
 	mov	r4, r1		; Return DEST
 	rts
+#endif
+	.size _memcpy, . - _memcpy
diff --git a/newlib/libc/machine/rx/memmove.S b/newlib/libc/machine/rx/memmove.S
index 4b126ba..60b7683 100644
--- a/newlib/libc/machine/rx/memmove.S
+++ b/newlib/libc/machine/rx/memmove.S
@@ -4,6 +4,39 @@
 	.global  _memmove
 	.type	 _memmove,@function
 _memmove:
+	;; R1: DEST
+	;; R2: SRC
+	;; R3: COUNT
+#ifdef __RX_DISALLOW_STRING_INSNS__
+	/* Do not use the string instructions - they might prefetch
+	   bytes from outside of valid memory.  This is particularly
+	   dangerous in I/O space.  */
+
+	cmp	 #0, r3	      	; If the count is zero, do nothing
+	beq	 4f
+	
+	cmp	 r1, r2
+	blt	 3f		; If SRC < DEST copy backwards
+
+	mov	 r1, r14	; Save a copy of DEST
+
+5:	mov.b	 [r2+], r5
+	mov.b	 r5, [r14+]
+	sub	 #1, r3
+	bne	 5b
+	
+4:	rts
+
+3:	add	 r3, r1
+	add	 r3, r2
+
+6:	mov.b	 [-r2], r5
+	mov.b	 r5, [-r1]
+	sub	 #1, r3
+	bne	 6b
+
+	rts
+#else	
 	mov	r1, r4		; Save a copy of DEST
 	cmp	r1, r2
 	blt	2f		; If SRC (r2) is less than DEST (r1) then copy backwards
@@ -18,3 +51,7 @@ _memmove:
 	sub	#1, r1		; additions and subtractions.
 	smovb
 	bra	1b
+
+#endif /* SMOVF allowed.  */
+
+	.size _memmove, . - _memmove
diff --git a/newlib/libc/machine/rx/mempcpy.S b/newlib/libc/machine/rx/mempcpy.S
index c679d04..f824524 100644
--- a/newlib/libc/machine/rx/mempcpy.S
+++ b/newlib/libc/machine/rx/mempcpy.S
@@ -4,5 +4,22 @@
 	.global  _mempcpy
 	.type	 _mempcpy,@function
 _mempcpy:
+#ifdef __RX_DISALLOW_STRING_INSNS__
+	/* Do not use the string instructions - they might prefetch
+	   bytes from outside of valid memory.  This is particularly
+	   dangerous in I/O space.  */
+
+	cmp	 #0, r3	      	; If the count is zero, do nothing
+	beq	 2f
+	
+1:	mov.b	 [r2+], r5
+	mov.b	 r5, [r1+]
+	sub	 #1, r3
+	bne	 1b
+
+2:	rts
+#else
 	smovf
 	rts
+#endif
+	.size _mempcpy, . - _mempcpy
diff --git a/newlib/libc/machine/rx/memset.S b/newlib/libc/machine/rx/memset.S
index edab446..5ce7a3b 100644
--- a/newlib/libc/machine/rx/memset.S
+++ b/newlib/libc/machine/rx/memset.S
@@ -8,3 +8,6 @@ _memset:
 	sstr.b
 	mov	r4, r1
 	rts
+
+	.size _memset, . - _memset
+	
diff --git a/newlib/libc/machine/rx/strcat.S b/newlib/libc/machine/rx/strcat.S
index 7ceffb7..22533fc 100644
--- a/newlib/libc/machine/rx/strcat.S
+++ b/newlib/libc/machine/rx/strcat.S
@@ -6,6 +6,22 @@
 _strcat:
 	;; On entry: r1 => Destination
 	;;           r2 => Source
+#ifdef __RX_DISALLOW_STRING_INSNS__
+	mov 	r1, r4		; Save a copy of the dest pointer.
+	
+1:	mov.b	[r4+], r5	; Find the NUL byte at the end of R4.
+	cmp	#0, r5
+	bne	1b
+
+	sub	#1, r4		; Move R4 back to point at the NUL byte.
+
+2:	mov.b	[r2+], r5	; Copy bytes from R2 to R4 until we reach a NUL byte.
+	mov.b	r5, [r4+]
+	cmp	#0, r5
+	bne 	2b
+
+	rts
+#else
 	mov 	r1, r4		; Save a copy of the dest pointer.
 	mov 	r2, r5		; Save a copy of the source pointer.
 	
@@ -20,3 +36,6 @@ _strcat:
 
 	mov	r4, r1		; Return the original dest pointer.
 	rts
+#endif
+	.size _strcat, . - _strcat
+	
diff --git a/newlib/libc/machine/rx/strcmp.S b/newlib/libc/machine/rx/strcmp.S
index 397415b..6a06e6c 100644
--- a/newlib/libc/machine/rx/strcmp.S
+++ b/newlib/libc/machine/rx/strcmp.S
@@ -5,6 +5,21 @@
 	.global  _strcmp
 	.type	 _strcmp,@function
 _strcmp:
+#ifdef __RX_DISALLOW_STRING_INSNS__
+2:	mov.b	[r1+], r4
+	mov.b	[r2+], r5
+	cmp	#0, r4
+	beq	3f
+	cmp	#0, r5
+	beq	3f
+	cmp	r4, r5
+	beq	2b
+
+3:	and	#0xff, r4	; We need to perform an unsigned comparison of the bytes.
+	and	#0xff, r5
+	sub	r5, r4, r1
+	rts
+#else
 	mov	#-1, r3		; Strictly speaking this is incorrect, but I doubt if anyone will ever know.
 	scmpu			; Perform the string comparison
 	bnc	1f		; If Carry is not set skip over
@@ -13,3 +28,6 @@ _strcmp:
 1:				;
 	mov	#-1,r1		; Carry not set, result should be negative
 	rts			;
+#endif
+	.size _strcmp, . - _strcmp
+	
diff --git a/newlib/libc/machine/rx/strcpy.S b/newlib/libc/machine/rx/strcpy.S
index a2dc174..05766cc 100644
--- a/newlib/libc/machine/rx/strcpy.S
+++ b/newlib/libc/machine/rx/strcpy.S
@@ -4,8 +4,22 @@
 	.global  _strcpy
 	.type	 _strcpy,@function
 _strcpy:
+	;; R1: dest
+	;; R2: source
+#ifdef __RX_DISALLOW_STRING_INSNS__
+	mov	r1, r4		; Leave the destination address unchanged in the result register.
+
+1:	mov.b	[r2+], r5
+	mov.b	r5, [r4+]
+	cmp	#0, r5
+	bne	1b
+
+	rts
+#else
 	mov	r1, r4
 	mov	#-1, r3		; Strictly speaking this is incorrect, but I doubt if anyone will ever know.
 	smovu
 	mov	r4, r1
 	rts
+#endif
+	.size _strcpy, . - _strcpy
diff --git a/newlib/libc/machine/rx/strlen.S b/newlib/libc/machine/rx/strlen.S
index c07b429..bf12c0c 100644
--- a/newlib/libc/machine/rx/strlen.S
+++ b/newlib/libc/machine/rx/strlen.S
@@ -5,6 +5,17 @@
 	.global  _strlen
 	.type	 _strlen,@function
 _strlen:
+#ifdef __RX_DISALLOW_STRING_INSNS__
+	mov	r1, r4
+
+1:	mov.b	[r1+], r5
+	cmp	#0, r5
+	bne	1b
+
+	sub	#1, r1
+	sub	r4, r1
+	rts
+#else
 	add	#0, r1, r4	; Save a copy of the string start address and set the condition flags.
 	beq     null_string	; Test for a NULL pointer.
 	mov	#-1, r3		; Set a limit on the number of bytes examined.
@@ -14,3 +25,5 @@ _strlen:
 null_string:
 	sub	r4, r1		; Compute the length.
 	rts
+#endif
+	.size _strlen, . - _strlen
diff --git a/newlib/libc/machine/rx/strncat.S b/newlib/libc/machine/rx/strncat.S
index 3bc6b75..ba544a4 100644
--- a/newlib/libc/machine/rx/strncat.S
+++ b/newlib/libc/machine/rx/strncat.S
@@ -7,7 +7,27 @@ _strncat:
 	;; On entry: r1 => Destination
 	;;           r2 => Source
 	;; 	     r3 => Max number of bytes to copy
+#ifdef __RX_DISALLOW_STRING_INSNS__
+	cmp	#0, r3		; If max is zero we have nothing to do.
+	beq	2f
 	
+	mov 	r1, r4		; Leave the desintation pointer intact for the return value.
+	
+1:	mov.b	[r4+], r5	; Find the NUL byte at the end of the destination.
+	cmp	#0, r5
+	bne	1b
+
+	sub	#1, r4
+
+3:	mov.b	[r2+], r5	; Copy bytes from the source into the destination ...
+	mov.b	r5, [r4+]
+	cmp	#0, r5		; ... until we reach a NUL byte ...
+	beq 	2f
+	sub	#1, r3
+	bne	3b		; ... or we have copied N bytes.
+	
+2:	rts
+#else
 	mov 	r1, r4		; Save a copy of the dest pointer.
 	mov 	r2, r5		; Save a copy of the source pointer.
 	mov 	r3, r14		; Save a copy of the byte count.
@@ -33,3 +53,6 @@ _strncat:
 1:	
 	mov	r4, r1		; Return the original dest pointer.
 	rts
+#endif
+	.size _strncat, . - _strncat
+	
diff --git a/newlib/libc/machine/rx/strncmp.S b/newlib/libc/machine/rx/strncmp.S
index 929e9cb..4be8076 100644
--- a/newlib/libc/machine/rx/strncmp.S
+++ b/newlib/libc/machine/rx/strncmp.S
@@ -4,6 +4,32 @@
 	.global  _strncmp
 	.type	 _strncmp,@function
 _strncmp:
+	;; R1: string1
+	;; R2: string2
+	;; R3: max number of bytes to compare
+#ifdef __RX_DISALLOW_STRING_INSNS__
+	cmp	#0, r3		; For a length of zero, return zero
+	beq	4f
+
+2:	mov.b	[r1+], r4
+	mov.b	[r2+], r5
+	cmp	#0, r4
+	beq	3f
+	cmp	#0, r5
+	beq	3f
+	sub	#1, r3
+	beq	3f
+	cmp	r4, r5
+	beq	2b
+
+3:	and	#0xff, r4	; We need to perform an unsigned comparison of the bytes.
+	and	#0xff, r5
+	sub	r5, r4, r1
+	rts
+
+4:	mov	#0, r1
+	rts
+#else
 	scmpu			; Perform the string comparison
 	bnc	1f		; If Carry is not set skip over
 	scne.L	r1		; Set result based on Z flag
@@ -11,3 +37,5 @@ _strncmp:
 1:				;
 	mov	#-1,r1		; Carry not set, result should be negative
 	rts			;
+#endif
+	.size _strncmp, . - _strncmp
diff --git a/newlib/libc/machine/rx/strncpy.S b/newlib/libc/machine/rx/strncpy.S
index e04922a..e5b6a83 100644
--- a/newlib/libc/machine/rx/strncpy.S
+++ b/newlib/libc/machine/rx/strncpy.S
@@ -4,6 +4,26 @@
 	.global  _strncpy
 	.type	 _strncpy,@function
 _strncpy:
+#ifdef __RX_DISALLOW_STRING_INSNS__
+	cmp	#0, r3
+	beq	3f
+	
+	mov	r1, r4		; Preserve R1 for the return value.
+
+2:	mov.b	[r2+], r5	; Copy bytes until...
+	mov.b	r5, [r4+]
+	sub	#1, r3
+	beq	3f		; ... our count reaches zero
+	cmp	#0, r5
+	bne	2b		; ... or we have written a NUL byte
+
+4:	mov.b	r5, [r4+]	; Continue to write further NUL bytes
+	sub	#1, r3
+	bne	4b		; until the count reaches zero.
+
+3:	rts
+	
+#else
 	mov	r1, r4		; Save a copy of the dest pointer.
 	mov	r3, r5		; Save a copy of the byte count
 	smovu	    		; Copy the bytes
@@ -16,3 +36,6 @@ _strncpy:
 1:
 	mov	r4, r1		; Return the destination pointer
 	rts
+#endif
+	.size _strncpy, . - _strncpy
+


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]