github.com/llir/llvm@v0.3.6/ir/inst_vector.go (about) 1 package ir 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/llir/llvm/ir/types" 8 "github.com/llir/llvm/ir/value" 9 ) 10 11 // --- [ Vector instructions ] ------------------------------------------------- 12 13 // ~~~ [ extractelement ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 14 15 // InstExtractElement is an LLVM IR extractelement instruction. 16 type InstExtractElement struct { 17 // Name of local variable associated with the result. 18 LocalIdent 19 // Vector. 20 X value.Value 21 // Element index. 22 Index value.Value 23 24 // extra. 25 26 // Type of result produced by the instruction. 27 Typ types.Type 28 // (optional) Metadata. 29 Metadata 30 } 31 32 // NewExtractElement returns a new extractelement instruction based on the given 33 // vector and element index. 34 func NewExtractElement(x, index value.Value) *InstExtractElement { 35 inst := &InstExtractElement{X: x, Index: index} 36 // Compute type. 37 inst.Type() 38 return inst 39 } 40 41 // String returns the LLVM syntax representation of the instruction as a 42 // type-value pair. 43 func (inst *InstExtractElement) String() string { 44 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 45 } 46 47 // Type returns the type of the instruction. 48 func (inst *InstExtractElement) Type() types.Type { 49 // Cache type if not present. 50 if inst.Typ == nil { 51 t, ok := inst.X.Type().(*types.VectorType) 52 if !ok { 53 panic(fmt.Errorf("invalid vector type; expected *types.VectorType, got %T", inst.X.Type())) 54 } 55 inst.Typ = t.ElemType 56 } 57 return inst.Typ 58 } 59 60 // LLString returns the LLVM syntax representation of the instruction. 61 // 62 // 'extractelement' X=TypeValue ',' Index=TypeValue Metadata=(',' MetadataAttachment)+? 63 func (inst *InstExtractElement) LLString() string { 64 buf := &strings.Builder{} 65 fmt.Fprintf(buf, "%s = ", inst.Ident()) 66 fmt.Fprintf(buf, "extractelement %s, %s", inst.X, inst.Index) 67 for _, md := range inst.Metadata { 68 fmt.Fprintf(buf, ", %s", md) 69 } 70 return buf.String() 71 } 72 73 // Operands returns a mutable list of operands of the given instruction. 74 func (inst *InstExtractElement) Operands() []*value.Value { 75 return []*value.Value{&inst.X, &inst.Index} 76 } 77 78 // ~~~ [ insertelement ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 79 80 // InstInsertElement is an LLVM IR insertelement instruction. 81 type InstInsertElement struct { 82 // Name of local variable associated with the result. 83 LocalIdent 84 // Vector. 85 X value.Value 86 // Element to insert. 87 Elem value.Value 88 // Element index. 89 Index value.Value 90 91 // extra. 92 93 // Type of result produced by the instruction. 94 Typ *types.VectorType 95 // (optional) Metadata. 96 Metadata 97 } 98 99 // NewInsertElement returns a new insertelement instruction based on the given 100 // vector, element and element index. 101 func NewInsertElement(x, elem, index value.Value) *InstInsertElement { 102 inst := &InstInsertElement{X: x, Elem: elem, Index: index} 103 // Compute type. 104 inst.Type() 105 return inst 106 } 107 108 // String returns the LLVM syntax representation of the instruction as a 109 // type-value pair. 110 func (inst *InstInsertElement) String() string { 111 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 112 } 113 114 // Type returns the type of the instruction. 115 func (inst *InstInsertElement) Type() types.Type { 116 // Cache type if not present. 117 if inst.Typ == nil { 118 t, ok := inst.X.Type().(*types.VectorType) 119 if !ok { 120 panic(fmt.Errorf("invalid vector type; expected *types.VectorType, got %T", inst.X.Type())) 121 } 122 inst.Typ = t 123 } 124 return inst.Typ 125 } 126 127 // LLString returns the LLVM syntax representation of the instruction. 128 // 129 // 'insertelement' X=TypeValue ',' Elem=TypeValue ',' Index=TypeValue 130 // Metadata=(',' MetadataAttachment)+? 131 func (inst *InstInsertElement) LLString() string { 132 buf := &strings.Builder{} 133 fmt.Fprintf(buf, "%s = ", inst.Ident()) 134 fmt.Fprintf(buf, "insertelement %s, %s, %s", inst.X, inst.Elem, inst.Index) 135 for _, md := range inst.Metadata { 136 fmt.Fprintf(buf, ", %s", md) 137 } 138 return buf.String() 139 } 140 141 // Operands returns a mutable list of operands of the given instruction. 142 func (inst *InstInsertElement) Operands() []*value.Value { 143 return []*value.Value{&inst.X, &inst.Elem, &inst.Index} 144 } 145 146 // ~~~ [ shufflevector ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 147 148 // InstShuffleVector is an LLVM IR shufflevector instruction. 149 type InstShuffleVector struct { 150 // Name of local variable associated with the result. 151 LocalIdent 152 // Vectors. 153 X, Y value.Value 154 // Shuffle mask. 155 Mask value.Value 156 157 // extra. 158 159 // Type of result produced by the instruction. 160 Typ *types.VectorType 161 // (optional) Metadata. 162 Metadata 163 } 164 165 // NewShuffleVector returns a new shufflevector instruction based on the given 166 // vectors and shuffle mask. 167 func NewShuffleVector(x, y, mask value.Value) *InstShuffleVector { 168 inst := &InstShuffleVector{X: x, Y: y, Mask: mask} 169 // Compute type. 170 inst.Type() 171 return inst 172 } 173 174 // String returns the LLVM syntax representation of the instruction as a 175 // type-value pair. 176 func (inst *InstShuffleVector) String() string { 177 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 178 } 179 180 // Type returns the type of the instruction. 181 func (inst *InstShuffleVector) Type() types.Type { 182 // Cache type if not present. 183 if inst.Typ == nil { 184 xType, ok := inst.X.Type().(*types.VectorType) 185 if !ok { 186 panic(fmt.Errorf("invalid vector type; expected *types.VectorType, got %T", inst.X.Type())) 187 } 188 maskType, ok := inst.Mask.Type().(*types.VectorType) 189 if !ok { 190 panic(fmt.Errorf("invalid vector type; expected *types.VectorType, got %T", inst.Mask.Type())) 191 } 192 inst.Typ = types.NewVector(maskType.Len, xType.ElemType) 193 } 194 return inst.Typ 195 } 196 197 // LLString returns the LLVM syntax representation of the instruction. 198 // 199 // 'shufflevector' X=TypeValue ',' Y=TypeValue ',' Mask=TypeValue 200 // Metadata=(',' MetadataAttachment)+? 201 func (inst *InstShuffleVector) LLString() string { 202 buf := &strings.Builder{} 203 fmt.Fprintf(buf, "%s = ", inst.Ident()) 204 fmt.Fprintf(buf, "shufflevector %s, %s, %s", inst.X, inst.Y, inst.Mask) 205 for _, md := range inst.Metadata { 206 fmt.Fprintf(buf, ", %s", md) 207 } 208 return buf.String() 209 } 210 211 // Operands returns a mutable list of operands of the given instruction. 212 func (inst *InstShuffleVector) Operands() []*value.Value { 213 return []*value.Value{&inst.X, &inst.Y, &inst.Mask} 214 }