{% comment %} // vim: set syntax=asm : // TODO[TSolberg] : Not validated. System V ABI: args: rdi, rsi, rdx, rcx, r8, r9 preserve: rbx, rsp, rbp, r12, r13, r14, r15 scratch: rax, rdi, rsi, rdx, rcx, r8, r9, r10, r11 return: rax (+rdx) Windows ABI: args: RCX, RDX, R8, R9 preserve: RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15, and XMM6-15 scratch: RAX, RCX, RDX, R8, R9, R10, R11, XMM0-5, and the upper portions of ZMM0-15 and ZMM0-15 return: rax (+rdx) {% endcomment %} {% if msvc %} _text segment avx512_tanh_f32_{{suffix}} proc {% else %} .intel_syntax noprefix .text .p2align 5 .globl {{G}}avx512_tanh_f32_{{suffix}} {{G}}avx512_tanh_f32_{{suffix}}: .cfi_startproc {% endif %} push rbp mov rbp, rsp {% if family == "windows" %} // https://www.agner.org/optimize/calling_conventions.pdf xmm6-15 are not scratch // https://stackoverflow.com/questions/43358429/save-value-of-xmm-registers and rsp,-16 lea rsp,[rsp-160] vmovaps [rsp], xmm6 vmovaps [rsp+16*1],xmm7 vmovaps [rsp+16*2],xmm8 vmovaps [rsp+16*3],xmm9 vmovaps [rsp+16*4],xmm10 vmovaps [rsp+16*5],xmm11 vmovaps [rsp+16*6],xmm12 vmovaps [rsp+16*7],xmm13 vmovaps [rsp+16*8],xmm14 vmovaps [rsp+16*9],xmm15 // move around arguments to mimick SysV rdi,rsi passing push rdi push rsi mov rdi, rcx mov rsi, rdx {% endif %} push rbx push r12 push r13 push r14 push r15 sub rsp, 8 {% if family == "unix" %} // FIXME // .cfi_def_cfa_offset 64 {% endif %} stmxcsr [rsp + 4] {% if msvc %} mov rax, 1FC0h {% else %} mov rax, 0x1FC0 {% endif %} mov [rsp], eax ldmxcsr [rsp] // ---------------------------------------------------------------------- {%capture offset%}{% if msvc %} offset {%else%} rip + {%endif%} {%endcapture%} cmp rsi, 0 je {{L}}done cmp rsi, 32 jl {{L}}loop_1 {{L}}loop_4: vmovaps zmm4, [rdi] vmovaps zmm5, [rdi + 64] vmovaps zmm6, [rdi + 128] vmovaps zmm7, [rdi + 192] vbroadcastss zmm0, dword ptr [{{offset}} {{L}}coeffs_num_low] vbroadcastss zmm1, dword ptr [{{offset}} {{L}}coeffs_num_high] vbroadcastss zmm2, dword ptr [{{offset}} {{L}}coeffs_num_alpha_13] vbroadcastss zmm3, dword ptr [{{offset}} {{L}}coeffs_num_alpha_11] vmaxps zmm4, zmm4, zmm0 vmaxps zmm5, zmm5, zmm0 vmaxps zmm6, zmm6, zmm0 vmaxps zmm7, zmm7, zmm0 vbroadcastss zmm0, dword ptr [{{offset}} {{L}}coeffs_num_alpha_9] vminps zmm4, zmm4, zmm1 vminps zmm5, zmm5, zmm1 vminps zmm6, zmm6, zmm1 vminps zmm7, zmm7, zmm1 // zmm4..7 <- x vbroadcastss zmm1, dword ptr [{{offset}} {{L}}coeffs_num_alpha_7] vmulps zmm8, zmm4, zmm4 vmulps zmm9, zmm5, zmm5 vmulps zmm10, zmm6, zmm6 vmulps zmm11, zmm7, zmm7 // zmm8..11 <- x^2 vmovaps zmm12, zmm2 vmovaps zmm13, zmm2 vmovaps zmm14, zmm2 vmovaps zmm15, zmm2 vbroadcastss zmm2, dword ptr [{{offset}} {{L}}coeffs_num_alpha_5] vfmadd132ps zmm12, zmm3, zmm8 vfmadd132ps zmm13, zmm3, zmm9 vfmadd132ps zmm14, zmm3, zmm10 vfmadd132ps zmm15, zmm3, zmm11 vbroadcastss zmm3, dword ptr [{{offset}} {{L}}coeffs_num_alpha_3] vfmadd132ps zmm12, zmm0, zmm8 vfmadd132ps zmm13, zmm0, zmm9 vfmadd132ps zmm14, zmm0, zmm10 vfmadd132ps zmm15, zmm0, zmm11 vbroadcastss zmm0, dword ptr [{{offset}} {{L}}coeffs_num_alpha_1] vfmadd132ps zmm12, zmm1, zmm8 vfmadd132ps zmm13, zmm1, zmm9 vfmadd132ps zmm14, zmm1, zmm10 vfmadd132ps zmm15, zmm1, zmm11 vbroadcastss zmm1, dword ptr [{{offset}} {{L}}coeffs_num_beta_6] vfmadd132ps zmm12, zmm2, zmm8 vfmadd132ps zmm13, zmm2, zmm9 vfmadd132ps zmm14, zmm2, zmm10 vfmadd132ps zmm15, zmm2, zmm11 vbroadcastss zmm2, dword ptr [{{offset}} {{L}}coeffs_num_beta_4] vfmadd132ps zmm12, zmm3, zmm8 vfmadd132ps zmm13, zmm3, zmm9 vfmadd132ps zmm14, zmm3, zmm10 vfmadd132ps zmm15, zmm3, zmm11 vbroadcastss zmm3, dword ptr [{{offset}} {{L}}coeffs_num_beta_2] vfmadd132ps zmm12, zmm0, zmm8 vfmadd132ps zmm13, zmm0, zmm9 vfmadd132ps zmm14, zmm0, zmm10 vfmadd132ps zmm15, zmm0, zmm11 vbroadcastss zmm0, dword ptr [{{offset}} {{L}}coeffs_num_beta_0] vmulps zmm4, zmm4, zmm12 vmulps zmm5, zmm5, zmm13 vmulps zmm6, zmm6, zmm14 vmulps zmm7, zmm7, zmm15 // zmm4..7 <- num vmovaps zmm12, zmm1 vmovaps zmm13, zmm1 vmovaps zmm14, zmm1 vmovaps zmm15, zmm1 vfmadd132ps zmm12, zmm2, zmm8 vfmadd132ps zmm13, zmm2, zmm9 vfmadd132ps zmm14, zmm2, zmm10 vfmadd132ps zmm15, zmm2, zmm11 vfmadd132ps zmm12, zmm3, zmm8 vfmadd132ps zmm13, zmm3, zmm9 vfmadd132ps zmm14, zmm3, zmm10 vfmadd132ps zmm15, zmm3, zmm11 vfmadd132ps zmm12, zmm0, zmm8 vfmadd132ps zmm13, zmm0, zmm9 vfmadd132ps zmm14, zmm0, zmm10 vfmadd132ps zmm15, zmm0, zmm11 // zmm12..14 <- denum vdivps zmm4, zmm4, zmm12 vdivps zmm5, zmm5, zmm13 vdivps zmm6, zmm6, zmm14 vdivps zmm7, zmm7, zmm15 vmovaps [rdi], zmm4 vmovaps [rdi + 64], zmm5 vmovaps [rdi + 128], zmm6 vmovaps [rdi + 192], zmm7 add rdi, 256 sub rsi, 32 cmp rsi, 32 jg {{L}}loop_4 cmp rsi, 0 je {{L}}done {{L}}loop_1: vmovaps zmm4, [rdi] vbroadcastss zmm0, dword ptr [{{offset}} {{L}}coeffs_num_low] vbroadcastss zmm1, dword ptr [{{offset}} {{L}}coeffs_num_high] vbroadcastss zmm2, dword ptr [{{offset}} {{L}}coeffs_num_alpha_13] vbroadcastss zmm3, dword ptr [{{offset}} {{L}}coeffs_num_alpha_11] vmaxps zmm4, zmm4, zmm0 vbroadcastss zmm0, dword ptr [{{offset}} {{L}}coeffs_num_alpha_9] vminps zmm4, zmm4, zmm1 // zmm4 <- x vbroadcastss zmm1, dword ptr [{{offset}} {{L}}coeffs_num_alpha_7] vmulps zmm8, zmm4, zmm4 // zmm8 <- x^2 vmovaps zmm12, zmm2 vbroadcastss zmm2, dword ptr [{{offset}} {{L}}coeffs_num_alpha_5] vfmadd132ps zmm12, zmm3, zmm8 vbroadcastss zmm3, dword ptr [{{offset}} {{L}}coeffs_num_alpha_3] vfmadd132ps zmm12, zmm0, zmm8 vbroadcastss zmm0, dword ptr [{{offset}} {{L}}coeffs_num_alpha_1] vfmadd132ps zmm12, zmm1, zmm8 vbroadcastss zmm1, dword ptr [{{offset}} {{L}}coeffs_num_beta_6] vfmadd132ps zmm12, zmm2, zmm8 vbroadcastss zmm2, dword ptr [{{offset}} {{L}}coeffs_num_beta_4] vfmadd132ps zmm12, zmm3, zmm8 vbroadcastss zmm3, dword ptr [{{offset}} {{L}}coeffs_num_beta_2] vfmadd132ps zmm12, zmm0, zmm8 vbroadcastss zmm0, dword ptr [{{offset}} {{L}}coeffs_num_beta_0] vmulps zmm4, zmm4, zmm12 vmovaps zmm12, zmm1 vfmadd132ps zmm12, zmm2, zmm8 vfmadd132ps zmm12, zmm3, zmm8 vfmadd132ps zmm12, zmm0, zmm8 vdivps zmm4, zmm4, zmm12 vmovaps [rdi], zmm4 add rdi, 32 sub rsi, 8 jnz {{L}}loop_1 {{L}}done: // ---------------------------------------------------------------------- ldmxcsr [rsp + 4] add rsp, 8 pop r15 pop r14 pop r13 pop r12 pop rbx {% if family == "windows" %} pop rsi pop rdi vmovaps xmm15, [rsp+16*9] vmovaps xmm14, [rsp+16*8] vmovaps xmm13, [rsp+16*7] vmovaps xmm12, [rsp+16*6] vmovaps xmm11, [rsp+16*5] vmovaps xmm10, [rsp+16*4] vmovaps xmm9, [rsp+16*3] vmovaps xmm8, [rsp+16*2] vmovaps xmm7, [rsp+16*1] vmovaps xmm6, [rsp] {% endif %} mov rsp, rbp pop rbp ret {%capture float%}{% if msvc %} real4 {%else%} .float {%endif%}{%endcapture%} {{L}}coeffs_num_low: {{float}} -9.0 // low {{L}}coeffs_num_high: {{float}} 9.0 // high {{L}}coeffs_num_alpha_13: {{float}} -2.76076847742355e-16 // alpha_13 {{L}}coeffs_num_alpha_11: {{float}} 2.00018790482477e-13 // alpha_11 {{L}}coeffs_num_alpha_9: {{float}} -8.60467152213735e-11 // alpha_9 {{L}}coeffs_num_alpha_7: {{float}} 5.12229709037114e-08 // alpha_7 {{L}}coeffs_num_alpha_5: {{float}} 1.48572235717979e-05 // alpha_5 {{L}}coeffs_num_alpha_3: {{float}} 6.37261928875436e-04 // alpha_3 {{L}}coeffs_num_alpha_1: {{float}} 4.89352455891786e-03 // alpha_1 {{L}}coeffs_num_beta_6: {{float}} 1.19825839466702e-06 // beta_6 {{L}}coeffs_num_beta_4: {{float}} 1.18534705686654e-04 // beta_4 {{L}}coeffs_num_beta_2: {{float}} 2.26843463243900e-03 // beta_2 {{L}}coeffs_num_beta_0: {{float}} 4.89352518554385e-03 // beta_0 {% if msvc %} avx512_tanh_f32_{{suffix}} endp _text ends end {% else %} .cfi_endproc {% endif %}