/* This C language subroutine provides heap memory management for the runtime library. The Run Time Library for the C Language. Gordon A. Sterling (617) 461 - 3076 DSP Development Tools Engineering Created on 12/9/90 Updated on 5/94 by AS #include
void *realloc(void *ptr, size_t new_size); */ #include "lib_glob.h" #include "sdl_glob.h" .SEGMENT/CODE Code_Space_Name; .FILE RTL_FILENAME; .EXTERN _malloc, _free; .GLOBAL _realloc; _realloc: put(R3); put(R13); CALL (PC, ___lib_get_heap_info) (DB); /*Read heap information*/ R2=PASS R8, put(R14); R8=PASS R4, put(R15); realloc_core: R0=PASS R2; /*Test for zero input*/ IF EQ JUMP (PC, restore_state); /*Return NULL ptr*/ R3=PASS R3; /*Test for DM/PM alloc*/ IF GT JUMP (PC, pm_reallocation) (DB); /*Allocated from PM*/ dm_lnt=0; /*Clear length registers*/ pm_lnt=0; /* for DM and PM*/ dm_reallocation:R12=R8-1; dm_ptr=R12; /*First test if current block is ok*/ R12=DM(dm_M1, dm_ptr); /*Read length of original block*/ R4=R2-R12, R0=R8; /*Test for new block <= old block*/ IF LE JUMP (PC, no_malloc_dm); /*Do not need to malloc, return input*/ malloc_block_dm:R14=PASS R2, R15=R8; /*Save these during malloc*/ R4=PASS R2, CALLER_HOLD(R2) CALLER_SWAP RTLCALL (PC, _malloc) (DB); SAVE_OLD_FRAME(R2) SAVE_RET_ADDR R0=PASS R0; /*Test for NULL*/ IF EQ JUMP (PC, restore_state); /*If NULL return NULL*/ copy_blocks_dm: R2=PASS R14, R8=R15; /*Restore from call */ R15=dma_i; R14=dma_l; dm_ptr=R8; /*Point to old block*/ dma_i=R0; /*Point to new block*/ dma_l=0; /*Shut of circular addressing*/ R4=DM(-2, dm_ptr); /*Get length of old block*/ R12=DM(-2, dma_i); /*Get length of new block*/ R4=MIN(R4,R12); /*Get minimum length of two blocks*/ LCNTR=R4, DO move_block_dm UNTIL LCE; /*Copy the original block to new block*/ R12=DM(dm_ptr,dm_1); move_block_dm: DM(dma_i,dm_1)=R12; dma_i=R15; dma_l=R14; free_blocks_dm: R14=PASS R8, R4=R8; /*Copy address to be freed*/ R15=PASS R0, CALLER_HOLD(R2) CALLER_SWAP RTLCALL (PC, _free) (DB); SAVE_OLD_FRAME(R2) SAVE_RET_ADDR JUMP (PC, restore_state) (DB); R0=PASS R15; nop; no_malloc_dm: R4=ABS R4; /*Compute size to free*/ R12=3; /*Minimum size to free*/ COMP(R12,R4); IF GT JUMP (PC, restore_state); /*Not worth freeing, return now*/ R12=R2+R8, DM(dm_M1,dm_ptr)=R2; /*Compute end of new block, set new len*/ R4=R4-1, dm_ptr=R12; /*Point to end of new block*/ JUMP (PC, free_blocks_dm) (DB); /*Free end of block and return */ R12=R12+1; /*Point to block+1 for free*/ R8=PASS R12, DM(dm_ptr,dm_0)=R4; /*Set length of block*/ pm_reallocation:R12=R8-1; pm_ptr=R12; /*First test if current block is ok*/ R12=PM(pm_M1, pm_ptr); /*Read length of original block*/ R4=R2-R12, R0=R8; /*Test for new block <= old block*/ IF LE JUMP (PC, no_malloc_pm); /*Do not need to malloc, return input*/ malloc_block_pm:R14=PASS R2, R15=R8; /*Save these during malloc*/ R4=PASS R2, CALLER_HOLD(R2) CALLER_SWAP RTLCALL (PC, _malloc) (DB); SAVE_OLD_FRAME(R2) SAVE_RET_ADDR R0=PASS R0; /*Test for NULL*/ IF EQ JUMP restore_state; /*If NULL return NULL*/ copy_blocks_pm: R2=PASS R14, R8=R15; /*Restore from call */ R15=pma_i; R14=pma_l; pm_ptr=R8; /*Point to old block*/ pma_i=R0; /*Point to new block*/ pma_l=0; /*Shut of circular addressing*/ R4=PM(pm_M1,pm_ptr); /*Get length of old block*/ R12=PM(pm_M1,pma_i); /*Get length of new block*/ R4=MIN(R4,R12); /*Get minimum length of two blocks*/ LCNTR=R4, DO move_block_pm UNTIL LCE; /*Copy the original block to new block*/ R12=PM(pm_ptr,pm_1); move_block_pm: PM(pma_i,pm_1)=R12; pma_i=R15; pma_l=R14; free_blocks_pm: R14=PASS R8, R4=R8; /*Copy address of block to be freed*/ R15=PASS R0, CALLER_HOLD(R2) CALLER_SWAP RTLCALL (PC, _free) (DB); SAVE_OLD_FRAME(R2) SAVE_RET_ADDR JUMP (PC, restore_state) (DB); nop; R0=PASS R15; no_malloc_pm: R4=ABS R4; /*Compute size to free*/ R12=3; /*Minimum size to free*/ COMP(R12,R4); IF GT JUMP (PC, restore_state); /*Not worth freeing, return now*/ R12=R2+R8, PM(pm_M1,pm_ptr)=R2; /*Compute end of new block, set new length*/ R4=R4-1, pm_ptr=R12; /*Point to end of new block*/ JUMP (PC, free_blocks_pm) (DB); /*Free end of block and return */ R12=R12+1; /*Point to block+1 for free*/ R8=PASS R12, PM(pm_ptr,pm_0)=R4; /*Set length of block*/ restore_state: FETCH_RETURN get(R15,1); get(R14,2); get(R13,3); get(R3,4); RETURN (DB); RESTORE_STACK RESTORE_FRAME .ENDSEG;