github.com/llir/llvm@v0.3.6/ir/inst_binary.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 // --- [ Binary instructions ] ------------------------------------------------- 13 14 // ~~~ [ add ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 15 16 // InstAdd is an LLVM IR add instruction. 17 type InstAdd 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 // NewAdd returns a new add instruction based on the given operands. 34 func NewAdd(x, y value.Value) *InstAdd { 35 inst := &InstAdd{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 *InstAdd) 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 *InstAdd) 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 // 'add' OverflowFlags=OverflowFlag* X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 59 func (inst *InstAdd) LLString() string { 60 buf := &strings.Builder{} 61 fmt.Fprintf(buf, "%s = ", inst.Ident()) 62 buf.WriteString("add") 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 *InstAdd) Operands() []*value.Value { 75 return []*value.Value{&inst.X, &inst.Y} 76 } 77 78 // ~~~ [ fadd ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 79 80 // InstFAdd is an LLVM IR fadd instruction. 81 type InstFAdd struct { 82 // Name of local variable associated with the result. 83 LocalIdent 84 // Operands. 85 X, Y value.Value // floating-point scalar or floating-point vector 86 87 // extra. 88 89 // Type of result produced by the instruction. 90 Typ types.Type 91 // (optional) Fast math flags. 92 FastMathFlags []enum.FastMathFlag 93 // (optional) Metadata. 94 Metadata 95 } 96 97 // NewFAdd returns a new fadd instruction based on the given operands. 98 func NewFAdd(x, y value.Value) *InstFAdd { 99 inst := &InstFAdd{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 *InstFAdd) 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 *InstFAdd) 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 // 'fadd' FastMathFlags=FastMathFlag* X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 123 func (inst *InstFAdd) LLString() string { 124 buf := &strings.Builder{} 125 fmt.Fprintf(buf, "%s = ", inst.Ident()) 126 buf.WriteString("fadd") 127 for _, flag := range inst.FastMathFlags { 128 fmt.Fprintf(buf, " %s", flag) 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 *InstFAdd) Operands() []*value.Value { 139 return []*value.Value{&inst.X, &inst.Y} 140 } 141 142 // ~~~ [ sub ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 143 144 // InstSub is an LLVM IR sub instruction. 145 type InstSub struct { 146 // Name of local variable associated with the result. 147 LocalIdent 148 // Operands. 149 X, Y value.Value // integer scalar or integer vector 150 151 // extra. 152 153 // Type of result produced by the instruction. 154 Typ types.Type 155 // (optional) Overflow flags. 156 OverflowFlags []enum.OverflowFlag 157 // (optional) Metadata. 158 Metadata 159 } 160 161 // NewSub returns a new sub instruction based on the given operands. 162 func NewSub(x, y value.Value) *InstSub { 163 inst := &InstSub{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 *InstSub) 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 *InstSub) 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 // 'sub' OverflowFlags=OverflowFlag* X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 187 func (inst *InstSub) LLString() string { 188 buf := &strings.Builder{} 189 fmt.Fprintf(buf, "%s = ", inst.Ident()) 190 buf.WriteString("sub") 191 for _, flag := range inst.OverflowFlags { 192 fmt.Fprintf(buf, " %s", flag) 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 *InstSub) Operands() []*value.Value { 203 return []*value.Value{&inst.X, &inst.Y} 204 } 205 206 // ~~~ [ fsub ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 207 208 // InstFSub is an LLVM IR fsub instruction. 209 type InstFSub struct { 210 // Name of local variable associated with the result. 211 LocalIdent 212 // Operands. 213 X, Y value.Value // floating-point scalar or floating-point vector 214 215 // extra. 216 217 // Type of result produced by the instruction. 218 Typ types.Type 219 // (optional) Fast math flags. 220 FastMathFlags []enum.FastMathFlag 221 // (optional) Metadata. 222 Metadata 223 } 224 225 // NewFSub returns a new fsub instruction based on the given operands. 226 func NewFSub(x, y value.Value) *InstFSub { 227 inst := &InstFSub{X: x, Y: y} 228 // Compute type. 229 inst.Type() 230 return inst 231 } 232 233 // String returns the LLVM syntax representation of the instruction as a 234 // type-value pair. 235 func (inst *InstFSub) String() string { 236 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 237 } 238 239 // Type returns the type of the instruction. 240 func (inst *InstFSub) Type() types.Type { 241 // Cache type if not present. 242 if inst.Typ == nil { 243 inst.Typ = inst.X.Type() 244 } 245 return inst.Typ 246 } 247 248 // LLString returns the LLVM syntax representation of the instruction. 249 // 250 // 'fsub' FastMathFlags=FastMathFlag* X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 251 func (inst *InstFSub) LLString() string { 252 buf := &strings.Builder{} 253 fmt.Fprintf(buf, "%s = ", inst.Ident()) 254 buf.WriteString("fsub") 255 for _, flag := range inst.FastMathFlags { 256 fmt.Fprintf(buf, " %s", flag) 257 } 258 fmt.Fprintf(buf, " %s, %s", inst.X, inst.Y.Ident()) 259 for _, md := range inst.Metadata { 260 fmt.Fprintf(buf, ", %s", md) 261 } 262 return buf.String() 263 } 264 265 // Operands returns a mutable list of operands of the given instruction. 266 func (inst *InstFSub) Operands() []*value.Value { 267 return []*value.Value{&inst.X, &inst.Y} 268 } 269 270 // ~~~ [ mul ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 271 272 // InstMul is an LLVM IR mul instruction. 273 type InstMul struct { 274 // Name of local variable associated with the result. 275 LocalIdent 276 // Operands. 277 X, Y value.Value // integer scalar or integer vector 278 279 // extra. 280 281 // Type of result produced by the instruction. 282 Typ types.Type 283 // (optional) Overflow flags. 284 OverflowFlags []enum.OverflowFlag 285 // (optional) Metadata. 286 Metadata 287 } 288 289 // NewMul returns a new mul instruction based on the given operands. 290 func NewMul(x, y value.Value) *InstMul { 291 inst := &InstMul{X: x, Y: y} 292 // Compute type. 293 inst.Type() 294 return inst 295 } 296 297 // String returns the LLVM syntax representation of the instruction as a 298 // type-value pair. 299 func (inst *InstMul) String() string { 300 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 301 } 302 303 // Type returns the type of the instruction. 304 func (inst *InstMul) Type() types.Type { 305 // Cache type if not present. 306 if inst.Typ == nil { 307 inst.Typ = inst.X.Type() 308 } 309 return inst.Typ 310 } 311 312 // LLString returns the LLVM syntax representation of the instruction. 313 // 314 // 'mul' OverflowFlags=OverflowFlag* X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 315 func (inst *InstMul) LLString() string { 316 buf := &strings.Builder{} 317 fmt.Fprintf(buf, "%s = ", inst.Ident()) 318 buf.WriteString("mul") 319 for _, flag := range inst.OverflowFlags { 320 fmt.Fprintf(buf, " %s", flag) 321 } 322 fmt.Fprintf(buf, " %s, %s", inst.X, inst.Y.Ident()) 323 for _, md := range inst.Metadata { 324 fmt.Fprintf(buf, ", %s", md) 325 } 326 return buf.String() 327 } 328 329 // Operands returns a mutable list of operands of the given instruction. 330 func (inst *InstMul) Operands() []*value.Value { 331 return []*value.Value{&inst.X, &inst.Y} 332 } 333 334 // ~~~ [ fmul ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 335 336 // InstFMul is an LLVM IR fmul instruction. 337 type InstFMul struct { 338 // Name of local variable associated with the result. 339 LocalIdent 340 // Operands. 341 X, Y value.Value // floating-point scalar or floating-point vector 342 343 // extra. 344 345 // Type of result produced by the instruction. 346 Typ types.Type 347 // (optional) Fast math flags. 348 FastMathFlags []enum.FastMathFlag 349 // (optional) Metadata. 350 Metadata 351 } 352 353 // NewFMul returns a new fmul instruction based on the given operands. 354 func NewFMul(x, y value.Value) *InstFMul { 355 inst := &InstFMul{X: x, Y: y} 356 // Compute type. 357 inst.Type() 358 return inst 359 } 360 361 // String returns the LLVM syntax representation of the instruction as a 362 // type-value pair. 363 func (inst *InstFMul) String() string { 364 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 365 } 366 367 // Type returns the type of the instruction. 368 func (inst *InstFMul) Type() types.Type { 369 // Cache type if not present. 370 if inst.Typ == nil { 371 inst.Typ = inst.X.Type() 372 } 373 return inst.Typ 374 } 375 376 // LLString returns the LLVM syntax representation of the instruction. 377 // 378 // 'fmul' FastMathFlags=FastMathFlag* X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 379 func (inst *InstFMul) LLString() string { 380 buf := &strings.Builder{} 381 fmt.Fprintf(buf, "%s = ", inst.Ident()) 382 buf.WriteString("fmul") 383 for _, flag := range inst.FastMathFlags { 384 fmt.Fprintf(buf, " %s", flag) 385 } 386 fmt.Fprintf(buf, " %s, %s", inst.X, inst.Y.Ident()) 387 for _, md := range inst.Metadata { 388 fmt.Fprintf(buf, ", %s", md) 389 } 390 return buf.String() 391 } 392 393 // Operands returns a mutable list of operands of the given instruction. 394 func (inst *InstFMul) Operands() []*value.Value { 395 return []*value.Value{&inst.X, &inst.Y} 396 } 397 398 // ~~~ [ udiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 399 400 // InstUDiv is an LLVM IR udiv instruction. 401 type InstUDiv struct { 402 // Name of local variable associated with the result. 403 LocalIdent 404 // Operands. 405 X, Y value.Value // integer scalar or integer vector 406 407 // extra. 408 409 // Type of result produced by the instruction. 410 Typ types.Type 411 // (optional) Exact. 412 Exact bool 413 // (optional) Metadata. 414 Metadata 415 } 416 417 // NewUDiv returns a new udiv instruction based on the given operands. 418 func NewUDiv(x, y value.Value) *InstUDiv { 419 inst := &InstUDiv{X: x, Y: y} 420 // Compute type. 421 inst.Type() 422 return inst 423 } 424 425 // String returns the LLVM syntax representation of the instruction as a 426 // type-value pair. 427 func (inst *InstUDiv) String() string { 428 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 429 } 430 431 // Type returns the type of the instruction. 432 func (inst *InstUDiv) Type() types.Type { 433 // Cache type if not present. 434 if inst.Typ == nil { 435 inst.Typ = inst.X.Type() 436 } 437 return inst.Typ 438 } 439 440 // LLString returns the LLVM syntax representation of the instruction. 441 // 442 // 'udiv' Exactopt X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 443 func (inst *InstUDiv) LLString() string { 444 buf := &strings.Builder{} 445 fmt.Fprintf(buf, "%s = ", inst.Ident()) 446 buf.WriteString("udiv") 447 if inst.Exact { 448 buf.WriteString(" exact") 449 } 450 fmt.Fprintf(buf, " %s, %s", inst.X, inst.Y.Ident()) 451 for _, md := range inst.Metadata { 452 fmt.Fprintf(buf, ", %s", md) 453 } 454 return buf.String() 455 } 456 457 // Operands returns a mutable list of operands of the given instruction. 458 func (inst *InstUDiv) Operands() []*value.Value { 459 return []*value.Value{&inst.X, &inst.Y} 460 } 461 462 // ~~~ [ sdiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 463 464 // InstSDiv is an LLVM IR sdiv instruction. 465 type InstSDiv struct { 466 // Name of local variable associated with the result. 467 LocalIdent 468 // Operands. 469 X, Y value.Value // integer scalar or integer vector 470 471 // extra. 472 473 // Type of result produced by the instruction. 474 Typ types.Type 475 // (optional) Exact. 476 Exact bool 477 // (optional) Metadata. 478 Metadata 479 } 480 481 // NewSDiv returns a new sdiv instruction based on the given operands. 482 func NewSDiv(x, y value.Value) *InstSDiv { 483 inst := &InstSDiv{X: x, Y: y} 484 // Compute type. 485 inst.Type() 486 return inst 487 } 488 489 // String returns the LLVM syntax representation of the instruction as a 490 // type-value pair. 491 func (inst *InstSDiv) String() string { 492 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 493 } 494 495 // Type returns the type of the instruction. 496 func (inst *InstSDiv) Type() types.Type { 497 // Cache type if not present. 498 if inst.Typ == nil { 499 inst.Typ = inst.X.Type() 500 } 501 return inst.Typ 502 } 503 504 // LLString returns the LLVM syntax representation of the instruction. 505 // 506 // 'sdiv' Exactopt X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 507 func (inst *InstSDiv) LLString() string { 508 buf := &strings.Builder{} 509 fmt.Fprintf(buf, "%s = ", inst.Ident()) 510 buf.WriteString("sdiv") 511 if inst.Exact { 512 buf.WriteString(" exact") 513 } 514 fmt.Fprintf(buf, " %s, %s", inst.X, inst.Y.Ident()) 515 for _, md := range inst.Metadata { 516 fmt.Fprintf(buf, ", %s", md) 517 } 518 return buf.String() 519 } 520 521 // Operands returns a mutable list of operands of the given instruction. 522 func (inst *InstSDiv) Operands() []*value.Value { 523 return []*value.Value{&inst.X, &inst.Y} 524 } 525 526 // ~~~ [ fdiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 527 528 // InstFDiv is an LLVM IR fdiv instruction. 529 type InstFDiv struct { 530 // Name of local variable associated with the result. 531 LocalIdent 532 // Operands. 533 X, Y value.Value // floating-point scalar or floating-point vector 534 535 // extra. 536 537 // Type of result produced by the instruction. 538 Typ types.Type 539 // (optional) Fast math flags. 540 FastMathFlags []enum.FastMathFlag 541 // (optional) Metadata. 542 Metadata 543 } 544 545 // NewFDiv returns a new fdiv instruction based on the given operands. 546 func NewFDiv(x, y value.Value) *InstFDiv { 547 inst := &InstFDiv{X: x, Y: y} 548 // Compute type. 549 inst.Type() 550 return inst 551 } 552 553 // String returns the LLVM syntax representation of the instruction as a 554 // type-value pair. 555 func (inst *InstFDiv) String() string { 556 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 557 } 558 559 // Type returns the type of the instruction. 560 func (inst *InstFDiv) Type() types.Type { 561 // Cache type if not present. 562 if inst.Typ == nil { 563 inst.Typ = inst.X.Type() 564 } 565 return inst.Typ 566 } 567 568 // LLString returns the LLVM syntax representation of the instruction. 569 // 570 // 'fdiv' FastMathFlags=FastMathFlag* X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 571 func (inst *InstFDiv) LLString() string { 572 buf := &strings.Builder{} 573 fmt.Fprintf(buf, "%s = ", inst.Ident()) 574 buf.WriteString("fdiv") 575 for _, flag := range inst.FastMathFlags { 576 fmt.Fprintf(buf, " %s", flag) 577 } 578 fmt.Fprintf(buf, " %s, %s", inst.X, inst.Y.Ident()) 579 for _, md := range inst.Metadata { 580 fmt.Fprintf(buf, ", %s", md) 581 } 582 return buf.String() 583 } 584 585 // Operands returns a mutable list of operands of the given instruction. 586 func (inst *InstFDiv) Operands() []*value.Value { 587 return []*value.Value{&inst.X, &inst.Y} 588 } 589 590 // ~~~ [ urem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 591 592 // InstURem is an LLVM IR urem instruction. 593 type InstURem struct { 594 // Name of local variable associated with the result. 595 LocalIdent 596 // Operands. 597 X, Y value.Value // integer scalar or integer vector 598 599 // extra. 600 601 // Type of result produced by the instruction. 602 Typ types.Type 603 // (optional) Metadata. 604 Metadata 605 } 606 607 // NewURem returns a new urem instruction based on the given operands. 608 func NewURem(x, y value.Value) *InstURem { 609 inst := &InstURem{X: x, Y: y} 610 // Compute type. 611 inst.Type() 612 return inst 613 } 614 615 // String returns the LLVM syntax representation of the instruction as a 616 // type-value pair. 617 func (inst *InstURem) String() string { 618 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 619 } 620 621 // Type returns the type of the instruction. 622 func (inst *InstURem) Type() types.Type { 623 // Cache type if not present. 624 if inst.Typ == nil { 625 inst.Typ = inst.X.Type() 626 } 627 return inst.Typ 628 } 629 630 // LLString returns the LLVM syntax representation of the instruction. 631 // 632 // 'urem' X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 633 func (inst *InstURem) LLString() string { 634 buf := &strings.Builder{} 635 fmt.Fprintf(buf, "%s = ", inst.Ident()) 636 fmt.Fprintf(buf, "urem %s, %s", inst.X, inst.Y.Ident()) 637 for _, md := range inst.Metadata { 638 fmt.Fprintf(buf, ", %s", md) 639 } 640 return buf.String() 641 } 642 643 // Operands returns a mutable list of operands of the given instruction. 644 func (inst *InstURem) Operands() []*value.Value { 645 return []*value.Value{&inst.X, &inst.Y} 646 } 647 648 // ~~~ [ srem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 649 650 // InstSRem is an LLVM IR srem instruction. 651 type InstSRem struct { 652 // Name of local variable associated with the result. 653 LocalIdent 654 // Operands. 655 X, Y value.Value // integer scalar or integer vector 656 657 // extra. 658 659 // Type of result produced by the instruction. 660 Typ types.Type 661 // (optional) Metadata. 662 Metadata 663 } 664 665 // NewSRem returns a new srem instruction based on the given operands. 666 func NewSRem(x, y value.Value) *InstSRem { 667 inst := &InstSRem{X: x, Y: y} 668 // Compute type. 669 inst.Type() 670 return inst 671 } 672 673 // String returns the LLVM syntax representation of the instruction as a 674 // type-value pair. 675 func (inst *InstSRem) String() string { 676 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 677 } 678 679 // Type returns the type of the instruction. 680 func (inst *InstSRem) Type() types.Type { 681 // Cache type if not present. 682 if inst.Typ == nil { 683 inst.Typ = inst.X.Type() 684 } 685 return inst.Typ 686 } 687 688 // LLString returns the LLVM syntax representation of the instruction. 689 // 690 // 'srem' X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 691 func (inst *InstSRem) LLString() string { 692 buf := &strings.Builder{} 693 fmt.Fprintf(buf, "%s = ", inst.Ident()) 694 fmt.Fprintf(buf, "srem %s, %s", inst.X, inst.Y.Ident()) 695 for _, md := range inst.Metadata { 696 fmt.Fprintf(buf, ", %s", md) 697 } 698 return buf.String() 699 } 700 701 // Operands returns a mutable list of operands of the given instruction. 702 func (inst *InstSRem) Operands() []*value.Value { 703 return []*value.Value{&inst.X, &inst.Y} 704 } 705 706 // ~~~ [ frem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 707 708 // InstFRem is an LLVM IR frem instruction. 709 type InstFRem struct { 710 // Name of local variable associated with the result. 711 LocalIdent 712 // Operands. 713 X, Y value.Value // floating-point scalar or floating-point vector 714 715 // extra. 716 717 // Type of result produced by the instruction. 718 Typ types.Type 719 // (optional) Fast math flags. 720 FastMathFlags []enum.FastMathFlag 721 // (optional) Metadata. 722 Metadata 723 } 724 725 // NewFRem returns a new frem instruction based on the given operands. 726 func NewFRem(x, y value.Value) *InstFRem { 727 inst := &InstFRem{X: x, Y: y} 728 // Compute type. 729 inst.Type() 730 return inst 731 } 732 733 // String returns the LLVM syntax representation of the instruction as a 734 // type-value pair. 735 func (inst *InstFRem) String() string { 736 return fmt.Sprintf("%s %s", inst.Type(), inst.Ident()) 737 } 738 739 // Type returns the type of the instruction. 740 func (inst *InstFRem) Type() types.Type { 741 // Cache type if not present. 742 if inst.Typ == nil { 743 inst.Typ = inst.X.Type() 744 } 745 return inst.Typ 746 } 747 748 // LLString returns the LLVM syntax representation of the instruction. 749 // 750 // 'frem' FastMathFlags=FastMathFlag* X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+? 751 func (inst *InstFRem) LLString() string { 752 buf := &strings.Builder{} 753 fmt.Fprintf(buf, "%s = ", inst.Ident()) 754 buf.WriteString("frem") 755 for _, flag := range inst.FastMathFlags { 756 fmt.Fprintf(buf, " %s", flag) 757 } 758 fmt.Fprintf(buf, " %s, %s", inst.X, inst.Y.Ident()) 759 for _, md := range inst.Metadata { 760 fmt.Fprintf(buf, ", %s", md) 761 } 762 return buf.String() 763 } 764 765 // Operands returns a mutable list of operands of the given instruction. 766 func (inst *InstFRem) Operands() []*value.Value { 767 return []*value.Value{&inst.X, &inst.Y} 768 }