|
| 1 | +//go:build ignore |
| 2 | + |
| 3 | +package main |
| 4 | + |
| 5 | +import ( |
| 6 | + . "github.com/mmcloughlin/avo/build" |
| 7 | + . "github.com/mmcloughlin/avo/operand" |
| 8 | + "github.com/mmcloughlin/avo/reg" |
| 9 | +) |
| 10 | + |
| 11 | +// main generates assembly code for NEON on ARM aarch64. |
| 12 | +func main() { |
| 13 | + TEXT("findInChunk", NOSPLIT, "func(needle []byte, haystack []byte) int64") |
| 14 | + Doc("findInChunk is only generated for testing.") |
| 15 | + //hptr := Load(Param("haystack").Base(), GP64()) |
| 16 | + needleLen := Load(Param("needle").Len(), GP64()); DECQ(needleLen) |
| 17 | + needle := Load(Param("needle").Base(), GP64()) |
| 18 | + _, _ = inlineSplat(needle, needleLen) |
| 19 | + |
| 20 | + //offset := inlineFindInChunk("test", f, l, hptr, needle, needleLen) |
| 21 | + offset := GP64() |
| 22 | + |
| 23 | + Store(offset, ReturnIndex(0)) |
| 24 | + RET() |
| 25 | +} |
| 26 | + |
| 27 | +// inlineSplat fills one 128bit register with repeated first neelde char and |
| 28 | +// another with repeated last needle char. |
| 29 | +func inlineSplat(needle0, needleLen reg.Register) (reg.VecVirtual, reg.VecVirtual) { |
| 30 | + Comment("create vector filled with first and last character") |
| 31 | + f := YMM() |
| 32 | + l := YMM() |
| 33 | + |
| 34 | + VDUP |
| 35 | + |
| 36 | + needle1 := GP64(); MOVQ(needle0, needle1); |
| 37 | + ADDQ(needleLen, needle1) |
| 38 | + VPBROADCASTB(Mem{Base: needle0}, f) |
| 39 | + VPBROADCASTB(Mem{Base: needle1}, l) |
| 40 | + |
| 41 | + return f, l |
| 42 | +} |
0 commit comments