#ifndef STACK1_C #define STACK1_C // obsolete; should be replaced by gts_stack.c but string_to_graph still uses this // file. #include "globals.h" #include "global_registers.h" .align 4 .data .align 4 stackTop: .long 0 stackBottom: .long 0 // ----------------------------------------------------------------------------------- descStackTop: .long 0 // initialized at stackTop; is stack pointer .text .macro _pushl_descriptor_prefix2 dest // descStackTop points to last element #ifdef COLOUR_GRAPH subl $3,free // free -= 3 (= 3 * 4 bytes) #else subl $2,free // free -= 2 (= 2 * 4 bytes) #endif js garbage_collection movl descStackTop,\dest // dest = descStackTop #ifdef COLOUR_GRAPH #define DESCRIPTOR1_PREFIX_ENTRY_SIZE 16 #define DPT1_PREFIX_SET_AND_STRING_PTR 0 #define DPT1_VIRTUAL_BASE 4 #define DPT1_LIBRARY_NUMBER 8 #define DPT1_DESCP_USAGE_SET_PTR 12 subl $ DESCRIPTOR_PR1EFIX_ENTRY_SIZE,\dest // dest -= 8 #else subl $8,\dest // dest -= 8 #endif movl \dest,descStackTop // descStackTop -= 8 .endm // ----------------------------------------------------------------------------------- .macro _pushl1 reg //label //gc cmpl stackTop,stackP // stackP > stackTop ja 0f //jae \label subl $1,free js garbage_collection // \gc subl $4,stackTop // stackTop -= 4 0: subl $4,stackP // stackP -= 4 movl \reg,(stackP) .endm // stack // copy of above; replaced garbage_collection by garbage_collection2 .macro _pushl3 reg //label //gc cmpl stackTop,stackP // stackP > stackTop ja 0f //\label //jae \label subl $1,free js garbage_collection2 // \gc subl $4,stackTop // stackTop -= 4 0: subl $4,stackP // stackP -= 4 movl \reg,(stackP) .endm // _popl .macro _popl1 reg _popl_gc \reg garbage_collection .endm .macro _popl3 reg _popl_gc \reg garbage_collection2 .endm .macro _popl_gc reg gc cmpl stackBottom,stackP je \gc movl (stackP),\reg addl $4,stackP .endm // _stack_empty .macro _stack_empty3 label _stack_empty \label .endm .macro _stack_empty label cmpl stackBottom,stackP je \label .endm .macro N_reserve_stack_block t // l1 l2 movl stackP,\t subl stackTop,\t // temp = stackP - stackTop shrl $2,\t cmpl \t,arity // arity < temp jbe 0f // \l1 // enough space between stackTop and stackP // arity > temp // arity = arity - temp subl \t,arity // arity - available space between stackTop and stackP subl arity,free // free -= rest of arity js garbage_collection addl \t,arity shll $2,arity subl arity,stackP // stackP -= arity movl stackP,stackTop shrl $2,arity // arity /= 4 jmp 1f //\l2 0: // \l1: movl arity,\t shll $2,arity // arity *= 4 subl arity,stackP // reserve space between stackTop and stackP movl \t,arity 1: // \l2: .endm /* ** _copy_heap_block: ** ** call by: ** ** - source ** the source address ** - arity ** number of longs to copy */ .macro _copy_heap_block subl arity,free // free < length js garbage_collection cld rep movsl .endm /* ** _copy_stack_block: ** ** call by: ** - source ** the source address ** - arity ** number of longs to copy ** - t ** temporary register ** - l ** a globally unique label name ** ** result: ** - if possible arity * 4 longs of the stack have been reserved, containing ** the longs stored at source; the first long is stored at the tos. */ /* .macro N_copy_stack_block t l1 l2 N_copy_stack_block_gc \t \l1 \l2 garbage_collection .endm */ .macro N_copy_stack_block t // l1 l2 /* ** N_reserve_stack_block \t \l1 \l2 */ movl stackP,\t subl stackTop,\t // temp = stackP - stackTop shrl $2,\t cmpl \t,arity // arity < temp jbe 0f // \l1 // enough space between stackTop and stackP // arity > temp // arity = arity - temp subl \t,arity // arity - available space between stackTop and stackP subl arity,free // free -= rest of arity js garbage_collection addl \t,arity shll $2,arity subl arity,stackP // stackP -= arity movl stackP,stackTop // subl arity,stackTop // stackTop -= arity shrl $2,arity // arity /= 4 jmp 1f // \l2 0: // \l1: movl arity,\t shll $2,arity // arity *= 4 subl arity,stackP // reserve space between stackTop and stackP movl \t,arity 1: //\l2: /* ** Copy part */ movl heapP,\t movl stackP,heapP cld rep movsl movl \t,heapP .endm // copy of the above; instead garbage_collection2 is called .macro N_copy_stack_block3 t //l1 l2 /* ** N_reserve_stack_block \t \l1 \l2 */ movl stackP,\t subl stackTop,\t // temp = stackP - stackTop shrl $2,\t cmpl \t,arity // arity < temp jbe 0f //\l1 // enough space between stackTop and stackP // arity > temp // arity = arity - temp subl \t,arity // arity - available space between stackTop and stackP subl arity,free // free -= rest of arity js garbage_collection2 addl \t,arity shll $2,arity subl arity,stackP // stackP -= arity movl stackP,stackTop // subl arity,stackTop // stackTop -= arity shrl $2,arity // arity /= 4 jmp 1f //\l2 0: // \L1: movl arity,\t shll $2,arity // arity *= 4 subl arity,stackP // reserve space between stackTop and stackP movl \t,arity 1: //\l2: /* ** Copy part */ movl heapP,\t movl stackP,heapP cld rep movsl movl \t,heapP .endm //#ifdef DYNAMIC_SUPPORT .macro _done //okdone cmpl esp_backup,%esp je 0f // \okdone ret 0: //\okdone: .endm //#endif .macro _reserve_stack_block2 t cmpl stackTop,stackP // stackP <= stackTop jbe garbage_collection2 // stackP > stackTop movl stackP,\t subl stackTop,\t // free_stack_space = stackP - stackTop shrl $2,\t // free_stack_space in longs cmpl \t,arity // arity > free_stack_space ja garbage_collection2 // out of memory, garbage collect // Enough space available movl arity,\t shll $2,\t // temp = arity * 4 subl \t,stackP // stackP -= arity * 4 .endm .macro _copy_stack_block2 t cmpl stackTop,stackP // stackP <= stackTop jbe garbage_collection2 // stackP > stackTop movl stackP,\t subl stackTop,\t // free_stack_space = stackP - stackTop shrl $2,\t // free_stack_space in longs cmpl \t,arity // arity > free_stack_space ja garbage_collection2 // out of memory, garbage collect // Enough space available, reserve stack memory movl arity,\t shll $2,\t // temp = arity * 4 subl \t,stackP // stackP -= arity * 4 // Copy to reserved memory area movl heapP,\t // backup heapP movl stackP,heapP // set destination cld rep movsl movl \t,heapP // restore heapP .endm //#ifdef zzz .macro _pushl2 reg /* cmpl stackTop,stackP // stackP <= stackTop jbe garbage_collection2 */ subl $4,stackP movl \reg,(stackP) .endm //#endif // ------------------------------------------------------------------------------------------ // support for a moveable stack // ecx = amount of bytes to move; preserves all registers except for status .align 4 .text nop nop nop nop move_stack_downwards: #define n_bytes %ecx pushl %esi pushl %edi pushl %eax pushl %ebx #define newStackP %eax #define temp %ebx movl stackP,newStackP subl n_bytes,newStackP // newStackP = stackP - n_bytes pushl newStackP move_stack_loop: cmpl stackP,stackBottom je move_stack_downwards2 movl (stackP),temp movl temp,(newStackP) addl $4,stackP addl $4,newStackP jmp move_stack_loop move_stack_downwards2: popl stackP movl stackBottom,temp subl n_bytes,temp movl temp,stackBottom // stackBotom -= n_words movl stackTop,temp subl n_bytes,temp movl temp,stackTop // stackTop -= n_words #undef temp #undef newStackP popl %ebx popl %eax popl %edi popl %esi ret nop nop nop nop nop nop #undef n_bytes #endif