1
2
3
4
5 package sgutil
6
7 import (
8 "bytes"
9 "io"
10 "text/template"
11 )
12
13 type TforAsBits interface {
14 ElemBits() int
15 Name_() string
16 }
17
18 const (
19 ToBitsName = "ToBits"
20 ToIntsName = "BitsToInt{{.To.ElemBits}}"
21 ConvertToIntName = "ConvertToInt{{.To.ElemBits}}"
22 ConvertToUintName = "ConvertToUint{{.From.ElemBits}}"
23 ToFloatsName = "BitsToFloat{{.To.ElemBits}}"
24 ReshapeName = "ReshapeToUint{{.To.ElemBits}}s"
25 )
26
27 func templateOf(name, text string) *template.Template {
28 return template.Must(template.New(name).Parse(text))
29 }
30
31 var ToBitsCall = templateOf("toBitsCall", "."+ToBitsName+"()")
32 var ToIntsCall = templateOf("toBitsCall", "."+ToIntsName+"()")
33 var ToFloatsCall = templateOf("toBitsCall", "."+ToFloatsName+"()")
34 var ReshapeCall = templateOf("toBitsCall", "."+ReshapeName+"()")
35
36 var ToBitsDcl = templateOf("toBitsDcl", `
37 // `+ToBitsName+` reinterprets the bits of a {{.From.Name_}} vector as a {{.To.Name_}} vector
38 func (x {{.From.Name_}}) `+ToBitsName+`() {{.To.Name_}}
39 `)
40
41
42 var ToBitsIntrinsic = templateOf("toBitsIntrin", `{{.To.Name_}}.`+ToBitsName)
43
44 var ToIntsDcl = templateOf("toIntsDcl", `
45 // `+ToIntsName+` reinterprets the bits of a {{.From.Name_}} vector as a {{.To.Name_}} vector
46 func (x {{.From.Name_}}) `+ToIntsName+`() {{.To.Name_}}
47
48 // `+ConvertToIntName+` converts a {{.From.Name_}} vector to a {{.To.Name_}} vector
49 func (x {{.From.Name_}}) `+ConvertToIntName+`() {{.To.Name_}}
50
51 // `+ConvertToUintName+` converts a {{.To.Name_}} vector to a {{.From.Name_}} vector
52 func (x {{.To.Name_}}) `+ConvertToUintName+`() {{.From.Name_}}
53 `)
54
55 var ToIntsIntrinsic = templateOf("toIntsIntrin", `{{.From.Name_}}.`+ToIntsName)
56 var CvtToIntsIntrinsic = templateOf("cvtToIntIntrin", `{{.From.Name_}}.`+ConvertToIntName)
57
58
59 var CvtToUintsIntrinsic = templateOf("cvtToUintIntrin", `{{.To.Name_}}.`+ConvertToUintName)
60
61 var ToFloatsDcl = templateOf("toFloatsDcl", `
62 // `+ToFloatsName+` reinterprets the bits of a {{.From.Name_}} vector as a {{.To.Name_}} vector
63 func (x {{.From.Name_}}) `+ToFloatsName+`() {{.To.Name_}}
64 `)
65
66 var ToFloatsIntrinsic = templateOf("toFloatsIntrin", `{{.From.Name_}}.`+ToFloatsName)
67
68 var ReshapeDcl = templateOf("reshapeDcl", `
69 // `+ReshapeName+` reinterprets the bits of a {{.From.Name_}} vector as a {{.To.Name_}} vector
70 func (x {{.From.Name_}}) `+ReshapeName+`() {{.To.Name_}}
71 `)
72
73 var ReshapeIntrinsic = templateOf("reshapeIntrinsic", `{{.From.Name_}}.`+ReshapeName)
74
75 var AsOp = templateOf("asConversion", `
76 // As{{.To.Name}} reinterprets the bits of a {{.From.Name}} vector as a {{.To.Name}} vector
77 //
78 // Deprecated: use combinations of ToBits, BitsTo{Int<N>,Float<N>}, ReshapeToUint<N>
79 //
80 //go:fix inline
81 func (x {{.From.Name}}) As{{.To.Name}}() {{.To.Name}} {
82 return x{{.AsTranslation}}
83 }
84 `)
85
86 type AsConversion struct {
87 From, To TforAsBits
88 }
89
90 func Conversion(from, to TforAsBits) *AsConversion {
91 return &AsConversion{from, to}
92 }
93
94 type TypeDotMethod struct {
95 TypeDotMethod string
96 }
97
98 func (c *AsConversion) TypeDotMethod(t *template.Template) *TypeDotMethod {
99 var b bytes.Buffer
100 t.Execute(&b, c)
101 return &TypeDotMethod{b.String()}
102 }
103
104
105
106 func (c *AsConversion) ExecuteIntrinsicTemplateOfTypeDotMethod(w io.Writer, t *template.Template) {
107 from, to := c.From, c.To
108 switch to.Name_()[0] {
109 case 'F':
110 t.Execute(w, c.TypeDotMethod(ToFloatsIntrinsic))
111 t.Execute(w, c.TypeDotMethod(ToBitsIntrinsic))
112 case 'I':
113 t.Execute(w, c.TypeDotMethod(ToIntsIntrinsic))
114 t.Execute(w, c.TypeDotMethod(CvtToIntsIntrinsic))
115 t.Execute(w, c.TypeDotMethod(CvtToUintsIntrinsic))
116 t.Execute(w, c.TypeDotMethod(ToBitsIntrinsic))
117 case 'U':
118 if from.Name_()[0] == 'U' {
119 t.Execute(w, c.TypeDotMethod(ReshapeIntrinsic))
120 }
121 }
122 }
123
124 func (a *AsConversion) AsTranslation() string {
125 var b bytes.Buffer
126 if a.From.Name_()[0] != 'U' {
127 ToBitsCall.Execute(&b, a)
128 }
129 if a.From.ElemBits() != a.To.ElemBits() {
130 ReshapeCall.Execute(&b, a)
131 }
132 if a.To.Name_()[0] == 'F' {
133 ToFloatsCall.Execute(&b, a)
134 }
135 if a.To.Name_()[0] == 'I' {
136 ToIntsCall.Execute(&b, a)
137 }
138 return b.String()
139 }
140
View as plain text