master
   1//! Machine Intermediate Representation.
   2//! This data is produced by x86_64 Codegen and consumed by x86_64 Isel.
   3//! These instructions have a 1:1 correspondence with machine code instructions
   4//! for the target. MIR can be lowered to source-annotated textual assembly code
   5//! instructions, or it can be lowered to machine code.
   6//! The main purpose of MIR is to postpone the assignment of offsets until Isel,
   7//! so that, for example, the smaller encodings of jump instructions can be used.
   8
   9instructions: std.MultiArrayList(Inst).Slice,
  10/// The meaning of this data is determined by `Inst.Tag` value.
  11extra: []const u32,
  12string_bytes: []const u8,
  13locals: []const Local,
  14table: []const Inst.Index,
  15/// Optional data which, when present, can be used to accelerate encoding speed.
  16memoized_encodings: []const u0 = &.{},
  17frame_locs: std.MultiArrayList(FrameLoc).Slice,
  18
  19pub const Inst = struct {
  20    tag: Tag,
  21    ops: Ops,
  22    data: Data,
  23
  24    pub const Index = u32;
  25
  26    pub const Fixes = enum(u8) {
  27        /// ___
  28        @"_",
  29
  30        /// ___ 0
  31        _0,
  32        /// ___ 1
  33        _1,
  34        /// ___ 2
  35        _2,
  36        /// ___ 3
  37        _3,
  38        /// ___ 4
  39        _4,
  40
  41        /// ___ Demote
  42        _demote,
  43        /// ___ Flush
  44        _flush,
  45        /// ___ Flush Optimized
  46        _flushopt,
  47        /// ___ Instructions With T0 Hint
  48        _it0,
  49        /// ___ Instructions With T0 Hint
  50        _it1,
  51        /// ___ With NTA Hint
  52        _nta,
  53        /// System Call ___
  54        sys_,
  55        /// ___ With T0 Hint
  56        _t0,
  57        /// ___ With T1 Hint
  58        _t1,
  59        /// ___ With T2 Hint
  60        _t2,
  61        /// ___ Write Back
  62        _wb,
  63        /// ___ With Intent to Write and T1 Hint
  64        _wt1,
  65
  66        /// ___ crement Shadow Stack Pointer Doubleword
  67        _csspd,
  68        /// ___ crement Shadow Stack Pointer Quadword
  69        _csspq,
  70        /// ___ FS Segment Base
  71        _fsbase,
  72        /// ___ GS
  73        _gs,
  74        /// ___ GS Segment Base
  75        _gsbase,
  76        /// ___ Model Specific Register
  77        _msr,
  78        /// ___ MXCSR
  79        _mxcsr,
  80        /// ___ Processor ID
  81        _pid,
  82        /// ___ Protection Key Rights For User Pages
  83        _pkru,
  84        /// ___ Performance-Monitoring Counters
  85        _pmc,
  86        /// ___ Random Number
  87        _rand,
  88        /// ___ r Busy Flag in a Supervisor Shadow Stack token
  89        _rssbsy,
  90        /// ___ Random Seed
  91        _seed,
  92        /// ___ Shadow Stack Doubleword
  93        _ssd,
  94        /// ___ Shadow Stack Quadword
  95        _ssq,
  96        /// ___ Shadow Stack Pointer Doubleword
  97        _sspd,
  98        /// ___ Shadow Stack Pointer Quadword
  99        _sspq,
 100        /// ___ Time-Stamp Counter
 101        _tsc,
 102        /// ___ Time-Stamp Counter And Processor ID
 103        _tscp,
 104        /// ___ User Shadow Stack Doubleword
 105        _ussd,
 106        /// ___ User Shadow Stack Quadword
 107        _ussq,
 108        /// VEX-Encoded ___ MXCSR
 109        v_mxcsr,
 110
 111        /// Byte ___
 112        b_,
 113        /// Interrupt ___
 114        /// Integer ___
 115        i_,
 116        /// Interrupt ___ Word
 117        i_w,
 118        /// Interrupt ___ Doubleword
 119        i_d,
 120        /// Interrupt ___ Quadword
 121        i_q,
 122        /// User-Interrupt ___
 123        ui_,
 124
 125        /// ___ mp
 126        _mp,
 127        /// ___ if CX register is 0
 128        _cxz,
 129        /// ___ if ECX register is 0
 130        _ecxz,
 131        /// ___ if RCX register is 0
 132        _rcxz,
 133
 134        /// ___ Addition
 135        _a,
 136        /// ___ Subtraction
 137        _s,
 138        /// ___ Multiply
 139        _m,
 140        /// ___ Division
 141        _d,
 142
 143        /// ___ Without Affecting Flags
 144        _x,
 145        /// ___ Left
 146        _l,
 147        /// ___ Left Double
 148        _ld,
 149        /// ___ Left Without Affecting Flags
 150        _lx,
 151        /// ___ Mask
 152        _msk,
 153        /// ___ Right
 154        /// ___ For Reading
 155        /// ___ Register
 156        _r,
 157        /// ___ Right Double
 158        _rd,
 159        /// ___ Right Without Affecting Flags
 160        _rx,
 161
 162        /// ___ Forward
 163        _f,
 164        /// ___ Reverse
 165        //_r,
 166
 167        /// ___ Above
 168        //_a,
 169        /// ___ Above Or Equal
 170        _ae,
 171        /// ___ Below
 172        _b,
 173        /// ___ Below Or Equal
 174        /// ___ Big Endian
 175        _be,
 176        /// ___ Carry
 177        /// ___ Carry Flag
 178        _c,
 179        /// ___ Equal
 180        _e,
 181        /// ___ Greater
 182        _g,
 183        /// ___ Greater Or Equal
 184        _ge,
 185        /// ___ Less
 186        //_l,
 187        /// ___ Less Or Equal
 188        _le,
 189        /// ___ Not Above
 190        _na,
 191        /// ___ Not Above Or Equal
 192        _nae,
 193        /// ___ Not Below
 194        _nb,
 195        /// ___ Not Below Or Equal
 196        _nbe,
 197        /// ___ Not Carry
 198        _nc,
 199        /// ___ Not Equal
 200        _ne,
 201        /// ___ Not Greater
 202        _ng,
 203        /// ___ Not Greater Or Equal
 204        _nge,
 205        /// ___ Not Less
 206        _nl,
 207        /// ___ Not Less Or Equal
 208        _nle,
 209        /// ___ Not Overflow
 210        _no,
 211        /// ___ Not Parity
 212        _np,
 213        /// ___ Not Sign
 214        _ns,
 215        /// ___ Not Zero
 216        _nz,
 217        /// ___ Overflow
 218        _o,
 219        /// ___ Parity
 220        _p,
 221        /// ___ Parity Even
 222        _pe,
 223        /// ___ Parity Odd
 224        _po,
 225        /// ___ Sign
 226        //_s,
 227        /// ___ Zero
 228        _z,
 229        /// ___ Alignment Check Flag
 230        _ac,
 231        /// ___ Direction Flag
 232        //_d,
 233        /// ___ Interrupt Flag
 234        _i,
 235        /// ___ Task-Switched Flag In CR0
 236        _ts,
 237        /// ___ User Interrupt Flag
 238        _ui,
 239
 240        /// ___ Byte
 241        //_b,
 242        /// ___ Word
 243        /// ___ For Writing
 244        /// ___ With Intent to Write
 245        _w,
 246        /// ___ Doubleword
 247        //_d,
 248        /// ___ Double Quadword to Quadword
 249        _dq2q,
 250        /// ___ QuadWord
 251        _q,
 252        /// ___ Quadword to Double Quadword
 253        _q2dq,
 254
 255        /// ___ String
 256        //_s,
 257        /// ___ String Byte
 258        _sb,
 259        /// ___ String Word
 260        _sw,
 261        /// ___ String Doubleword
 262        _sd,
 263        /// ___ String Quadword
 264        _sq,
 265
 266        /// Repeat ___ String
 267        @"rep _s",
 268        /// Repeat ___ String Byte
 269        @"rep _sb",
 270        /// Repeat ___ String Word
 271        @"rep _sw",
 272        /// Repeat ___ String Doubleword
 273        @"rep _sd",
 274        /// Repeat ___ String Quadword
 275        @"rep _sq",
 276
 277        /// Repeat Equal ___ String
 278        @"repe _s",
 279        /// Repeat Equal ___ String Byte
 280        @"repe _sb",
 281        /// Repeat Equal ___ String Word
 282        @"repe _sw",
 283        /// Repeat Equal ___ String Doubleword
 284        @"repe _sd",
 285        /// Repeat Equal ___ String Quadword
 286        @"repe _sq",
 287
 288        /// Repeat Not Equal ___ String
 289        @"repne _s",
 290        /// Repeat Not Equal ___ String Byte
 291        @"repne _sb",
 292        /// Repeat Not Equal ___ String Word
 293        @"repne _sw",
 294        /// Repeat Not Equal ___ String Doubleword
 295        @"repne _sd",
 296        /// Repeat Not Equal ___ String Quadword
 297        @"repne _sq",
 298
 299        /// Repeat Not Zero ___ String
 300        @"repnz _s",
 301        /// Repeat Not Zero ___ String Byte
 302        @"repnz _sb",
 303        /// Repeat Not Zero ___ String Word
 304        @"repnz _sw",
 305        /// Repeat Not Zero ___ String Doubleword
 306        @"repnz _sd",
 307        /// Repeat Not Zero ___ String Quadword
 308        @"repnz _sq",
 309
 310        /// Repeat Zero ___ String
 311        @"repz _s",
 312        /// Repeat Zero ___ String Byte
 313        @"repz _sb",
 314        /// Repeat Zero ___ String Word
 315        @"repz _sw",
 316        /// Repeat Zero ___ String Doubleword
 317        @"repz _sd",
 318        /// Repeat Zero ___ String Quadword
 319        @"repz _sq",
 320
 321        /// Locked ___
 322        @"lock _",
 323        /// ___ And Complement
 324        //_c,
 325        /// Locked ___ And Complement
 326        @"lock _c",
 327        /// ___ And Reset
 328        //_r,
 329        /// Locked ___ And Reset
 330        @"lock _r",
 331        /// ___ And Set
 332        //_s,
 333        /// Locked ___ And Set
 334        @"lock _s",
 335        /// ___ 8 Bytes
 336        _8b,
 337        /// Locked ___ 8 Bytes
 338        @"lock _8b",
 339        /// ___ 16 Bytes
 340        _16b,
 341        /// Locked ___ 16 Bytes
 342        @"lock _16b",
 343
 344        /// Float ___
 345        f_,
 346        /// Float ___ +1.0
 347        /// Float ___ 1
 348        f_1,
 349        /// Float ___ Below
 350        f_b,
 351        /// Float ___ Below Or Equal
 352        f_be,
 353        /// Float ___ Control Word
 354        f_cw,
 355        /// Float ___ Equal
 356        f_e,
 357        /// Float ___ Environment
 358        f_env,
 359        /// Float ___ log_2(e)
 360        f_l2e,
 361        /// Float ___ log_2(10)
 362        f_l2t,
 363        /// Float ___ log_10(2)
 364        f_lg2,
 365        /// Float ___ log_e(2)
 366        f_ln2,
 367        /// Float ___ Not Below
 368        f_nb,
 369        /// Float ___ Not Below Or Equal
 370        f_nbe,
 371        /// Float ___ Not Equal
 372        f_ne,
 373        /// Float ___ Not Unordered
 374        f_nu,
 375        /// Float ___ Pop
 376        f_p,
 377        /// Float ___ +1
 378        f_p1,
 379        /// Float ___ π
 380        f_pi,
 381        /// Float ___ Pop Pop
 382        f_pp,
 383        /// Float ___ crement Stack-Top Pointer
 384        f_cstp,
 385        /// Float ___ Status Word
 386        f_sw,
 387        /// Float ___ Unordered
 388        f_u,
 389        /// Float ___ +0.0
 390        f_z,
 391        /// Float BCD ___
 392        fb_,
 393        /// Float BCD ___ Pop
 394        fb_p,
 395        /// Float And Integer ___
 396        fi_,
 397        /// Float And Integer ___ Pop
 398        fi_p,
 399        /// Float No Wait ___
 400        fn_,
 401        /// Float No Wait ___ Control Word
 402        fn_cw,
 403        /// Float No Wait ___ Environment
 404        fn_env,
 405        /// Float No Wait ___ status word
 406        fn_sw,
 407        /// Float Extended ___
 408        fx_,
 409        /// Float Extended ___ 64
 410        fx_64,
 411
 412        /// ___ in 32-bit and Compatibility Mode
 413        _32,
 414        /// ___ in 64-bit Mode
 415        _64,
 416
 417        /// Packed ___
 418        p_,
 419        /// Packed ___ Byte
 420        p_b,
 421        /// Packed ___ Word
 422        p_w,
 423        /// Packed ___ Doubleword
 424        p_d,
 425        /// Packed ___ Quadword
 426        p_q,
 427        /// Packed ___ Double Quadword
 428        /// Packed ___ Doubleword to Quadword
 429        p_dq,
 430        /// Packed ___ Unsigned Doubleword to Quadword
 431        p_udq,
 432        /// Packed Carry-Less ___ Quadword to Double Quadword
 433        pcl_qdq,
 434        /// Packed Half ___ Doubleword
 435        ph_d,
 436        /// Packed Half ___ Saturate Word
 437        ph_sw,
 438        /// Packed Half ___ Word
 439        ph_w,
 440        /// ___ Aligned Packed Integer Values
 441        _dqa,
 442        /// ___ Unaligned Packed Integer Values
 443        _dqu,
 444
 445        /// ___ Scalar Single-Precision Values
 446        _ss,
 447        /// ___ Packed Single-Precision Values
 448        _ps,
 449        /// ___ Scalar Double-Precision Values
 450        //_sd,
 451        /// ___ Packed Double-Precision Values
 452        _pd,
 453        /// Half ___ Packed Single-Precision Values
 454        h_ps,
 455        /// Half ___ Packed Double-Precision Values
 456        h_pd,
 457
 458        /// ___ Internal Caches
 459        //_d,
 460        /// ___ TLB Entries
 461        _lpg,
 462        /// ___ Process-Context Identifier
 463        _pcid,
 464
 465        /// Load ___
 466        l_,
 467        /// Memory ___
 468        m_,
 469        /// Store ___
 470        s_,
 471        /// Timed ___
 472        t_,
 473        /// User Level Monitor ___
 474        um_,
 475
 476        /// VEX-Encoded ___
 477        v_,
 478        /// VEX-Encoded ___ Byte
 479        v_b,
 480        /// VEX-Encoded ___ Word
 481        v_w,
 482        /// VEX-Encoded ___ Doubleword
 483        v_d,
 484        /// VEX-Encoded ___ Quadword
 485        v_q,
 486        /// VEX-Encoded ___ Aligned Packed Integer Values
 487        v_dqa,
 488        /// VEX-Encoded ___ Unaligned Packed Integer Values
 489        v_dqu,
 490        /// VEX-Encoded ___ Integer Data
 491        v_i128,
 492        /// VEX-Encoded Packed ___
 493        vp_,
 494        /// VEX-Encoded Packed ___ Byte
 495        vp_b,
 496        /// VEX-Encoded Packed ___ Word
 497        vp_w,
 498        /// VEX-Encoded Packed ___ Doubleword
 499        vp_d,
 500        /// VEX-Encoded Packed ___ Quadword
 501        vp_q,
 502        /// VEX-Encoded Packed ___ Double Quadword
 503        /// VEX-Encoded Packed ___ Doubleword to Quadword
 504        vp_dq,
 505        /// VEX-Encoded Packed ___ Unsigned Doubleword to Quadword
 506        vp_udq,
 507        /// VEx-Encoded Packed Carry-Less ___ Quadword to Double Quadword
 508        vpcl_qdq,
 509        /// VEX-Encoded Packed Half ___ Doubleword
 510        vph_d,
 511        /// VEX-Encoded Packed Half ___ Saturate Word
 512        vph_sw,
 513        /// VEX-Encoded Packed Half ___ Word
 514        vph_w,
 515        /// VEX-Encoded ___ Scalar Single-Precision Values
 516        v_ss,
 517        /// VEX-Encoded ___ Packed Single-Precision Values
 518        v_ps,
 519        /// VEX-Encoded ___ Scalar Double-Precision Values
 520        v_sd,
 521        /// VEX-Encoded ___ Packed Double-Precision Values
 522        v_pd,
 523        /// VEX-Encoded ___ 128-Bits Of Floating-Point Data
 524        v_f128,
 525        /// VEX-Encoded Half ___ Packed Single-Precision Values
 526        vh_ps,
 527        /// VEX-Encoded Half ___ Packed Double-Precision Values
 528        vh_pd,
 529
 530        /// ___ 128-bit key with key locker
 531        _128,
 532        /// ___ 256-bit key with key locker
 533        _256,
 534        /// ___ with key locker using 128-bit key
 535        _128kl,
 536        /// ___ with key locker using 256-bit key
 537        _256kl,
 538        /// ___ with key locker on 8 blocks using 128-bit key
 539        _wide128kl,
 540        /// ___ with key locker on 8 blocks using 256-bit key
 541        _wide256kl,
 542
 543        /// Mask ___ Byte
 544        k_b,
 545        /// Mask ___ Word
 546        k_w,
 547        /// Mask ___ Doubleword
 548        k_d,
 549        /// Mask ___ Quadword
 550        k_q,
 551
 552        pub fn fromCond(cc: bits.Condition) Fixes {
 553            return switch (cc) {
 554                inline else => |cc_tag| @field(Fixes, "_" ++ @tagName(cc_tag)),
 555                .z_and_np, .nz_or_p => unreachable,
 556            };
 557        }
 558    };
 559
 560    pub const Tag = enum(u8) {
 561        // General-purpose
 562        /// ASCII adjust al after addition
 563        /// ASCII adjust ax before division
 564        /// ASCII adjust ax after multiply
 565        /// ASCII adjust al after subtraction
 566        aa,
 567        /// Add with carry
 568        /// Unsigned integer addition of two operands with carry flag
 569        adc,
 570        /// Add
 571        /// Add packed integers
 572        /// Add packed single-precision floating-point values
 573        /// Add scalar single-precision floating-point values
 574        /// Add packed double-precision floating-point values
 575        /// Add scalar double-precision floating-point values
 576        /// Packed single-precision floating-point horizontal add
 577        /// Packed double-precision floating-point horizontal add
 578        /// Packed horizontal add
 579        /// Packed horizontal add and saturate
 580        add,
 581        /// Logical and
 582        /// Bitwise logical and of packed single-precision floating-point values
 583        /// Bitwise logical and of packed double-precision floating-point values
 584        @"and",
 585        /// Adjust RPL field of segment selector
 586        arpl,
 587        /// Bit scan forward
 588        /// Bit scan reverse
 589        bs,
 590        /// Byte swap
 591        /// Swap GS base register
 592        swap,
 593        /// Bit test
 594        /// Bit test and complement
 595        /// Bit test and reset
 596        /// Bit test and set
 597        bt,
 598        /// Check array index against bounds
 599        bound,
 600        /// Call
 601        /// Fast system call
 602        call,
 603        /// Convert byte to word
 604        cbw,
 605        /// Convert doubleword to quadword
 606        cdq,
 607        /// Convert doubleword to quadword
 608        cdqe,
 609        /// Clear AC flag in EFLAGS register
 610        /// Clear carry flag
 611        /// Clear direction flag
 612        /// Clear interrupt flag
 613        /// Clear task-switched flag in CR0
 614        /// Clear user interrupt flag
 615        /// Cache line demote
 616        /// Flush cache line
 617        /// Flush cache line optimized
 618        /// Clear busy flag in a supervisor shadow stack token
 619        /// Cache line write back
 620        cl,
 621        /// Complement carry flag
 622        cmc,
 623        /// Conditional move
 624        cmov,
 625        /// Logical compare
 626        /// Compare string
 627        /// Compare scalar single-precision floating-point values
 628        /// Compare scalar double-precision floating-point values
 629        cmp,
 630        /// Compare and exchange
 631        /// Compare and exchange bytes
 632        cmpxchg,
 633        /// CPU identification
 634        cpuid,
 635        /// Convert doubleword to quadword
 636        cqo,
 637        /// Convert word to doubleword
 638        cwd,
 639        /// Convert word to doubleword
 640        cwde,
 641        /// Decimal adjust AL after addition
 642        /// Decimal adjust AL after subtraction
 643        da,
 644        /// Decrement by 1
 645        /// Decrement stack-top pointer
 646        /// Decrement shadow stack pointer
 647        de,
 648        /// Unsigned division
 649        /// Signed division
 650        /// Divide
 651        /// Divide packed single-precision floating-point values
 652        /// Divide scalar single-precision floating-point values
 653        /// Divide packed double-precision floating-point values
 654        /// Divide scalar double-precision floating-point values
 655        div,
 656        /// Terminate and indirect branch in 32-bit and compatibility mode
 657        /// Terminate and indirect branch in 64-bit mode
 658        endbr,
 659        /// Enqueue command
 660        /// Enqueue command supervisor
 661        enqcmd,
 662        /// Make stack frame for procedure parameters
 663        /// Fast system call
 664        enter,
 665        /// Fast return from fast system call
 666        exit,
 667        /// Load fence
 668        /// Memory fence
 669        /// Store fence
 670        fence,
 671        /// Halt
 672        hlt,
 673        /// History reset
 674        hreset,
 675        /// Input from port
 676        /// Input from port to string
 677        /// Increment by 1
 678        /// Increment stack-top pointer
 679        /// Increment shadow stack pointer
 680        in,
 681        /// Call to interrupt procedure
 682        int,
 683        /// Invalidate internal caches
 684        /// Invalidate TLB entries
 685        /// Invalidate process-context identifier
 686        inv,
 687        /// Conditional jump
 688        /// Jump
 689        j,
 690        /// Load status flags into AH register
 691        lahf,
 692        /// Load access right byte
 693        lar,
 694        /// Load effective address
 695        lea,
 696        /// High level procedure exit
 697        leave,
 698        /// Load global descriptor table register
 699        lgdt,
 700        /// Load interrupt descriptor table register
 701        lidt,
 702        /// Load local descriptor table register
 703        lldt,
 704        /// Load machine status word
 705        lmsw,
 706        /// Load string
 707        lod,
 708        /// Loop according to ECX counter
 709        loop,
 710        /// Load segment limit
 711        lsl,
 712        /// Load task register
 713        ltr,
 714        /// Count the number of leading zero bits
 715        lzcnt,
 716        /// Move
 717        /// Move data from string to string
 718        /// Move data after swapping bytes
 719        /// Move scalar single-precision floating-point value
 720        /// Move scalar double-precision floating-point value
 721        /// Move doubleword
 722        /// Move quadword
 723        /// Move aligned packed integer values
 724        /// Move unaligned packed integer values
 725        /// Move quadword from XMM to MMX technology register
 726        /// Move quadword from MMX technology to XMM register
 727        mov,
 728        /// Move with sign extension
 729        movsx,
 730        /// Move with zero extension
 731        movzx,
 732        /// Multiply
 733        /// Signed multiplication
 734        /// Multiply packed single-precision floating-point values
 735        /// Multiply scalar single-precision floating-point values
 736        /// Multiply packed double-precision floating-point values
 737        /// Multiply scalar double-precision floating-point values
 738        /// Multiply packed unsigned doubleword integers
 739        /// Multiply packed doubleword integers
 740        /// Carry-less multiplication quadword
 741        mul,
 742        /// Two's complement negation
 743        neg,
 744        /// No-op
 745        /// No operation
 746        nop,
 747        /// One's complement negation
 748        not,
 749        /// Logical or
 750        /// Bitwise logical or of packed single-precision floating-point values
 751        /// Bitwise logical or of packed double-precision floating-point values
 752        @"or",
 753        /// Output to port
 754        /// Output string to port
 755        out,
 756        /// Spin loop hint
 757        /// Timed pause
 758        pause,
 759        /// Pop
 760        pop,
 761        /// Return the count of number of bits set to 1
 762        popcnt,
 763        /// Pop stack into EFLAGS register
 764        popf,
 765        /// Push
 766        push,
 767        /// Push EFLAGS register onto the stack
 768        pushf,
 769        /// Rotate left through carry
 770        /// Rotate right through carry
 771        rc,
 772        /// Read FS segment base
 773        /// Read GS segment base
 774        /// Read from model specific register
 775        /// Read processor ID
 776        /// Read protection key rights for user pages
 777        /// Read performance-monitoring counters
 778        /// Read random number
 779        /// Read random seed
 780        /// Read shadow stack pointer
 781        /// Read time-stamp counter
 782        /// Read time-stamp counter and processor ID
 783        rd,
 784        /// Return
 785        /// Return from fast system call
 786        /// Interrupt return
 787        /// User-interrupt return
 788        ret,
 789        /// Rotate left
 790        /// Rotate right
 791        /// Rotate right logical without affecting flags
 792        ro,
 793        /// Resume from system management mode
 794        rsm,
 795        /// Arithmetic shift left
 796        /// Arithmetic shift right
 797        /// Shift left arithmetic without affecting flags
 798        sa,
 799        /// Store AH into flags
 800        sahf,
 801        /// Integer subtraction with borrow
 802        sbb,
 803        /// Scan string
 804        sca,
 805        /// Send user interprocessor interrupt
 806        senduipi,
 807        /// Serialize instruction execution
 808        serialize,
 809        /// Set byte on condition
 810        set,
 811        /// Logical shift left
 812        /// Double precision shift left
 813        /// Logical shift right
 814        /// Double precision shift right
 815        /// Shift left logical without affecting flags
 816        /// Shift right logical without affecting flags
 817        sh,
 818        /// Store interrupt descriptor table register
 819        sidt,
 820        /// Store local descriptor table register
 821        sldt,
 822        /// Store machine status word
 823        smsw,
 824        /// Subtract
 825        /// Subtract packed integers
 826        /// Subtract packed single-precision floating-point values
 827        /// Subtract scalar single-precision floating-point values
 828        /// Subtract packed double-precision floating-point values
 829        /// Subtract scalar double-precision floating-point values
 830        /// Packed single-precision floating-point horizontal subtract
 831        /// Packed double-precision floating-point horizontal subtract
 832        /// Packed horizontal subtract
 833        /// Packed horizontal subtract and saturate
 834        sub,
 835        /// Set carry flag
 836        /// Set direction flag
 837        /// Set interrupt flag
 838        /// Store binary coded decimal integer and pop
 839        /// Store floating-point value
 840        /// Store integer
 841        /// Store x87 FPU control word
 842        /// Store x87 FPU environment
 843        /// Store x87 FPU status word
 844        /// Store MXCSR register state
 845        st,
 846        /// Store string
 847        sto,
 848        /// Test condition
 849        /// Logical compare
 850        /// Packed bit test
 851        @"test",
 852        /// Undefined instruction
 853        ud,
 854        /// User level set up monitor address
 855        umonitor,
 856        /// Verify a segment for reading
 857        /// Verify a segment for writing
 858        ver,
 859        /// Write to model specific register
 860        /// Write to model specific register
 861        /// Write to model specific register
 862        /// Write to shadow stack
 863        /// Write to user shadow stack
 864        wr,
 865        /// Exchange and add
 866        xadd,
 867        /// Exchange register/memory with register
 868        /// Exchange register contents
 869        xch,
 870        /// Get value of extended control register
 871        xgetbv,
 872        /// Table look-up translation
 873        xlat,
 874        /// Logical exclusive-or
 875        /// Bitwise logical xor of packed single-precision floating-point values
 876        /// Bitwise logical xor of packed double-precision floating-point values
 877        xor,
 878
 879        // X87
 880        /// Compute 2^x-1
 881        @"2xm1",
 882        /// Absolute value
 883        abs,
 884        /// Change sign
 885        chs,
 886        /// Clear exceptions
 887        clex,
 888        /// Compare floating-point values
 889        com,
 890        /// Compare floating-point values and set EFLAGS
 891        /// Compare scalar ordered single-precision floating-point values
 892        /// Compare scalar ordered double-precision floating-point values
 893        comi,
 894        /// Cosine
 895        cos,
 896        /// Reverse divide
 897        divr,
 898        /// Free floating-point register
 899        free,
 900        /// Initialize floating-point unit
 901        init,
 902        /// Load binary coded decimal integer
 903        /// Load floating-point value
 904        /// Load integer
 905        /// Load constant
 906        /// Load x87 FPU control word
 907        /// Load x87 FPU environment
 908        /// Load MXCSR register state
 909        ld,
 910        /// Partial arctangent
 911        patan,
 912        /// Partial remainder
 913        prem,
 914        /// Partial tangent
 915        ptan,
 916        /// Round to integer
 917        rndint,
 918        /// Restore x87 FPU state
 919        /// Restore x87 FPU, MMX, XMM, and MXCSR state
 920        rstor,
 921        /// Store x87 FPU state
 922        /// Save x87 FPU, MMX technology, and MXCSR state
 923        save,
 924        /// Scale
 925        scale,
 926        /// Sine
 927        sin,
 928        /// Sine and cosine
 929        sincos,
 930        /// Square root
 931        /// Square root of packed single-precision floating-point values
 932        /// Square root of scalar single-precision floating-point value
 933        /// Square root of packed double-precision floating-point values
 934        /// Square root of scalar double-precision floating-point value
 935        sqrt,
 936        /// Store integer with truncation
 937        stt,
 938        /// Reverse subtract
 939        subr,
 940        /// Test
 941        tst,
 942        /// Unordered compare floating-point values
 943        ucom,
 944        /// Unordered compare floating-point values and set EFLAGS
 945        /// Unordered compare scalar single-precision floating-point values
 946        /// Unordered compare scalar double-precision floating-point values
 947        ucomi,
 948        /// Wait
 949        /// User level monitor wait
 950        wait,
 951        /// Examine floating-point
 952        xam,
 953        /// Extract exponent and significand
 954        xtract,
 955        /// Compute y * log2x
 956        /// Compute y * log2(x + 1)
 957        yl2x,
 958
 959        // MMX
 960        /// Pack with signed saturation
 961        ackssw,
 962        /// Pack with signed saturation
 963        ackssd,
 964        /// Pack with unsigned saturation
 965        ackusw,
 966        /// Add packed signed integers with signed saturation
 967        adds,
 968        /// Add packed unsigned integers with unsigned saturation
 969        addus,
 970        /// Logical and not
 971        /// Bitwise logical and not of packed single-precision floating-point values
 972        /// Bitwise logical and not of packed double-precision floating-point values
 973        andn,
 974        /// Compare packed data for equal
 975        cmpeq,
 976        /// Compare packed data for greater than
 977        cmpgt,
 978        /// Empty MMX technology state
 979        emms,
 980        /// Multiply and add packed signed and unsigned bytes
 981        maddubs,
 982        /// Multiply and add packed integers
 983        maddw,
 984        /// Multiply packed signed integers and store low result
 985        mull,
 986        /// Multiply packed signed integers and store high result
 987        mulh,
 988        /// Shift packed data left logical
 989        sll,
 990        /// Shift packed data right arithmetic
 991        sra,
 992        /// Shift packed data right logical
 993        srl,
 994        /// Subtract packed signed integers with signed saturation
 995        subs,
 996        /// Subtract packed unsigned integers with unsigned saturation
 997        subus,
 998        /// Unpack high data
 999        unpckhbw,
1000        /// Unpack high data
1001        unpckhdq,
1002        /// Unpack high data
1003        unpckhwd,
1004        /// Unpack low data
1005        unpcklbw,
1006        /// Unpack low data
1007        unpckldq,
1008        /// Unpack low data
1009        unpcklwd,
1010
1011        // SSE
1012        /// Average packed integers
1013        avg,
1014        /// Convert packed doubleword integers to packed single-precision floating-point values
1015        /// Convert packed doubleword integers to packed double-precision floating-point values
1016        cvtpi2,
1017        /// Convert packed single-precision floating-point values to packed doubleword integers
1018        cvtps2pi,
1019        /// Convert doubleword integer to scalar single-precision floating-point value
1020        /// Convert doubleword integer to scalar double-precision floating-point value
1021        cvtsi2,
1022        /// Convert scalar single-precision floating-point value to doubleword integer
1023        cvtss2si,
1024        /// Convert with truncation packed single-precision floating-point values to packed doubleword integers
1025        cvttps2pi,
1026        /// Convert with truncation scalar single-precision floating-point value to doubleword integer
1027        cvttss2si,
1028        /// Extract byte
1029        /// Extract word
1030        /// Extract doubleword
1031        /// Extract quadword
1032        extr,
1033        /// Insert byte
1034        /// Insert word
1035        /// Insert doubleword
1036        /// Insert quadword
1037        insr,
1038        /// Maximum of packed single-precision floating-point values
1039        /// Maximum of scalar single-precision floating-point values
1040        /// Maximum of packed double-precision floating-point values
1041        /// Maximum of scalar double-precision floating-point values
1042        max,
1043        /// Maximum of packed signed integers
1044        maxs,
1045        /// Maximum of packed unsigned integers
1046        maxu,
1047        /// Minimum of packed single-precision floating-point values
1048        /// Minimum of scalar single-precision floating-point values
1049        /// Minimum of packed double-precision floating-point values
1050        /// Minimum of scalar double-precision floating-point values
1051        min,
1052        /// Minimum of packed signed integers
1053        mins,
1054        /// Minimum of packed unsigned integers
1055        minu,
1056        /// Move aligned packed single-precision floating-point values
1057        /// Move aligned packed double-precision floating-point values
1058        mova,
1059        /// Move high packed single-precision floating-point values
1060        /// Move high packed double-precision floating-point values
1061        movh,
1062        /// Move packed single-precision floating-point values high to low
1063        movhl,
1064        /// Move low packed single-precision floating-point values
1065        /// Move low packed double-precision floating-point values
1066        movl,
1067        /// Move packed single-precision floating-point values low to high
1068        movlh,
1069        /// Move byte mask
1070        /// Extract packed single precision floating-point sign mask
1071        /// Extract packed double precision floating-point sign mask
1072        movmsk,
1073        /// Move unaligned packed single-precision floating-point values
1074        /// Move unaligned packed double-precision floating-point values
1075        movu,
1076        /// Multiply packed unsigned integers and store high result
1077        mulhu,
1078        /// Prefetch data into caches
1079        /// Prefetch data into caches with intent to write
1080        prefetch,
1081        /// Compute sum of absolute differences
1082        sadb,
1083        /// Packed interleave shuffle of quadruplets of single-precision floating-point values
1084        /// Packed interleave shuffle of pairs of double-precision floating-point values
1085        /// Shuffle packed doublewords
1086        /// Shuffle packed words
1087        shuf,
1088        /// Unpack and interleave high packed single-precision floating-point values
1089        /// Unpack and interleave high packed double-precision floating-point values
1090        unpckh,
1091        /// Unpack and interleave low packed single-precision floating-point values
1092        /// Unpack and interleave low packed double-precision floating-point values
1093        unpckl,
1094
1095        // SSE2
1096        /// Convert packed doubleword integers to packed single-precision floating-point values
1097        /// Convert packed doubleword integers to packed double-precision floating-point values
1098        cvtdq2,
1099        /// Convert packed double-precision floating-point values to packed doubleword integers
1100        cvtpd2dq,
1101        /// Convert packed double-precision floating-point values to packed doubleword integers
1102        cvtpd2pi,
1103        /// Convert packed double-precision floating-point values to packed single-precision floating-point values
1104        cvtpd2,
1105        /// Convert packed single-precision floating-point values to packed doubleword integers
1106        cvtps2dq,
1107        /// Convert packed single-precision floating-point values to packed double-precision floating-point values
1108        cvtps2,
1109        /// Convert scalar double-precision floating-point value to doubleword integer
1110        cvtsd2si,
1111        /// Convert scalar double-precision floating-point value to scalar single-precision floating-point value
1112        cvtsd2,
1113        /// Convert scalar single-precision floating-point value to scalar double-precision floating-point value
1114        cvtss2,
1115        /// Convert with truncation packed double-precision floating-point values to packed doubleword integers
1116        cvttpd2dq,
1117        /// Convert with truncation packed double-precision floating-point values to packed doubleword integers
1118        cvttpd2pi,
1119        /// Convert with truncation packed single-precision floating-point values to packed doubleword integers
1120        cvttps2dq,
1121        /// Convert with truncation scalar double-precision floating-point value to doubleword integer
1122        cvttsd2si,
1123        /// Galois field affine transformation inverse
1124        gf2p8affineinvq,
1125        /// Galois field affine transformation
1126        gf2p8affineq,
1127        /// Galois field multiply bytes
1128        gf2p8mul,
1129        /// Shuffle packed high words
1130        shufh,
1131        /// Shuffle packed low words
1132        shufl,
1133        /// Unpack high data
1134        unpckhqdq,
1135        /// Unpack low data
1136        unpcklqdq,
1137
1138        // SSE3
1139        /// Packed single-precision floating-point add/subtract
1140        /// Packed double-precision floating-point add/subtract
1141        addsub,
1142        /// Replicate double floating-point values
1143        movddup,
1144        /// Replicate single floating-point values
1145        movshdup,
1146        /// Replicate single floating-point values
1147        movsldup,
1148
1149        // SSSE3
1150        /// Packed align right
1151        alignr,
1152        /// Packed multiply high with round and scale
1153        mulhrs,
1154        /// Packed sign
1155        sign,
1156
1157        // SSE4.1
1158        /// Pack with unsigned saturation
1159        ackusd,
1160        /// Blend packed single-precision floating-point values
1161        /// Blend scalar single-precision floating-point values
1162        /// Blend packed double-precision floating-point values
1163        /// Blend scalar double-precision floating-point values
1164        /// Blend packed dwords
1165        blend,
1166        /// Variable blend packed single-precision floating-point values
1167        /// Variable blend scalar single-precision floating-point values
1168        /// Variable blend packed double-precision floating-point values
1169        /// Variable blend scalar double-precision floating-point values
1170        blendv,
1171        /// Dot product of packed single-precision floating-point values
1172        /// Dot product of packed double-precision floating-point values
1173        dp,
1174        /// Extract packed floating-point values
1175        /// Extract packed integer values
1176        extract,
1177        /// Insert scalar single-precision floating-point value
1178        /// Insert packed floating-point values
1179        insert,
1180        /// Packed horizontal word minimum
1181        minposu,
1182        /// Packed move with sign extend
1183        movsxb,
1184        movsxd,
1185        movsxw,
1186        /// Packed move with zero extend
1187        movzxb,
1188        movzxd,
1189        movzxw,
1190        /// Round packed single-precision floating-point values
1191        /// Round scalar single-precision floating-point value
1192        /// Round packed double-precision floating-point values
1193        /// Round scalar double-precision floating-point value
1194        round,
1195
1196        // SSE4.2
1197        /// Accumulate CRC32 value
1198        crc32,
1199
1200        // AES
1201        /// Perform one round of an AES decryption flow
1202        /// Perform ten rounds of AES decryption flow with key locker using 128-bit key
1203        /// Perform ten rounds of AES decryption flow with key locker using 256-bit key
1204        /// Perform ten rounds of AES decryption flow with key locker on 8 blocks using 128-bit key
1205        /// Perform ten rounds of AES decryption flow with key locker on 8 blocks using 256-bit key
1206        aesdec,
1207        /// Perform last round of an AES decryption flow
1208        aesdeclast,
1209        /// Perform one round of an AES encryption flow
1210        /// Perform ten rounds of AES encryption flow with key locker using 128-bit key
1211        /// Perform ten rounds of AES encryption flow with key locker using 256-bit key
1212        /// Perform ten rounds of AES encryption flow with key locker on 8 blocks using 128-bit key
1213        /// Perform ten rounds of AES encryption flow with key locker on 8 blocks using 256-bit key
1214        aesenc,
1215        /// Perform last round of an AES encryption flow
1216        aesenclast,
1217        /// Perform the AES InvMixColumn transformation
1218        aesimc,
1219        /// AES round key generation assist
1220        aeskeygenassist,
1221
1222        // SHA
1223        /// Perform four rounds of SHA1 operation
1224        sha1rnds,
1225        /// Calculate SHA1 state variable E after four rounds
1226        sha1nexte,
1227        /// Perform an intermediate calculation for the next four SHA1 message dwords
1228        /// Perform a final calculation for the next four SHA1 message dwords
1229        sha1msg,
1230        /// Perform an intermediate calculation for the next four SHA256 message dwords
1231        /// Perform a final calculation for the next four SHA256 message dwords
1232        sha256msg,
1233        /// Perform two rounds of SHA256 operation
1234        sha256rnds,
1235
1236        // AVX
1237        /// Load with broadcast floating-point data
1238        /// Load integer and broadcast
1239        broadcast,
1240        /// Conditional SIMD packed loads and stores
1241        /// Condition SIMD integer packed loads and stores
1242        maskmov,
1243        /// Permute floating-point values
1244        /// Permute integer values
1245        perm2,
1246        /// Permute in-lane pairs of double-precision floating-point values
1247        /// Permute in-lane quadruples of single-precision floating-point values
1248        permil,
1249
1250        // BMI
1251        /// Bit field extract
1252        bextr,
1253        /// Extract lowest set isolated bit
1254        /// Get mask up to lowest set bit
1255        /// Reset lowest set bit
1256        bls,
1257        /// Count the number of trailing zero bits
1258        tzcnt,
1259
1260        // BMI2
1261        /// Zero high bits starting with specified bit position
1262        bzhi,
1263        /// Parallel bits deposit
1264        pdep,
1265        /// Parallel bits extract
1266        pext,
1267
1268        // F16C
1269        /// Convert 16-bit floating-point values to single-precision floating-point values
1270        cvtph2,
1271        /// Convert single-precision floating-point values to 16-bit floating-point values
1272        cvtps2ph,
1273
1274        // FMA
1275        /// Fused multiply-add of packed single-precision floating-point values
1276        /// Fused multiply-add of scalar single-precision floating-point values
1277        /// Fused multiply-add of packed double-precision floating-point values
1278        /// Fused multiply-add of scalar double-precision floating-point values
1279        fmadd132,
1280        /// Fused multiply-add of packed single-precision floating-point values
1281        /// Fused multiply-add of scalar single-precision floating-point values
1282        /// Fused multiply-add of packed double-precision floating-point values
1283        /// Fused multiply-add of scalar double-precision floating-point values
1284        fmadd213,
1285        /// Fused multiply-add of packed single-precision floating-point values
1286        /// Fused multiply-add of scalar single-precision floating-point values
1287        /// Fused multiply-add of packed double-precision floating-point values
1288        /// Fused multiply-add of scalar double-precision floating-point values
1289        fmadd231,
1290
1291        // AVX2
1292        /// Permute packed doubleword elements
1293        /// Permute packed qword elements
1294        /// Permute double-precision floating-point elements
1295        /// Permute single-precision floating-point elements
1296        perm,
1297        /// Variable bit shift left logical
1298        sllv,
1299        /// Variable bit shift right arithmetic
1300        srav,
1301        /// Variable bit shift right logical
1302        srlv,
1303
1304        // ADX
1305        /// Unsigned integer addition of two operands with overflow flag
1306        ado,
1307
1308        // AESKLE
1309        /// Encode 128-bit key with key locker
1310        /// Encode 256-bit key with key locker
1311        encodekey,
1312        /// Load internal wrapping key with key locker
1313        loadiwkey,
1314
1315        /// A pseudo instruction that requires special lowering.
1316        /// This should be the only tag in this enum that doesn't
1317        /// directly correspond to one or more instruction mnemonics.
1318        pseudo,
1319    };
1320
1321    pub const FixedTag = struct { Fixes, Tag };
1322
1323    pub const Ops = enum(u8) {
1324        /// No data associated with this instruction (only mnemonic is used).
1325        none,
1326        /// Single register operand.
1327        /// Uses `r` payload.
1328        r,
1329        /// Register, register operands.
1330        /// Uses `rr` payload.
1331        rr,
1332        /// Register, register, register operands.
1333        /// Uses `rrr` payload.
1334        rrr,
1335        /// Register, register, register, register operands.
1336        /// Uses `rrrr` payload.
1337        rrrr,
1338        /// Register, register, register, immediate (byte) operands.
1339        /// Uses `rrri` payload.
1340        rrri,
1341        /// Register, register, immediate (sign-extended) operands.
1342        /// Uses `rri`  payload.
1343        rri_s,
1344        /// Register, register, immediate (unsigned) operands.
1345        /// Uses `rri`  payload.
1346        rri_u,
1347        /// Register, immediate (sign-extended) operands.
1348        /// Uses `ri` payload.
1349        ri_s,
1350        /// Register, immediate (unsigned) operands.
1351        /// Uses `ri` payload.
1352        ri_u,
1353        /// Register, 64-bit unsigned immediate operands.
1354        /// Uses `ri` payload with `i` index of extra data of type `Imm64`.
1355        ri_64,
1356        /// Immediate (sign-extended) operand.
1357        /// Uses `i` payload.
1358        i_s,
1359        /// Immediate (unsigned) operand.
1360        /// Uses `i` payload.
1361        i_u,
1362        /// Immediate (word), immediate (byte) operands.
1363        /// Uses `ii` payload.
1364        ii,
1365        /// Immediate (byte), register operands.
1366        /// Uses `ri` payload.
1367        ir,
1368        /// Register, memory operands.
1369        /// Uses `rx` payload with extra data of type `Memory`.
1370        rm,
1371        /// Register, memory, register operands.
1372        /// Uses `rrx` payload with extra data of type `Memory`.
1373        rmr,
1374        /// Register, memory, immediate (word) operands.
1375        /// Uses `rix` payload with extra data of type `Memory`.
1376        rmi,
1377        /// Register, memory, immediate (signed) operands.
1378        /// Uses `rx` payload with extra data of type `Imm32` followed by `Memory`.
1379        rmi_s,
1380        /// Register, memory, immediate (unsigned) operands.
1381        /// Uses `rx` payload with extra data of type `Imm32` followed by `Memory`.
1382        rmi_u,
1383        /// Register, register, memory.
1384        /// Uses `rrix` payload with extra data of type `Memory`.
1385        rrm,
1386        /// Register, register, memory, register.
1387        /// Uses `rrrx` payload with extra data of type `Memory`.
1388        rrmr,
1389        /// Register, register, memory, immediate (byte) operands.
1390        /// Uses `rrix` payload with extra data of type `Memory`.
1391        rrmi,
1392        /// Single memory operand.
1393        /// Uses `x` payload with extra data of type `Memory`.
1394        m,
1395        /// Memory, immediate (sign-extend) operands.
1396        /// Uses `x` payload with extra data of type `Imm32` followed by `Memory`.
1397        mi_s,
1398        /// Memory, immediate (unsigned) operands.
1399        /// Uses `x` payload with extra data of type `Imm32` followed by `Memory`.
1400        mi_u,
1401        /// Memory, register operands.
1402        /// Uses `rx` payload with extra data of type `Memory`.
1403        mr,
1404        /// Memory, register, register operands.
1405        /// Uses `rrx` payload with extra data of type `Memory`.
1406        mrr,
1407        /// Memory, register, immediate (word) operands.
1408        /// Uses `rix` payload with extra data of type `Memory`.
1409        mri,
1410        /// References another Mir instruction directly.
1411        /// Uses `inst` payload.
1412        inst,
1413        /// References a nav.
1414        /// Uses `nav` payload.
1415        nav,
1416        /// References an uav.
1417        /// Uses `uav` payload.
1418        uav,
1419        /// References a lazy symbol.
1420        /// Uses `lazy_sym` payload.
1421        lazy_sym,
1422        /// References an external symbol.
1423        /// Uses `extern_func` payload.
1424        extern_func,
1425
1426        // Pseudo instructions:
1427
1428        /// Conditional move if zero flag set and parity flag not set
1429        /// Clobbers the source operand!
1430        /// Uses `rr` payload.
1431        pseudo_cmov_z_and_np_rr,
1432        /// Conditional move if zero flag not set or parity flag set
1433        /// Uses `rr` payload.
1434        pseudo_cmov_nz_or_p_rr,
1435        /// Conditional move if zero flag not set or parity flag set
1436        /// Uses `rx` payload.
1437        pseudo_cmov_nz_or_p_rm,
1438        /// Set byte if zero flag set and parity flag not set
1439        /// Requires a scratch register!
1440        /// Uses `rr` payload.
1441        pseudo_set_z_and_np_r,
1442        /// Set byte if zero flag set and parity flag not set
1443        /// Requires a scratch register!
1444        /// Uses `rx` payload.
1445        pseudo_set_z_and_np_m,
1446        /// Set byte if zero flag not set or parity flag set
1447        /// Requires a scratch register!
1448        /// Uses `rr` payload.
1449        pseudo_set_nz_or_p_r,
1450        /// Set byte if zero flag not set or parity flag set
1451        /// Requires a scratch register!
1452        /// Uses `rx` payload.
1453        pseudo_set_nz_or_p_m,
1454        /// Jump if zero flag set and parity flag not set
1455        /// Uses `inst` payload.
1456        pseudo_j_z_and_np_inst,
1457        /// Jump if zero flag not set or parity flag set
1458        /// Uses `inst` payload.
1459        pseudo_j_nz_or_p_inst,
1460
1461        /// Probe alignment
1462        /// Uses `ri` payload.
1463        pseudo_probe_align_ri_s,
1464        /// Probe adjust unrolled
1465        /// Uses `ri` payload.
1466        pseudo_probe_adjust_unrolled_ri_s,
1467        /// Probe adjust setup
1468        /// Uses `rri` payload.
1469        pseudo_probe_adjust_setup_rri_s,
1470        /// Probe adjust loop
1471        /// Uses `rr` payload.
1472        pseudo_probe_adjust_loop_rr,
1473
1474        /// Push registers
1475        /// Uses `reg_list` payload.
1476        pseudo_push_reg_list,
1477        /// Pop registers
1478        /// Uses `reg_list` payload.
1479        pseudo_pop_reg_list,
1480
1481        /// Define cfa rule as offset from register.
1482        /// Uses `ri` payload.
1483        pseudo_cfi_def_cfa_ri_s,
1484        /// Modify cfa rule register.
1485        /// Uses `r` payload.
1486        pseudo_cfi_def_cfa_register_r,
1487        /// Modify cfa rule offset.
1488        /// Uses `i` payload.
1489        pseudo_cfi_def_cfa_offset_i_s,
1490        /// Offset cfa rule offset.
1491        /// Uses `i` payload.
1492        pseudo_cfi_adjust_cfa_offset_i_s,
1493        /// Define register rule as stored at offset from cfa.
1494        /// Uses `ri` payload.
1495        pseudo_cfi_offset_ri_s,
1496        /// Define register rule as offset from cfa.
1497        /// Uses `ri` payload.
1498        pseudo_cfi_val_offset_ri_s,
1499        /// Define register rule as stored at offset from cfa rule register.
1500        /// Uses `ri` payload.
1501        pseudo_cfi_rel_offset_ri_s,
1502        /// Define register rule as register.
1503        /// Uses `rr` payload.
1504        pseudo_cfi_register_rr,
1505        /// Define register rule from initial.
1506        /// Uses `r` payload.
1507        pseudo_cfi_restore_r,
1508        /// Define register rule as undefined.
1509        /// Uses `r` payload.
1510        pseudo_cfi_undefined_r,
1511        /// Define register rule as itself.
1512        /// Uses `r` payload.
1513        pseudo_cfi_same_value_r,
1514        /// Push cfi state.
1515        pseudo_cfi_remember_state_none,
1516        /// Pop cfi state.
1517        pseudo_cfi_restore_state_none,
1518        /// Raw cfi bytes.
1519        /// Uses `bytes` payload.
1520        pseudo_cfi_escape_bytes,
1521
1522        /// End of prologue
1523        /// Uses `none` payload.
1524        pseudo_dbg_prologue_end_none,
1525        /// Update debug line with is_stmt register set
1526        /// Uses `line_column` payload.
1527        pseudo_dbg_line_stmt_line_column,
1528        /// Update debug line with is_stmt register clear
1529        /// Uses `line_column` payload.
1530        pseudo_dbg_line_line_column,
1531        /// Start of epilogue
1532        /// Uses `none` payload.
1533        pseudo_dbg_epilogue_begin_none,
1534        /// Start of lexical block
1535        /// Uses `none` payload.
1536        pseudo_dbg_enter_block_none,
1537        /// End of lexical block
1538        /// Uses `none` payload.
1539        pseudo_dbg_leave_block_none,
1540        /// Start of inline function
1541        /// Uses `ip_index` payload.
1542        pseudo_dbg_enter_inline_func,
1543        /// End of inline function
1544        /// Uses `ip_index` payload.
1545        pseudo_dbg_leave_inline_func,
1546        /// Local argument.
1547        /// Uses `none` payload.
1548        pseudo_dbg_arg_none,
1549        /// Local argument.
1550        /// Uses `i` payload.
1551        pseudo_dbg_arg_i_s,
1552        /// Local argument.
1553        /// Uses `i` payload.
1554        pseudo_dbg_arg_i_u,
1555        /// Local argument.
1556        /// Uses `i64` payload.
1557        pseudo_dbg_arg_i_64,
1558        /// Local argument.
1559        /// Uses `ro` payload.
1560        pseudo_dbg_arg_ro,
1561        /// Local argument.
1562        /// Uses `fa` payload.
1563        pseudo_dbg_arg_fa,
1564        /// Local argument.
1565        /// Uses `x` payload with extra data of type `Memory`.
1566        pseudo_dbg_arg_m,
1567        /// Local argument.
1568        /// Uses `ip_index` payload.
1569        pseudo_dbg_arg_val,
1570        /// Remaining arguments are varargs.
1571        pseudo_dbg_var_args_none,
1572        /// Local variable.
1573        /// Uses `none` payload.
1574        pseudo_dbg_var_none,
1575        /// Local variable.
1576        /// Uses `i` payload.
1577        pseudo_dbg_var_i_s,
1578        /// Local variable.
1579        /// Uses `i` payload.
1580        pseudo_dbg_var_i_u,
1581        /// Local variable.
1582        /// Uses `i64` payload.
1583        pseudo_dbg_var_i_64,
1584        /// Local variable.
1585        /// Uses `ro` payload.
1586        pseudo_dbg_var_ro,
1587        /// Local variable.
1588        /// Uses `fa` payload.
1589        pseudo_dbg_var_fa,
1590        /// Local variable.
1591        /// Uses `x` payload with extra data of type `Memory`.
1592        pseudo_dbg_var_m,
1593        /// Local variable.
1594        /// Uses `ip_index` payload.
1595        pseudo_dbg_var_val,
1596
1597        /// Tombstone
1598        /// Emitter should skip this instruction.
1599        pseudo_dead_none,
1600    };
1601
1602    pub const Data = union {
1603        none: struct {
1604            fixes: Fixes = ._,
1605        },
1606        /// References another Mir instruction.
1607        inst: struct {
1608            fixes: Fixes = ._,
1609            inst: Index,
1610        },
1611        /// A 32-bit immediate value.
1612        i64: u64,
1613        i: struct {
1614            fixes: Fixes = ._,
1615            i: u32,
1616        },
1617        ii: struct {
1618            fixes: Fixes = ._,
1619            i1: u16,
1620            i2: u8,
1621        },
1622        r: struct {
1623            fixes: Fixes = ._,
1624            r1: Register,
1625        },
1626        rr: struct {
1627            fixes: Fixes = ._,
1628            r1: Register,
1629            r2: Register,
1630        },
1631        rrr: struct {
1632            fixes: Fixes = ._,
1633            r1: Register,
1634            r2: Register,
1635            r3: Register,
1636        },
1637        rrrr: struct {
1638            fixes: Fixes = ._,
1639            r1: Register,
1640            r2: Register,
1641            r3: Register,
1642            r4: Register,
1643        },
1644        rrri: struct {
1645            fixes: Fixes = ._,
1646            r1: Register,
1647            r2: Register,
1648            r3: Register,
1649            i: u8,
1650        },
1651        rri: struct {
1652            fixes: Fixes = ._,
1653            r1: Register,
1654            r2: Register,
1655            i: u32,
1656        },
1657        /// Register, immediate.
1658        ri: struct {
1659            fixes: Fixes = ._,
1660            r1: Register,
1661            i: u32,
1662        },
1663        /// Register, followed by custom payload found in extra.
1664        rx: struct {
1665            fixes: Fixes = ._,
1666            r1: Register,
1667            payload: u32,
1668        },
1669        /// Register, register, followed by Custom payload found in extra.
1670        rrx: struct {
1671            fixes: Fixes = ._,
1672            r1: Register,
1673            r2: Register,
1674            payload: u32,
1675        },
1676        /// Register, register, register, followed by Custom payload found in extra.
1677        rrrx: struct {
1678            fixes: Fixes = ._,
1679            r1: Register,
1680            r2: Register,
1681            r3: Register,
1682            payload: u32,
1683        },
1684        /// Register, byte immediate, followed by Custom payload found in extra.
1685        rix: struct {
1686            fixes: Fixes = ._,
1687            r1: Register,
1688            i: u16,
1689            payload: u32,
1690        },
1691        /// Register, register, byte immediate, followed by Custom payload found in extra.
1692        rrix: struct {
1693            fixes: Fixes = ._,
1694            r1: Register,
1695            r2: Register,
1696            i: u8,
1697            payload: u32,
1698        },
1699        /// Custom payload found in extra.
1700        x: struct {
1701            fixes: Fixes = ._,
1702            payload: u32,
1703        },
1704        bytes: struct {
1705            payload: u32,
1706            len: u32,
1707
1708            pub fn get(bytes: @This(), mir: Mir) []const u8 {
1709                return std.mem.sliceAsBytes(mir.extra[bytes.payload..])[0..bytes.len];
1710            }
1711        },
1712        fa: bits.FrameAddr,
1713        ro: bits.RegisterOffset,
1714        nav: bits.NavOffset,
1715        uav: InternPool.Key.Ptr.BaseAddr.Uav,
1716        lazy_sym: link.File.LazySymbol,
1717        extern_func: Mir.NullTerminatedString,
1718        /// Debug line and column position
1719        line_column: struct {
1720            line: u32,
1721            column: u32,
1722        },
1723        ip_index: InternPool.Index,
1724        /// Register list
1725        reg_list: RegisterList,
1726    };
1727
1728    comptime {
1729        if (!std.debug.runtime_safety) {
1730            // Make sure we don't accidentally make instructions bigger than expected.
1731            // Note that in safety builds, Zig is allowed to insert a secret field for safety checks.
1732            assert(@sizeOf(Data) == 8);
1733        }
1734        const Mnemonic = @import("Encoding.zig").Mnemonic;
1735        if (@typeInfo(Mnemonic).@"enum".fields.len != 978 or
1736            @typeInfo(Fixes).@"enum".fields.len != 231 or
1737            @typeInfo(Tag).@"enum".fields.len != 251)
1738        {
1739            const cond_src = (struct {
1740                fn src() std.builtin.SourceLocation {
1741                    return @src();
1742                }
1743            }).src();
1744            @setEvalBranchQuota(2_000_000);
1745            for (@typeInfo(Mnemonic).@"enum".fields) |mnemonic| {
1746                if (mnemonic.name[0] == '.') continue;
1747                for (@typeInfo(Fixes).@"enum".fields) |fixes| {
1748                    const pattern = fixes.name[if (std.mem.indexOfScalar(u8, fixes.name, ' ')) |index| index + " ".len else 0..];
1749                    const wildcard_index = std.mem.indexOfScalar(u8, pattern, '_').?;
1750                    const mnem_prefix = pattern[0..wildcard_index];
1751                    const mnem_suffix = pattern[wildcard_index + "_".len ..];
1752                    if (!std.mem.startsWith(u8, mnemonic.name, mnem_prefix)) continue;
1753                    if (!std.mem.endsWith(u8, mnemonic.name, mnem_suffix)) continue;
1754                    if (@hasField(
1755                        Tag,
1756                        mnemonic.name[mnem_prefix.len .. mnemonic.name.len - mnem_suffix.len],
1757                    )) break;
1758                } else @compileError("'" ++ mnemonic.name ++ "' is not encodable in Mir");
1759            }
1760            @compileError(std.fmt.comptimePrint(
1761                \\All mnemonics are encodable in Mir! You may now change the condition at {s}:{d} to:
1762                \\if (@typeInfo(Mnemonic).@"enum".fields.len != {d} or
1763                \\    @typeInfo(Fixes).@"enum".fields.len != {d} or
1764                \\    @typeInfo(Tag).@"enum".fields.len != {d})
1765            , .{
1766                cond_src.file,
1767                cond_src.line - 6,
1768                @typeInfo(Mnemonic).@"enum".fields.len,
1769                @typeInfo(Fixes).@"enum".fields.len,
1770                @typeInfo(Tag).@"enum".fields.len,
1771            }));
1772        }
1773    }
1774};
1775
1776/// Used in conjunction with payload to transfer a list of used registers in a compact manner.
1777pub const RegisterList = struct {
1778    bitset: BitSet,
1779
1780    const BitSet = std.bit_set.IntegerBitSet(32);
1781    const Self = @This();
1782
1783    pub const empty: RegisterList = .{ .bitset = .initEmpty() };
1784
1785    fn getIndexForReg(registers: []const Register, reg: Register) BitSet.MaskInt {
1786        for (registers, 0..) |cpreg, i| {
1787            if (reg.id() == cpreg.id()) return @intCast(i);
1788        }
1789        unreachable; // register not in input register list!
1790    }
1791
1792    pub fn push(self: *Self, registers: []const Register, reg: Register) void {
1793        const index = getIndexForReg(registers, reg);
1794        self.bitset.set(index);
1795    }
1796
1797    pub fn isSet(self: Self, registers: []const Register, reg: Register) bool {
1798        const index = getIndexForReg(registers, reg);
1799        return self.bitset.isSet(index);
1800    }
1801
1802    pub fn iterator(self: Self, comptime options: std.bit_set.IteratorOptions) BitSet.Iterator(options) {
1803        return self.bitset.iterator(options);
1804    }
1805
1806    pub fn count(self: Self) i32 {
1807        return @intCast(self.bitset.count());
1808    }
1809
1810    pub fn size(self: Self, target: *const std.Target) i32 {
1811        return @intCast(self.bitset.count() * @as(u4, switch (target.cpu.arch) {
1812            else => unreachable,
1813            .x86 => 4,
1814            .x86_64 => 8,
1815        }));
1816    }
1817};
1818
1819pub const NullTerminatedString = enum(u32) {
1820    none = std.math.maxInt(u32),
1821    _,
1822
1823    pub fn toSlice(nts: NullTerminatedString, mir: *const Mir) ?[:0]const u8 {
1824        if (nts == .none) return null;
1825        const string_bytes = mir.string_bytes[@intFromEnum(nts)..];
1826        return string_bytes[0..std.mem.indexOfScalar(u8, string_bytes, 0).? :0];
1827    }
1828};
1829
1830pub const Local = struct {
1831    name: NullTerminatedString,
1832    type: InternPool.Index,
1833};
1834
1835pub const Imm32 = struct {
1836    imm: u32,
1837};
1838
1839pub const Imm64 = struct {
1840    msb: u32,
1841    lsb: u32,
1842
1843    pub fn encode(v: u64) Imm64 {
1844        return .{
1845            .msb = @truncate(v >> 32),
1846            .lsb = @truncate(v),
1847        };
1848    }
1849
1850    pub fn decode(imm: Imm64) u64 {
1851        var res: u64 = 0;
1852        res |= @as(u64, @intCast(imm.msb)) << 32;
1853        res |= @as(u64, @intCast(imm.lsb));
1854        return res;
1855    }
1856};
1857
1858pub const Memory = struct {
1859    info: Info,
1860    base: u32,
1861    off: u32,
1862    extra: u32,
1863
1864    pub const Info = packed struct(u32) {
1865        base: @typeInfo(bits.Memory.Base).@"union".tag_type.?,
1866        mod: @typeInfo(bits.Memory.Mod).@"union".tag_type.?,
1867        size: bits.Memory.Size,
1868        index: Register,
1869        scale: bits.Memory.Scale,
1870        _: u13 = undefined,
1871    };
1872
1873    pub fn encode(mem: bits.Memory) Memory {
1874        return .{
1875            .info = .{
1876                .base = mem.base,
1877                .mod = mem.mod,
1878                .size = switch (mem.mod) {
1879                    .rm => |rm| rm.size,
1880                    .off => undefined,
1881                },
1882                .index = switch (mem.mod) {
1883                    .rm => |rm| rm.index,
1884                    .off => undefined,
1885                },
1886                .scale = switch (mem.mod) {
1887                    .rm => |rm| rm.scale,
1888                    .off => undefined,
1889                },
1890            },
1891            .base = switch (mem.base) {
1892                .none, .table => undefined,
1893                .reg => |reg| @intFromEnum(reg),
1894                .frame => |frame_index| @intFromEnum(frame_index),
1895                .rip_inst => |inst_index| inst_index,
1896                .nav => |nav| @intFromEnum(nav),
1897                .uav => |uav| @intFromEnum(uav.val),
1898                .lazy_sym => |lazy_sym| @intFromEnum(lazy_sym.ty),
1899                .extern_func => |extern_func| @intFromEnum(extern_func),
1900            },
1901            .off = switch (mem.mod) {
1902                .rm => |rm| @bitCast(rm.disp),
1903                .off => |off| @truncate(off),
1904            },
1905            .extra = switch (mem.mod) {
1906                .rm => switch (mem.base) {
1907                    else => undefined,
1908                    .uav => |uav| @intFromEnum(uav.orig_ty),
1909                    .lazy_sym => |lazy_sym| @intFromEnum(lazy_sym.kind),
1910                },
1911                .off => switch (mem.base) {
1912                    .reg => @intCast(mem.mod.off >> 32),
1913                    else => unreachable,
1914                },
1915            },
1916        };
1917    }
1918
1919    pub fn decode(mem: Memory) encoder.Instruction.Memory {
1920        switch (mem.info.mod) {
1921            .rm => {
1922                if (mem.info.base == .reg and @as(Register, @enumFromInt(mem.base)) == .rip) {
1923                    assert(mem.info.index == .none and mem.info.scale == .@"1");
1924                    return encoder.Instruction.Memory.initRip(mem.info.size, @bitCast(mem.off));
1925                }
1926                return encoder.Instruction.Memory.initSib(mem.info.size, .{
1927                    .disp = @bitCast(mem.off),
1928                    .base = switch (mem.info.base) {
1929                        .none => .none,
1930                        .reg => .{ .reg = @enumFromInt(mem.base) },
1931                        .frame => .{ .frame = @enumFromInt(mem.base) },
1932                        .table => .table,
1933                        .rip_inst => .{ .rip_inst = mem.base },
1934                        .nav => .{ .nav = @enumFromInt(mem.base) },
1935                        .uav => .{ .uav = .{ .val = @enumFromInt(mem.base), .orig_ty = @enumFromInt(mem.extra) } },
1936                        .lazy_sym => .{ .lazy_sym = .{ .kind = @enumFromInt(mem.extra), .ty = @enumFromInt(mem.base) } },
1937                        .extern_func => .{ .extern_func = @enumFromInt(mem.base) },
1938                    },
1939                    .scale_index = switch (mem.info.index) {
1940                        .none => null,
1941                        else => |index| .{ .scale = switch (mem.info.scale) {
1942                            inline else => |scale| comptime std.fmt.parseInt(
1943                                u4,
1944                                @tagName(scale),
1945                                10,
1946                            ) catch unreachable,
1947                        }, .index = index },
1948                    },
1949                });
1950            },
1951            .off => {
1952                assert(mem.info.base == .reg);
1953                return encoder.Instruction.Memory.initMoffs(
1954                    @enumFromInt(mem.base),
1955                    @as(u64, mem.extra) << 32 | mem.off,
1956                );
1957            },
1958        }
1959    }
1960};
1961
1962pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
1963    mir.instructions.deinit(gpa);
1964    gpa.free(mir.extra);
1965    gpa.free(mir.string_bytes);
1966    gpa.free(mir.locals);
1967    gpa.free(mir.table);
1968    gpa.free(mir.memoized_encodings);
1969    mir.frame_locs.deinit(gpa);
1970    mir.* = undefined;
1971}
1972
1973pub fn emit(
1974    mir: Mir,
1975    lf: *link.File,
1976    pt: Zcu.PerThread,
1977    src_loc: Zcu.LazySrcLoc,
1978    func_index: InternPool.Index,
1979    atom_index: u32,
1980    w: *std.Io.Writer,
1981    debug_output: link.File.DebugInfoOutput,
1982) codegen.CodeGenError!void {
1983    const zcu = pt.zcu;
1984    const comp = zcu.comp;
1985    const gpa = comp.gpa;
1986    const func = zcu.funcInfo(func_index);
1987    const fn_info = zcu.typeToFunc(.fromInterned(func.ty)).?;
1988    const nav = func.owner_nav;
1989    const mod = zcu.navFileScope(nav).mod.?;
1990    var e: Emit = .{
1991        .lower = .{
1992            .target = &mod.resolved_target.result,
1993            .allocator = gpa,
1994            .mir = mir,
1995            .cc = fn_info.cc,
1996            .src_loc = src_loc,
1997        },
1998        .bin_file = lf,
1999        .pt = pt,
2000        .pic = mod.pic,
2001        .atom_index = atom_index,
2002        .debug_output = debug_output,
2003        .w = w,
2004
2005        .prev_di_loc = .{
2006            .line = func.lbrace_line,
2007            .column = func.lbrace_column,
2008            .is_stmt = switch (debug_output) {
2009                .dwarf => |dwarf| dwarf.dwarf.debug_line.header.default_is_stmt,
2010                .none => undefined,
2011            },
2012        },
2013        .prev_di_pc = 0,
2014
2015        .code_offset_mapping = .empty,
2016        .relocs = .empty,
2017        .table_relocs = .empty,
2018    };
2019    defer e.deinit();
2020    e.emitMir() catch |err| switch (err) {
2021        error.LowerFail, error.EmitFail => return zcu.codegenFailMsg(nav, e.lower.err_msg.?),
2022        error.InvalidInstruction, error.CannotEncode => return zcu.codegenFail(nav, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}),
2023        else => return zcu.codegenFail(nav, "emit MIR failed: {s}", .{@errorName(err)}),
2024    };
2025}
2026
2027pub fn emitLazy(
2028    mir: Mir,
2029    lf: *link.File,
2030    pt: Zcu.PerThread,
2031    src_loc: Zcu.LazySrcLoc,
2032    lazy_sym: link.File.LazySymbol,
2033    atom_index: u32,
2034    w: *std.Io.Writer,
2035    debug_output: link.File.DebugInfoOutput,
2036) codegen.CodeGenError!void {
2037    const zcu = pt.zcu;
2038    const comp = zcu.comp;
2039    const gpa = comp.gpa;
2040    const mod = comp.root_mod;
2041    var e: Emit = .{
2042        .lower = .{
2043            .target = &mod.resolved_target.result,
2044            .allocator = gpa,
2045            .mir = mir,
2046            .cc = .auto,
2047            .src_loc = src_loc,
2048        },
2049        .bin_file = lf,
2050        .pt = pt,
2051        .pic = mod.pic,
2052        .atom_index = atom_index,
2053        .debug_output = debug_output,
2054        .w = w,
2055
2056        .prev_di_loc = undefined,
2057        .prev_di_pc = undefined,
2058
2059        .code_offset_mapping = .empty,
2060        .relocs = .empty,
2061        .table_relocs = .empty,
2062    };
2063    defer e.deinit();
2064    e.emitMir() catch |err| switch (err) {
2065        error.LowerFail, error.EmitFail => return zcu.codegenFailTypeMsg(lazy_sym.ty, e.lower.err_msg.?),
2066        error.InvalidInstruction, error.CannotEncode => return zcu.codegenFailType(lazy_sym.ty, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}),
2067        else => return zcu.codegenFailType(lazy_sym.ty, "emit MIR failed: {s}", .{@errorName(err)}),
2068    };
2069}
2070
2071pub fn extraData(mir: Mir, comptime T: type, index: u32) struct { data: T, end: u32 } {
2072    const fields = std.meta.fields(T);
2073    var i: u32 = index;
2074    var result: T = undefined;
2075    inline for (fields) |field| {
2076        @field(result, field.name) = switch (field.type) {
2077            u32 => mir.extra[i],
2078            i32, Memory.Info => @bitCast(mir.extra[i]),
2079            bits.FrameIndex => @enumFromInt(mir.extra[i]),
2080            else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),
2081        };
2082        i += 1;
2083    }
2084    return .{
2085        .data = result,
2086        .end = i,
2087    };
2088}
2089
2090pub const FrameLoc = struct {
2091    base: Register,
2092    disp: i32,
2093};
2094
2095pub fn resolveFrameAddr(mir: Mir, frame_addr: bits.FrameAddr) bits.RegisterOffset {
2096    const frame_loc = mir.frame_locs.get(@intFromEnum(frame_addr.index));
2097    return .{ .reg = frame_loc.base, .off = frame_loc.disp + frame_addr.off };
2098}
2099
2100pub fn resolveMemoryExtra(mir: Mir, payload: u32) Memory {
2101    const mem = mir.extraData(Mir.Memory, payload).data;
2102    return switch (mem.info.base) {
2103        .none, .reg, .table, .rip_inst, .nav, .uav, .lazy_sym, .extern_func => mem,
2104        .frame => if (mir.frame_locs.len > 0) .{
2105            .info = .{
2106                .base = .reg,
2107                .mod = mem.info.mod,
2108                .size = mem.info.size,
2109                .index = mem.info.index,
2110                .scale = mem.info.scale,
2111            },
2112            .base = @intFromEnum(mir.frame_locs.items(.base)[mem.base]),
2113            .off = @bitCast(mir.frame_locs.items(.disp)[mem.base] + @as(i32, @bitCast(mem.off))),
2114            .extra = mem.extra,
2115        } else mem,
2116    };
2117}
2118
2119const assert = std.debug.assert;
2120const bits = @import("bits.zig");
2121const builtin = @import("builtin");
2122const encoder = @import("encoder.zig");
2123const std = @import("std");
2124
2125const InternPool = @import("../../InternPool.zig");
2126const Mir = @This();
2127const Register = bits.Register;
2128const Emit = @import("Emit.zig");
2129const codegen = @import("../../codegen.zig");
2130const link = @import("../../link.zig");
2131const Zcu = @import("../../Zcu.zig");