999999999适合32位整数.对于硬编码值,编译器会注意到这一点,并将所有操作降级为32位操作,这些操作的执行速度比128位 routine 快far,后者没有本机编译器支持.
比较非硬编码循环的程序集(但删除了clap,就像Schwern的版本一样):
xorl %esi, %esi
cmpq $2, %r15
movq %rdx, %rax
sbbq $0, %rax
movl $0, %r13d
jb .LBB5_9
movq %r15, %rsi
addq $-1, %rsi
movq %rdx, %rdi
adcq $-1, %rdi
movq %r15, %rax
addq $-2, %rax
movq %rdx, %rcx
adcq $-1, %rcx
movq %rsi, 32(%rsp)
andl $3, %esi
movq %rsi, 40(%rsp)
cmpq $3, %rax
sbbq $0, %rcx
movq %rdx, 8(%rsp)
jae .LBB5_4
xorl %ebp, %ebp
movl $1, %edx
xorl %r13d, %r13d
xorl %ecx, %ecx
jmp .LBB5_6
.LBB5_4:
andq $-4, 32(%rsp)
movl $1, %edx
xorl %ebp, %ebp
xorl %r13d, %r13d
xorl %ecx, %ecx
xorl %esi, %esi
xorl %ebx, %ebx
movq %rdi, 64(%rsp)
.LBB5_5:
movq %rbx, 88(%rsp)
movq %rsi, 96(%rsp)
movq %rcx, 16(%rsp)
movq %rdx, (%rsp)
addq $1, %rdx
movq %rdx, 24(%rsp)
movq %rcx, %rbx
adcq $0, %rbx
movq %r15, %rdi
movq 8(%rsp), %rsi
movq (%rsp), %rdx
movq 16(%rsp), %rcx
movq __udivti3@GOTPCREL(%rip), %r14
callq *%r14
movq %r14, %r8
movq %rax, %r14
movq %rdx, %r12
addq %rbp, %r14
adcq %r13, %r12
movq (%rsp), %rax
addq $2, %rax
movq %rax, 80(%rsp)
movq 16(%rsp), %rax
adcq $0, %rax
movq %rax, 72(%rsp)
movq %r15, %rdi
movq 8(%rsp), %rsi
movq 24(%rsp), %rdx
movq %rbx, %rcx
movq %r8, %rbx
callq *%r8
movq %rbx, %r8
movq %rax, %rbx
movq %r15, %r13
movq %rdx, %rbp
addq %r14, %rbx
adcq %r12, %rbp
movq (%rsp), %rax
addq $3, %rax
movq %rax, 24(%rsp)
movq 16(%rsp), %r15
adcq $0, %r15
movq %r13, %rdi
movq 8(%rsp), %rsi
movq 80(%rsp), %rdx
movq 72(%rsp), %rcx
movq %r8, %r14
callq *%r8
movq %r14, %r8
movq %rax, %r12
movq %rdx, %r14
addq %rbx, %r12
adcq %rbp, %r14
addq $4, (%rsp)
adcq $0, 16(%rsp)
movq %r13, %rdi
movq 8(%rsp), %rsi
movq 24(%rsp), %rdx
movq %r15, %rcx
movq %r13, %r15
callq *%r8
movq 88(%rsp), %rbx
movq 96(%rsp), %rsi
movq 64(%rsp), %rdi
movq %rax, %rbp
movq %rdx, %r13
movq (%rsp), %rdx
addq %r12, %rbp
adcq %r14, %r13
addq $4, %rsi
adcq $0, %rbx
movq %rsi, %rax
xorq 32(%rsp), %rax
movq %rbx, %rcx
xorq %rdi, %rcx
orq %rax, %rcx
movq 16(%rsp), %rcx
jne .LBB5_5
.LBB5_6:
cmpq $0, 40(%rsp)
movq %rbp, %rsi
je .LBB5_9
xorl %r12d, %r12d
xorl %ebp, %ebp
movq %rdx, %rbx
movq %rcx, %r14
.LBB5_8:
movq %rsi, (%rsp)
addq $1, %rbx
adcq $0, %r14
movq %r15, %rdi
movq 8(%rsp), %rsi
callq *__udivti3@GOTPCREL(%rip)
movq (%rsp), %rsi
addq %rax, %rsi
adcq %rdx, %r13
addq $1, %r12
adcq $0, %rbp
movq %r12, %rax
xorq 40(%rsp), %rax
orq %rbp, %rax
movq %rbx, %rdx
movq %r14, %rcx
jne .LBB5_8
到硬编码循环:
.LBB5_1:
movl $999999999, %eax
xorl %edx, %edx
divl %r8d
movl %eax, %r9d
addq %rcx, %r9
adcq $0, %rdi
addq $2, %r10
adcq $0, %r11
leal 1(%r8), %ecx
movl $999999999, %eax
xorl %edx, %edx
divl %ecx
movl %eax, %ecx
addq %r9, %rcx
adcq $0, %rdi
cmpq $999999997, %r8
sbbq $0, %rsi
movq %r10, %r8
movq %r11, %rsi
jb .LBB5_1
subq $88, %rsp
movq %rcx, 24(%rsp)
movq %rdi, 32(%rsp)
leaq 24(%rsp), %rax
movq %rax, 8(%rsp)
movq core::fmt::num::<impl core::fmt::Display for u128>::fmt@GOTPCREL(%rip), %rax
movq %rax, 16(%rsp)
leaq .L__unnamed_2(%rip), %rax
movq %rax, 56(%rsp)
movq $2, 64(%rsp)
movq $0, 40(%rsp)
leaq 8(%rsp), %rax
movq %rax, 72(%rsp)
movq $1, 80(%rsp)
leaq 40(%rsp), %rdi
callq *std::io::stdio::_print@GOTPCREL(%rip)
addq $88, %rsp
retq
特别要注意的是,在这个版本中完全没有调用__udivti3
.