gitee.com/quant1x/gox@v1.7.6/num/asm/find.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 genFind_F64() {
    10  	TEXT("Find_AVX2_F64", NOSPLIT, "func(x []float64, a float64) int")
    11  	Pragma("noescape")
    12  	Load(Param("x").Base(), RDI)
    13  	Load(Param("a"), X0)
    14  	Load(Param("x").Len(), RSI)
    15  
    16  	MOVQ(RSI, RCX)
    17  	ANDQ(I32(-8), RCX)
    18  	JE(LabelRef("tail"))
    19  	VPBROADCASTQ(X0, Y1)
    20  	XORL(EAX, EAX)
    21  
    22  	Label("loop")
    23  	{
    24  		VPCMPEQQ(Mem{Base: RDI}.Idx(RAX, 8), Y1, Y2)
    25  		VPCMPEQQ(Mem{Base: RDI}.Idx(RAX, 8).Offset(32), Y1, Y3)
    26  		VPOR(Y2, Y3, Y4)
    27  		VPTEST(Y4, Y4)
    28  		JNE(LabelRef("mask"))
    29  		ADDQ(Imm(8), RAX)
    30  		CMPQ(RAX, RCX)
    31  		JB(LabelRef("loop"))
    32  		CMPQ(RAX, RSI)
    33  		JB(LabelRef("tailbody"))
    34  	}
    35  
    36  	Label("return")
    37  	{
    38  		VZEROUPPER()
    39  		Store(RAX, ReturnIndex(0))
    40  		RET()
    41  	}
    42  
    43  	Label("tail")
    44  	{
    45  		XORL(EAX, EAX)
    46  		CMPQ(RAX, RSI)
    47  		JAE(LabelRef("return"))
    48  	}
    49  
    50  	Label("tailbody")
    51  	{
    52  		VUCOMISD(Mem{Base: RDI}.Idx(RAX, 8), X0)
    53  		JE(LabelRef("return"))
    54  		ADDQ(Imm(1), RAX)
    55  		CMPQ(RSI, RAX)
    56  		JNE(LabelRef("tailbody"))
    57  		MOVQ(RSI, RAX)
    58  		VZEROUPPER()
    59  		Store(RAX, ReturnIndex(0))
    60  		RET()
    61  	}
    62  
    63  	Label("mask")
    64  	{
    65  		VMOVMSKPD(Y3, ECX)
    66  		SHLL(Imm(4), ECX)
    67  		VMOVMSKPD(Y2, EDX)
    68  		ORL(ECX, EDX)
    69  		BSFL(EDX, ECX)
    70  		ADDQ(RCX, RAX)
    71  		VZEROUPPER()
    72  		Store(RAX, ReturnIndex(0))
    73  		RET()
    74  	}
    75  }
    76  
    77  func genFind_F32() {
    78  	TEXT("Find_AVX2_F32", NOSPLIT, "func(x []float32, a float32) int")
    79  	Pragma("noescape")
    80  	Load(Param("x").Base(), RDI)
    81  	Load(Param("a"), X0)
    82  	Load(Param("x").Len(), RSI)
    83  
    84  	MOVQ(RSI, RCX)
    85  	ANDQ(I32(-16), RCX)
    86  	JE(LabelRef("tail"))
    87  	VPBROADCASTD(X0, Y1)
    88  	XORL(EAX, EAX)
    89  
    90  	Label("loop")
    91  	{
    92  		VPCMPEQD(Mem{Base: RDI}.Idx(RAX, 4), Y1, Y2)
    93  		VPCMPEQD(Mem{Base: RDI}.Idx(RAX, 4).Offset(32), Y1, Y3)
    94  		VPOR(Y2, Y3, Y4)
    95  		VPTEST(Y4, Y4)
    96  		JNE(LabelRef("mask"))
    97  		ADDQ(Imm(16), RAX)
    98  		CMPQ(RAX, RCX)
    99  		JB(LabelRef("loop"))
   100  		CMPQ(RAX, RSI)
   101  		JB(LabelRef("tailbody"))
   102  	}
   103  
   104  	Label("return")
   105  	{
   106  		VZEROUPPER()
   107  		Store(RAX, ReturnIndex(0))
   108  		RET()
   109  	}
   110  
   111  	Label("tail")
   112  	{
   113  		XORL(EAX, EAX)
   114  		CMPQ(RAX, RSI)
   115  		JAE(LabelRef("return"))
   116  	}
   117  
   118  	Label("tailbody")
   119  	{
   120  		VUCOMISS(Mem{Base: RDI}.Idx(RAX, 4), X0)
   121  		JE(LabelRef("return"))
   122  		ADDQ(I32(1), RAX)
   123  		CMPQ(RSI, RAX)
   124  		JNE(LabelRef("tailbody"))
   125  		MOVQ(RSI, RAX)
   126  		VZEROUPPER()
   127  		Store(RAX, ReturnIndex(0))
   128  		RET()
   129  	}
   130  
   131  	Label("mask")
   132  	{
   133  		VMOVMSKPS(Y3, ECX)
   134  		SHLL(Imm(8), ECX)
   135  		VMOVMSKPS(Y2, EDX)
   136  		ORL(ECX, EDX)
   137  		BSFL(EDX, ECX)
   138  		ADDQ(RCX, RAX)
   139  		VZEROUPPER()
   140  		Store(RAX, ReturnIndex(0))
   141  		RET()
   142  	}
   143  }