github.com/llir/llvm@v0.3.6/ir/constant/expr_binary.go (about) 1 package constant 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/llir/llvm/ir/enum" 8 "github.com/llir/llvm/ir/types" 9 ) 10 11 // --- [ Binary expressions ] -------------------------------------------------- 12 13 // ~~~ [ add ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 14 15 // ExprAdd is an LLVM IR add expression. 16 type ExprAdd struct { 17 // Operands. 18 X, Y Constant // integer scalar or vector constants 19 20 // extra. 21 22 // Type of result produced by the constant expression. 23 Typ types.Type 24 // (optional) Integer overflow flags. 25 OverflowFlags []enum.OverflowFlag 26 } 27 28 // NewAdd returns a new add expression based on the given operands. 29 func NewAdd(x, y Constant) *ExprAdd { 30 e := &ExprAdd{X: x, Y: y} 31 // Compute type. 32 e.Type() 33 return e 34 } 35 36 // String returns the LLVM syntax representation of the constant expression as a 37 // type-value pair. 38 func (e *ExprAdd) String() string { 39 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 40 } 41 42 // Type returns the type of the constant expression. 43 func (e *ExprAdd) Type() types.Type { 44 // Cache type if not present. 45 if e.Typ == nil { 46 e.Typ = e.X.Type() 47 } 48 return e.Typ 49 } 50 51 // Ident returns the identifier associated with the constant expression. 52 func (e *ExprAdd) Ident() string { 53 // 'add' OverflowFlags=OverflowFlag* '(' X=TypeConst ',' Y=TypeConst ')' 54 buf := &strings.Builder{} 55 buf.WriteString("add") 56 for _, flag := range e.OverflowFlags { 57 fmt.Fprintf(buf, " %s", flag) 58 } 59 fmt.Fprintf(buf, " (%s, %s)", e.X, e.Y) 60 return buf.String() 61 } 62 63 // ~~~ [ fadd ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 64 65 // ExprFAdd is an LLVM IR fadd expression. 66 type ExprFAdd struct { 67 // Operands. 68 X, Y Constant // floating-point scalar or vector constants 69 70 // extra. 71 72 // Type of result produced by the constant expression. 73 Typ types.Type 74 } 75 76 // NewFAdd returns a new fadd expression based on the given operands. 77 func NewFAdd(x, y Constant) *ExprFAdd { 78 e := &ExprFAdd{X: x, Y: y} 79 // Compute type. 80 e.Type() 81 return e 82 } 83 84 // String returns the LLVM syntax representation of the constant expression as a 85 // type-value pair. 86 func (e *ExprFAdd) String() string { 87 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 88 } 89 90 // Type returns the type of the constant expression. 91 func (e *ExprFAdd) Type() types.Type { 92 // Cache type if not present. 93 if e.Typ == nil { 94 e.Typ = e.X.Type() 95 } 96 return e.Typ 97 } 98 99 // Ident returns the identifier associated with the constant expression. 100 func (e *ExprFAdd) Ident() string { 101 // 'fadd' '(' X=TypeConst ',' Y=TypeConst ')' 102 return fmt.Sprintf("fadd (%s, %s)", e.X, e.Y) 103 } 104 105 // ~~~ [ sub ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 106 107 // ExprSub is an LLVM IR sub expression. 108 type ExprSub struct { 109 // Operands. 110 X, Y Constant // integer scalar or vector constants 111 112 // extra. 113 114 // Type of result produced by the constant expression. 115 Typ types.Type 116 // (optional) Integer overflow flags. 117 OverflowFlags []enum.OverflowFlag 118 } 119 120 // NewSub returns a new sub expression based on the given operands. 121 func NewSub(x, y Constant) *ExprSub { 122 e := &ExprSub{X: x, Y: y} 123 // Compute type. 124 e.Type() 125 return e 126 } 127 128 // String returns the LLVM syntax representation of the constant expression as a 129 // type-value pair. 130 func (e *ExprSub) String() string { 131 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 132 } 133 134 // Type returns the type of the constant expression. 135 func (e *ExprSub) Type() types.Type { 136 // Cache type if not present. 137 if e.Typ == nil { 138 e.Typ = e.X.Type() 139 } 140 return e.Typ 141 } 142 143 // Ident returns the identifier associated with the constant expression. 144 func (e *ExprSub) Ident() string { 145 // 'sub' OverflowFlags=OverflowFlag* '(' X=TypeConst ',' Y=TypeConst ')' 146 buf := &strings.Builder{} 147 buf.WriteString("sub") 148 for _, flag := range e.OverflowFlags { 149 fmt.Fprintf(buf, " %s", flag) 150 } 151 fmt.Fprintf(buf, " (%s, %s)", e.X, e.Y) 152 return buf.String() 153 } 154 155 // ~~~ [ fsub ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 156 157 // ExprFSub is an LLVM IR fsub expression. 158 type ExprFSub struct { 159 // Operands. 160 X, Y Constant // floating-point scalar or vector constants 161 162 // extra. 163 164 // Type of result produced by the constant expression. 165 Typ types.Type 166 } 167 168 // NewFSub returns a new fsub expression based on the given operands. 169 func NewFSub(x, y Constant) *ExprFSub { 170 e := &ExprFSub{X: x, Y: y} 171 // Compute type. 172 e.Type() 173 return e 174 } 175 176 // String returns the LLVM syntax representation of the constant expression as a 177 // type-value pair. 178 func (e *ExprFSub) String() string { 179 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 180 } 181 182 // Type returns the type of the constant expression. 183 func (e *ExprFSub) Type() types.Type { 184 // Cache type if not present. 185 if e.Typ == nil { 186 e.Typ = e.X.Type() 187 } 188 return e.Typ 189 } 190 191 // Ident returns the identifier associated with the constant expression. 192 func (e *ExprFSub) Ident() string { 193 // 'fsub' '(' X=TypeConst ',' Y=TypeConst ')' 194 return fmt.Sprintf("fsub (%s, %s)", e.X, e.Y) 195 } 196 197 // ~~~ [ mul ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 198 199 // ExprMul is an LLVM IR mul expression. 200 type ExprMul struct { 201 // Operands. 202 X, Y Constant // integer scalar or vector constants 203 204 // extra. 205 206 // Type of result produced by the constant expression. 207 Typ types.Type 208 // (optional) Integer overflow flags. 209 OverflowFlags []enum.OverflowFlag 210 } 211 212 // NewMul returns a new mul expression based on the given operands. 213 func NewMul(x, y Constant) *ExprMul { 214 e := &ExprMul{X: x, Y: y} 215 // Compute type. 216 e.Type() 217 return e 218 } 219 220 // String returns the LLVM syntax representation of the constant expression as a 221 // type-value pair. 222 func (e *ExprMul) String() string { 223 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 224 } 225 226 // Type returns the type of the constant expression. 227 func (e *ExprMul) Type() types.Type { 228 // Cache type if not present. 229 if e.Typ == nil { 230 e.Typ = e.X.Type() 231 } 232 return e.Typ 233 } 234 235 // Ident returns the identifier associated with the constant expression. 236 func (e *ExprMul) Ident() string { 237 // 'mul' OverflowFlags=OverflowFlag* '(' X=TypeConst ',' Y=TypeConst ')' 238 buf := &strings.Builder{} 239 buf.WriteString("mul") 240 for _, flag := range e.OverflowFlags { 241 fmt.Fprintf(buf, " %s", flag) 242 } 243 fmt.Fprintf(buf, " (%s, %s)", e.X, e.Y) 244 return buf.String() 245 } 246 247 // ~~~ [ fmul ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 248 249 // ExprFMul is an LLVM IR fmul expression. 250 type ExprFMul struct { 251 // Operands. 252 X, Y Constant // floating-point scalar or vector constants 253 254 // extra. 255 256 // Type of result produced by the constant expression. 257 Typ types.Type 258 } 259 260 // NewFMul returns a new fmul expression based on the given operands. 261 func NewFMul(x, y Constant) *ExprFMul { 262 e := &ExprFMul{X: x, Y: y} 263 // Compute type. 264 e.Type() 265 return e 266 } 267 268 // String returns the LLVM syntax representation of the constant expression as a 269 // type-value pair. 270 func (e *ExprFMul) String() string { 271 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 272 } 273 274 // Type returns the type of the constant expression. 275 func (e *ExprFMul) Type() types.Type { 276 // Cache type if not present. 277 if e.Typ == nil { 278 e.Typ = e.X.Type() 279 } 280 return e.Typ 281 } 282 283 // Ident returns the identifier associated with the constant expression. 284 func (e *ExprFMul) Ident() string { 285 // 'fmul' '(' X=TypeConst ',' Y=TypeConst ')' 286 return fmt.Sprintf("fmul (%s, %s)", e.X, e.Y) 287 } 288 289 // ~~~ [ udiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 290 291 // ExprUDiv is an LLVM IR udiv expression. 292 type ExprUDiv struct { 293 // Operands. 294 X, Y Constant // integer scalar or vector constants 295 296 // extra. 297 298 // Type of result produced by the constant expression. 299 Typ types.Type 300 // (optional) The result is a poison value if X is not a multiple of Y. 301 Exact bool 302 } 303 304 // NewUDiv returns a new udiv expression based on the given operands. 305 func NewUDiv(x, y Constant) *ExprUDiv { 306 e := &ExprUDiv{X: x, Y: y} 307 // Compute type. 308 e.Type() 309 return e 310 } 311 312 // String returns the LLVM syntax representation of the constant expression as a 313 // type-value pair. 314 func (e *ExprUDiv) String() string { 315 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 316 } 317 318 // Type returns the type of the constant expression. 319 func (e *ExprUDiv) Type() types.Type { 320 // Cache type if not present. 321 if e.Typ == nil { 322 e.Typ = e.X.Type() 323 } 324 return e.Typ 325 } 326 327 // Ident returns the identifier associated with the constant expression. 328 func (e *ExprUDiv) Ident() string { 329 // 'udiv' Exactopt '(' X=TypeConst ',' Y=TypeConst ')' 330 buf := &strings.Builder{} 331 buf.WriteString("udiv") 332 if e.Exact { 333 buf.WriteString(" exact") 334 } 335 fmt.Fprintf(buf, " (%s, %s)", e.X, e.Y) 336 return buf.String() 337 } 338 339 // ~~~ [ sdiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 340 341 // ExprSDiv is an LLVM IR sdiv expression. 342 type ExprSDiv struct { 343 // Operands. 344 X, Y Constant // integer scalar or vector constants 345 346 // extra. 347 348 // Type of result produced by the constant expression. 349 Typ types.Type 350 // (optional) The result is a poison value if the result would be rounded. 351 Exact bool 352 } 353 354 // NewSDiv returns a new sdiv expression based on the given operands. 355 func NewSDiv(x, y Constant) *ExprSDiv { 356 e := &ExprSDiv{X: x, Y: y} 357 // Compute type. 358 e.Type() 359 return e 360 } 361 362 // String returns the LLVM syntax representation of the constant expression as a 363 // type-value pair. 364 func (e *ExprSDiv) String() string { 365 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 366 } 367 368 // Type returns the type of the constant expression. 369 func (e *ExprSDiv) Type() types.Type { 370 // Cache type if not present. 371 if e.Typ == nil { 372 e.Typ = e.X.Type() 373 } 374 return e.Typ 375 } 376 377 // Ident returns the identifier associated with the constant expression. 378 func (e *ExprSDiv) Ident() string { 379 // 'sdiv' Exactopt '(' X=TypeConst ',' Y=TypeConst ')' 380 buf := &strings.Builder{} 381 buf.WriteString("sdiv") 382 if e.Exact { 383 buf.WriteString(" exact") 384 } 385 fmt.Fprintf(buf, " (%s, %s)", e.X, e.Y) 386 return buf.String() 387 } 388 389 // ~~~ [ fdiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 390 391 // ExprFDiv is an LLVM IR fdiv expression. 392 type ExprFDiv struct { 393 // Operands. 394 X, Y Constant // floating-point scalar or vector constants 395 396 // extra. 397 398 // Type of result produced by the constant expression. 399 Typ types.Type 400 } 401 402 // NewFDiv returns a new fdiv expression based on the given operands. 403 func NewFDiv(x, y Constant) *ExprFDiv { 404 e := &ExprFDiv{X: x, Y: y} 405 // Compute type. 406 e.Type() 407 return e 408 } 409 410 // String returns the LLVM syntax representation of the constant expression as a 411 // type-value pair. 412 func (e *ExprFDiv) String() string { 413 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 414 } 415 416 // Type returns the type of the constant expression. 417 func (e *ExprFDiv) Type() types.Type { 418 // Cache type if not present. 419 if e.Typ == nil { 420 e.Typ = e.X.Type() 421 } 422 return e.Typ 423 } 424 425 // Ident returns the identifier associated with the constant expression. 426 func (e *ExprFDiv) Ident() string { 427 // 'fdiv' '(' X=TypeConst ',' Y=TypeConst ')' 428 return fmt.Sprintf("fdiv (%s, %s)", e.X, e.Y) 429 } 430 431 // ~~~ [ urem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 432 433 // ExprURem is an LLVM IR urem expression. 434 type ExprURem struct { 435 // Operands. 436 X, Y Constant // integer scalar or vector constants 437 438 // extra. 439 440 // Type of result produced by the constant expression. 441 Typ types.Type 442 } 443 444 // NewURem returns a new urem expression based on the given operands. 445 func NewURem(x, y Constant) *ExprURem { 446 e := &ExprURem{X: x, Y: y} 447 // Compute type. 448 e.Type() 449 return e 450 } 451 452 // String returns the LLVM syntax representation of the constant expression as a 453 // type-value pair. 454 func (e *ExprURem) String() string { 455 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 456 } 457 458 // Type returns the type of the constant expression. 459 func (e *ExprURem) Type() types.Type { 460 // Cache type if not present. 461 if e.Typ == nil { 462 e.Typ = e.X.Type() 463 } 464 return e.Typ 465 } 466 467 // Ident returns the identifier associated with the constant expression. 468 func (e *ExprURem) Ident() string { 469 // 'urem' '(' X=TypeConst ',' Y=TypeConst ')' 470 return fmt.Sprintf("urem (%s, %s)", e.X, e.Y) 471 } 472 473 // ~~~ [ srem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 474 475 // ExprSRem is an LLVM IR srem expression. 476 type ExprSRem struct { 477 // Operands. 478 X, Y Constant // integer scalar or vector constants 479 480 // extra. 481 482 // Type of result produced by the constant expression. 483 Typ types.Type 484 } 485 486 // NewSRem returns a new srem expression based on the given operands. 487 func NewSRem(x, y Constant) *ExprSRem { 488 e := &ExprSRem{X: x, Y: y} 489 // Compute type. 490 e.Type() 491 return e 492 } 493 494 // String returns the LLVM syntax representation of the constant expression as a 495 // type-value pair. 496 func (e *ExprSRem) String() string { 497 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 498 } 499 500 // Type returns the type of the constant expression. 501 func (e *ExprSRem) Type() types.Type { 502 // Cache type if not present. 503 if e.Typ == nil { 504 e.Typ = e.X.Type() 505 } 506 return e.Typ 507 } 508 509 // Ident returns the identifier associated with the constant expression. 510 func (e *ExprSRem) Ident() string { 511 // 'srem' '(' X=TypeConst ',' Y=TypeConst ')' 512 return fmt.Sprintf("srem (%s, %s)", e.X, e.Y) 513 } 514 515 // ~~~ [ frem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 516 517 // ExprFRem is an LLVM IR frem expression. 518 type ExprFRem struct { 519 // Operands. 520 X, Y Constant // floating-point scalar or vector constants 521 522 // extra. 523 524 // Type of result produced by the constant expression. 525 Typ types.Type 526 } 527 528 // NewFRem returns a new frem expression based on the given operands. 529 func NewFRem(x, y Constant) *ExprFRem { 530 e := &ExprFRem{X: x, Y: y} 531 // Compute type. 532 e.Type() 533 return e 534 } 535 536 // String returns the LLVM syntax representation of the constant expression as a 537 // type-value pair. 538 func (e *ExprFRem) String() string { 539 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 540 } 541 542 // Type returns the type of the constant expression. 543 func (e *ExprFRem) Type() types.Type { 544 // Cache type if not present. 545 if e.Typ == nil { 546 e.Typ = e.X.Type() 547 } 548 return e.Typ 549 } 550 551 // Ident returns the identifier associated with the constant expression. 552 func (e *ExprFRem) Ident() string { 553 // 'frem' '(' X=TypeConst ',' Y=TypeConst ')' 554 return fmt.Sprintf("frem (%s, %s)", e.X, e.Y) 555 }