| // Copyright 2025 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package main |
| |
| import ( |
| "fmt" |
| ) |
| |
| const simdIntrinsicsTmpl = `// Code generated by x/arch/internal/simdgen using 'go run . -xedPath $XED_PATH -o godefs -goroot $GOROOT go.yaml types.yaml categories.yaml'; DO NOT EDIT. |
| package ssagen |
| |
| import ( |
| "cmd/compile/internal/ir" |
| "cmd/compile/internal/ssa" |
| "cmd/compile/internal/types" |
| "cmd/internal/sys" |
| ) |
| |
| const simdPackage = "` + simdPackage + `" |
| |
| func simdIntrinsics(addF func(pkg, fn string, b intrinsicBuilder, archFamilies ...sys.ArchFamily)) { |
| {{- range .OpsLen1}} |
| addF(simdPackage, "{{(index .In 0).Go}}.{{.Go}}", opLen1(ssa.Op{{.Go}}{{(index .In 0).Go}}, {{.GoArch}}), sys.AMD64) |
| {{- end}} |
| {{- range .OpsLen2}} |
| addF(simdPackage, "{{(index .In 0).Go}}.{{.Go}}", opLen2(ssa.Op{{.Go}}{{(index .In 0).Go}}, {{.GoArch}}), sys.AMD64) |
| {{- end}} |
| {{- range .OpsLen3}} |
| addF(simdPackage, "{{(index .In 0).Go}}.{{.Go}}", opLen3(ssa.Op{{.Go}}{{(index .In 0).Go}}, {{.GoArch}}), sys.AMD64) |
| {{- end}} |
| |
| {{- range .VectorConversions }} |
| addF(simdPackage, "{{.Tsrc.Name}}.As{{.Tdst.Name}}", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.AMD64) |
| {{- end}} |
| |
| {{- range $size, $ts := .TypeMap }} |
| {{- range $t := $ts }} |
| addF(simdPackage, "Load{{$t.Name}}", simdLoad(), sys.AMD64) |
| addF(simdPackage, "{{$t.Name}}.Store", simdStore(), sys.AMD64) |
| {{- end}} |
| {{- end}} |
| {{- range .Masks }} |
| addF(simdPackage, "{{.Name}}.As{{.VectorCounterpart}}", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.AMD64) |
| addF(simdPackage, "{{.VectorCounterpart}}.As{{.Name}}", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.AMD64) |
| addF(simdPackage, "{{.Name}}.And", opLen2(ssa.OpAnd{{.ReshapedVectorWithAndOr}}, types.TypeVec{{.Size}}), sys.AMD64) |
| addF(simdPackage, "{{.Name}}.Or", opLen2(ssa.OpOr{{.ReshapedVectorWithAndOr}}, types.TypeVec{{.Size}}), sys.AMD64) |
| {{- end}} |
| } |
| |
| func opLen1(op ssa.Op, t *types.Type) func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { |
| return func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { |
| return s.newValue1(op, t, args[0]) |
| } |
| } |
| |
| func opLen2(op ssa.Op, t *types.Type) func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { |
| return func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { |
| return s.newValue2(op, t, args[0], args[1]) |
| } |
| } |
| |
| func opLen3(op ssa.Op, t *types.Type) func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { |
| return func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { |
| return s.newValue3(op, t, args[0], args[1], args[2]) |
| } |
| } |
| |
| func simdLoad() func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { |
| return func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { |
| return s.newValue2(ssa.OpLoad, n.Type(), args[0], s.mem()) |
| } |
| } |
| |
| func simdStore() func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { |
| return func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { |
| s.store(args[0].Type, args[1], args[0]) |
| return nil |
| } |
| } |
| ` |
| |
| // writeSIMDIntrinsics generates the intrinsic mappings and writes it to simdintrinsics.go |
| // within the specified directory. |
| func writeSIMDIntrinsics(directory string, ops []Operation, typeMap simdTypeMap) error { |
| file, t, err := openFileAndPrepareTemplate(directory, "src/cmd/compile/internal/ssagen/simdintrinsics.go", simdIntrinsicsTmpl) |
| if err != nil { |
| return err |
| } |
| defer file.Close() |
| opsLen1, opsLen2, opsLen3, err := genericOpsByLen(ops) |
| if err != nil { |
| return err |
| } |
| |
| type templateData struct { |
| OpsLen1 []Operation |
| OpsLen2 []Operation |
| OpsLen3 []Operation |
| TypeMap simdTypeMap |
| VectorConversions []simdTypePair |
| Masks []simdType |
| } |
| err = t.Execute(file, templateData{opsLen1, opsLen2, opsLen3, typeMap, vConvertFromTypeMap(typeMap), masksFromTypeMap(typeMap)}) |
| if err != nil { |
| return fmt.Errorf("failed to execute template: %w", err) |
| } |
| |
| return nil |
| } |