X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fx86-assem.S;h=9470533fbb24860fae70a5b79dc6df2ec40ad0c5;hb=57d7dd0f59b9df89feb1175b0efc449bb0b8d400;hp=d5b3d4b81f968195b41d65adf5394b8c76644d50;hpb=a6c61ba848e9ed11118b6fb579fe237d0b1cf9c6;p=sbcl.git diff --git a/src/runtime/x86-assem.S b/src/runtime/x86-assem.S index d5b3d4b..9470533 100644 --- a/src/runtime/x86-assem.S +++ b/src/runtime/x86-assem.S @@ -124,7 +124,7 @@ GNAME(call_into_c): cld # clear out DF: Darwin, Solaris and Win32 at # least need this, and it should not hurt others - + call *%eax # normal callout using Lisp stack movl %eax,%ecx # remember integer return value @@ -166,7 +166,7 @@ Lfp_rtn_value: /* We don't need to restore eax, because the result is in st(0). */ -/* Return. */ +/* Return. FIXME: It would be nice to restructure this to use RET. */ jmp *%ebx SIZE(GNAME(call_into_c)) @@ -422,9 +422,7 @@ GNAME(do_pending_interrupt): ret SIZE(GNAME(do_pending_interrupt)) - -/* - * Allocate bytes and return the start of the allocated space +/* Allocate bytes and return the start of the allocated space * in the specified destination register. * * In the general case the size will be in the destination register. @@ -432,315 +430,128 @@ GNAME(do_pending_interrupt): * All registers must be preserved except the destination. * The C conventions will preserve ebx, esi, edi, and ebp. * So only eax, ecx, and edx need special care here. + * + * ALLOC factors out the logic of calling alloc(): stack alignment, etc. + * + * DEFINE_ALLOC_TO_FOO defines an alloction routine. */ - - .globl GNAME(alloc_to_eax) - TYPE(GNAME(alloc_to_eax)) - .align align_4byte,0x90 -GNAME(alloc_to_eax): - pushl %ecx # Save ecx and edx as C could destroy them. - pushl %edx - pushl %eax # Push the size. - call GNAME(alloc) - addl $4,%esp # Pop the size arg. - popl %edx # Restore ecx and edx. - popl %ecx - ret - SIZE(GNAME(alloc_to_eax)) - - .globl GNAME(alloc_8_to_eax) - TYPE(GNAME(alloc_8_to_eax)) - .align align_4byte,0x90 -GNAME(alloc_8_to_eax): - pushl %ecx # Save ecx and edx as C could destroy them. - pushl %edx - pushl $8 # Push the size. - call GNAME(alloc) - addl $4,%esp # Pop the size arg. - popl %edx # Restore ecx and edx. - popl %ecx - ret - SIZE(GNAME(alloc_8_to_eax)) - .globl GNAME(alloc_8_to_eax) - TYPE(GNAME(alloc_8_to_eax)) - .align align_4byte,0x90 - - .globl GNAME(alloc_16_to_eax) - TYPE(GNAME(alloc_16_to_eax)) - .align align_4byte,0x90 -GNAME(alloc_16_to_eax): - pushl %ecx # Save ecx and edx as C could destroy them. - pushl %edx - pushl $16 # Push the size. - call GNAME(alloc) - addl $4,%esp # Pop the size arg. - popl %edx # Restore ecx and edx. - popl %ecx - ret - SIZE(GNAME(alloc_16_to_eax)) - - .globl GNAME(alloc_to_ecx) - TYPE(GNAME(alloc_to_ecx)) - .align align_4byte,0x90 -GNAME(alloc_to_ecx): - pushl %eax # Save eax and edx as C could destroy them. - pushl %edx - pushl %ecx # Push the size. - call GNAME(alloc) - addl $4,%esp # Pop the size arg. - movl %eax,%ecx # Set up the destination. - popl %edx # Restore eax and edx. - popl %eax - ret - SIZE(GNAME(alloc_to_ecx)) - - .globl GNAME(alloc_8_to_ecx) - TYPE(GNAME(alloc_8_to_ecx)) - .align align_4byte,0x90 -GNAME(alloc_8_to_ecx): - pushl %eax # Save eax and edx as C could destroy them. - pushl %edx - pushl $8 # Push the size. - call GNAME(alloc) - addl $4,%esp # Pop the size arg. - movl %eax,%ecx # Set up the destination. - popl %edx # Restore eax and edx. - popl %eax - ret - SIZE(GNAME(alloc_8_to_ecx)) - - .globl GNAME(alloc_16_to_ecx) - TYPE(GNAME(alloc_16_to_ecx)) - .align align_4byte,0x90 -GNAME(alloc_16_to_ecx): - pushl %eax # Save eax and edx as C could destroy them. - pushl %edx - pushl $16 # Push the size. - call GNAME(alloc) - addl $4,%esp # Pop the size arg. - movl %eax,%ecx # Set up the destination. - popl %edx # Restore eax and edx. - popl %eax - ret - SIZE(GNAME(alloc_16_to_ecx)) - - - .globl GNAME(alloc_to_edx) - TYPE(GNAME(alloc_to_edx)) - .align align_4byte,0x90 -GNAME(alloc_to_edx): - pushl %eax # Save eax and ecx as C could destroy them. - pushl %ecx - pushl %edx # Push the size. - call GNAME(alloc) - addl $4,%esp # Pop the size arg. - movl %eax,%edx # Set up the destination. - popl %ecx # Restore eax and ecx. - popl %eax - ret - SIZE(GNAME(alloc_to_edx)) - - .globl GNAME(alloc_8_to_edx) - TYPE(GNAME(alloc_8_to_edx)) - .align align_4byte,0x90 -GNAME(alloc_8_to_edx): - pushl %eax # Save eax and ecx as C could destroy them. - pushl %ecx - pushl $8 # Push the size. - call GNAME(alloc) - addl $4,%esp # Pop the size arg. - movl %eax,%edx # Set up the destination. - popl %ecx # Restore eax and ecx. - popl %eax - ret - SIZE(GNAME(alloc_8_to_edx)) - - .globl GNAME(alloc_16_to_edx) - TYPE(GNAME(alloc_16_to_edx)) - .align align_4byte,0x90 -GNAME(alloc_16_to_edx): - pushl %eax # Save eax and ecx as C could destroy them. - pushl %ecx - pushl $16 # Push the size. - call GNAME(alloc) - addl $4,%esp # Pop the size arg. - movl %eax,%edx # Set up the destination. - popl %ecx # Restore eax and ecx. - popl %eax - ret - SIZE(GNAME(alloc_16_to_edx)) - - - - .globl GNAME(alloc_to_ebx) - TYPE(GNAME(alloc_to_ebx)) - .align align_4byte,0x90 -GNAME(alloc_to_ebx): - pushl %eax # Save eax, ecx, and edx as C could destroy them. - pushl %ecx - pushl %edx - pushl %ebx # Push the size. - call GNAME(alloc) - addl $4,%esp # Pop the size arg. - movl %eax,%ebx # Set up the destination. - popl %edx # Restore eax, ecx and edx. - popl %ecx - popl %eax - ret - SIZE(GNAME(alloc_to_ebx)) - - .globl GNAME(alloc_8_to_ebx) - TYPE(GNAME(alloc_8_to_ebx)) - .align align_4byte,0x90 -GNAME(alloc_8_to_ebx): - pushl %eax # Save eax, ecx, and edx as C could destroy them. - pushl %ecx - pushl %edx - pushl $8 # Push the size. - call GNAME(alloc) - addl $4,%esp # Pop the size arg. - movl %eax,%ebx # Set up the destination. - popl %edx # Restore eax, ecx and edx. - popl %ecx - popl %eax - ret - SIZE(GNAME(alloc_8_to_ebx)) - - .globl GNAME(alloc_16_to_ebx) - TYPE(GNAME(alloc_16_to_ebx)) - .align align_4byte,0x90 -GNAME(alloc_16_to_ebx): - pushl %eax # Save eax, ecx, and edx as C could destroy them. - pushl %ecx - pushl %edx - pushl $16 # Push the size - call GNAME(alloc) - addl $4,%esp # pop the size arg. - movl %eax,%ebx # setup the destination. - popl %edx # Restore eax, ecx and edx. - popl %ecx - popl %eax - ret - SIZE(GNAME(alloc_16_to_ebx)) - - - - .globl GNAME(alloc_to_esi) - TYPE(GNAME(alloc_to_esi)) - .align align_4byte,0x90 -GNAME(alloc_to_esi): - pushl %eax # Save eax, ecx, and edx as C could destroy them. - pushl %ecx - pushl %edx - pushl %esi # Push the size - call GNAME(alloc) - addl $4,%esp # pop the size arg. - movl %eax,%esi # setup the destination. - popl %edx # Restore eax, ecx and edx. - popl %ecx - popl %eax - ret - SIZE(GNAME(alloc_to_esi)) - - .globl GNAME(alloc_8_to_esi) - TYPE(GNAME(alloc_8_to_esi)) - .align align_4byte,0x90 -GNAME(alloc_8_to_esi): - pushl %eax # Save eax, ecx, and edx as C could destroy them. - pushl %ecx - pushl %edx - pushl $8 # Push the size - call GNAME(alloc) - addl $4,%esp # pop the size arg. - movl %eax,%esi # setup the destination. - popl %edx # Restore eax, ecx and edx. - popl %ecx - popl %eax - ret - SIZE(GNAME(alloc_8_to_esi)) - - .globl GNAME(alloc_16_to_esi) - TYPE(GNAME(alloc_16_to_esi)) - .align align_4byte,0x90 -GNAME(alloc_16_to_esi): - pushl %eax # Save eax, ecx, and edx as C could destroy them. - pushl %ecx - pushl %edx - pushl $16 # Push the size - call GNAME(alloc) - addl $4,%esp # pop the size arg. - movl %eax,%esi # setup the destination. - popl %edx # Restore eax, ecx and edx. - popl %ecx - popl %eax - ret - SIZE(GNAME(alloc_16_to_esi)) - - - .globl GNAME(alloc_to_edi) - TYPE(GNAME(alloc_to_edi)) - .align align_4byte,0x90 -GNAME(alloc_to_edi): - pushl %eax # Save eax, ecx, and edx as C could destroy them. - pushl %ecx - pushl %edx - pushl %edi # Push the size - call GNAME(alloc) - addl $4,%esp # pop the size arg. - movl %eax,%edi # setup the destination. - popl %edx # Restore eax, ecx and edx. - popl %ecx - popl %eax - ret - SIZE(GNAME(alloc_to_edi)) - - .globl GNAME(alloc_8_to_edi) - TYPE(GNAME(alloc_8_to_edi)) - .align align_4byte,0x90 -GNAME(alloc_8_to_edi): - pushl %eax # Save eax, ecx, and edx as C could destroy them. - pushl %ecx - pushl %edx - pushl $8 # Push the size - call GNAME(alloc) - addl $4,%esp # pop the size arg. - movl %eax,%edi # setup the destination. - popl %edx # Restore eax, ecx and edx. - popl %ecx - popl %eax - ret - SIZE(GNAME(alloc_8_to_edi)) +#ifdef LISP_FEATURE_DARWIN +#define ALLOC(size) \ + pushl %ebp; /* Save EBP */ \ + movl %esp,%ebp; /* Save ESP to EBP */ \ + andl $0xfffffff0,%esp; /* Align stack */ \ + pushl $0; /* Padding */ \ + pushl size; /* Argument to alloc */ \ + cld; /* Clear DF */ \ + call GNAME(alloc); \ + movl %ebp,%esp; /* Restore ESP from EBP */ \ + popl %ebp; /* Restore EBP */ +#else +#define ALLOC(size) \ + pushl size; /* Argument to alloc */ \ + cld; /* Clear DF */ \ + call GNAME(alloc); \ + addl $4,%esp; /* Pop argument */ +#endif - .globl GNAME(alloc_16_to_edi) - TYPE(GNAME(alloc_16_to_edi)) - .align align_4byte,0x90 -GNAME(alloc_16_to_edi): - pushl %eax # Save eax, ecx, and edx as C could destroy them. - pushl %ecx - pushl %edx - pushl $16 # Push the size - call GNAME(alloc) - addl $4,%esp # pop the size arg. - movl %eax,%edi # setup the destination. - popl %edx # Restore eax, ecx and edx. - popl %ecx - popl %eax - ret - SIZE(GNAME(alloc_16_to_edi)) +#define DEFINE_ALLOC_TO_EAX(name,size) \ + .globl GNAME(name); \ + TYPE(GNAME(name)); \ + .align align_4byte,0x90; \ +GNAME(name): \ + pushl %ecx; /* Save ECX and EDX */ \ + pushl %edx; \ + ALLOC(size) \ + popl %edx; /* Restore ECX and EDX */ \ + popl %ecx; \ + ret; \ + SIZE(GNAME(name)) + +#define DEFINE_ALLOC_TO_ECX(name,size) \ + .globl GNAME(name); \ + TYPE(GNAME(name)); \ + .align align_4byte,0x90; \ +GNAME(name): \ + pushl %eax; /* Save EAX and EDX */ \ + pushl %edx; \ + ALLOC(size) \ + movl %eax,%ecx; /* Result to destination */ \ + popl %edx; \ + popl %eax; \ + ret; \ + SIZE(GNAME(name)) + +#define DEFINE_ALLOC_TO_EDX(name,size) \ + .globl GNAME(name); \ + TYPE(GNAME(name)); \ + .align align_4byte,0x90; \ +GNAME(name): \ + pushl %eax; /* Save EAX and ECX */ \ + pushl %ecx; \ + ALLOC(size) \ + movl %eax,%edx; /* Restore EAX and ECX */ \ + popl %ecx; \ + popl %eax; \ + ret; \ + SIZE(GNAME(name)) + +#define DEFINE_ALLOC_TO_REG(name,reg,size) \ + .globl GNAME(name); \ + TYPE(GNAME(name)); \ + .align align_4byte,0x90; \ +GNAME(name): \ + pushl %eax; /* Save EAX, ECX, and EDX */ \ + pushl %ecx; \ + pushl %edx; \ + ALLOC(size) \ + movl %eax,reg; /* Restore them */ \ + popl %edx; \ + popl %ecx; \ + popl %eax; \ + ret; \ + SIZE(GNAME(name)) + +DEFINE_ALLOC_TO_EAX(alloc_to_eax,%eax) +DEFINE_ALLOC_TO_EAX(alloc_8_to_eax,$8) +DEFINE_ALLOC_TO_EAX(alloc_16_to_eax,$16) + +DEFINE_ALLOC_TO_ECX(alloc_to_ecx,%ecx) +DEFINE_ALLOC_TO_ECX(alloc_8_to_ecx,$8) +DEFINE_ALLOC_TO_ECX(alloc_16_to_ecx,$16) + +DEFINE_ALLOC_TO_EDX(alloc_to_edx,%edx) +DEFINE_ALLOC_TO_EDX(alloc_8_to_edx,$8) +DEFINE_ALLOC_TO_EDX(alloc_16_to_edx,$16) + +DEFINE_ALLOC_TO_REG(alloc_to_ebx,%ebx,%ebx) +DEFINE_ALLOC_TO_REG(alloc_8_to_ebx,%ebx,$8) +DEFINE_ALLOC_TO_REG(alloc_16_to_ebx,%ebx,$16) + +DEFINE_ALLOC_TO_REG(alloc_to_esi,%esi,%esi) +DEFINE_ALLOC_TO_REG(alloc_8_to_esi,%esi,$8) +DEFINE_ALLOC_TO_REG(alloc_16_to_esi,%esi,$16) + +DEFINE_ALLOC_TO_REG(alloc_to_edi,%edi,%edi) +DEFINE_ALLOC_TO_REG(alloc_8_to_edi,%edi,$8) +DEFINE_ALLOC_TO_REG(alloc_16_to_edi,%edi,$16) - /* Called from lisp when an inline allocation overflows. - Every register except the result needs to be preserved. - We depend on C to preserve ebx, esi, edi, and ebp. - But where necessary must save eax, ecx, edx. */ + * Every register except the result needs to be preserved. + * We depend on C to preserve ebx, esi, edi, and ebp. + * But where necessary must save eax, ecx, edx. */ #ifdef LISP_FEATURE_SB_THREAD #define START_REGION %fs:THREAD_ALLOC_REGION_OFFSET #else #define START_REGION GNAME(boxed_region) #endif - + +#define ALLOC_OVERFLOW(size) \ + /* Calculate the size for the allocation. */ \ + subl START_REGION,size; \ + ALLOC(size) + /* This routine handles an overflow with eax=crfp+size. So the size=eax-crfp. */ .align align_4byte @@ -749,11 +560,7 @@ GNAME(alloc_16_to_edi): GNAME(alloc_overflow_eax): pushl %ecx # Save ecx pushl %edx # Save edx - /* Calculate the size for the allocation. */ - subl START_REGION,%eax - pushl %eax # Push the size - call GNAME(alloc) - addl $4,%esp # pop the size arg. + ALLOC_OVERFLOW(%eax) popl %edx # Restore edx. popl %ecx # Restore ecx. ret @@ -765,11 +572,7 @@ GNAME(alloc_overflow_eax): GNAME(alloc_overflow_ecx): pushl %eax # Save eax pushl %edx # Save edx - /* Calculate the size for the allocation. */ - subl START_REGION,%ecx - pushl %ecx # Push the size - call GNAME(alloc) - addl $4,%esp # pop the size arg. + ALLOC_OVERFLOW(%ecx) movl %eax,%ecx # setup the destination. popl %edx # Restore edx. popl %eax # Restore eax. @@ -782,11 +585,7 @@ GNAME(alloc_overflow_ecx): GNAME(alloc_overflow_edx): pushl %eax # Save eax pushl %ecx # Save ecx - /* Calculate the size for the allocation. */ - subl START_REGION,%edx - pushl %edx # Push the size - call GNAME(alloc) - addl $4,%esp # pop the size arg. + ALLOC_OVERFLOW(%edx) movl %eax,%edx # setup the destination. popl %ecx # Restore ecx. popl %eax # Restore eax. @@ -802,11 +601,7 @@ GNAME(alloc_overflow_ebx): pushl %eax # Save eax pushl %ecx # Save ecx pushl %edx # Save edx - /* Calculate the size for the allocation. */ - subl START_REGION,%ebx - pushl %ebx # Push the size - call GNAME(alloc) - addl $4,%esp # pop the size arg. + ALLOC_OVERFLOW(%ebx) movl %eax,%ebx # setup the destination. popl %edx # Restore edx. popl %ecx # Restore ecx. @@ -823,11 +618,7 @@ GNAME(alloc_overflow_esi): pushl %eax # Save eax pushl %ecx # Save ecx pushl %edx # Save edx - /* Calculate the size for the allocation. */ - subl START_REGION,%esi - pushl %esi # Push the size - call GNAME(alloc) - addl $4,%esp # pop the size arg. + ALLOC_OVERFLOW(%esi) movl %eax,%esi # setup the destination. popl %edx # Restore edx. popl %ecx # Restore ecx. @@ -842,11 +633,7 @@ GNAME(alloc_overflow_edi): pushl %eax # Save eax pushl %ecx # Save ecx pushl %edx # Save edx - /* Calculate the size for the allocation. */ - subl START_REGION,%edi - pushl %edi # Push the size - call GNAME(alloc) - addl $4,%esp # pop the size arg. + ALLOC_OVERFLOW(%edi) movl %eax,%edi # setup the destination. popl %edx # Restore edx. popl %ecx # Restore ecx.