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

commit ab8bc7614c596ba842b014cc55adce8e8715b9d6
Author: Nick Clifton <[email protected]>
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  <[email protected]>
+
+       * rx/crt0.S (_start): If string instructions are not allowed,
+       avoid using SMOVF.
+
 2015-04-08  Nick Clifton  <[email protected]>
 
        * 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  <[email protected]>
+
+       * 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  <[email protected]>
 
        * 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
+

Reply via email to