Created
March 8, 2017 02:24
-
-
Save ZipCPU/29f3898b970c15e64239afbcab449237 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//////////////////////////////////////////////////////////////////// | |
// | |
// Filename: string.c | |
// | |
// Project: CMod S6 System on a Chip, ZipCPU demonstration project | |
// | |
// Purpose: To provide *some* of the C-library's capabilities, without | |
// using perfectly optimal functions--but rather simple things that | |
// can be easily tested and debugged. | |
// | |
// Creator: Dan Gisselquist, Ph.D. | |
// Gisselquist Technology, LLC | |
// | |
//////////////////////////////////////////////////////////////////////////////// | |
// | |
// Copyright (C) 2017, Gisselquist Technology, LLC | |
// | |
// This program is free software (firmware): you can redistribute it and/or | |
// modify it under the terms of the GNU General Public License as published | |
// by the Free Software Foundation, either version 3 of the License, or (at | |
// your option) any later version. | |
// | |
// This program is distributed in the hope that it will be useful, but WITHOUT | |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or | |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
// for more details. | |
// | |
// You should have received a copy of the GNU General Public License along | |
// with this program. (It's in the $(ROOT)/doc directory. Run make with no | |
// target there if the PDF file isn't present.) If not, see | |
// <http://www.gnu.org/licenses/> for a copy. | |
// | |
// License: GPL, v3, as defined and found on www.gnu.org, | |
// http://www.gnu.org/licenses/gpl.html | |
// | |
// | |
//////////////////////////////////////////////////////////////////////////////// | |
// | |
// | |
#include "string.h" | |
char * | |
strcpy(char *dst, const char *src) { | |
char v, *d = dst; | |
do { | |
*dst++ = (v = *src++); | |
} while(v); | |
return d; | |
} | |
char * | |
strcat(char *dst, const char *src) { | |
char v, *d = dst; | |
do { | |
v = *dst++; | |
} while(v); | |
dst--; | |
strcpy(dst, src); | |
return d; | |
} | |
#ifdef C_STRING_FNS | |
size_t | |
strlen(const char *str) { | |
size_t ln = 0; | |
while(*str++) | |
ln++; | |
return ln; | |
} | |
#else | |
asm("\t.section\t.text\n" | |
"\t.global\tstrlen\n" | |
"strlen:\n" | |
"\tMOV\tR1,R2\n" | |
"\tCLR\tR1\n" | |
".Lstrlen_loop:\n" | |
"\tLB\t(R2),R3\n" | |
"\tCMP\t0,R3\n" | |
"\tRTN.Z\n" | |
"\tADD\t1,R2\n" | |
"\tADD\t1,R1\n" | |
"\tBRA\t.Lstrlen_loop\n"); | |
#endif | |
void *memcpy(void *dest, const void *src, size_t ln) { | |
char *d = dest; const char *s = src; | |
if (((((unsigned)d ^ (unsigned)s)&3)==0)&&(ln>4)) { | |
// Source and destination are aligned with each other | |
// Align them to a word boundary | |
int n = (3-(((unsigned)d)&3)); | |
ln -= n; | |
while(n>0) { | |
*d++ = *s++; n--; | |
} | |
int *id = (int *)d; | |
const int *is = (const int *)s; | |
while(ln >= 4) { | |
*id++ = *is++; ln-=4; | |
} d = (char *)id; s = (const char *)is; | |
} | |
while(ln > 0) { | |
*d++ = *s++; ln--; | |
} return dest; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.file "string.c" | |
.section .text | |
.global strlen | |
strlen: | |
MOV R1,R2 | |
CLR R1 | |
.Lstrlen_loop: | |
LB (R2),R3 | |
CMP 0,R3 | |
RTN.Z | |
ADD 1,R2 | |
ADD 1,R1 | |
BRA .Lstrlen_loop | |
.text | |
.align 2 | |
.global strcpy | |
.type strcpy, @function | |
strcpy: | |
MOV R1,R3 | |
.L2: | |
ADD 1,R3 ; addsi3 | |
ADD 1,R2 ; addsi3 | |
LB -1(R2),R4 ; Zero-Extend:QI | |
SB R4,-1(R3) | |
CMP 0,R4 | |
BNZ .L2 | |
RETN | |
.size strcpy, .-strcpy | |
.align 2 | |
.global strcat | |
.type strcat, @function | |
strcat: | |
MOV R1,R3 | |
BRA .L5 | |
.L7: | |
.L5: | |
ADD 1,R3 ; addsi3_raw | |
LB -1(R3),R4 ; Zero-Extend:QI | |
CMP 0,R4 | |
BNZ .L7 | |
.L6: | |
ADD 1,R2 ; addsi3 | |
LB -1(R2),R4 ; Zero-Extend:QI | |
SB R4,-1(R3) | |
CMP 0,R4 | |
RETN.Z | |
MOV 1(R3),R3 | |
BRA .L6 | |
.size strcat, .-strcat | |
.align 2 | |
.global memcpy | |
.type memcpy, @function | |
memcpy: | |
SUB 24,SP ; subsi3 | |
SW R5,(SP) | |
SW R6,4(SP) | |
SW R7,8(SP) | |
SW R8,12(SP) | |
SW R9,16(SP) | |
SW R10,20(SP) | |
MOV R2,R4 | |
XOR R1,R4 ; xorsi3 | |
TEST 3,R4 | |
LDI 0,R4 | |
LDI.Z 1,R4 ; cmov | |
CMP 5,R3 | |
LDI 0,R5 | |
LDI.NC 1,R5 ; cmov | |
TEST R5,R4 | |
BNZ .L11 | |
MOV R1,R4 | |
.L16: | |
CMP 0,R3 | |
BNZ .L12 | |
BRA .L30 | |
.L11: | |
MOV R1,R4 | |
XOR -1,R4 ; xorsi3 | |
AND 3,R4 ; andsi3 | |
SUB R4,R3 ; subsi3_raw | |
CMP 0,R4 | |
BZ .L25 | |
LB (R2),R5 ; Zero-Extend:QI | |
SB R5,(R1) | |
MOV R4,R5 | |
ADD -1,R5 ; addsi3_raw | |
BZ .L14 | |
LB 1(R2),R8 ; Zero-Extend:QI | |
SB R8,1(R1) | |
CMP 2,R4 | |
[NZ] LB 2(R2),R10 ; Zero-Extend:QI | |
[NZ] SB R10,2(R1) | |
.L14: | |
ADD R4,R2 ; addsi3 | |
MOV R1,R5 | |
ADD R4,R5 ; addsi3 | |
MOV R5,R4 | |
BRA .L13 | |
.L25: | |
MOV R1,R4 | |
.L13: | |
CMP 4,R3 | |
BC .L26 | |
MOV R2,R7 | |
MOV R4,R6 | |
MOV R3,R5 | |
.L15: | |
ADD 4,R6 ; addsi3 | |
LW (R7),R8 | |
ADD 4,R7 ; addsi3_raw | |
SW R8,-4(R6) | |
ADD -4,R5 ; addsi3_raw | |
CMP 4,R5 | |
BNC .L15 | |
MOV R3,R5 | |
ADD -4,R5 ; addsi3 | |
AND -4,R5 ; andsi3 | |
ADD 4,R5 ; addsi3 | |
AND 3,R3 ; andsi3 | |
ADD R5,R2 ; addsi3 | |
ADD R5,R4 ; addsi3 | |
BRA .L16 | |
.L26: | |
.L12: | |
MOV R2,R5 | |
ADD 4,R5 ; addsi3_raw | |
CMP R5,R4 | |
LDI 0,R5 | |
LDI.NC 1,R5 ; cmov | |
MOV R4,R6 | |
ADD 4,R6 ; addsi3_raw | |
CMP R6,R2 | |
OR.NC 1,R5 ; cior | |
MOV R5,R6 | |
CMP 10,R3 | |
LDI 0,R5 | |
LDI.NC 1,R5 ; cmov | |
AND R6,R5 ; andsi3 | |
MOV R5,R6 | |
MOV R4,R5 | |
OR R2,R5 ; iorsi3 | |
TEST 3,R5 | |
LDI 0,R5 | |
LDI.Z 1,R5 ; cmov | |
TEST R6,R5 | |
BZ .L17 | |
MOV R3,R5 | |
ADD -4,R5 ; addsi3 | |
LSR 2,R5 ; lshrsi3 | |
ADD 1,R5 ; addsi3 | |
MOV R5,R9 | |
LSL 2,R9 ; ashlsi3 | |
MOV R2,R8 | |
MOV R4,R7 | |
LDI 0,R6 | |
.L18: | |
LW (R8),R10 | |
SW R10,(R7) | |
ADD 1,R6 ; addsi3 | |
ADD 4,R8 ; addsi3 | |
ADD 4,R7 ; addsi3_raw | |
CMP R5,R6 | |
BC .L18 | |
BRA .L40 | |
.L21: | |
LB 2(R2),R2 ; Zero-Extend:QI | |
SB R2,2(R4) | |
BRA .L30 | |
.L40: | |
MOV R3,R5 | |
SUB R9,R5 ; subsi3 | |
ADD R9,R4 ; addsi3 | |
ADD R9,R2 ; addsi3_raw | |
CMP R3,R9 | |
BZ .L30 | |
LB (R2),R3 ; Zero-Extend:QI | |
SB R3,(R4) | |
MOV R5,R3 | |
ADD -1,R3 ; addsi3_raw | |
BZ .L30 | |
LB 1(R2),R8 ; Zero-Extend:QI | |
SB R8,1(R4) | |
CMP 2,R5 | |
BNZ .L21 | |
BRA .L30 | |
.L17: | |
MOV R4,R10 | |
ADD R3,R10 ; addsi3 | |
MOV R10,R3 | |
.L23: | |
ADD 1,R4 ; addsi3 | |
ADD 1,R2 ; addsi3 | |
LB -1(R2),R5 ; Zero-Extend:QI | |
SB R5,-1(R4) | |
CMP R3,R4 | |
BNZ .L23 | |
.L30: | |
LW (SP),R5 | |
LW 4(SP),R6 | |
LW 8(SP),R7 | |
LW 12(SP),R8 | |
LW 16(SP),R9 | |
LW 20(SP),R10 | |
ADD 24,SP ; addsi3 | |
RETN | |
.size memcpy, .-memcpy | |
.ident "GCC: (zip-gcc-170306) 6.2.0" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment