/* * void memset64(uint64_t dst, int c, uint64_t len) * (Unlike ansi-C, does not return first arg!) * * Layout on stack: * len 28,32 - misaligned due to x86 call stack layout. * c 24 * dst 16,20 * retaddr 12 * %ebx 8 * %esi 4 * %edi 0 */ .globl memset64 .type memset64,@function .size memset64,ememset64-memset64 /* arrive here in 32 bit mode */ memset64: pushl %ebx pushl %esi pushl %edi call base base: popl %esi /* relocatable address of "base" */ /* Set up for inter-segment jump to 64 bit code mode */ movl %esi,%edx addl $to64-base,%edx pushl $43 /* $GSEL(GUCODE_SEL, SEL_UPL) */ pushl %edx lretl .code64 .p2align 4 to64: movq %rsi,%r9 /* Set up our escape to 32 bit */ addq $to32-base,%r9 movq 16(%rsp),%rdi /* dst */ movl 24(%rsp),%eax /* c */ movq 28(%rsp),%rdx /* len */ andl $0xff,%eax movq %rdx,%rcx cld /* set fill direction forward */ cmpq $16,%rcx /* too short? (just do byte fill) */ jb 1f movb %al,%ah /* Expand char to all bytes in word */ movl %eax,%edx sall $16,%eax orl %edx,%eax movl %eax,%edx salq $32,%rax orq %rdx,%rax movq %rdi,%rdx /* misalignment */ negq %rdx andq $7,%rdx movq %rcx,%r8 subq %rdx,%r8 movq %rdx,%rcx rep /* zero till aligned */ stosb movq %r8,%rcx /* zero rest of words */ shrq $3,%rcx rep stosq movq %r8,%rcx /* zero remainder by bytes */ andq $7,%rcx 1: rep stosb /* Jump back to 32 bit code segment */ pushq $27 /* GSEL(GUCODE32_UPL, SEL_UPL) */ pushq %r9 lretq .code32 .p2align 4 to32: popl %edi popl %esi popl %ebx ret ememset64: