gitee.com/quant1x/gox@v1.7.6/num/asm/distance.go (about)

     1  package main
     2  
     3  import (
     4  	. "github.com/mmcloughlin/avo/build"
     5  	. "github.com/mmcloughlin/avo/operand"
     6  	. "github.com/mmcloughlin/avo/reg"
     7  )
     8  
     9  func genDot_F64() {
    10  
    11  	TEXT("Dot_AVX2_F64", NOSPLIT, "func(x, y []float64) float64")
    12  	Pragma("noescape")
    13  	Load(Param("x").Base(), RDI)
    14  	Load(Param("y").Base(), RSI)
    15  	Load(Param("x").Len(), RDX)
    16  
    17  	TESTQ(RDX, RDX)
    18  	JE(LabelRef("LBB0_1"))
    19  	CMPQ(RDX, Imm(16))
    20  	JAE(LabelRef("LBB0_4"))
    21  	VXORPD(X0, X0, X0)
    22  	XORL(EAX, EAX)
    23  	JMP(LabelRef("LBB0_7"))
    24  
    25  	Label("LBB0_1")
    26  	{
    27  		VXORPS(X0, X0, X0)
    28  		Store(X0, ReturnIndex(0))
    29  		RET()
    30  	}
    31  
    32  	Label("LBB0_4")
    33  	{
    34  		MOVQ(RDX, RAX)
    35  		ANDQ(I32(-16), RAX)
    36  		VXORPD(X0, X0, X0)
    37  		XORL(ECX, ECX)
    38  		VXORPD(X1, X1, X1)
    39  		VXORPD(X2, X2, X2)
    40  		VXORPD(X3, X3, X3)
    41  	}
    42  
    43  	Label("LBB0_5")
    44  	{
    45  		VMOVUPD(Mem{Base: RSI}.Idx(RCX, 8), Y4)
    46  		VMOVUPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(32), Y5)
    47  		VMOVUPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(64), Y6)
    48  		VMOVUPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(96), Y7)
    49  		VFMADD231PD(Mem{Base: RDI}.Idx(RCX, 8), Y4, Y0)
    50  		VFMADD231PD(Mem{Base: RDI}.Idx(RCX, 8).Offset(32), Y5, Y1)
    51  		VFMADD231PD(Mem{Base: RDI}.Idx(RCX, 8).Offset(64), Y6, Y2)
    52  		VFMADD231PD(Mem{Base: RDI}.Idx(RCX, 8).Offset(96), Y7, Y3)
    53  		ADDQ(Imm(16), RCX)
    54  		CMPQ(RAX, RCX)
    55  		JNE(LabelRef("LBB0_5"))
    56  		VADDPD(Y0, Y1, Y0)
    57  		VADDPD(Y0, Y2, Y0)
    58  		VADDPD(Y0, Y3, Y0)
    59  		VEXTRACTF128(Imm(1), Y0, X1)
    60  		VADDPD(X1, X0, X0)
    61  		VPERMILPD(Imm(1), X0, X1)
    62  		VADDSD(X1, X0, X0)
    63  		CMPQ(RAX, RDX)
    64  		JE(LabelRef("LBB0_8"))
    65  	}
    66  
    67  	Label("LBB0_7")
    68  	{
    69  		VMOVSD(Mem{Base: RSI}.Idx(RAX, 8), X1)
    70  		VFMADD231SD(Mem{Base: RDI}.Idx(RAX, 8), X1, X0)
    71  		ADDQ(Imm(1), RAX)
    72  		CMPQ(RDX, RAX)
    73  		JNE(LabelRef("LBB0_7"))
    74  	}
    75  
    76  	Label("LBB0_8")
    77  	{
    78  		VZEROUPPER()
    79  		Store(X0, ReturnIndex(0))
    80  		RET()
    81  	}
    82  }
    83  
    84  func genDot_F32() {
    85  
    86  	TEXT("Dot_AVX2_F32", NOSPLIT, "func(x, y []float32) float32")
    87  	Pragma("noescape")
    88  	Load(Param("x").Base(), RDI)
    89  	Load(Param("y").Base(), RSI)
    90  	Load(Param("x").Len(), RDX)
    91  
    92  	TESTQ(RDX, RDX)
    93  	JE(LabelRef("LBB1_1"))
    94  	CMPQ(RDX, Imm(32))
    95  	JAE(LabelRef("LBB1_4"))
    96  	VXORPS(X0, X0, X0)
    97  	XORL(EAX, EAX)
    98  	JMP(LabelRef("LBB1_7"))
    99  
   100  	Label("LBB1_1")
   101  	{
   102  		VXORPS(X0, X0, X0)
   103  		Store(X0, ReturnIndex(0))
   104  		RET()
   105  	}
   106  
   107  	Label("LBB1_4")
   108  	{
   109  		MOVQ(RDX, RAX)
   110  		ANDQ(I32(-32), RAX)
   111  		VXORPS(X0, X0, X0)
   112  		XORL(ECX, ECX)
   113  		VXORPS(X1, X1, X1)
   114  		VXORPS(X2, X2, X2)
   115  		VXORPS(X3, X3, X3)
   116  	}
   117  
   118  	Label("LBB1_5")
   119  	{
   120  		VMOVUPS(Mem{Base: RSI}.Idx(RCX, 4), Y4)
   121  		VMOVUPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(32), Y5)
   122  		VMOVUPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(64), Y6)
   123  		VMOVUPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(96), Y7)
   124  		VFMADD231PS(Mem{Base: RDI}.Idx(RCX, 4), Y4, Y0)
   125  		VFMADD231PS(Mem{Base: RDI}.Idx(RCX, 4).Offset(32), Y5, Y1)
   126  		VFMADD231PS(Mem{Base: RDI}.Idx(RCX, 4).Offset(64), Y6, Y2)
   127  		VFMADD231PS(Mem{Base: RDI}.Idx(RCX, 4).Offset(96), Y7, Y3)
   128  		ADDQ(Imm(32), RCX)
   129  		CMPQ(RAX, RCX)
   130  		JNE(LabelRef("LBB1_5"))
   131  		VADDPS(Y0, Y1, Y0)
   132  		VADDPS(Y0, Y2, Y0)
   133  		VADDPS(Y0, Y3, Y0)
   134  		VEXTRACTF128(Imm(1), Y0, X1)
   135  		VADDPS(X1, X0, X0)
   136  		VPERMILPD(Imm(1), X0, X1)
   137  		VADDPS(X1, X0, X0)
   138  		VMOVSHDUP(X0, X1)
   139  		VADDSS(X1, X0, X0)
   140  		CMPQ(RAX, RDX)
   141  		JE(LabelRef("LBB1_8"))
   142  	}
   143  
   144  	Label("LBB1_7")
   145  	{
   146  		VMOVSS(Mem{Base: RSI}.Idx(RAX, 4), X1)
   147  		VFMADD231SS(Mem{Base: RDI}.Idx(RAX, 4), X1, X0)
   148  		ADDQ(Imm(1), RAX)
   149  		CMPQ(RDX, RAX)
   150  		JNE(LabelRef("LBB1_7"))
   151  	}
   152  
   153  	Label("LBB1_8")
   154  	{
   155  		VZEROUPPER()
   156  		Store(X0, ReturnIndex(0))
   157  		RET()
   158  	}
   159  }
   160  
   161  func genNorm_F64() {
   162  
   163  	TEXT("Norm_AVX2_F64", NOSPLIT, "func(x []float64) float64")
   164  	Pragma("noescape")
   165  	Load(Param("x").Base(), RDI)
   166  	Load(Param("x").Len(), RSI)
   167  
   168  	TESTQ(RSI, RSI)
   169  	JE(LabelRef("LBB2_1"))
   170  	CMPQ(RSI, Imm(16))
   171  	JAE(LabelRef("LBB2_4"))
   172  	VXORPD(X0, X0, X0)
   173  	XORL(EAX, EAX)
   174  	JMP(LabelRef("LBB2_11"))
   175  
   176  	Label("LBB2_1")
   177  	{
   178  		VXORPD(X0, X0, X0)
   179  		VSQRTSD(X0, X0, X0)
   180  		Store(X0, ReturnIndex(0))
   181  		RET()
   182  	}
   183  
   184  	Label("LBB2_4")
   185  	{
   186  		MOVQ(RSI, RAX)
   187  		ANDQ(I32(-16), RAX)
   188  		LEAQ(Mem{Base: RAX}.Offset(-16), RCX)
   189  		MOVQ(RCX, R8)
   190  		SHRQ(Imm(4), R8)
   191  		ADDQ(Imm(1), R8)
   192  		TESTQ(RCX, RCX)
   193  		JE(LabelRef("LBB2_5"))
   194  		MOVQ(R8, RCX)
   195  		ANDQ(I32(-2), RCX)
   196  		VXORPD(X0, X0, X0)
   197  		XORL(EDX, EDX)
   198  		VXORPD(X1, X1, X1)
   199  		VXORPD(X2, X2, X2)
   200  		VXORPD(X3, X3, X3)
   201  	}
   202  
   203  	Label("LBB2_7")
   204  	{
   205  		VMOVUPD(Mem{Base: RDI}.Idx(RDX, 8), Y4)
   206  		VMOVUPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(32), Y5)
   207  		VMOVUPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(64), Y6)
   208  		VMOVUPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(96), Y7)
   209  		VFMADD213PD(Y0, Y4, Y4)
   210  		VFMADD213PD(Y1, Y5, Y5)
   211  		VFMADD213PD(Y2, Y6, Y6)
   212  		VFMADD213PD(Y3, Y7, Y7)
   213  		VMOVUPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(128), Y0)
   214  		VMOVUPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(160), Y1)
   215  		VMOVUPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(192), Y2)
   216  		VMOVUPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(224), Y3)
   217  		VFMADD213PD(Y4, Y0, Y0)
   218  		VFMADD213PD(Y5, Y1, Y1)
   219  		VFMADD213PD(Y6, Y2, Y2)
   220  		VFMADD213PD(Y7, Y3, Y3)
   221  		ADDQ(Imm(32), RDX)
   222  		ADDQ(I32(-2), RCX)
   223  		JNE(LabelRef("LBB2_7"))
   224  		TESTB(Imm(1), R8B)
   225  		JE(LabelRef("LBB2_10"))
   226  	}
   227  
   228  	Label("LBB2_9")
   229  	{
   230  		VMOVUPD(Mem{Base: RDI}.Idx(RDX, 8), Y4)
   231  		VMOVUPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(32), Y5)
   232  		VMOVUPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(64), Y6)
   233  		VMOVUPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(96), Y7)
   234  		VFMADD231PD(Y4, Y4, Y0)
   235  		VFMADD231PD(Y5, Y5, Y1)
   236  		VFMADD231PD(Y6, Y6, Y2)
   237  		VFMADD231PD(Y7, Y7, Y3)
   238  	}
   239  
   240  	Label("LBB2_10")
   241  	{
   242  		VADDPD(Y3, Y1, Y1)
   243  		VADDPD(Y2, Y0, Y0)
   244  		VADDPD(Y1, Y0, Y0)
   245  		VEXTRACTF128(Imm(1), Y0, X1)
   246  		VADDPD(X1, X0, X0)
   247  		VPERMILPD(Imm(1), X0, X1)
   248  		VADDSD(X1, X0, X0)
   249  		CMPQ(RAX, RSI)
   250  		JE(LabelRef("LBB2_12"))
   251  	}
   252  
   253  	Label("LBB2_11")
   254  	{
   255  		VMOVSD(Mem{Base: RDI}.Idx(RAX, 8), X1)
   256  		VFMADD231SD(X1, X1, X0)
   257  		ADDQ(Imm(1), RAX)
   258  		CMPQ(RSI, RAX)
   259  		JNE(LabelRef("LBB2_11"))
   260  	}
   261  
   262  	Label("LBB2_12")
   263  	{
   264  		VSQRTSD(X0, X0, X0)
   265  		VZEROUPPER()
   266  		Store(X0, ReturnIndex(0))
   267  		RET()
   268  	}
   269  
   270  	Label("LBB2_5")
   271  	{
   272  		VXORPD(X0, X0, X0)
   273  		XORL(EDX, EDX)
   274  		VXORPD(X1, X1, X1)
   275  		VXORPD(X2, X2, X2)
   276  		VXORPD(X3, X3, X3)
   277  		TESTB(Imm(1), R8B)
   278  		JNE(LabelRef("LBB2_9"))
   279  		JMP(LabelRef("LBB2_10"))
   280  	}
   281  }
   282  
   283  func genNorm_F32() {
   284  
   285  	data := GLOBL("dataNormF32", RODATA|NOPTR)
   286  	DATA(0, U32(0xc0400000))
   287  	DATA(4, U32(0xbf000000))
   288  	DATA(8, U32(0x7fffffff))
   289  	DATA(12, U32(0x00800000))
   290  
   291  	TEXT("Norm_AVX2_F32", NOSPLIT, "func(x []float32) float32")
   292  	Pragma("noescape")
   293  	Load(Param("x").Base(), RDI)
   294  	Load(Param("x").Len(), RSI)
   295  
   296  	TESTQ(RSI, RSI)
   297  	JE(LabelRef("LBB3_1"))
   298  	CMPQ(RSI, Imm(32))
   299  	JAE(LabelRef("LBB3_4"))
   300  	VXORPS(X0, X0, X0)
   301  	XORL(EAX, EAX)
   302  	JMP(LabelRef("LBB3_11"))
   303  
   304  	Label("LBB3_1")
   305  	{
   306  		VXORPS(X0, X0, X0)
   307  		JMP(LabelRef("LBB3_12"))
   308  	}
   309  
   310  	Label("LBB3_4")
   311  	{
   312  		MOVQ(RSI, RAX)
   313  		ANDQ(I32(-32), RAX)
   314  		LEAQ(Mem{Base: RAX}.Offset(-32), RCX)
   315  		MOVQ(RCX, R8)
   316  		SHRQ(Imm(5), R8)
   317  		ADDQ(Imm(1), R8)
   318  		TESTQ(RCX, RCX)
   319  		JE(LabelRef("LBB3_5"))
   320  		MOVQ(R8, RCX)
   321  		ANDQ(I32(-2), RCX)
   322  		VXORPS(X0, X0, X0)
   323  		XORL(EDX, EDX)
   324  		VXORPS(X1, X1, X1)
   325  		VXORPS(X2, X2, X2)
   326  		VXORPS(X3, X3, X3)
   327  	}
   328  
   329  	Label("LBB3_7")
   330  	{
   331  		VMOVUPS(Mem{Base: RDI}.Idx(RDX, 4), Y4)
   332  		VMOVUPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(32), Y5)
   333  		VMOVUPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(64), Y6)
   334  		VMOVUPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(96), Y7)
   335  		VFMADD213PS(Y0, Y4, Y4)
   336  		VFMADD213PS(Y1, Y5, Y5)
   337  		VFMADD213PS(Y2, Y6, Y6)
   338  		VFMADD213PS(Y3, Y7, Y7)
   339  		VMOVUPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(128), Y0)
   340  		VMOVUPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(160), Y1)
   341  		VMOVUPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(192), Y2)
   342  		VMOVUPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(224), Y3)
   343  		VFMADD213PS(Y4, Y0, Y0)
   344  		VFMADD213PS(Y5, Y1, Y1)
   345  		VFMADD213PS(Y6, Y2, Y2)
   346  		VFMADD213PS(Y7, Y3, Y3)
   347  		ADDQ(Imm(64), RDX)
   348  		ADDQ(I32(-2), RCX)
   349  		JNE(LabelRef("LBB3_7"))
   350  		TESTB(Imm(1), R8B)
   351  		JE(LabelRef("LBB3_10"))
   352  	}
   353  
   354  	Label("LBB3_9")
   355  	{
   356  		VMOVUPS(Mem{Base: RDI}.Idx(RDX, 4), Y4)
   357  		VMOVUPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(32), Y5)
   358  		VMOVUPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(64), Y6)
   359  		VMOVUPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(96), Y7)
   360  		VFMADD231PS(Y4, Y4, Y0)
   361  		VFMADD231PS(Y5, Y5, Y1)
   362  		VFMADD231PS(Y6, Y6, Y2)
   363  		VFMADD231PS(Y7, Y7, Y3)
   364  	}
   365  
   366  	Label("LBB3_10")
   367  	{
   368  		VADDPS(Y3, Y1, Y1)
   369  		VADDPS(Y2, Y0, Y0)
   370  		VADDPS(Y1, Y0, Y0)
   371  		VEXTRACTF128(Imm(1), Y0, X1)
   372  		VADDPS(X1, X0, X0)
   373  		VPERMILPD(Imm(1), X0, X1)
   374  		VADDPS(X1, X0, X0)
   375  		VMOVSHDUP(X0, X1)
   376  		VADDSS(X1, X0, X0)
   377  		CMPQ(RAX, RSI)
   378  		JE(LabelRef("LBB3_12"))
   379  	}
   380  
   381  	Label("LBB3_11")
   382  	{
   383  		VMOVSS(Mem{Base: RDI}.Idx(RAX, 4), X1)
   384  		VFMADD231SS(X1, X1, X0)
   385  		ADDQ(Imm(1), RAX)
   386  		CMPQ(RSI, RAX)
   387  		JNE(LabelRef("LBB3_11"))
   388  	}
   389  
   390  	Label("LBB3_12")
   391  	{
   392  		VRSQRTSS(X0, X0, X1)
   393  		VMULSS(X1, X0, X2)
   394  		VFMADD213SS(data.Offset(0), X2, X1)
   395  		VMULSS(data.Offset(4), X2, X2)
   396  		VMULSS(X1, X2, X1)
   397  		VBROADCASTSS(data.Offset(8), X2)
   398  		VANDPS(X2, X0, X0)
   399  		VCMPSS(Imm(1), data.Offset(12), X0, X0)
   400  		VANDNPS(X1, X0, X0)
   401  		VZEROUPPER()
   402  		Store(X0, ReturnIndex(0))
   403  		RET()
   404  	}
   405  
   406  	Label("LBB3_5")
   407  	{
   408  		VXORPS(X0, X0, X0)
   409  		XORL(EDX, EDX)
   410  		VXORPS(X1, X1, X1)
   411  		VXORPS(X2, X2, X2)
   412  		VXORPS(X3, X3, X3)
   413  		TESTB(Imm(1), R8B)
   414  		JNE(LabelRef("LBB3_9"))
   415  		JMP(LabelRef("LBB3_10"))
   416  	}
   417  }
   418  
   419  func genDistance_F64() {
   420  
   421  	TEXT("Distance_AVX2_F64", NOSPLIT, "func(x, y []float64) float64")
   422  	Pragma("noescape")
   423  	Load(Param("x").Base(), RDI)
   424  	Load(Param("y").Base(), RSI)
   425  	Load(Param("x").Len(), RDX)
   426  
   427  	TESTQ(RDX, RDX)
   428  	JE(LabelRef("LBB4_1"))
   429  	CMPQ(RDX, Imm(16))
   430  	JAE(LabelRef("LBB4_4"))
   431  	VXORPD(X0, X0, X0)
   432  	XORL(EAX, EAX)
   433  	JMP(LabelRef("LBB4_7"))
   434  
   435  	Label("LBB4_1")
   436  	{
   437  		VXORPD(X0, X0, X0)
   438  		VSQRTSD(X0, X0, X0)
   439  		Store(X0, ReturnIndex(0))
   440  		RET()
   441  	}
   442  
   443  	Label("LBB4_4")
   444  	{
   445  		MOVQ(RDX, RAX)
   446  		ANDQ(I32(-16), RAX)
   447  		VXORPD(X0, X0, X0)
   448  		XORL(ECX, ECX)
   449  		VXORPD(X1, X1, X1)
   450  		VXORPD(X2, X2, X2)
   451  		VXORPD(X3, X3, X3)
   452  	}
   453  
   454  	Label("LBB4_5")
   455  	{
   456  		VMOVUPD(Mem{Base: RDI}.Idx(RCX, 8), Y4)
   457  		VMOVUPD(Mem{Base: RDI}.Idx(RCX, 8).Offset(32), Y5)
   458  		VMOVUPD(Mem{Base: RDI}.Idx(RCX, 8).Offset(64), Y6)
   459  		VMOVUPD(Mem{Base: RDI}.Idx(RCX, 8).Offset(96), Y7)
   460  		VSUBPD(Mem{Base: RSI}.Idx(RCX, 8), Y4, Y4)
   461  		VSUBPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(32), Y5, Y5)
   462  		VSUBPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(64), Y6, Y6)
   463  		VSUBPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(96), Y7, Y7)
   464  		VFMADD231PD(Y4, Y4, Y0)
   465  		VFMADD231PD(Y5, Y5, Y1)
   466  		VFMADD231PD(Y6, Y6, Y2)
   467  		VFMADD231PD(Y7, Y7, Y3)
   468  		ADDQ(Imm(16), RCX)
   469  		CMPQ(RAX, RCX)
   470  		JNE(LabelRef("LBB4_5"))
   471  		VADDPD(Y0, Y1, Y0)
   472  		VADDPD(Y0, Y2, Y0)
   473  		VADDPD(Y0, Y3, Y0)
   474  		VEXTRACTF128(Imm(1), Y0, X1)
   475  		VADDPD(X1, X0, X0)
   476  		VPERMILPD(Imm(1), X0, X1)
   477  		VADDSD(X1, X0, X0)
   478  		CMPQ(RAX, RDX)
   479  		JE(LabelRef("LBB4_8"))
   480  	}
   481  
   482  	Label("LBB4_7")
   483  	{
   484  		VMOVSD(Mem{Base: RDI}.Idx(RAX, 8), X1)
   485  		VSUBSD(Mem{Base: RSI}.Idx(RAX, 8), X1, X1)
   486  		VFMADD231SD(X1, X1, X0)
   487  		ADDQ(Imm(1), RAX)
   488  		CMPQ(RDX, RAX)
   489  		JNE(LabelRef("LBB4_7"))
   490  	}
   491  
   492  	Label("LBB4_8")
   493  	{
   494  		VSQRTSD(X0, X0, X0)
   495  		VZEROUPPER()
   496  		Store(X0, ReturnIndex(0))
   497  		RET()
   498  	}
   499  }
   500  
   501  func genDistance_F32() {
   502  	data := GLOBL("dataDistanceF32", RODATA|NOPTR)
   503  	DATA(0, U32(0xc0400000))
   504  	DATA(4, U32(0xbf000000))
   505  	DATA(8, U32(0x7fffffff))
   506  	DATA(12, U32(0x00800000))
   507  
   508  	TEXT("Distance_AVX2_F32", NOSPLIT, "func(x, y []float32) float32")
   509  	Pragma("noescape")
   510  	Load(Param("x").Base(), RDI)
   511  	Load(Param("y").Base(), RSI)
   512  	Load(Param("x").Len(), RDX)
   513  
   514  	TESTQ(RDX, RDX)
   515  	JE(LabelRef("LBB5_1"))
   516  	CMPQ(RDX, Imm(32))
   517  	JAE(LabelRef("LBB5_4"))
   518  	VXORPS(X0, X0, X0)
   519  	XORL(EAX, EAX)
   520  	JMP(LabelRef("LBB5_7"))
   521  
   522  	Label("LBB5_1")
   523  	{
   524  		VXORPS(X0, X0, X0)
   525  		JMP(LabelRef("LBB5_8"))
   526  	}
   527  
   528  	Label("LBB5_4")
   529  	{
   530  		MOVQ(RDX, RAX)
   531  		ANDQ(I32(-32), RAX)
   532  		VXORPS(X0, X0, X0)
   533  		XORL(ECX, ECX)
   534  		VXORPS(X1, X1, X1)
   535  		VXORPS(X2, X2, X2)
   536  		VXORPS(X3, X3, X3)
   537  	}
   538  
   539  	Label("LBB5_5")
   540  	{
   541  		VMOVUPS(Mem{Base: RDI}.Idx(RCX, 4), Y4)
   542  		VMOVUPS(Mem{Base: RDI}.Idx(RCX, 4).Offset(32), Y5)
   543  		VMOVUPS(Mem{Base: RDI}.Idx(RCX, 4).Offset(64), Y6)
   544  		VMOVUPS(Mem{Base: RDI}.Idx(RCX, 4).Offset(96), Y7)
   545  		VSUBPS(Mem{Base: RSI}.Idx(RCX, 4), Y4, Y4)
   546  		VSUBPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(32), Y5, Y5)
   547  		VSUBPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(64), Y6, Y6)
   548  		VSUBPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(96), Y7, Y7)
   549  		VFMADD231PS(Y4, Y4, Y0)
   550  		VFMADD231PS(Y5, Y5, Y1)
   551  		VFMADD231PS(Y6, Y6, Y2)
   552  		VFMADD231PS(Y7, Y7, Y3)
   553  		ADDQ(Imm(32), RCX)
   554  		CMPQ(RAX, RCX)
   555  		JNE(LabelRef("LBB5_5"))
   556  		VADDPS(Y0, Y1, Y0)
   557  		VADDPS(Y0, Y2, Y0)
   558  		VADDPS(Y0, Y3, Y0)
   559  		VEXTRACTF128(Imm(1), Y0, X1)
   560  		VADDPS(X1, X0, X0)
   561  		VPERMILPD(Imm(1), X0, X1)
   562  		VADDPS(X1, X0, X0)
   563  		VMOVSHDUP(X0, X1)
   564  		VADDSS(X1, X0, X0)
   565  		CMPQ(RAX, RDX)
   566  		JE(LabelRef("LBB5_8"))
   567  	}
   568  
   569  	Label("LBB5_7")
   570  	{
   571  		VMOVSS(Mem{Base: RDI}.Idx(RAX, 4), X1)
   572  		VSUBSS(Mem{Base: RSI}.Idx(RAX, 4), X1, X1)
   573  		VFMADD231SS(X1, X1, X0)
   574  		ADDQ(Imm(1), RAX)
   575  		CMPQ(RDX, RAX)
   576  		JNE(LabelRef("LBB5_7"))
   577  	}
   578  
   579  	Label("LBB5_8")
   580  	{
   581  		VRSQRTSS(X0, X0, X1)
   582  		VMULSS(X1, X0, X2)
   583  		VFMADD213SS(data.Offset(0), X2, X1)
   584  		VMULSS(data.Offset(4), X2, X2)
   585  		VMULSS(X1, X2, X1)
   586  		VBROADCASTSS(data.Offset(8), X2)
   587  		VANDPS(X2, X0, X0)
   588  		VCMPSS(Imm(1), data.Offset(12), X0, X0)
   589  		VANDNPS(X1, X0, X0)
   590  		VZEROUPPER()
   591  		Store(X0, ReturnIndex(0))
   592  		RET()
   593  	}
   594  }
   595  
   596  func genManhattanNorm_F64() {
   597  
   598  	data := GLOBL("dataManhattanNormF64", RODATA|NOPTR)
   599  	DATA(0, U64(0x7fffffffffffffff))
   600  	DATA(8, U64(0x7fffffffffffffff))
   601  	DATA(16, U64(0x7fffffffffffffff))
   602  
   603  	TEXT("ManhattanNorm_AVX2_F64", NOSPLIT, "func(x []float64) float64")
   604  	Pragma("noescape")
   605  	Load(Param("x").Base(), RDI)
   606  	Load(Param("x").Len(), RSI)
   607  
   608  	TESTQ(RSI, RSI)
   609  	JE(LabelRef("LBB6_1"))
   610  	CMPQ(RSI, Imm(16))
   611  	JAE(LabelRef("LBB6_4"))
   612  	VXORPD(X0, X0, X0)
   613  	XORL(EAX, EAX)
   614  	JMP(LabelRef("LBB6_7"))
   615  
   616  	Label("LBB6_1")
   617  	{
   618  		VXORPS(X0, X0, X0)
   619  		Store(X0, ReturnIndex(0))
   620  		RET()
   621  	}
   622  
   623  	Label("LBB6_4")
   624  	{
   625  		MOVQ(RSI, RAX)
   626  		ANDQ(I32(-16), RAX)
   627  		VXORPD(X0, X0, X0)
   628  		VBROADCASTSD(data.Offset(0), Y1)
   629  		XORL(ECX, ECX)
   630  		VXORPD(X2, X2, X2)
   631  		VXORPD(X3, X3, X3)
   632  		VXORPD(X4, X4, X4)
   633  	}
   634  
   635  	Label("LBB6_5")
   636  	{
   637  		VANDPD(Mem{Base: RDI}.Idx(RCX, 8), Y1, Y5)
   638  		VADDPD(Y0, Y5, Y0)
   639  		VANDPD(Mem{Base: RDI}.Idx(RCX, 8).Offset(32), Y1, Y5)
   640  		VADDPD(Y2, Y5, Y2)
   641  		VANDPD(Mem{Base: RDI}.Idx(RCX, 8).Offset(64), Y1, Y5)
   642  		VANDPD(Mem{Base: RDI}.Idx(RCX, 8).Offset(96), Y1, Y6)
   643  		VADDPD(Y3, Y5, Y3)
   644  		VADDPD(Y4, Y6, Y4)
   645  		ADDQ(Imm(16), RCX)
   646  		CMPQ(RAX, RCX)
   647  		JNE(LabelRef("LBB6_5"))
   648  		VADDPD(Y0, Y2, Y0)
   649  		VADDPD(Y0, Y3, Y0)
   650  		VADDPD(Y0, Y4, Y0)
   651  		VEXTRACTF128(Imm(1), Y0, X1)
   652  		VADDPD(X1, X0, X0)
   653  		VPERMILPD(Imm(1), X0, X1)
   654  		VADDSD(X1, X0, X0)
   655  		CMPQ(RAX, RSI)
   656  		JE(LabelRef("LBB6_9"))
   657  	}
   658  
   659  	Label("LBB6_7")
   660  	{
   661  		VMOVUPD(data.Offset(8), X1)
   662  	}
   663  
   664  	Label("LBB6_8")
   665  	{
   666  		VMOVSD(Mem{Base: RDI}.Idx(RAX, 8), X2)
   667  		VANDPD(X1, X2, X2)
   668  		VADDSD(X0, X2, X0)
   669  		ADDQ(Imm(1), RAX)
   670  		CMPQ(RSI, RAX)
   671  		JNE(LabelRef("LBB6_8"))
   672  	}
   673  
   674  	Label("LBB6_9")
   675  	{
   676  		VZEROUPPER()
   677  		Store(X0, ReturnIndex(0))
   678  		RET()
   679  	}
   680  }
   681  
   682  func genManhattanNorm_F32() {
   683  	data := GLOBL("dataManhattanNormF32", RODATA|NOPTR)
   684  	DATA(0, U32(0x7fffffff))
   685  
   686  	TEXT("ManhattanNorm_AVX2_F32", NOSPLIT, "func(x []float32) float32")
   687  	Pragma("noescape")
   688  	Load(Param("x").Base(), RDI)
   689  	Load(Param("x").Len(), RSI)
   690  
   691  	TESTQ(RSI, RSI)
   692  	JE(LabelRef("LBB7_1"))
   693  	CMPQ(RSI, Imm(32))
   694  	JAE(LabelRef("LBB7_4"))
   695  	VXORPS(X0, X0, X0)
   696  	XORL(EAX, EAX)
   697  	JMP(LabelRef("LBB7_7"))
   698  
   699  	Label("LBB7_1")
   700  	{
   701  		VXORPS(X0, X0, X0)
   702  		Store(X0, ReturnIndex(0))
   703  		RET()
   704  	}
   705  
   706  	Label("LBB7_4")
   707  	{
   708  		MOVQ(RSI, RAX)
   709  		ANDQ(I32(-32), RAX)
   710  		VXORPS(X0, X0, X0)
   711  		VBROADCASTSS(data.Offset(0), Y1)
   712  		XORL(ECX, ECX)
   713  		VXORPS(X2, X2, X2)
   714  		VXORPS(X3, X3, X3)
   715  		VXORPS(X4, X4, X4)
   716  	}
   717  
   718  	Label("LBB7_5")
   719  	{
   720  		VANDPS(Mem{Base: RDI}.Idx(RCX, 4), Y1, Y5)
   721  		VADDPS(Y0, Y5, Y0)
   722  		VANDPS(Mem{Base: RDI}.Idx(RCX, 4).Offset(32), Y1, Y5)
   723  		VADDPS(Y2, Y5, Y2)
   724  		VANDPS(Mem{Base: RDI}.Idx(RCX, 4).Offset(64), Y1, Y5)
   725  		VANDPS(Mem{Base: RDI}.Idx(RCX, 4).Offset(96), Y1, Y6)
   726  		VADDPS(Y3, Y5, Y3)
   727  		VADDPS(Y4, Y6, Y4)
   728  		ADDQ(Imm(32), RCX)
   729  		CMPQ(RAX, RCX)
   730  		JNE(LabelRef("LBB7_5"))
   731  		VADDPS(Y0, Y2, Y0)
   732  		VADDPS(Y0, Y3, Y0)
   733  		VADDPS(Y0, Y4, Y0)
   734  		VEXTRACTF128(Imm(1), Y0, X1)
   735  		VADDPS(X1, X0, X0)
   736  		VPERMILPD(Imm(1), X0, X1)
   737  		VADDPS(X1, X0, X0)
   738  		VMOVSHDUP(X0, X1)
   739  		VADDSS(X1, X0, X0)
   740  		CMPQ(RAX, RSI)
   741  		JE(LabelRef("LBB7_9"))
   742  	}
   743  
   744  	Label("LBB7_7")
   745  	{
   746  		VBROADCASTSS(data.Offset(0), X1)
   747  	}
   748  
   749  	Label("LBB7_8")
   750  	{
   751  		VMOVSS(Mem{Base: RDI}.Idx(RAX, 4), X2)
   752  		VANDPS(X1, X2, X2)
   753  		VADDSS(X0, X2, X0)
   754  		ADDQ(Imm(1), RAX)
   755  		CMPQ(RSI, RAX)
   756  		JNE(LabelRef("LBB7_8"))
   757  	}
   758  
   759  	Label("LBB7_9")
   760  	{
   761  		VZEROUPPER()
   762  		Store(X0, ReturnIndex(0))
   763  		RET()
   764  	}
   765  }
   766  
   767  func genManhattanDistance_F64() {
   768  	data := GLOBL("dataManhattanDistanceF64", RODATA|NOPTR)
   769  	DATA(0, U64(0x7fffffffffffffff))
   770  	DATA(8, U64(0x7fffffffffffffff))
   771  	DATA(16, U64(0x7fffffffffffffff))
   772  
   773  	TEXT("ManhattanDistance_AVX2_F64", NOSPLIT, "func(x, y []float64) float64")
   774  	Pragma("noescape")
   775  	Load(Param("x").Base(), RDI)
   776  	Load(Param("y").Base(), RSI)
   777  	Load(Param("x").Len(), RDX)
   778  
   779  	TESTQ(RDX, RDX)
   780  	JE(LabelRef("LBB8_1"))
   781  	CMPQ(RDX, Imm(16))
   782  	JAE(LabelRef("LBB8_4"))
   783  	VXORPD(X0, X0, X0)
   784  	XORL(EAX, EAX)
   785  	JMP(LabelRef("LBB8_7"))
   786  
   787  	Label("LBB8_1")
   788  	{
   789  		VXORPS(X0, X0, X0)
   790  		Store(X0, ReturnIndex(0))
   791  		RET()
   792  	}
   793  
   794  	Label("LBB8_4")
   795  	{
   796  		MOVQ(RDX, RAX)
   797  		ANDQ(I32(-16), RAX)
   798  		VXORPD(X0, X0, X0)
   799  		VBROADCASTSD(data.Offset(0), Y1)
   800  		XORL(ECX, ECX)
   801  		VXORPD(X2, X2, X2)
   802  		VXORPD(X3, X3, X3)
   803  		VXORPD(X4, X4, X4)
   804  	}
   805  
   806  	Label("LBB8_5")
   807  	{
   808  		VMOVUPD(Mem{Base: RDI}.Idx(RCX, 8), Y5)
   809  		VMOVUPD(Mem{Base: RDI}.Idx(RCX, 8).Offset(32), Y6)
   810  		VMOVUPD(Mem{Base: RDI}.Idx(RCX, 8).Offset(64), Y7)
   811  		VMOVUPD(Mem{Base: RDI}.Idx(RCX, 8).Offset(96), Y8)
   812  		VSUBPD(Mem{Base: RSI}.Idx(RCX, 8), Y5, Y5)
   813  		VSUBPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(32), Y6, Y6)
   814  		VSUBPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(64), Y7, Y7)
   815  		VSUBPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(96), Y8, Y8)
   816  		VANDPD(Y1, Y5, Y5)
   817  		VADDPD(Y0, Y5, Y0)
   818  		VANDPD(Y1, Y6, Y5)
   819  		VADDPD(Y2, Y5, Y2)
   820  		VANDPD(Y1, Y7, Y5)
   821  		VADDPD(Y3, Y5, Y3)
   822  		VANDPD(Y1, Y8, Y5)
   823  		VADDPD(Y4, Y5, Y4)
   824  		ADDQ(Imm(16), RCX)
   825  		CMPQ(RAX, RCX)
   826  		JNE(LabelRef("LBB8_5"))
   827  		VADDPD(Y0, Y2, Y0)
   828  		VADDPD(Y0, Y3, Y0)
   829  		VADDPD(Y0, Y4, Y0)
   830  		VEXTRACTF128(Imm(1), Y0, X1)
   831  		VADDPD(X1, X0, X0)
   832  		VPERMILPD(Imm(1), X0, X1)
   833  		VADDSD(X1, X0, X0)
   834  		CMPQ(RAX, RDX)
   835  		JE(LabelRef("LBB8_9"))
   836  	}
   837  
   838  	Label("LBB8_7")
   839  	{
   840  		VMOVUPD(data.Offset(8), X1)
   841  	}
   842  
   843  	Label("LBB8_8")
   844  	{
   845  		VMOVSD(Mem{Base: RDI}.Idx(RAX, 8), X2)
   846  		VSUBSD(Mem{Base: RSI}.Idx(RAX, 8), X2, X2)
   847  		VANDPD(X1, X2, X2)
   848  		VADDSD(X0, X2, X0)
   849  		ADDQ(Imm(1), RAX)
   850  		CMPQ(RDX, RAX)
   851  		JNE(LabelRef("LBB8_8"))
   852  	}
   853  
   854  	Label("LBB8_9")
   855  	{
   856  		VZEROUPPER()
   857  		Store(X0, ReturnIndex(0))
   858  		RET()
   859  	}
   860  }
   861  
   862  func genManhattanDistance_F32() {
   863  	data := GLOBL("dataManhattanDistanceF32", RODATA|NOPTR)
   864  	DATA(0, U32(0x7fffffff))
   865  
   866  	TEXT("ManhattanDistance_AVX2_F32", NOSPLIT, "func(x, y []float32) float32")
   867  	Pragma("noescape")
   868  	Load(Param("x").Base(), RDI)
   869  	Load(Param("y").Base(), RSI)
   870  	Load(Param("x").Len(), RDX)
   871  
   872  	TESTQ(RDX, RDX)
   873  	JE(LabelRef("LBB9_1"))
   874  	CMPQ(RDX, Imm(32))
   875  	JAE(LabelRef("LBB9_4"))
   876  	VXORPS(X0, X0, X0)
   877  	XORL(EAX, EAX)
   878  	JMP(LabelRef("LBB9_7"))
   879  
   880  	Label("LBB9_1")
   881  	{
   882  		VXORPS(X0, X0, X0)
   883  		Store(X0, ReturnIndex(0))
   884  		RET()
   885  	}
   886  
   887  	Label("LBB9_4")
   888  	{
   889  		MOVQ(RDX, RAX)
   890  		ANDQ(I32(-32), RAX)
   891  		VXORPS(X0, X0, X0)
   892  		VBROADCASTSS(data.Offset(0), Y1)
   893  		XORL(ECX, ECX)
   894  		VXORPS(X2, X2, X2)
   895  		VXORPS(X3, X3, X3)
   896  		VXORPS(X4, X4, X4)
   897  	}
   898  
   899  	Label("LBB9_5")
   900  	{
   901  		VMOVUPS(Mem{Base: RDI}.Idx(RCX, 4), Y5)
   902  		VMOVUPS(Mem{Base: RDI}.Idx(RCX, 4).Offset(32), Y6)
   903  		VMOVUPS(Mem{Base: RDI}.Idx(RCX, 4).Offset(64), Y7)
   904  		VMOVUPS(Mem{Base: RDI}.Idx(RCX, 4).Offset(96), Y8)
   905  		VSUBPS(Mem{Base: RSI}.Idx(RCX, 4), Y5, Y5)
   906  		VSUBPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(32), Y6, Y6)
   907  		VSUBPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(64), Y7, Y7)
   908  		VSUBPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(96), Y8, Y8)
   909  		VANDPS(Y1, Y5, Y5)
   910  		VADDPS(Y0, Y5, Y0)
   911  		VANDPS(Y1, Y6, Y5)
   912  		VADDPS(Y2, Y5, Y2)
   913  		VANDPS(Y1, Y7, Y5)
   914  		VADDPS(Y3, Y5, Y3)
   915  		VANDPS(Y1, Y8, Y5)
   916  		VADDPS(Y4, Y5, Y4)
   917  		ADDQ(Imm(32), RCX)
   918  		CMPQ(RAX, RCX)
   919  		JNE(LabelRef("LBB9_5"))
   920  		VADDPS(Y0, Y2, Y0)
   921  		VADDPS(Y0, Y3, Y0)
   922  		VADDPS(Y0, Y4, Y0)
   923  		VEXTRACTF128(Imm(1), Y0, X1)
   924  		VADDPS(X1, X0, X0)
   925  		VPERMILPD(Imm(1), X0, X1)
   926  		VADDPS(X1, X0, X0)
   927  		VMOVSHDUP(X0, X1)
   928  		VADDSS(X1, X0, X0)
   929  		CMPQ(RAX, RDX)
   930  		JE(LabelRef("LBB9_9"))
   931  	}
   932  
   933  	Label("LBB9_7")
   934  	{
   935  		VBROADCASTSS(data.Offset(0), X1)
   936  	}
   937  
   938  	Label("LBB9_8")
   939  	{
   940  		VMOVSS(Mem{Base: RDI}.Idx(RAX, 4), X2)
   941  		VSUBSS(Mem{Base: RSI}.Idx(RAX, 4), X2, X2)
   942  		VANDPS(X1, X2, X2)
   943  		VADDSS(X0, X2, X0)
   944  		ADDQ(Imm(1), RAX)
   945  		CMPQ(RDX, RAX)
   946  		JNE(LabelRef("LBB9_8"))
   947  	}
   948  
   949  	Label("LBB9_9")
   950  	{
   951  		VZEROUPPER()
   952  		Store(X0, ReturnIndex(0))
   953  		RET()
   954  	}
   955  }
   956  
   957  func genCosineSimilarity_F64() {
   958  
   959  	TEXT("CosineSimilarity_AVX2_F64", NOSPLIT, "func(x, y []float64) float64")
   960  	Pragma("noescape")
   961  	Load(Param("x").Base(), RDI)
   962  	Load(Param("y").Base(), RSI)
   963  	Load(Param("x").Len(), RDX)
   964  
   965  	TESTQ(RDX, RDX)
   966  	JE(LabelRef("LBB2_1"))
   967  	CMPQ(RDX, Imm(8))
   968  	JAE(LabelRef("LBB2_5"))
   969  	VXORPD(X1, X1, X1)
   970  	XORL(EAX, EAX)
   971  	VXORPD(X2, X2, X2)
   972  	VXORPD(X0, X0, X0)
   973  	JMP(LabelRef("LBB2_4"))
   974  
   975  	Label("LBB2_1")
   976  	{
   977  		VXORPD(X0, X0, X0)
   978  		VXORPD(X1, X1, X1)
   979  		VSQRTSD(X1, X1, X1)
   980  		VDIVSD(X1, X0, X0)
   981  		Store(X0, ReturnIndex(0))
   982  		RET()
   983  	}
   984  
   985  	Label("LBB2_5")
   986  	{
   987  		MOVQ(RDX, RAX)
   988  		ANDQ(I32(-8), RAX)
   989  		VXORPD(X1, X1, X1)
   990  		XORL(ECX, ECX)
   991  		VXORPD(X3, X3, X3)
   992  		VXORPD(X2, X2, X2)
   993  		VXORPD(X4, X4, X4)
   994  		VXORPD(X0, X0, X0)
   995  		VXORPD(X5, X5, X5)
   996  	}
   997  
   998  	Label("LBB2_6")
   999  	{
  1000  		VMOVUPD(Mem{Base: RDI}.Idx(RCX, 8), Y6)
  1001  		VMOVUPD(Mem{Base: RDI}.Idx(RCX, 8).Offset(32), Y7)
  1002  		VMOVUPD(Mem{Base: RSI}.Idx(RCX, 8), Y8)
  1003  		VMOVUPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(32), Y9)
  1004  		VFMADD231PD(Y6, Y8, Y0)
  1005  		VFMADD231PD(Y7, Y9, Y5)
  1006  		VFMADD231PD(Y6, Y6, Y2)
  1007  		VFMADD231PD(Y7, Y7, Y4)
  1008  		VFMADD231PD(Y8, Y8, Y1)
  1009  		VFMADD231PD(Y9, Y9, Y3)
  1010  		ADDQ(Imm(8), RCX)
  1011  		CMPQ(RAX, RCX)
  1012  		JNE(LabelRef("LBB2_6"))
  1013  		VADDPD(Y0, Y5, Y0)
  1014  		VEXTRACTF128(Imm(1), Y0, X5)
  1015  		VADDPD(X5, X0, X0)
  1016  		VPERMILPD(Imm(1), X0, X5)
  1017  		VADDSD(X5, X0, X0)
  1018  		VADDPD(Y2, Y4, Y2)
  1019  		VEXTRACTF128(Imm(1), Y2, X4)
  1020  		VADDPD(X4, X2, X2)
  1021  		VPERMILPD(Imm(1), X2, X4)
  1022  		VADDSD(X4, X2, X2)
  1023  		VADDPD(Y1, Y3, Y1)
  1024  		VEXTRACTF128(Imm(1), Y1, X3)
  1025  		VADDPD(X3, X1, X1)
  1026  		VPERMILPD(Imm(1), X1, X3)
  1027  		VADDSD(X3, X1, X1)
  1028  		CMPQ(RAX, RDX)
  1029  		JE(LabelRef("LBB2_8"))
  1030  	}
  1031  
  1032  	Label("LBB2_4")
  1033  	{
  1034  		VMOVSD(Mem{Base: RDI}.Idx(RAX, 8), X3)
  1035  		VMOVSD(Mem{Base: RSI}.Idx(RAX, 8), X4)
  1036  		VFMADD231SD(X3, X4, X0)
  1037  		VFMADD231SD(X3, X3, X2)
  1038  		VFMADD231SD(X4, X4, X1)
  1039  		ADDQ(Imm(1), RAX)
  1040  		CMPQ(RDX, RAX)
  1041  		JNE(LabelRef("LBB2_4"))
  1042  	}
  1043  
  1044  	Label("LBB2_8")
  1045  	{
  1046  		VMULSD(X2, X1, X1)
  1047  		VSQRTSD(X1, X1, X1)
  1048  		VDIVSD(X1, X0, X0)
  1049  		VZEROUPPER()
  1050  		Store(X0, ReturnIndex(0))
  1051  		RET()
  1052  	}
  1053  }
  1054  
  1055  func genCosineSimilarity_F32() {
  1056  	data := GLOBL("dataCosineSimilarityF32", RODATA|NOPTR)
  1057  	DATA(0, U32(0xc0400000))
  1058  	DATA(4, U32(0xbf000000))
  1059  
  1060  	TEXT("CosineSimilarity_AVX2_F32", NOSPLIT, "func(x, y []float32) float32")
  1061  	Pragma("noescape")
  1062  	Load(Param("x").Base(), RDI)
  1063  	Load(Param("y").Base(), RSI)
  1064  	Load(Param("x").Len(), RDX)
  1065  
  1066  	TESTQ(RDX, RDX)
  1067  	JE(LabelRef("LBB3_1"))
  1068  	CMPQ(RDX, Imm(16))
  1069  	JAE(LabelRef("LBB3_5"))
  1070  	VXORPS(X1, X1, X1)
  1071  	XORL(EAX, EAX)
  1072  	VXORPS(X2, X2, X2)
  1073  	VXORPS(X0, X0, X0)
  1074  	JMP(LabelRef("LBB3_4"))
  1075  
  1076  	Label("LBB3_1")
  1077  	{
  1078  		VXORPS(X0, X0, X0)
  1079  		VXORPS(X1, X1, X1)
  1080  		JMP(LabelRef("LBB3_9"))
  1081  	}
  1082  
  1083  	Label("LBB3_5")
  1084  	{
  1085  		MOVQ(RDX, RAX)
  1086  		ANDQ(I32(-16), RAX)
  1087  		VXORPS(X1, X1, X1)
  1088  		XORL(ECX, ECX)
  1089  		VXORPS(X3, X3, X3)
  1090  		VXORPS(X2, X2, X2)
  1091  		VXORPS(X4, X4, X4)
  1092  		VXORPS(X0, X0, X0)
  1093  		VXORPS(X5, X5, X5)
  1094  	}
  1095  
  1096  	Label("LBB3_6")
  1097  	{
  1098  		VMOVUPS(Mem{Base: RDI}.Idx(RCX, 4), Y6)
  1099  		VMOVUPS(Mem{Base: RDI}.Idx(RCX, 4).Offset(32), Y7)
  1100  		VMOVUPS(Mem{Base: RSI}.Idx(RCX, 4), Y8)
  1101  		VMOVUPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(32), Y9)
  1102  		VFMADD231PS(Y6, Y8, Y0)
  1103  		VFMADD231PS(Y7, Y9, Y5)
  1104  		VFMADD231PS(Y6, Y6, Y2)
  1105  		VFMADD231PS(Y7, Y7, Y4)
  1106  		VFMADD231PS(Y8, Y8, Y1)
  1107  		VFMADD231PS(Y9, Y9, Y3)
  1108  		ADDQ(Imm(16), RCX)
  1109  		CMPQ(RAX, RCX)
  1110  		JNE(LabelRef("LBB3_6"))
  1111  		VADDPS(Y0, Y5, Y0)
  1112  		VEXTRACTF128(Imm(1), Y0, X5)
  1113  		VADDPS(X5, X0, X0)
  1114  		VPERMILPD(Imm(1), X0, X5)
  1115  		VADDPS(X5, X0, X0)
  1116  		VMOVSHDUP(X0, X5)
  1117  		VADDSS(X5, X0, X0)
  1118  		VADDPS(Y2, Y4, Y2)
  1119  		VEXTRACTF128(Imm(1), Y2, X4)
  1120  		VADDPS(X4, X2, X2)
  1121  		VPERMILPD(Imm(1), X2, X4)
  1122  		VADDPS(X4, X2, X2)
  1123  		VMOVSHDUP(X2, X4)
  1124  		VADDSS(X4, X2, X2)
  1125  		VADDPS(Y1, Y3, Y1)
  1126  		VEXTRACTF128(Imm(1), Y1, X3)
  1127  		VADDPS(X3, X1, X1)
  1128  		VPERMILPD(Imm(1), X1, X3)
  1129  		VADDPS(X3, X1, X1)
  1130  		VMOVSHDUP(X1, X3)
  1131  		VADDSS(X3, X1, X1)
  1132  		CMPQ(RAX, RDX)
  1133  		JE(LabelRef("LBB3_8"))
  1134  	}
  1135  
  1136  	Label("LBB3_4")
  1137  	{
  1138  		VMOVSS(Mem{Base: RDI}.Idx(RAX, 4), X3)
  1139  		VMOVSS(Mem{Base: RSI}.Idx(RAX, 4), X4)
  1140  		VFMADD231SS(X3, X4, X0)
  1141  		VFMADD231SS(X3, X3, X2)
  1142  		VFMADD231SS(X4, X4, X1)
  1143  		ADDQ(Imm(1), RAX)
  1144  		CMPQ(RDX, RAX)
  1145  		JNE(LabelRef("LBB3_4"))
  1146  	}
  1147  
  1148  	Label("LBB3_8")
  1149  	{
  1150  		VMULSS(X2, X1, X1)
  1151  	}
  1152  
  1153  	Label("LBB3_9")
  1154  	{
  1155  		VRSQRTSS(X1, X1, X2)
  1156  		VMULSS(X2, X1, X1)
  1157  		VFMADD213SS(data.Offset(0), X2, X1)
  1158  		VMULSS(data.Offset(4), X2, X2)
  1159  		VMULSS(X0, X2, X0)
  1160  		VMULSS(X0, X1, X0)
  1161  		VZEROUPPER()
  1162  		Store(X0, ReturnIndex(0))
  1163  		RET()
  1164  	}
  1165  }