Merge pull request #10 from Diegoisawesome/master

Ported libc from pokeruby
This commit is contained in:
YamaArashi 2016-11-01 08:21:13 -07:00 committed by GitHub
commit 2ec5b0cedd
5 changed files with 179 additions and 217 deletions

View File

@ -59,8 +59,7 @@ asm/libmks4agb.o \
asm/libagbbackup.o \ asm/libagbbackup.o \
asm/librtc.o \ asm/librtc.o \
asm/librfu.o \ asm/librfu.o \
asm/libagbsyscall.o \ asm/libagbsyscall.o
asm/libc.o
DATA_ASM_OBJS := data/data2.o data/anim_mon_front_pics.o \ DATA_ASM_OBJS := data/data2.o data/anim_mon_front_pics.o \
data/graphics.o data/unknown_serial_data.o data/multiboot_berry_glitch_fix.o \ data/graphics.o data/unknown_serial_data.o data/multiboot_berry_glitch_fix.o \
@ -102,6 +101,9 @@ include graphics_file_rules.mk
%.lz: % ; $(GFX) $< $@ %.lz: % ; $(GFX) $< $@
%.rl: % ; $(GFX) $< $@ %.rl: % ; $(GFX) $< $@
src/libc.o: CC1 := tools/agbcc/bin/old_agbcc
src/libc.o: CFLAGS := -O2
src/siirtc.o: CFLAGS := -mthumb-interwork src/siirtc.o: CFLAGS := -mthumb-interwork
src/agb_flash.o: CFLAGS := -O -mthumb-interwork src/agb_flash.o: CFLAGS := -O -mthumb-interwork

View File

@ -1,213 +0,0 @@
.include "asm/macros.s"
.syntax unified
.text
thumb_func_start memcpy
@ void *memcpy(void *dest, void *src, int size)
memcpy: @ 82E93D4
push {r4,r5,lr}
adds r5, r0, 0
adds r4, r5, 0
adds r3, r1, 0
cmp r2, 0xF
bls _082E9414
adds r0, r3, 0
orrs r0, r5
movs r1, 0x3
ands r0, r1
cmp r0, 0
bne _082E9414
adds r1, r5, 0
_082E93EE:
ldm r3!, {r0}
stm r1!, {r0}
ldm r3!, {r0}
stm r1!, {r0}
ldm r3!, {r0}
stm r1!, {r0}
ldm r3!, {r0}
stm r1!, {r0}
subs r2, 0x10
cmp r2, 0xF
bhi _082E93EE
cmp r2, 0x3
bls _082E9412
_082E9408:
ldm r3!, {r0}
stm r1!, {r0}
subs r2, 0x4
cmp r2, 0x3
bhi _082E9408
_082E9412:
adds r4, r1, 0
_082E9414:
subs r2, 0x1
movs r0, 0x1
negs r0, r0
cmp r2, r0
beq _082E942E
adds r1, r0, 0
_082E9420:
ldrb r0, [r3]
strb r0, [r4]
adds r3, 0x1
adds r4, 0x1
subs r2, 0x1
cmp r2, r1
bne _082E9420
_082E942E:
adds r0, r5, 0
pop {r4,r5,pc}
thumb_func_end memcpy
thumb_func_start memset
@ void *memset(void *dest, char c, int size)
memset: @ 82E9434
push {r4,r5,lr}
adds r5, r0, 0
adds r4, r1, 0
adds r3, r5, 0
cmp r2, 0x3
bls _082E947A
movs r0, 0x3
ands r0, r5
cmp r0, 0
bne _082E947A
adds r1, r5, 0
movs r0, 0xFF
ands r4, r0
lsls r3, r4, 8
orrs r3, r4
lsls r0, r3, 16
orrs r3, r0
cmp r2, 0xF
bls _082E946E
_082E945A:
stm r1!, {r3}
stm r1!, {r3}
stm r1!, {r3}
stm r1!, {r3}
subs r2, 0x10
cmp r2, 0xF
bhi _082E945A
b _082E946E
_082E946A:
stm r1!, {r3}
subs r2, 0x4
_082E946E:
cmp r2, 0x3
bhi _082E946A
adds r3, r1, 0
b _082E947A
_082E9476:
strb r4, [r3]
adds r3, 0x1
_082E947A:
adds r0, r2, 0
subs r2, 0x1
cmp r0, 0
bne _082E9476
adds r0, r5, 0
pop {r4,r5,pc}
thumb_func_end memset
thumb_func_start strcmp
@ int strcmp(char *s1, char *s2)
strcmp: @ 82E9488
push {r4,r5,lr}
adds r2, r0, 0
adds r3, r1, 0
orrs r0, r3
movs r1, 0x3
ands r0, r1
cmp r0, 0
bne _082E94CE
ldr r1, [r2]
ldr r0, [r3]
cmp r1, r0
bne _082E94CE
ldr r5, _082E94B4
ldr r4, _082E94B8
_082E94A4:
ldr r1, [r2]
adds r0, r1, r5
bics r0, r1
ands r0, r4
cmp r0, 0
beq _082E94BC
movs r0, 0
b _082E94E0
.align 2, 0
_082E94B4: .4byte 0xfefefeff
_082E94B8: .4byte 0x80808080
_082E94BC:
adds r2, 0x4
adds r3, 0x4
ldr r1, [r2]
ldr r0, [r3]
cmp r1, r0
beq _082E94A4
b _082E94CE
_082E94CA:
adds r2, 0x1
adds r3, 0x1
_082E94CE:
ldrb r0, [r2]
cmp r0, 0
beq _082E94DA
ldrb r1, [r3]
cmp r0, r1
beq _082E94CA
_082E94DA:
ldrb r2, [r2]
ldrb r3, [r3]
subs r0, r2, r3
_082E94E0:
pop {r4,r5,pc}
thumb_func_end strcmp
thumb_func_start strcat
strcat: @ 82E94E4
push {r4-r6,lr}
adds r6, r0, 0
adds r3, r6, 0
adds r2, r1, 0
adds r0, r2, 0
orrs r0, r6
movs r1, 0x3
ands r0, r1
cmp r0, 0
bne _082E951C
ldr r1, [r2]
ldr r5, _082E9504
adds r0, r1, r5
bics r0, r1
ldr r4, _082E9508
b _082E9516
.align 2, 0
_082E9504: .4byte 0xfefefeff
_082E9508: .4byte 0x80808080
_082E950C:
ldm r2!, {r0}
stm r3!, {r0}
ldr r1, [r2]
adds r0, r1, r5
bics r0, r1
_082E9516:
ands r0, r4
cmp r0, 0
beq _082E950C
_082E951C:
ldrb r0, [r2]
strb r0, [r3]
lsls r0, 24
adds r2, 0x1
adds r3, 0x1
cmp r0, 0
bne _082E951C
adds r0, r6, 0
pop {r4-r6,pc}
.align 2, 0 @ Don't pad with nop.

View File

@ -2523,7 +2523,7 @@ task00_link_test: @ 800A850
sub sp, 0x20 sub sp, 0x20
ldr r1, =gUnknown_082ED1E4 ldr r1, =gUnknown_082ED1E4
mov r0, sp mov r0, sp
bl strcat bl strcpy
mov r0, sp mov r0, sp
movs r1, 0x5 movs r1, 0x5
movs r2, 0x2 movs r2, 0x2

View File

@ -86,7 +86,7 @@ SECTIONS {
tools/agbcc/lib/libgcc.a:fp-bit.o(.text); tools/agbcc/lib/libgcc.a:fp-bit.o(.text);
tools/agbcc/lib/libgcc.a:_lshrdi3.o(.text); tools/agbcc/lib/libgcc.a:_lshrdi3.o(.text);
tools/agbcc/lib/libgcc.a:_negdi2.o(.text); tools/agbcc/lib/libgcc.a:_negdi2.o(.text);
asm/libc.o(.text); src/libc.o(.text);
} =0 } =0
.rodata : .rodata :

173
src/libc.c Normal file
View File

@ -0,0 +1,173 @@
#include "global.h"
#include <stddef.h>
#define LBLOCKSIZE (sizeof(long))
// Nonzero if (long)X contains a NULL byte.
#define CONTAINSNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
// Nonzero if X is not aligned on a "long" boundary.
#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
void *memcpy(void *dst0, const void *src0, size_t len0)
{
char *dst = dst0;
const char *src = src0;
long *aligned_dst;
const long *aligned_src;
unsigned int len = len0;
// If the size is small, or either src or dst is unaligned,
// then go to the byte copy loop. This should be rare.
if(len >= 16 && !(UNALIGNED(src) | UNALIGNED(dst)))
{
aligned_dst = (long *)dst;
aligned_src = (long *)src;
// Copy 4X long words at a time if possible.
while(len >= 16)
{
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
len -= 16;
}
// Copy one long word at a time if possible
while(len >= 4)
{
*aligned_dst++ = *aligned_src++;
len -= 4;
}
dst = (char *)aligned_dst;
src = (char *)aligned_src;
}
// Pick up any remaining bytes with a byte copier.
while(len--)
*dst++ = *src++;
return dst0;
}
void *memset(void *m, int c, size_t n)
{
char *s = (char *)m;
int count, i;
unsigned long buffer;
unsigned long *aligned_addr;
unsigned char *unaligned_addr;
// If the size is small or m is unaligned,
// then go to the byte copy loop. This should be rare.
if(n >= LBLOCKSIZE && !UNALIGNED(m))
{
// We know that n is large and m is word-aligned.
aligned_addr = (unsigned long *)m;
// Store C into each char sized location in buffer so that
// we can set large blocks quickly.
c &= 0xFF;
if(LBLOCKSIZE == 4)
{
buffer = (c << 8) | c;
buffer |= (buffer << 16);
}
else
{
buffer = 0;
for(i = 0; i < LBLOCKSIZE; i++)
buffer = (buffer << 8) | c;
}
while(n >= LBLOCKSIZE * 4)
{
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
n -= LBLOCKSIZE * 4;
}
while(n >= LBLOCKSIZE)
{
*aligned_addr++ = buffer;
n -= LBLOCKSIZE;
}
s = (char *)aligned_addr;
}
// Pick up the remainder with a bytewise loop.
while(n--)
*s++ = (char)c;
return m;
}
int strcmp(const char *s1, const char *s2)
{
unsigned long *a1;
unsigned long *a2;
// If s1 or s2 are unaligned, then skip this and compare bytes.
if(!(UNALIGNED(s1) | UNALIGNED(s2)))
{
// Compare them a word at a time.
a1 = (unsigned long *)s1;
a2 = (unsigned long *)s2;
while(*a1 == *a2)
{
// If *a1 == *a2, and we find a null in *a1,
// then the strings must be equal, so return zero.
if(CONTAINSNULL(*a1))
return 0;
a1++;
a2++;
}
s1 = (char *)a1;
s2 = (char *)a2;
}
// Check the remaining few bytes.
while(*s1 != '\0' && *s1 == *s2)
{
s1++;
s2++;
}
return (*(unsigned char *) s1) - (*(unsigned char *) s2);
}
char* strcpy(char *dst0, const char *src0)
{
char *dst = dst0;
const char *src = src0;
unsigned long *a1;
const unsigned long *a2;
/* If SRC or DEST is unaligned, then copy bytes. */
if(!(UNALIGNED(src) | UNALIGNED(dst)))
{
/* SRC and DEST are both "long int" aligned, try to do "long int"
sized copies. */
a1 = (unsigned long *)dst;
a2 = (unsigned long *)src;
while(!CONTAINSNULL(*a2))
{
*a1++ = *a2++;
}
dst = (char *)a1;
src = (char *)a2;
}
// Copy the remaining few bytes.
while(*dst++ = *src++);
return dst0;
}