diff --git a/src/libc/allocator.src b/src/libc/allocator.src new file mode 100644 index 000000000..b235f7ae7 --- /dev/null +++ b/src/libc/allocator.src @@ -0,0 +1,51 @@ + assume adl=1 + + section .text + public _malloc, _calloc, _free, _realloc + + public _calloc +_calloc: + pop de + pop bc + ex (sp),hl + push bc + push de + call __imulu + push hl + call _malloc + add hl,de + xor a,a + sbc hl,de + ld e,a + push de + push hl + call nz,_memset + pop hl + pop de + pop bc + ret + +if defined ALLOCATOR_SIMPLE + +_malloc := __simple_malloc +_free := __simple_free +_realloc := __simple_realloc + +end if + +if defined ALLOCATOR_STANDARD + +_malloc := __standard_malloc +_free := __standard_free +_realloc := __standard_realloc + +end if + + extern __simple_free + extern __simple_malloc + extern __simple_realloc + extern __standard_malloc + extern __standard_free + extern __standard_realloc + extern __imulu + extern _memset diff --git a/src/libc/allocator_simple.src b/src/libc/allocator_simple.src new file mode 100644 index 000000000..d8ac259c2 --- /dev/null +++ b/src/libc/allocator_simple.src @@ -0,0 +1,39 @@ + assume adl = 1 + + section .text + public __malloc_simple +__simple_malloc: + pop bc + ex (sp),de + push bc + ld bc,___heapbot + ld iy,(_heap_size) + add iy,de + lea hl,iy + or a,a + sbc hl,bc + jr nc,.full + ld (_heap_size),iy + ld hl,___heapbot + add hl,de + ret +.full: + or a,a + sbc hl,hl + ret + + public __simple_free +__simple_free: + ret + + public __simple_realloc +__simple_realloc: + or a,a + sbc hl,hl + ret + + section .bss + private _heap_size +_heap_size: + rb 3 + diff --git a/src/libc/allocator_standard.c b/src/libc/allocator_standard.c new file mode 100644 index 000000000..7a5205f28 --- /dev/null +++ b/src/libc/allocator_standard.c @@ -0,0 +1,129 @@ +#include +#include +#include +#include + +typedef struct __attribute__((packed)) block +{ + struct block *ptr; + size_t size; +} __attribute__((packed)) block_t; + +extern uint8_t ___heapbot[]; +extern uint8_t ___heaptop[]; +static uintptr_t heap_ptr = (uintptr_t)___heapbot; +static block_t _alloc_base; + +void *_standard_malloc(size_t alloc_size) +{ + uintptr_t heap_ptr_new; + block_t *p; + block_t *q; + block_t *r; + size_t size; + + /* add size of block header to real size */ + size = alloc_size + sizeof(block_t); + if (size < alloc_size) + { + return NULL; + } + + for (p = &_alloc_base; (q = p->ptr); p = q) + { + if (q->size >= size) + { + if (q->size <= size + sizeof(block_t)) + { + p->ptr = q->ptr; + } + else + { + q->size -= size; + q = (block_t*)(((uint8_t*)q) + q->size); + q->size = size; + } + + return q + 1; + } + } + + /* compute next heap pointer */ + heap_ptr_new = heap_ptr + size; + if (heap_ptr_new < heap_ptr) + { + return NULL; + } + + /* ensure there's enough room in the heap */ + if (heap_ptr_new >= (uintptr_t)___heaptop) + { + return NULL; + } + + r = (block_t*)heap_ptr; + r->size = size; + + heap_ptr = heap_ptr_new; + + return r + 1; +} + +void _standard_free(void *ptr) +{ + if (ptr != NULL) + { + block_t *p; + block_t *q; + + q = (block_t*)ptr - 1; + + for (p = &_alloc_base; p->ptr && p->ptr < q; p = p->ptr); + + if ((uint8_t*)p->ptr == ((uint8_t*)q) + q->size) + { + q->size += p->ptr->size; + q->ptr = p->ptr->ptr; + } + else + { + q->ptr = p->ptr; + } + + if (((uint8_t*)p) + p->size == (uint8_t*)q) + { + p->size += q->size; + p->ptr = q->ptr; + } + else + { + p->ptr = q; + } + } +} + +void *_standard_realloc(void *ptr, size_t size) +{ + block_t *h; + void *p; + + if (ptr == NULL) + { + return malloc(size); + } + + h = (block_t*)((uint8_t*)ptr - sizeof(block_t)); + + if (h->size >= (size + sizeof(block_t))) + { + return ptr; + } + + if ((p = malloc(size))) + { + memcpy(p, ptr, size); + free(ptr); + } + + return p; +} diff --git a/src/libc/calloc.src b/src/libc/calloc.src deleted file mode 100644 index fef5c2ca6..000000000 --- a/src/libc/calloc.src +++ /dev/null @@ -1,29 +0,0 @@ - assume adl=1 - - section .text - public _calloc -_calloc: - pop de - pop bc - pop hl - push hl - push bc - push de - call __imulu - push hl - call _malloc - add hl,de - xor a,a - sbc hl,de - ld e,a - push de - push hl - call nz,_memset - pop hl - pop de - pop bc - ret - - extern __imulu - extern _malloc - extern _memset diff --git a/src/libc/free.c b/src/libc/free.c deleted file mode 100644 index 2e1f47e8e..000000000 --- a/src/libc/free.c +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************/ -/* */ -/* Copyright (C) 2000-2008 Zilog, Inc. */ -/* */ -/* San Jose, California */ -/* */ -/***************************************************************/ -#include - -/************************************************* -* -* free - free up allocated memory -* -* Inputs: -* ap - pointer to allocated memory -* -* Returns: -* nothing -* -*************************************************/ -extern HEADER _alloc_base; - -void free(void *ap) { - HEADER *p; - HEADER *q; - - if (!ap) { - return; - } - - q = (HEADER*)ap - 1; - - for (p = &_alloc_base; p->s.ptr && p->s.ptr < q; p = p->s.ptr); - - /* join upper */ - if ((char*)p->s.ptr == ((char*)q) + q->s.size) { - q->s.size += p->s.ptr->s.size; - q->s.ptr = p->s.ptr->s.ptr; - } else { - q->s.ptr = p->s.ptr; - } - - /* join lower */ - if (((char*)p) + p->s.size == (char*)q) { - p->s.size += q->s.size; - p->s.ptr = q->s.ptr; - } else { - p->s.ptr = q; - } -} - diff --git a/src/libc/include/stdlib.h b/src/libc/include/stdlib.h index a94702f5a..3be98a1ea 100644 --- a/src/libc/include/stdlib.h +++ b/src/libc/include/stdlib.h @@ -18,24 +18,12 @@ typedef struct { long long quot; } lldiv_t; -typedef char __align; -union header { - struct { - union header *ptr; - unsigned int size; - } s; - __align x; -}; -typedef union header _HEADER; - #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #define RAND_MAX 8388607 -#define HEADER _HEADER #define allocp _allocp -#define NALLOC 50 __BEGIN_DECLS diff --git a/src/libc/malloc.c b/src/libc/malloc.c deleted file mode 100644 index 838253b3e..000000000 --- a/src/libc/malloc.c +++ /dev/null @@ -1,89 +0,0 @@ -/************************************************************************/ -/* */ -/* Copyright (C)1987-2011 by */ -/* Zilog, Inc. */ -/* */ -/* San Jose, California */ -/* */ -/* This implements a straight forward version of malloc, allocating */ -/* memory between the first unused address in RAM (__heapbot) and */ -/* the current stack pointer; the stack pointer being initialized to */ -/* the top of RAM (__heaptop). */ -/* The Zilog real time kernel, RZK, implements an entirely */ -/* different version of malloc. */ -/* */ -/* ZDS arranges that this malloc does not get linked into RZK */ -/* applications by placing the C runtime library, crt.lib or */ -/* crtD.lib, after the RZK libraries in the linker command file. */ -/* */ -/************************************************************************/ -#include -#include - -HEADER _alloc_base; /* empty list to get started */ -extern void *sbrk(size_t); - -/************************************************* -* -* morecore - get more memory for heap -* -* Inputs: -* nu - number of units -* -* Returns: -* the address of the new memory -* -*************************************************/ - -static void* morecore(size_t nbytes) -{ - register void *cp; - if ((cp = sbrk(nbytes))) - { - ((HEADER*)cp)->s.size=nbytes; - cp = ((HEADER*)cp) + 1; - } - return cp; -} - -/************************************************* -* -* malloc - allocate heap storage -* -* Inputs: -* nbytes - number of bytes to allocate -* -* Returns: -* the address of the memory or NULL -* -*************************************************/ - -void *malloc(size_t nbytes) -{ - HEADER *p,*q; - size_t size = nbytes + sizeof(HEADER); - - if (size < nbytes) - return NULL; /* Happens on malloc(-1) or like stupidity */ - - for(p=&_alloc_base; (q=p->s.ptr); p=q) - { - if (q->s.size >= size) - { - /* big enough */ - if (q->s.size <= size+sizeof(HEADER)) - { - /* exactly enough */ - p->s.ptr = q->s.ptr; - } - else - { - q->s.size -= size; - q = (HEADER*)(((char*)q) + q->s.size); - q->s.size = size; - } - return((void*)(q+1)); - } - } - return(morecore(size)); -} diff --git a/src/libc/realloc.c b/src/libc/realloc.c deleted file mode 100644 index bc473b0b2..000000000 --- a/src/libc/realloc.c +++ /dev/null @@ -1,42 +0,0 @@ -/************************************************************************/ -/* */ -/* Copyright (C)1987-2008 by */ -/* Zilog, Inc. */ -/* */ -/* San Jose, California */ -/* */ -/************************************************************************/ -#include -#include -#include - -/************************************************* -* -* realloc - change the size of an allocated block -* -* Inputs: -* ptr - pointer to allocated memory -* size - new size of memory -* -* Returns: -* pointer to block - may have changed -* -*************************************************/ -void *realloc(void *ptr,size_t size) { - HEADER *h; - void *p; - - if (ptr) { - h = (HEADER *)((char *)ptr - sizeof(HEADER)); - if (h->s.size >= (size+sizeof(HEADER))) { - return(ptr); - } - - if ((p = malloc(size))) { - memcpy(p,ptr,size); - free(ptr); - } - return p; - } - return malloc(size); -} diff --git a/src/libc/sbrk.src b/src/libc/sbrk.src deleted file mode 100644 index 588245772..000000000 --- a/src/libc/sbrk.src +++ /dev/null @@ -1,30 +0,0 @@ - assume adl=1 - - section .text - public _sbrk -_sbrk: - pop de - ex (sp),hl - push de - ld de,(__sbrkbase) - add hl,de - jq c,.fail - ld bc,not ___heaptop - add hl,bc - jq c,.fail - sbc hl,bc - ld (__sbrkbase),hl - ex de,hl - ret -.fail: - or a,a - sbc hl,hl - ret - - section .data - private __sbrkbase -__sbrkbase: - dl ___heapbot - - extern ___heapbot - extern ___heaptop diff --git a/src/makefile.mk b/src/makefile.mk index f6ed79950..fb9ee53af 100644 --- a/src/makefile.mk +++ b/src/makefile.mk @@ -44,6 +44,7 @@ HAS_PRINTF ?= YES HAS_CUSTOM_FILE ?= NO HAS_LIBC ?= YES HAS_LIBCXX ?= YES +ALLOCATOR ?= STANDARD PREFER_OS_CRT ?= NO PREFER_OS_LIBC ?= YES LIBLOAD_OPTIONAL ?= @@ -261,6 +262,7 @@ FASMGFLAGS = \ -i $(call QUOTE_ARG,HAS_LIBCXX := $(LDHAS_LIBCXX)) \ -i $(call QUOTE_ARG,PREFER_OS_CRT := $(LDPREFER_OS_CRT)) \ -i $(call QUOTE_ARG,PREFER_OS_LIBC := $(LDPREFER_OS_LIBC)) \ + -i $(call QUOTE_ARG,ALLOCATOR_$(ALLOCATOR) := 1) \ -i $(call QUOTE_ARG,include $(call FASMG_FILES,$(LINKER_SCRIPT))) \ -i $(call QUOTE_ARG,range .bss $$$(BSSHEAP_LOW) : $$$(BSSHEAP_HIGH)) \ -i $(call QUOTE_ARG,provide __stack = $$$(STACK_HIGH)) \