github.com/llir/llvm@v0.3.6/ir/inst_bitwise.go (about) 1 package ir 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/llir/llvm/ir/enum" 8 "github.com/llir/llvm/ir/types" 9 "github.com/llir/llvm/ir/value" 10 ) 11 12 // --- [ Bitwise instructions ] ------------------------------------------------ 13 14 // ~~~ [ shl ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 15 16 // InstShl is an LLVM IR shl instruction. 17 type InstShl struct { 18 // Name of local variable associated with the result. 19 LocalIdent 20 // Operands. 21 X, Y value.Value // integer scalar or integer vector 22 23 // extra. 24 25 // Type of result produced by the instruction. 26 Typ types.Type 27 // (optional) Overflow flags. 28 OverflowFlags []enum.OverflowFlag 29 // (optional) Metadata. 30 Metadata 31 } 32 33 // NewShl returns a new shl instruction based on the given operands. 34 func NewShl(x, y value.Value) *InstShl { 35 inst := &InstShl{X: x, Y: y} 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 *InstShl) 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 *InstShl) Type() types.Type { 49 // Cache type if not present. 50 if inst.Typ == nil { 51 inst.Typ = inst.X.Type() 52 } 53 return inst.Typ 54 } 55 56 // LLString returns the LLVM syntax representation of the instruction. 57 // 58 // 'shl' OverflowFlags=OverflowFlag* X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 59 func (inst *InstShl) LLString() string { 60 buf := &strings.Builder{} 61 fmt.Fprintf(buf, "%s = ", inst.Ident()) 62 buf.WriteString("shl") 63 for _, flag := range inst.OverflowFlags { 64 fmt.Fprintf(buf, " %s", flag) 65 } 66 fmt.Fprintf(buf, " %s, %s", inst.X, inst.Y.Ident()) 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 *InstShl) Operands() []*value.Value { 75 return []*value.Value{&inst.X, &inst.Y} 76 } 77 78 // ~~~ [ lshr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 79 80 // InstLShr is an LLVM IR lshr instruction. 81 type InstLShr struct { 82 // Name of local variable associated with the result. 83 LocalIdent 84 // Operands. 85 X, Y value.Value // integer scalars or vectors 86 87 // extra. 88 89 // Type of result produced by the instruction. 90 Typ types.Type 91 // (optional) Exact. 92 Exact bool 93 // (optional) Metadata. 94 Metadata 95 } 96 97 // NewLShr returns a new lshr instruction based on the given operands. 98 func NewLShr(x, y value.Value) *InstLShr { 99 inst := &InstLShr{X: x, Y: y} 100 // Compute type. 101 inst.Type() 102 return inst 103 } 104 105 // String returns the LLVM syntax representation of the instruction as a 106 // type-value pair. 107 func (inst *InstLShr) String() string { 108 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 109 } 110 111 // Type returns the type of the instruction. 112 func (inst *InstLShr) Type() types.Type { 113 // Cache type if not present. 114 if inst.Typ == nil { 115 inst.Typ = inst.X.Type() 116 } 117 return inst.Typ 118 } 119 120 // LLString returns the LLVM syntax representation of the instruction. 121 // 122 // 'lshr' Exactopt X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 123 func (inst *InstLShr) LLString() string { 124 buf := &strings.Builder{} 125 fmt.Fprintf(buf, "%s = ", inst.Ident()) 126 buf.WriteString("lshr") 127 if inst.Exact { 128 buf.WriteString(" exact") 129 } 130 fmt.Fprintf(buf, " %s, %s", inst.X, inst.Y.Ident()) 131 for _, md := range inst.Metadata { 132 fmt.Fprintf(buf, ", %s", md) 133 } 134 return buf.String() 135 } 136 137 // Operands returns a mutable list of operands of the given instruction. 138 func (inst *InstLShr) Operands() []*value.Value { 139 return []*value.Value{&inst.X, &inst.Y} 140 } 141 142 // ~~~ [ ashr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 143 144 // InstAShr is an LLVM IR ashr instruction. 145 type InstAShr struct { 146 // Name of local variable associated with the result. 147 LocalIdent 148 // Operands. 149 X, Y value.Value // integer scalars or vectors 150 151 // extra. 152 153 // Type of result produced by the instruction. 154 Typ types.Type 155 // (optional) Exact. 156 Exact bool 157 // (optional) Metadata. 158 Metadata 159 } 160 161 // NewAShr returns a new ashr instruction based on the given operands. 162 func NewAShr(x, y value.Value) *InstAShr { 163 inst := &InstAShr{X: x, Y: y} 164 // Compute type. 165 inst.Type() 166 return inst 167 } 168 169 // String returns the LLVM syntax representation of the instruction as a 170 // type-value pair. 171 func (inst *InstAShr) String() string { 172 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 173 } 174 175 // Type returns the type of the instruction. 176 func (inst *InstAShr) Type() types.Type { 177 // Cache type if not present. 178 if inst.Typ == nil { 179 inst.Typ = inst.X.Type() 180 } 181 return inst.Typ 182 } 183 184 // LLString returns the LLVM syntax representation of the instruction. 185 // 186 // 'ashr' Exactopt X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 187 func (inst *InstAShr) LLString() string { 188 buf := &strings.Builder{} 189 fmt.Fprintf(buf, "%s = ", inst.Ident()) 190 buf.WriteString("ashr") 191 if inst.Exact { 192 buf.WriteString(" exact") 193 } 194 fmt.Fprintf(buf, " %s, %s", inst.X, inst.Y.Ident()) 195 for _, md := range inst.Metadata { 196 fmt.Fprintf(buf, ", %s", md) 197 } 198 return buf.String() 199 } 200 201 // Operands returns a mutable list of operands of the given instruction. 202 func (inst *InstAShr) Operands() []*value.Value { 203 return []*value.Value{&inst.X, &inst.Y} 204 } 205 206 // ~~~ [ and ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 207 208 // InstAnd is an LLVM IR and instruction. 209 type InstAnd struct { 210 // Name of local variable associated with the result. 211 LocalIdent 212 // Operands. 213 X, Y value.Value // integer scalars or vectors 214 215 // extra. 216 217 // Type of result produced by the instruction. 218 Typ types.Type 219 // (optional) Metadata. 220 Metadata 221 } 222 223 // NewAnd returns a new and instruction based on the given operands. 224 func NewAnd(x, y value.Value) *InstAnd { 225 inst := &InstAnd{X: x, Y: y} 226 // Compute type. 227 inst.Type() 228 return inst 229 } 230 231 // String returns the LLVM syntax representation of the instruction as a 232 // type-value pair. 233 func (inst *InstAnd) String() string { 234 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 235 } 236 237 // Type returns the type of the instruction. 238 func (inst *InstAnd) Type() types.Type { 239 // Cache type if not present. 240 if inst.Typ == nil { 241 inst.Typ = inst.X.Type() 242 } 243 return inst.Typ 244 } 245 246 // LLString returns the LLVM syntax representation of the instruction. 247 // 248 // 'and' X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 249 func (inst *InstAnd) LLString() string { 250 buf := &strings.Builder{} 251 fmt.Fprintf(buf, "%s = ", inst.Ident()) 252 fmt.Fprintf(buf, "and %s, %s", inst.X, inst.Y.Ident()) 253 for _, md := range inst.Metadata { 254 fmt.Fprintf(buf, ", %s", md) 255 } 256 return buf.String() 257 } 258 259 // Operands returns a mutable list of operands of the given instruction. 260 func (inst *InstAnd) Operands() []*value.Value { 261 return []*value.Value{&inst.X, &inst.Y} 262 } 263 264 // ~~~ [ or ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 265 266 // InstOr is an LLVM IR or instruction. 267 type InstOr struct { 268 // Name of local variable associated with the result. 269 LocalIdent 270 // Operands. 271 X, Y value.Value // integer scalars or vectors 272 273 // extra. 274 275 // Type of result produced by the instruction. 276 Typ types.Type 277 // (optional) Metadata. 278 Metadata 279 } 280 281 // NewOr returns a new or instruction based on the given operands. 282 func NewOr(x, y value.Value) *InstOr { 283 inst := &InstOr{X: x, Y: y} 284 // Compute type. 285 inst.Type() 286 return inst 287 } 288 289 // String returns the LLVM syntax representation of the instruction as a 290 // type-value pair. 291 func (inst *InstOr) String() string { 292 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 293 } 294 295 // Type returns the type of the instruction. 296 func (inst *InstOr) Type() types.Type { 297 // Cache type if not present. 298 if inst.Typ == nil { 299 inst.Typ = inst.X.Type() 300 } 301 return inst.Typ 302 } 303 304 // LLString returns the LLVM syntax representation of the instruction. 305 // 306 // 'or' X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 307 func (inst *InstOr) LLString() string { 308 buf := &strings.Builder{} 309 fmt.Fprintf(buf, "%s = ", inst.Ident()) 310 fmt.Fprintf(buf, "or %s, %s", inst.X, inst.Y.Ident()) 311 for _, md := range inst.Metadata { 312 fmt.Fprintf(buf, ", %s", md) 313 } 314 return buf.String() 315 } 316 317 // Operands returns a mutable list of operands of the given instruction. 318 func (inst *InstOr) Operands() []*value.Value { 319 return []*value.Value{&inst.X, &inst.Y} 320 } 321 322 // ~~~ [ xor ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 323 324 // InstXor is an LLVM IR xor instruction. 325 type InstXor struct { 326 // Name of local variable associated with the result. 327 LocalIdent 328 // Operands. 329 X, Y value.Value // integer scalars or vectors 330 331 // extra. 332 333 // Type of result produced by the instruction. 334 Typ types.Type 335 // (optional) Metadata. 336 Metadata 337 } 338 339 // NewXor returns a new xor instruction based on the given operands. 340 func NewXor(x, y value.Value) *InstXor { 341 inst := &InstXor{X: x, Y: y} 342 // Compute type. 343 inst.Type() 344 return inst 345 } 346 347 // String returns the LLVM syntax representation of the instruction as a 348 // type-value pair. 349 func (inst *InstXor) String() string { 350 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 351 } 352 353 // Type returns the type of the instruction. 354 func (inst *InstXor) Type() types.Type { 355 // Cache type if not present. 356 if inst.Typ == nil { 357 inst.Typ = inst.X.Type() 358 } 359 return inst.Typ 360 } 361 362 // LLString returns the LLVM syntax representation of the instruction. 363 // 364 // 'xor' X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 365 func (inst *InstXor) LLString() string { 366 buf := &strings.Builder{} 367 fmt.Fprintf(buf, "%s = ", inst.Ident()) 368 fmt.Fprintf(buf, "xor %s, %s", inst.X, inst.Y.Ident()) 369 for _, md := range inst.Metadata { 370 fmt.Fprintf(buf, ", %s", md) 371 } 372 return buf.String() 373 } 374 375 // Operands returns a mutable list of operands of the given instruction. 376 func (inst *InstXor) Operands() []*value.Value { 377 return []*value.Value{&inst.X, &inst.Y} 378 }