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.
This commit is contained in:
parent
45d0b17928
commit
cd0d459135
|
@ -120,6 +120,11 @@ END_RELOC_NUMBERS (R_RX_max)
|
||||||
#define E_FLAG_RX_PID (1 << 2) /* Unofficial - DJ */
|
#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_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. */
|
/* 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_IMM6 0x00000010 /* Imm8/16/24/32 at bit offset 6. */
|
||||||
#define RX_RELAXA_IMM12 0x00000020 /* Imm8/16/24/32 at bit offset 12. */
|
#define RX_RELAXA_IMM12 0x00000020 /* Imm8/16/24/32 at bit offset 12. */
|
||||||
|
|
|
@ -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>
|
2015-04-08 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* rx/rx.ld: Add .note and DWARF3 sections.
|
* rx/rx.ld: Add .note and DWARF3 sections.
|
||||||
|
|
|
@ -40,11 +40,24 @@ _start:
|
||||||
mov #__stack, r0
|
mov #__stack, r0
|
||||||
mvtc #__vectors, intb
|
mvtc #__vectors, intb
|
||||||
|
|
||||||
|
/* Copy the .data section from ROM into RAM. */
|
||||||
mov #__datastart, r1
|
mov #__datastart, r1
|
||||||
mov #__romdatastart, r2
|
mov #__romdatastart, r2
|
||||||
mov #__romdatacopysize, r3
|
mov #__romdatacopysize, r3
|
||||||
smovf
|
#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 #__bssstart, r1
|
||||||
mov #0, r2
|
mov #0, r2
|
||||||
mov #__bsssize, r3
|
mov #__bsssize, r3
|
||||||
|
|
|
@ -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>
|
2015-04-01 Corinna Vinschen <vinschen@redhat.com>
|
||||||
|
|
||||||
* libc/include/stdint.h: Throughout add parens around MIN/MAX values.
|
* libc/include/stdint.h: Throughout add parens around MIN/MAX values.
|
||||||
|
|
|
@ -5,9 +5,28 @@
|
||||||
.global _memchr
|
.global _memchr
|
||||||
.type _memchr,@function
|
.type _memchr,@function
|
||||||
_memchr:
|
_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...
|
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.
|
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.
|
suntil.b ; Search until *r1 == r2 or r3 bytes have been examined.
|
||||||
stnz #1, r1 ; If no match was found return NULL.
|
stnz #1, r1 ; If no match was found return NULL.
|
||||||
sub #1, r1 ; suntil.b leaves r1 pointing at the address *after* the match.
|
sub #1, r1 ; suntil.b leaves r1 pointing at the address *after* the match.
|
||||||
rts
|
rts
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.size _memchr, . - _memchr
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,28 @@
|
||||||
.global _memcpy
|
.global _memcpy
|
||||||
.type _memcpy,@function
|
.type _memcpy,@function
|
||||||
_memcpy:
|
_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
|
mov r1, r4 ; Save a copy of DEST
|
||||||
smovf ; Copy R2 (source) to R1 (dest). Stop after R3 bytes.
|
smovf ; Copy R2 (source) to R1 (dest). Stop after R3 bytes.
|
||||||
mov r4, r1 ; Return DEST
|
mov r4, r1 ; Return DEST
|
||||||
rts
|
rts
|
||||||
|
#endif
|
||||||
|
.size _memcpy, . - _memcpy
|
||||||
|
|
|
@ -4,6 +4,39 @@
|
||||||
.global _memmove
|
.global _memmove
|
||||||
.type _memmove,@function
|
.type _memmove,@function
|
||||||
_memmove:
|
_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
|
mov r1, r4 ; Save a copy of DEST
|
||||||
cmp r1, r2
|
cmp r1, r2
|
||||||
blt 2f ; If SRC (r2) is less than DEST (r1) then copy backwards
|
blt 2f ; If SRC (r2) is less than DEST (r1) then copy backwards
|
||||||
|
@ -18,3 +51,7 @@ _memmove:
|
||||||
sub #1, r1 ; additions and subtractions.
|
sub #1, r1 ; additions and subtractions.
|
||||||
smovb
|
smovb
|
||||||
bra 1b
|
bra 1b
|
||||||
|
|
||||||
|
#endif /* SMOVF allowed. */
|
||||||
|
|
||||||
|
.size _memmove, . - _memmove
|
||||||
|
|
|
@ -4,5 +4,22 @@
|
||||||
.global _mempcpy
|
.global _mempcpy
|
||||||
.type _mempcpy,@function
|
.type _mempcpy,@function
|
||||||
_mempcpy:
|
_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
|
smovf
|
||||||
rts
|
rts
|
||||||
|
#endif
|
||||||
|
.size _mempcpy, . - _mempcpy
|
||||||
|
|
|
@ -8,3 +8,6 @@ _memset:
|
||||||
sstr.b
|
sstr.b
|
||||||
mov r4, r1
|
mov r4, r1
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
.size _memset, . - _memset
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,22 @@
|
||||||
_strcat:
|
_strcat:
|
||||||
;; On entry: r1 => Destination
|
;; On entry: r1 => Destination
|
||||||
;; r2 => Source
|
;; 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 r1, r4 ; Save a copy of the dest pointer.
|
||||||
mov r2, r5 ; Save a copy of the source pointer.
|
mov r2, r5 ; Save a copy of the source pointer.
|
||||||
|
|
||||||
|
@ -20,3 +36,6 @@ _strcat:
|
||||||
|
|
||||||
mov r4, r1 ; Return the original dest pointer.
|
mov r4, r1 ; Return the original dest pointer.
|
||||||
rts
|
rts
|
||||||
|
#endif
|
||||||
|
.size _strcat, . - _strcat
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,21 @@
|
||||||
.global _strcmp
|
.global _strcmp
|
||||||
.type _strcmp,@function
|
.type _strcmp,@function
|
||||||
_strcmp:
|
_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.
|
mov #-1, r3 ; Strictly speaking this is incorrect, but I doubt if anyone will ever know.
|
||||||
scmpu ; Perform the string comparison
|
scmpu ; Perform the string comparison
|
||||||
bnc 1f ; If Carry is not set skip over
|
bnc 1f ; If Carry is not set skip over
|
||||||
|
@ -13,3 +28,6 @@ _strcmp:
|
||||||
1: ;
|
1: ;
|
||||||
mov #-1,r1 ; Carry not set, result should be negative
|
mov #-1,r1 ; Carry not set, result should be negative
|
||||||
rts ;
|
rts ;
|
||||||
|
#endif
|
||||||
|
.size _strcmp, . - _strcmp
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,22 @@
|
||||||
.global _strcpy
|
.global _strcpy
|
||||||
.type _strcpy,@function
|
.type _strcpy,@function
|
||||||
_strcpy:
|
_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 r1, r4
|
||||||
mov #-1, r3 ; Strictly speaking this is incorrect, but I doubt if anyone will ever know.
|
mov #-1, r3 ; Strictly speaking this is incorrect, but I doubt if anyone will ever know.
|
||||||
smovu
|
smovu
|
||||||
mov r4, r1
|
mov r4, r1
|
||||||
rts
|
rts
|
||||||
|
#endif
|
||||||
|
.size _strcpy, . - _strcpy
|
||||||
|
|
|
@ -5,6 +5,17 @@
|
||||||
.global _strlen
|
.global _strlen
|
||||||
.type _strlen,@function
|
.type _strlen,@function
|
||||||
_strlen:
|
_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.
|
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.
|
beq null_string ; Test for a NULL pointer.
|
||||||
mov #-1, r3 ; Set a limit on the number of bytes examined.
|
mov #-1, r3 ; Set a limit on the number of bytes examined.
|
||||||
|
@ -14,3 +25,5 @@ _strlen:
|
||||||
null_string:
|
null_string:
|
||||||
sub r4, r1 ; Compute the length.
|
sub r4, r1 ; Compute the length.
|
||||||
rts
|
rts
|
||||||
|
#endif
|
||||||
|
.size _strlen, . - _strlen
|
||||||
|
|
|
@ -7,7 +7,27 @@ _strncat:
|
||||||
;; On entry: r1 => Destination
|
;; On entry: r1 => Destination
|
||||||
;; r2 => Source
|
;; r2 => Source
|
||||||
;; r3 => Max number of bytes to copy
|
;; 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 r1, r4 ; Save a copy of the dest pointer.
|
||||||
mov r2, r5 ; Save a copy of the source pointer.
|
mov r2, r5 ; Save a copy of the source pointer.
|
||||||
mov r3, r14 ; Save a copy of the byte count.
|
mov r3, r14 ; Save a copy of the byte count.
|
||||||
|
@ -33,3 +53,6 @@ _strncat:
|
||||||
1:
|
1:
|
||||||
mov r4, r1 ; Return the original dest pointer.
|
mov r4, r1 ; Return the original dest pointer.
|
||||||
rts
|
rts
|
||||||
|
#endif
|
||||||
|
.size _strncat, . - _strncat
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,32 @@
|
||||||
.global _strncmp
|
.global _strncmp
|
||||||
.type _strncmp,@function
|
.type _strncmp,@function
|
||||||
_strncmp:
|
_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
|
scmpu ; Perform the string comparison
|
||||||
bnc 1f ; If Carry is not set skip over
|
bnc 1f ; If Carry is not set skip over
|
||||||
scne.L r1 ; Set result based on Z flag
|
scne.L r1 ; Set result based on Z flag
|
||||||
|
@ -11,3 +37,5 @@ _strncmp:
|
||||||
1: ;
|
1: ;
|
||||||
mov #-1,r1 ; Carry not set, result should be negative
|
mov #-1,r1 ; Carry not set, result should be negative
|
||||||
rts ;
|
rts ;
|
||||||
|
#endif
|
||||||
|
.size _strncmp, . - _strncmp
|
||||||
|
|
|
@ -4,6 +4,26 @@
|
||||||
.global _strncpy
|
.global _strncpy
|
||||||
.type _strncpy,@function
|
.type _strncpy,@function
|
||||||
_strncpy:
|
_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 r1, r4 ; Save a copy of the dest pointer.
|
||||||
mov r3, r5 ; Save a copy of the byte count
|
mov r3, r5 ; Save a copy of the byte count
|
||||||
smovu ; Copy the bytes
|
smovu ; Copy the bytes
|
||||||
|
@ -16,3 +36,6 @@ _strncpy:
|
||||||
1:
|
1:
|
||||||
mov r4, r1 ; Return the destination pointer
|
mov r4, r1 ; Return the destination pointer
|
||||||
rts
|
rts
|
||||||
|
#endif
|
||||||
|
.size _strncpy, . - _strncpy
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue