
import renmas3.switch as proc
from tdasm import Tdasm

def cos_ps():
   
    data = """
    #DATA
    uint32 _ps_am_inv_sign_mask[4] = 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF
    float _ps_am_pi_o_2[4] = 1.57079632679, 1.57079632679, 1.57079632679, 1.57079632679
    float _ps_am_2_o_pi[4] = 0.63661977236, 0.63661977236, 0.63661977236, 0.63661977236
    uint32 _epi32_1[4] = 1, 1, 1, 1
    float _ps_am_1[4] = 1.0, 1.0, 1.0, 1.0
    uint32 _epi32_2[4] = 2, 2, 2, 2

    float _ps_sincos_p3[4] = -0.00468175413, -0.00468175413, -0.00468175413, -0.00468175413
    float _ps_sincos_p2[4] = 0.0796926262, 0.0796926262, 0.0796926262, 0.0796926262
    float _ps_sincos_p1[4] = -0.64596409750621,-0.64596409750621,-0.64596409750621,-0.64596409750621 
    float _ps_sincos_p0[4] = 1.570796326794896, 1.570796326794896, 1.570796326794896, 1.570796326794896
    """

    asm_code = data + """

    #CODE
    global fast_cos_ps:
    andps	xmm0, oword [_ps_am_inv_sign_mask]
    addps	xmm0, oword [_ps_am_pi_o_2]
    mulps	xmm0, oword [_ps_am_2_o_pi]

    pxor	xmm3, xmm3
    movdqa	xmm5, oword [_epi32_1]
    movaps	xmm4, oword [_ps_am_1]
    cvttps2dq	xmm2, xmm0
    pand	xmm5, xmm2
    pcmpeqd	xmm5, xmm3
    cvtdq2ps	xmm6, xmm2
    pand	xmm2, oword [_epi32_2]
    pslld	xmm2, 30 

    subps	xmm0, xmm6
    minps	xmm0, xmm4
    subps	xmm4, xmm0
    andps	xmm0, xmm5
    andnps	xmm5, xmm4
    orps	xmm0, xmm5

    movaps	xmm1, xmm0
    mulps	xmm0, xmm0
    orps	xmm1, xmm2
    movaps	xmm7, xmm0
    mulps	xmm0, oword [_ps_sincos_p3]
    addps	xmm0, oword [_ps_sincos_p2]
    mulps	xmm0, xmm7
    addps	xmm0, oword [_ps_sincos_p1]
    mulps	xmm0, xmm7
    addps	xmm0, oword [_ps_sincos_p0]
    mulps	xmm0, xmm1
    ret
    """

    avx_code = data + """

    #CODE
    global fast_cos_ps:
    vandps	xmm0, xmm0, oword [_ps_am_inv_sign_mask]
    vaddps	xmm0, xmm0, oword [_ps_am_pi_o_2]
    vmulps	xmm0, xmm0, oword [_ps_am_2_o_pi]

    vpxor	xmm3, xmm3, xmm3
    vmovdqa	xmm5, oword [_epi32_1]
    vmovaps	xmm4, oword [_ps_am_1]
    vcvttps2dq	xmm2, xmm0
    vpand	xmm5, xmm5, xmm2
    vpcmpeqd	xmm5, xmm5, xmm3
    vcvtdq2ps	xmm6, xmm2
    vpand	xmm2, xmm2, oword [_epi32_2]
    vpslld	xmm2, xmm2, 30 

    vsubps	xmm0, xmm0, xmm6
    vminps	xmm0, xmm0, xmm4
    vsubps	xmm4, xmm4, xmm0
    vandps	xmm0, xmm0, xmm5
    vandnps	xmm5, xmm5, xmm4
    vorps	xmm0, xmm0, xmm5

    vmovaps	xmm1, xmm0
    vmulps	xmm0, xmm0, xmm0
    vorps	xmm1, xmm1, xmm2
    vmovaps	xmm7, xmm0
    vmulps	xmm0, xmm0, oword [_ps_sincos_p3]
    vaddps	xmm0, xmm0, oword [_ps_sincos_p2]
    vmulps	xmm0, xmm0, xmm7
    vaddps	xmm0, xmm0, oword [_ps_sincos_p1]
    vmulps	xmm0, xmm0, xmm7
    vaddps	xmm0, xmm0, oword [_ps_sincos_p0]
    vmulps	xmm0, xmm0, xmm1
    ret
    """

    asm = Tdasm()
    if proc.AVX:
        mc = asm.assemble(avx_code, True)
    else:
        mc = asm.assemble(asm_code, True)
   
    return mc

