1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-07 23:29:39 +00:00

Replaced free.c by an assembler version

git-svn-id: svn://svn.cc65.org/cc65/trunk@158 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2000-07-16 22:09:58 +00:00
parent c6546592b6
commit bc320797c6
3 changed files with 256 additions and 75 deletions

View File

@ -15,20 +15,73 @@
C_OBJS = fclose.o fgets.o fprintf.o strdup.o calloc.o _fopen.o\
fputs.o fread.o fwrite.o gets.o realloc.o bsearch.o strxfrm.o\
printf.o _hextab.o malloc.o free.o vfprintf.o fdopen.o strtok.o\
printf.o _hextab.o malloc.o vfprintf.o fdopen.o strtok.o\
_afailed.o fopen.o fgetc.o fputc.o puts.o gets.o perror.o getchar.o\
_printf.o vprintf.o vsprintf.o sprintf.o abort.o qsort.o putchar.o\
errormsg.o _hadd.o cprintf.o vcprintf.o freopen.o locale.o
S_OBJS = isalpha.o isdigit.o _file.o fmisc.o strlower.o strchr.o tolower.o\
toupper.o errno.o strcpy.o strlen.o strcat.o strcmp.o itoa.o\
strupper.o isalpha.o isalnum.o isgraph.o islower.o isupper.o\
isprint.o ispunct.o isspace.o isxdigit.o isblank.o strrchr.o\
_stksize.o _heap.o stricmp.o strncmp.o strncpy.o atoi.o setjmp.o\
longjmp.o rand.o atexit.o memset.o memcpy.o memchr.o memcmp.o\
ltoa.o strcspn.o strncat.o strpbrk.o strspn.o abs.o labs.o jmpvec.o\
_fdesc.o stkcheck.o zerobss.o copydata.o _swap.o strstr.o strcoll.o\
_sys.o getcpu.o _oserror.o strerror.o iscntrl.o maperrno.o
S_OBJS = _fdesc.o \
_file.o \
_heap.o \
_oserror.o \
_stksize.o \
_swap.o \
_sys.o \
abs.o \
atexit.o \
atoi.o \
copydata.o \
errno.o \
fmisc.o \
free.o \
getcpu.o \
isalnum.o \
isalpha.o \
isblank.o \
iscntrl.o \
isdigit.o \
isgraph.o \
islower.o \
isprint.o \
ispunct.o \
isspace.o \
isupper.o \
isxdigit.o \
itoa.o \
jmpvec.o \
labs.o \
longjmp.o \
ltoa.o \
maperrno.o \
memchr.o \
memcmp.o \
memcpy.o \
memset.o \
rand.o \
setjmp.o \
stkcheck.o \
strcat.o \
strchr.o \
strcmp.o \
strcoll.o \
strcpy.o \
strcspn.o \
strerror.o \
stricmp.o \
strlen.o \
strlower.o \
strncat.o \
strncmp.o \
strncpy.o \
strpbrk.o \
strrchr.o \
strspn.o \
strstr.o \
strupper.o \
tolower.o \
toupper.o \
zerobss.o
all: $(C_OBJS) $(S_OBJS)

View File

@ -1,65 +0,0 @@
/*
* free.c
*
* Ullrich von Bassewitz, 11.08.1998
*/
#include <stdlib.h>
#include "_heap.h"
void free (void* block)
/* Release an allocated memory block. The function will accept NULL pointers
* (and do nothing in this case).
*/
{
unsigned* b;
unsigned size;
struct freeblock* f;
/* Allow NULL arguments */
if (block == 0) {
return;
}
/* Get a pointer to the real memory block, then get the size */
b = (unsigned*) block;
size = *--b;
/* Check if the block is at the top of the heap */
if (((int) b) + size == (int) _hptr) {
/* Decrease _hptr to release the block */
_hptr = (unsigned*) (((int) _hptr) - size);
/* Check if the last block in the freelist is now at heap top. If so,
* remove this block from the freelist.
*/
if (f = _hlast) {
if (((int) f) + f->size == (int) _hptr) {
/* Remove the last block */
_hptr = (unsigned*) (((int) _hptr) - f->size);
if (_hlast = f->prev) {
/* Block before is now last block */
f->prev->next = 0;
} else {
/* The freelist is empty now */
_hfirst = 0;
}
}
}
} else {
/* Not at heap top, enter the block into the free list */
_hadd (b, size);
}
}

193
libsrc/common/free.s Normal file
View File

@ -0,0 +1,193 @@
;
; Ullrich von Bassewitz, 19.03.2000
;
; Free a block on the heap.
;
; void __fastcall__ free (void* block);
;
;
; C implementation was:
;
; void free (void* block)
; /* Release an allocated memory block. The function will accept NULL pointers
; * (and do nothing in this case).
; */
; {
; unsigned* b;
; unsigned size;
; struct freeblock* f;
;
;
; /* Allow NULL arguments */
; if (block == 0) {
; return;
; }
;
; /* Get a pointer to the real memory block, then get the size */
; b = (unsigned*) block;
; size = *--b;
;
; /* Check if the block is at the top of the heap */
; if (((int) b) + size == (int) _hptr) {
;
; /* Decrease _hptr to release the block */
; _hptr = (unsigned*) (((int) _hptr) - size);
;
; /* Check if the last block in the freelist is now at heap top. If so,
; * remove this block from the freelist.
; */
; if (f = _hlast) {
; if (((int) f) + f->size == (int) _hptr) {
; /* Remove the last block */
; _hptr = (unsigned*) (((int) _hptr) - f->size);
; if (_hlast = f->prev) {
; /* Block before is now last block */
; f->prev->next = 0;
; } else {
; /* The freelist is empty now */
; _hfirst = 0;
; }
; }
; }
;
; } else {
;
; /* Not at heap top, enter the block into the free list */
; _hadd (b, size);
;
; }
; }
;
.importzp ptr1, ptr2
.import __hptr, __hfirst, __hlast
.import pushax, __hadd
.export _free
; Offsets into struct freeblock
size = 0
next = 2
prev = 4
; Code
_free: sta ptr1
stx ptr1+1 ; Save block
; Is the argument NULL?
ora ptr1+1 ; Is the argument NULL?
beq @L9 ; Jump if yes
; Decrement the given pointer by 2. The size of the block is stored there.
; Remember the block size in ptr2.
sec
lda ptr1
sbc #2
sta ptr1
bcs @L1
dec ptr1+1
@L1: ldy #size+1
lda (ptr1),y ; High byte of size
sta ptr2+1 ; Save it
dey
lda (ptr1),y
sta ptr2
; Check if the block is on top of the heap
clc
adc ptr1
tay
lda ptr1+1
adc ptr2+1
cpy __hptr
bne @AddToFreeList
cmp __hptr+1
bne @AddToFreeList
; The pointer is located at the heap top. Lower the heap top pointer to
; release the block.
@L3: lda ptr1
sta __hptr
lda ptr1+1
sta __hptr+1
; Check if the last block in the freelist is now at heap top. If so, remove
; this block from the freelist.
lda __hlast
sta ptr2
ora __hlast+1
beq @L9 ; Jump if free list empty
lda __hlast+1
sta ptr2+1 ; Pointer to last block now in ptr2
clc
ldy #size
lda (ptr2),y ; Low byte of block size
adc ptr2
tax
iny ; High byte of block size
lda (ptr2),y
adc ptr2+1
cmp __hptr+1
bne @L9 ; Jump if last block not on top of heap
cpx __hptr
bne @L9 ; Jump if last block not on top of heap
; Remove the last block
lda ptr2
sta __hptr
lda ptr2+1
sta __hptr+1
; Correct the next pointer of the now last block
ldy #prev+1 ; Offset of ->prev field
lda (ptr2),y
sta ptr1+1 ; Remember f->prev in ptr1
sta __hlast+1
dey
lda (ptr2),y
sta ptr1 ; Remember f->prev in ptr1
sta __hlast
ora __hlast+1 ; -> prev == 0?
bne @L8 ; Jump if free list not empty
; Free list is now empty (A = 0)
sta __hfirst
sta __hfirst+1
; Done
@L9: rts
; Block before is now last block. ptr1 points to f->prev.
@L8: lda #$00
dey ; Points to high byte of ->next
sta (ptr1),y
dey ; Low byte of f->prev->next
sta (ptr1),y
rts ; Done
; The block is not on top of the heap. Add it to the free list.
@AddToFreeList:
lda ptr1
ldx ptr1+1
jsr pushax ; Push b
lda ptr2
ldx ptr2+1
jsr pushax ; Push size
jmp __hadd ; Add to free list and return