1
2
3
4
5 package main
6
7 import (
8 "fmt"
9 "slices"
10 "strings"
11 )
12
13
14
15
16
17
18 var sveImmRanges = map[string]func(esize int) (min, max int){
19
20 `Is the immediate shift amount, in the range 0 to number of bits per element minus 1, encoded in "tszh:tszl:imm3".`: func(esize int) (int, int) { return 0, esize - 1 },
21 }
22
23
24
25
26
27 func resolveSVEImmRanges(ops []Operation) error {
28 if !CurrentArch().isSVE() {
29 return nil
30 }
31 var errs []string
32 for i := range ops {
33 op := &ops[i]
34 for j := range op.In {
35 in := &op.In[j]
36 if in.Class != "immediate" || in.ImmDesc == nil {
37 continue
38 }
39 r, ok := sveImmRanges[*in.ImmDesc]
40 if !ok {
41 errs = append(errs, fmt.Sprintf("%s %s: no entry in sveImmRanges for %q", op.Go, op.Asm, *in.ImmDesc))
42 continue
43 }
44 lo, hi := r(sveImmElemBits(*op))
45 if lo != 0 && (op.NoTypes == nil || *op.NoTypes != "true") {
46 errs = append(errs, fmt.Sprintf("%s %s: immediate range %d to %d does not start at 0, which an API's range check cannot enforce", op.Go, op.Asm, lo, hi))
47 continue
48 }
49 in.ImmMin, in.ImmMax = &lo, &hi
50 }
51 }
52 if len(errs) > 0 {
53 slices.Sort(errs)
54 return fmt.Errorf("simdgen: SVE immediates:\n\t%s", strings.Join(slices.Compact(errs), "\n\t"))
55 }
56 return nil
57 }
58
59
60
61 func sveImmElemBits(op Operation) int {
62 for _, o := range append(slices.Clone(op.In), op.Out...) {
63 if o.Class == "vreg" && o.ElemBits != nil {
64 return *o.ElemBits
65 }
66 }
67 return 0
68 }
69
View as plain text