newlib-cygwin/newlib/libc/sys/go32/crt0.S

234 lines
4.1 KiB
ArmAsm

/*
** Called as start(argc, argv, envp)
*/
/* gs:edx points to prog_info structure. All other registers are OBSOLETE
** but included for backwards compatibility
*/
/* These symbols are for global constructors and destructors */
#if 0
.section .ctor
.globl ___go32_first_ctor
___go32_first_ctor:
.section .dtor
.globl ___go32_last_ctor
___go32_last_ctor:
.globl ___go32_first_dtor
___go32_first_dtor:
.data
.globl ___go32_last_dtor
___go32_last_dtor:
#endif
.text
.globl _start
_start:
.globl start
start:
#ifdef EMU387
pusha
push %gs
#endif
movl %eax,__hard_master
movl %esi,___pid
movl %edi,___transfer_buffer
movl %ebx,_ScreenPrimary
movl %ebp,_ScreenSecondary
cmpl $0, %edx
je Lcopy_none
movw %gs,%cx
movw %ds,%ax
cmpw %cx,%ax
je Lcopy_none
movl %gs:(%edx), %ecx
cmpl __go32_info_block, %ecx
jbe Lcopy_less
movl __go32_info_block, %ecx
Lcopy_less:
movl $__go32_info_block, %edi
addl $3, %ecx
andl $0xfffffffc, %ecx
movl %ecx, (%edi)
addl $4, %edi
addl $4, %edx
subl $4, %ecx
Lcopy_more:
movl %gs:(%edx), %eax
movl %eax, (%edi)
addl $4, %edx
addl $4, %edi
subl $4, %ecx
jnz Lcopy_more
movl __go32_info_block+4, %eax
movl %eax, _ScreenPrimary
movl __go32_info_block+8, %eax
movl %eax, _ScreenSecondary
/* Backward compatibility - do not copy this one!
** movl __go32_info_block+12, %eax
** movl %eax, ___transfer_buffer
*/
movl __go32_info_block+20, %eax
movl %eax, ___pid
movl __go32_info_block+24, %eax
movl %eax, __hard_master
jmp Lcopy_done
Lcopy_none:
movl %ebx,__go32_info_block+4
movl %ebp,__go32_info_block+8
movl %edi,__go32_info_block+12
movl $4096,__go32_info_block+16
movl %esi,__go32_info_block+20
movl %eax,__go32_info_block+24
movl $28, __go32_info_block
Lcopy_done:
#ifndef EMU387
call __setstack
#endif
xorl %esi,%esi
xorl %edi,%edi
xorl %ebp,%ebp
xorl %ebx,%ebx
movl %esp,%ebx
#ifdef MAKE_GCRT0
call mcount_init /* initialize the profiler */
#endif
movl 8(%ebx),%eax
pushl %eax
movl %eax,_environ
pushl 4(%ebx)
pushl (%ebx)
call ___main
call _main
addl $12,%esp
#ifdef EMU387
pop %gs
popa
#else
pushl %eax
call _exit
exit_again:
movl $0x4c00,%eax
int $0x21
jmp exit_again
#endif
ret
#ifdef MAKE_GCRT0
.globl __exit
__exit:
call mcount_write /* make sure we dump the output */
exit_again2:
movb 4(%esp),%al
movb $0x4c,%ah
int $0x21
jmp exit_again2
/* Here is where we initialize the timer interrupt - specific to go32 */
/* In this case, the timer calls mcount_isr */
.globl mcount_isr_init
mcount_isr_init:
movw __go32_info_block+36, %ax /* run mode */
cmp $1,%ax
jb skip_mcount
cmp $3,%ax
ja skip_mcount
movw $16,%ax
movw %ax,%gs
movzbl __hard_master,%eax /* timer is on irq 0 */
shll $3,%eax /* times 8 bpv */
/* movl $960,%eax vector 0x78 * 8 bpv */
movw %gs:(%eax),%cx
movw %cx,mc_chain
movw %gs:6(%eax),%cx
movw %cx,mc_chain_hi
movw %gs:2(%eax),%cx
movw %cx,mc_chain_sel
movl $mcount_isr,%ecx
movw %cx,%gs:(%eax)
movw $0xd8,%gs:2(%eax) /* selector 27 == 32-bit code */
movw $0x8f00,%gs:4(%eax)
rorl $16,%ecx
movw %cx,%gs:6(%eax)
movw %ds,%ax
movw %ax,%gs
skip_mcount:
movl mcount_histogram,%eax
movl $1,(%eax)
ret
/* Obtain the PC where we interrupted, and bump the histogram. We should */
/* do error checking here, but we don't. This routine is specific to go32 */
/* in some spots */
mcount_isr:
pushl %eax
cmpl $1,mcount_skip
je L0
movl 4(%esp),%eax /* get the PC */
subl $0x1020,%eax /* to fit in low..high */
andl $0xfffffffc,%eax
shrl $1,%eax /* now points to one 4-byte entry */
addl mcount_histogram,%eax
incw (%eax)
L0:
popl %eax
ljmp mc_chain /* chain to the next timer vector */
iret
#endif
.data
.globl _environ
_environ:
.long 0
.globl ___pid
___pid:
.long 42
.globl ___transfer_buffer
___transfer_buffer:
.long 0
.globl _ScreenPrimary
_ScreenPrimary:
.long 0
.globl _ScreenSecondary
_ScreenSecondary:
.long 0
.globl __hard_master
.globl __hard_slave
.globl __core_select
__hard_master:
.byte 0
__hard_slave:
.byte 0
__core_select:
.short 0
#ifdef MAKE_GCRT0
mc_chain:
.short 0
mc_chain_hi:
.short 0
mc_chain_sel:
.short 0
#endif