gitee.com/quant1x/gox@v1.7.6/num/asm/max.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 genMax_F64() {
    10  	data := GLOBL("dataMaxF64", RODATA|NOPTR)
    11  	DATA(0, U64(0xffefffffffffffff))
    12  
    13  	TEXT("Max_AVX2_F64", NOSPLIT, "func(x []float64) float64")
    14  	Pragma("noescape")
    15  	Load(Param("x").Base(), RDI)
    16  	Load(Param("x").Len(), RSI)
    17  
    18  	TESTQ(RSI, RSI)
    19  	JE(LabelRef("empty"))
    20  	CMPQ(RSI, Imm(16))
    21  	JAE(LabelRef("loop"))
    22  	VMOVSD(data, X0)
    23  	XORL(EAX, EAX)
    24  	JMP(LabelRef("collect"))
    25  
    26  	Label("empty")
    27  	{
    28  		VMOVSD(data, X0)
    29  		Store(X0, ReturnIndex(0))
    30  		RET()
    31  	}
    32  
    33  	Label("loop")
    34  	{
    35  		MOVQ(RSI, RAX)
    36  		ANDQ(I32(-16), RAX)
    37  		LEAQ(Mem{Base: RAX}.Offset(-16), RCX)
    38  		MOVQ(RCX, R8)
    39  		SHRQ(Imm(4), R8)
    40  		ADDQ(Imm(1), R8)
    41  		TESTQ(RCX, RCX)
    42  		JE(LabelRef("setmin"))
    43  		MOVQ(R8, RCX)
    44  		ANDQ(I32(-2), RCX)
    45  		VBROADCASTSD(data, Y0)
    46  		XORL(EDX, EDX)
    47  		VMOVAPD(Y0, Y1)
    48  		VMOVAPD(Y0, Y2)
    49  		VMOVAPD(Y0, Y3)
    50  	}
    51  
    52  	Label("body")
    53  	{
    54  		VMAXPD(Mem{Base: RDI}.Idx(RDX, 8), Y0, Y0)
    55  		VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(32), Y1, Y1)
    56  		VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(64), Y2, Y2)
    57  		VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(96), Y3, Y3)
    58  		VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(128), Y0, Y0)
    59  		VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(160), Y1, Y1)
    60  		VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(192), Y2, Y2)
    61  		VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(224), Y3, Y3)
    62  		ADDQ(I32(32), RDX)
    63  		ADDQ(I32(-2), RCX)
    64  		JNE(LabelRef("body"))
    65  		TESTB(Imm(1), R8B)
    66  		JE(LabelRef("combinevectors"))
    67  	}
    68  
    69  	Label("tail")
    70  	{
    71  		VMAXPD(Mem{Base: RDI}.Idx(RDX, 8), Y0, Y0)
    72  		VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(32), Y1, Y1)
    73  		VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(64), Y1, Y1)
    74  		VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(96), Y1, Y1)
    75  	}
    76  
    77  	Label("combinevectors")
    78  	{
    79  		VMAXPD(Y3, Y0, Y0)
    80  		VMAXPD(Y2, Y1, Y1)
    81  		VMAXPD(Y0, Y1, Y0)
    82  		VEXTRACTF128(Imm(1), Y0, X1)
    83  		VMAXPD(X1, X0, X0)
    84  		VPERMILPD(Imm(1), X0, X1)
    85  		VMAXSD(X1, X0, X0)
    86  		CMPQ(RAX, RSI)
    87  		JE(LabelRef("return"))
    88  	}
    89  
    90  	Label("collect")
    91  	{
    92  		VMAXSD(Mem{Base: RDI}.Idx(RAX, 8), X0, X0)
    93  		ADDQ(Imm(1), RAX)
    94  		CMPQ(RSI, RAX)
    95  		JNE(LabelRef("collect"))
    96  	}
    97  
    98  	Label("return")
    99  	{
   100  		VZEROUPPER()
   101  		Store(X0, ReturnIndex(0))
   102  		RET()
   103  	}
   104  
   105  	Label("setmin")
   106  	{
   107  		VBROADCASTSD(data, Y0)
   108  		XORL(EDX, EDX)
   109  		VMOVAPD(Y0, Y1)
   110  		VMOVAPD(Y0, Y2)
   111  		VMOVAPD(Y0, Y3)
   112  		TESTB(Imm(1), R8B)
   113  		JNE(LabelRef("tail"))
   114  		JMP(LabelRef("combinevectors"))
   115  	}
   116  }
   117  
   118  func genMax_F32() {
   119  	data := GLOBL("dataMaxF32", RODATA|NOPTR)
   120  	DATA(0, U32(0xff7fffff))
   121  
   122  	TEXT("Max_AVX2_F32", NOSPLIT, "func(x []float32) float32")
   123  	Pragma("noescape")
   124  	Load(Param("x").Base(), RDI)
   125  	Load(Param("x").Len(), RSI)
   126  
   127  	TESTQ(RSI, RSI)
   128  	JE(LabelRef("empty"))
   129  	CMPQ(RSI, Imm(32))
   130  	JAE(LabelRef("loop"))
   131  	VMOVSS(data, X0)
   132  	XORL(EAX, EAX)
   133  	JMP(LabelRef("collect"))
   134  
   135  	Label("empty")
   136  	{
   137  		VMOVSS(data, X0)
   138  		Store(X0, ReturnIndex(0))
   139  		RET()
   140  	}
   141  
   142  	Label("loop")
   143  	{
   144  		MOVQ(RSI, RAX)
   145  		ANDQ(I32(-32), RAX)
   146  		LEAQ(Mem{Base: RAX}.Offset(-32), RCX)
   147  		MOVQ(RCX, R8)
   148  		SHRQ(Imm(5), R8)
   149  		ADDQ(Imm(1), R8)
   150  		TESTQ(RCX, RCX)
   151  		JE(LabelRef("setmin"))
   152  		MOVQ(R8, RCX)
   153  		ANDQ(I32(-2), RCX)
   154  		VBROADCASTSS(data, Y0)
   155  		XORL(EDX, EDX)
   156  		VMOVAPD(Y0, Y1)
   157  		VMOVAPD(Y0, Y2)
   158  		VMOVAPD(Y0, Y3)
   159  	}
   160  
   161  	Label("body")
   162  	{
   163  		VMAXPS(Mem{Base: RDI}.Idx(RDX, 4), Y0, Y0)
   164  		VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(32), Y1, Y1)
   165  		VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(64), Y2, Y2)
   166  		VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(96), Y3, Y3)
   167  		VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(128), Y0, Y0)
   168  		VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(160), Y1, Y1)
   169  		VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(192), Y2, Y2)
   170  		VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(224), Y3, Y3)
   171  		ADDQ(I32(64), RDX)
   172  		ADDQ(I32(-2), RCX)
   173  		JNE(LabelRef("body"))
   174  		TESTB(Imm(1), R8B)
   175  		JE(LabelRef("combinevectors"))
   176  	}
   177  
   178  	Label("tail")
   179  	{
   180  		VMAXPS(Mem{Base: RDI}.Idx(RDX, 4), Y0, Y0)
   181  		VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(32), Y1, Y1)
   182  		VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(64), Y1, Y1)
   183  		VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(96), Y1, Y1)
   184  	}
   185  
   186  	Label("combinevectors")
   187  	{
   188  		VMAXPS(Y3, Y0, Y0)
   189  		VMAXPS(Y2, Y1, Y1)
   190  		VMAXPS(Y0, Y1, Y0)
   191  		VEXTRACTF128(Imm(1), Y0, X1)
   192  		VMAXPS(X1, X0, X0)
   193  		VPERMILPD(Imm(1), X0, X1)
   194  		VMAXPS(X1, X0, X0)
   195  		VMOVSHDUP(X0, X1)
   196  		VMAXSS(X1, X0, X0)
   197  		CMPQ(RAX, RSI)
   198  		JE(LabelRef("return"))
   199  	}
   200  
   201  	Label("collect")
   202  	{
   203  		VMAXSS(Mem{Base: RDI}.Idx(RAX, 4), X0, X0)
   204  		ADDQ(Imm(1), RAX)
   205  		CMPQ(RSI, RAX)
   206  		JNE(LabelRef("collect"))
   207  	}
   208  
   209  	Label("return")
   210  	{
   211  		VZEROUPPER()
   212  		Store(X0, ReturnIndex(0))
   213  		RET()
   214  	}
   215  
   216  	Label("setmin")
   217  	{
   218  		VBROADCASTSS(data, Y0)
   219  		XORL(EDX, EDX)
   220  		VMOVAPS(Y0, Y1)
   221  		VMOVAPS(Y0, Y2)
   222  		VMOVAPS(Y0, Y3)
   223  		TESTB(Imm(1), R8B)
   224  		JNE(LabelRef("tail"))
   225  		JMP(LabelRef("combinevectors"))
   226  	}
   227  }
   228  
   229  func genMaximum_F64() {
   230  	TEXT("Maximum_AVX2_F64", NOSPLIT, "func(x, y []float64)")
   231  	Pragma("noescape")
   232  	Load(Param("x").Base(), RDI)
   233  	Load(Param("y").Base(), RSI)
   234  	Load(Param("x").Len(), RDX)
   235  
   236  	TESTQ(RDX, RDX)
   237  	JE(LabelRef("return"))
   238  	CMPQ(RDX, Imm(16))
   239  	JAE(LabelRef("loop"))
   240  	XORL(EAX, EAX)
   241  	JMP(LabelRef("tailbody"))
   242  
   243  	Label("loop")
   244  	{
   245  		MOVQ(RDX, RAX)
   246  		ANDQ(I32(-16), RAX)
   247  		LEAQ(Mem{Base: RDI}.Offset(96), R8)
   248  		XORL(ECX, ECX)
   249  	}
   250  
   251  	Label("body")
   252  	{
   253  		VMOVUPD(Mem{Base: RSI}.Idx(RCX, 8), Y0)
   254  		VMOVUPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(32), Y1)
   255  		VMOVUPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(64), Y2)
   256  		VMOVUPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(96), Y3)
   257  		VMOVUPD(Mem{Base: R8}.Idx(RCX, 8).Offset(-96), Y4)
   258  		VMOVUPD(Mem{Base: R8}.Idx(RCX, 8).Offset(-64), Y5)
   259  		VMOVUPD(Mem{Base: R8}.Idx(RCX, 8).Offset(-32), Y6)
   260  		VMOVUPD(Mem{Base: R8}.Idx(RCX, 8), Y7)
   261  		VCMPPD(Imm(1), Y0, Y4, Y4)
   262  		VMASKMOVPD(Y0, Y4, Mem{Base: R8}.Idx(RCX, 8).Offset(-96))
   263  		VCMPPD(Imm(1), Y1, Y5, Y0)
   264  		VMASKMOVPD(Y1, Y0, Mem{Base: R8}.Idx(RCX, 8).Offset(-64))
   265  		VCMPPD(Imm(1), Y2, Y6, Y0)
   266  		VMASKMOVPD(Y2, Y0, Mem{Base: R8}.Idx(RCX, 8).Offset(-32))
   267  		VCMPPD(Imm(1), Y3, Y7, Y0)
   268  		VMASKMOVPD(Y3, Y0, Mem{Base: R8}.Idx(RCX, 8))
   269  		ADDQ(Imm(16), RCX)
   270  		CMPQ(RCX, RAX)
   271  		JNE(LabelRef("body"))
   272  		CMPQ(RDX, RAX)
   273  		JNE(LabelRef("tailbody"))
   274  	}
   275  
   276  	Label("return")
   277  	{
   278  		VZEROUPPER()
   279  		RET()
   280  	}
   281  
   282  	Label("tail")
   283  	{
   284  		ADDQ(Imm(1), RAX)
   285  		CMPQ(RAX, RDX)
   286  		JE(LabelRef("return"))
   287  	}
   288  
   289  	Label("tailbody")
   290  	{
   291  		VMOVSD(Mem{Base: RSI}.Idx(RAX, 8), X0)
   292  		VUCOMISD(Mem{Base: RDI}.Idx(RAX, 8), X0)
   293  		JBE(LabelRef("tail"))
   294  		VMOVSD(X0, Mem{Base: RDI}.Idx(RAX, 8))
   295  		JMP(LabelRef("tail"))
   296  	}
   297  }
   298  
   299  func genMaximum_F32() {
   300  	TEXT("Maximum_AVX2_F32", NOSPLIT, "func(x, y []float32)")
   301  	Pragma("noescape")
   302  	Load(Param("x").Base(), RDI)
   303  	Load(Param("y").Base(), RSI)
   304  	Load(Param("x").Len(), RDX)
   305  
   306  	TESTQ(RDX, RDX)
   307  	JE(LabelRef("return"))
   308  	CMPQ(RDX, Imm(32))
   309  	JAE(LabelRef("loop"))
   310  	XORL(EAX, EAX)
   311  	JMP(LabelRef("tailbody"))
   312  
   313  	Label("loop")
   314  	{
   315  		MOVQ(RDX, RAX)
   316  		ANDQ(I32(-32), RAX)
   317  		LEAQ(Mem{Base: RDI}.Offset(96), R8)
   318  		XORL(ECX, ECX)
   319  	}
   320  
   321  	Label("body")
   322  	{
   323  		VMOVUPS(Mem{Base: RSI}.Idx(RCX, 4), Y0)
   324  		VMOVUPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(32), Y1)
   325  		VMOVUPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(64), Y2)
   326  		VMOVUPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(96), Y3)
   327  		VMOVUPS(Mem{Base: R8}.Idx(RCX, 4).Offset(-96), Y4)
   328  		VMOVUPS(Mem{Base: R8}.Idx(RCX, 4).Offset(-64), Y5)
   329  		VMOVUPS(Mem{Base: R8}.Idx(RCX, 4).Offset(-32), Y6)
   330  		VMOVUPS(Mem{Base: R8}.Idx(RCX, 4), Y7)
   331  		VCMPPS(Imm(1), Y0, Y4, Y4)
   332  		VMASKMOVPS(Y0, Y4, Mem{Base: R8}.Idx(RCX, 4).Offset(-96))
   333  		VCMPPS(Imm(1), Y1, Y5, Y0)
   334  		VMASKMOVPS(Y1, Y0, Mem{Base: R8}.Idx(RCX, 4).Offset(-64))
   335  		VCMPPS(Imm(1), Y2, Y6, Y0)
   336  		VMASKMOVPS(Y2, Y0, Mem{Base: R8}.Idx(RCX, 4).Offset(-32))
   337  		VCMPPS(Imm(1), Y3, Y7, Y0)
   338  		VMASKMOVPS(Y3, Y0, Mem{Base: R8}.Idx(RCX, 4))
   339  		ADDQ(Imm(32), RCX)
   340  		CMPQ(RCX, RAX)
   341  		JNE(LabelRef("body"))
   342  		CMPQ(RDX, RAX)
   343  		JNE(LabelRef("tailbody"))
   344  	}
   345  
   346  	Label("return")
   347  	{
   348  		VZEROUPPER()
   349  		RET()
   350  	}
   351  
   352  	Label("tail")
   353  	{
   354  		ADDQ(Imm(1), RAX)
   355  		CMPQ(RAX, RDX)
   356  		JE(LabelRef("return"))
   357  	}
   358  
   359  	Label("tailbody")
   360  	{
   361  		VMOVSS(Mem{Base: RSI}.Idx(RAX, 4), X0)
   362  		VUCOMISS(Mem{Base: RDI}.Idx(RAX, 4), X0)
   363  		JBE(LabelRef("tail"))
   364  		VMOVSS(X0, Mem{Base: RDI}.Idx(RAX, 4))
   365  		JMP(LabelRef("tail"))
   366  	}
   367  }
   368  
   369  func genMaximumNumber_F64() {
   370  	TEXT("MaximumNumber_AVX2_F64", NOSPLIT, "func(x []float64, a float64)")
   371  	Pragma("noescape")
   372  	Load(Param("x").Base(), RDI)
   373  	Load(Param("a"), X0)
   374  	Load(Param("x").Len(), RSI)
   375  
   376  	TESTQ(RSI, RSI)
   377  	JE(LabelRef("return"))
   378  	CMPQ(RSI, Imm(16))
   379  	JAE(LabelRef("loop"))
   380  	XORL(EAX, EAX)
   381  	JMP(LabelRef("tailbody"))
   382  
   383  	Label("loop")
   384  	{
   385  		MOVQ(RSI, RAX)
   386  		ANDQ(I32(-16), RAX)
   387  		VBROADCASTSD(X0, Y1)
   388  		LEAQ(Mem{Base: RDI}.Offset(96), RCX)
   389  		XORL(EDX, EDX)
   390  	}
   391  
   392  	Label("body")
   393  	{
   394  		VMOVUPD(Mem{Base: RCX}.Idx(RDX, 8).Offset(-96), Y2)
   395  		VMOVUPD(Mem{Base: RCX}.Idx(RDX, 8).Offset(-64), Y3)
   396  		VMOVUPD(Mem{Base: RCX}.Idx(RDX, 8).Offset(-32), Y4)
   397  		VMOVUPD(Mem{Base: RCX}.Idx(RDX, 8), Y5)
   398  		VCMPPD(Imm(1), Y1, Y2, Y2)
   399  		VMASKMOVPD(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 8).Offset(-96))
   400  		VCMPPD(Imm(1), Y1, Y3, Y2)
   401  		VMASKMOVPD(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 8).Offset(-64))
   402  		VCMPPD(Imm(1), Y1, Y4, Y2)
   403  		VMASKMOVPD(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 8).Offset(-32))
   404  		VCMPPD(Imm(1), Y1, Y5, Y2)
   405  		VMASKMOVPD(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 8))
   406  		ADDQ(Imm(16), RDX)
   407  		CMPQ(RAX, RDX)
   408  		JNE(LabelRef("body"))
   409  		CMPQ(RAX, RSI)
   410  		JNE(LabelRef("tailbody"))
   411  	}
   412  
   413  	Label("return")
   414  	{
   415  		VZEROUPPER()
   416  		RET()
   417  	}
   418  
   419  	Label("tail")
   420  	{
   421  		ADDQ(Imm(1), RAX)
   422  		CMPQ(RSI, RAX)
   423  		JE(LabelRef("return"))
   424  	}
   425  
   426  	Label("tailbody")
   427  	{
   428  		VUCOMISD(Mem{Base: RDI}.Idx(RAX, 8), X0)
   429  		JBE(LabelRef("tail"))
   430  		VMOVSD(X0, Mem{Base: RDI}.Idx(RAX, 8))
   431  		JMP(LabelRef("tail"))
   432  	}
   433  }
   434  
   435  func genMaximumNumber_F32() {
   436  	TEXT("MaximumNumber_AVX2_F32", NOSPLIT, "func(x []float32, a float32)")
   437  	Pragma("noescape")
   438  	Load(Param("x").Base(), RDI)
   439  	Load(Param("a"), X0)
   440  	Load(Param("x").Len(), RSI)
   441  
   442  	TESTQ(RSI, RSI)
   443  	JE(LabelRef("return"))
   444  	CMPQ(RSI, Imm(32))
   445  	JAE(LabelRef("loop"))
   446  	XORL(EAX, EAX)
   447  	JMP(LabelRef("tailbody"))
   448  
   449  	Label("loop")
   450  	{
   451  		MOVQ(RSI, RAX)
   452  		ANDQ(I32(-32), RAX)
   453  		VBROADCASTSS(X0, Y1)
   454  		LEAQ(Mem{Base: RDI}.Offset(96), RCX)
   455  		XORL(EDX, EDX)
   456  	}
   457  
   458  	Label("body")
   459  	{
   460  		VMOVUPS(Mem{Base: RCX}.Idx(RDX, 4).Offset(-96), Y2)
   461  		VMOVUPS(Mem{Base: RCX}.Idx(RDX, 4).Offset(-64), Y3)
   462  		VMOVUPS(Mem{Base: RCX}.Idx(RDX, 4).Offset(-32), Y4)
   463  		VMOVUPS(Mem{Base: RCX}.Idx(RDX, 4), Y5)
   464  		VCMPPS(Imm(1), Y1, Y2, Y2)
   465  		VMASKMOVPS(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 4).Offset(-96))
   466  		VCMPPS(Imm(1), Y1, Y3, Y2)
   467  		VMASKMOVPS(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 4).Offset(-64))
   468  		VCMPPS(Imm(1), Y1, Y4, Y2)
   469  		VMASKMOVPS(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 4).Offset(-32))
   470  		VCMPPS(Imm(1), Y1, Y5, Y2)
   471  		VMASKMOVPS(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 4))
   472  		ADDQ(Imm(32), RDX)
   473  		CMPQ(RAX, RDX)
   474  		JNE(LabelRef("body"))
   475  		CMPQ(RAX, RSI)
   476  		JNE(LabelRef("tailbody"))
   477  	}
   478  
   479  	Label("return")
   480  	{
   481  		VZEROUPPER()
   482  		RET()
   483  	}
   484  
   485  	Label("tail")
   486  	{
   487  		ADDQ(Imm(1), RAX)
   488  		CMPQ(RSI, RAX)
   489  		JE(LabelRef("return"))
   490  	}
   491  
   492  	Label("tailbody")
   493  	{
   494  		VUCOMISS(Mem{Base: RDI}.Idx(RAX, 4), X0)
   495  		JBE(LabelRef("tail"))
   496  		VMOVSS(X0, Mem{Base: RDI}.Idx(RAX, 4))
   497  		JMP(LabelRef("tail"))
   498  	}
   499  }