Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-04-09 11:20:00 +0300
committerCorinna Vinschen <corinna@vinschen.de>2015-04-23 22:57:13 +0300
commitcd0d45913525ef09f0494a2f0c8e3d6fe8fface2 (patch)
treedcbb6a0c97dc45cc7df625cbeb4d1a99f503d247
parent45d0b17928067ee848aae2cd5bd332129ca35c42 (diff)
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.
-rw-r--r--include/elf/rx.h5
-rw-r--r--libgloss/ChangeLog5
-rw-r--r--libgloss/rx/crt0.S13
-rw-r--r--newlib/ChangeLog14
-rw-r--r--newlib/libc/machine/rx/memchr.S19
-rw-r--r--newlib/libc/machine/rx/memcpy.S21
-rw-r--r--newlib/libc/machine/rx/memmove.S37
-rw-r--r--newlib/libc/machine/rx/mempcpy.S17
-rw-r--r--newlib/libc/machine/rx/memset.S3
-rw-r--r--newlib/libc/machine/rx/strcat.S19
-rw-r--r--newlib/libc/machine/rx/strcmp.S18
-rw-r--r--newlib/libc/machine/rx/strcpy.S14
-rw-r--r--newlib/libc/machine/rx/strlen.S13
-rw-r--r--newlib/libc/machine/rx/strncat.S23
-rw-r--r--newlib/libc/machine/rx/strncmp.S28
-rw-r--r--newlib/libc/machine/rx/strncpy.S23
16 files changed, 272 insertions, 0 deletions
diff --git a/include/elf/rx.h b/include/elf/rx.h
index 83980853e..c17128c48 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 fc3674ebc..37cb4a581 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 222742352..6d7089d4d 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 470978d48..bca127755 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 937753cef..cdc97c874 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 3e0d50001..eb671c0ae 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 4b126bafc..60b76836b 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 c679d04ce..f82452462 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 edab44620..5ce7a3bca 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 7ceffb744..22533fc8d 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 397415bb4..6a06e6c9d 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 a2dc17464..05766ccef 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 c07b429b2..bf12c0ce1 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 3bc6b75ae..ba544a43a 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 929e9cb0a..4be8076db 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 e04922a59..e5b6a83ac 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
+