| ## How to add an operation to spec |
| |
| Read `doc.go` for overall guidance. |
| |
| Any operation we may add is already defined in the `simd` or `simd/archsimd` |
| packages. Use those as reference. Check their existing documentation using, for |
| example `GOEXPERIMENT=simd go doc simd ReduceSum` or `GOEXPERIMENT=simd |
| GOARCH=amd64 go doc archsimd MulAdd`. For each operation, check the archsimd |
| docs for GOARCH amd64, arm64, and wasm. |
| |
| If you are writing the function declaration, note that spec is maximalist, so |
| consider how an operation can be generalized past types that may appear in simd |
| or archsimd. For example, numerical operations on just ints can often be |
| generalized to ints or uints. Often, numerical operations on floats can be |
| generalized to ints or uints, though be wary of introducing new complicated |
| overflow or rounding behavior in this case. |
| |
| For the function implementation, look to `simd/simd_emulated.go` and |
| `simd/archsimd/internal/simd_test` for inspiration. `simd_emulated.go` operates |
| entirely on concrete types, while spec operates on generic types. Typically it's |
| easy to generalize across float types or int/uint types, though it may not be |
| easy to generalize one implementation for both float and int/uint. In that case, |
| it's okay to split it into two implementations (for an example, see `AbsFloat` |
| and `AbsInt`). |
| |
| You can write temporary tests to check your work, but don't keep them. We do not |
| test every operation in spec because it will ultimately be checked against the |
| hardware. |
| |
| Tell the user about any corner-case behavior, how you resolved it, and whether |
| or not it was consistent across `simd` and `archsimd` across platforms. |