|
| 1 | +# Copyright (c) Microsoft Corporation. |
| 2 | +# Licensed under the MIT License. |
| 3 | + |
| 4 | +"""Shared opcode constants for the Adaptive Profile QIR bytecode interpreter. |
| 5 | +
|
| 6 | +These constants define the bytecode encoding used by the Python AdaptiveProfilePass |
| 7 | +(emitter) and the Rust GPU receiver. Values must stay in sync with the Rust |
| 8 | +``bytecode.rs`` module and the WGSL interpreter. |
| 9 | +
|
| 10 | +Opcode word layout:: |
| 11 | +
|
| 12 | + bits [7:0] = primary opcode |
| 13 | + bits [15:8] = sub-opcode / condition code |
| 14 | + bits [23:16] = flags |
| 15 | +
|
| 16 | +Compose via bitwise OR: ``opcode | (sub << 8) | flag`` |
| 17 | +Example: ``OP_ICMP | (ICMP_SLE << 8) | FLAG_SRC1_IMM`` |
| 18 | +""" |
| 19 | + |
| 20 | +# ── Flags (pre-shifted to bit 16+) ────────────────────────────────────────── |
| 21 | +FLAG_DST_IMM = 1 << 18 # dst field is an immediate value, not a register |
| 22 | +FLAG_SRC0_IMM = 1 << 16 # src0 field is an immediate value, not a register |
| 23 | +FLAG_SRC1_IMM = 1 << 17 # src1 field is an immediate value, not a register |
| 24 | +FLAG_AUX0_IMM = 1 << 19 # aux0 field is an immediate value, not a register |
| 25 | +FLAG_AUX1_IMM = 1 << 20 # aux1 field is an immediate value, not a register |
| 26 | +FLAG_AUX2_IMM = 1 << 21 # aux2 field is an immediate value, not a register |
| 27 | +FLAG_AUX3_IMM = 1 << 22 # aux3 field is an immediate value, not a register |
| 28 | + |
| 29 | +FLAG_FLOAT = 1 << 23 # operation uses float semantics |
| 30 | + |
| 31 | + |
| 32 | +# ── Control Flow ───────────────────────────────────────────────────────────── |
| 33 | +OP_NOP = 0x00 |
| 34 | +OP_RET = 0x02 |
| 35 | +OP_JUMP = 0x04 |
| 36 | +OP_BRANCH = 0x05 |
| 37 | +OP_SWITCH = 0x06 |
| 38 | +OP_CALL = 0x07 |
| 39 | +OP_CALL_RETURN = 0x08 |
| 40 | + |
| 41 | +# ── Quantum ────────────────────────────────────────────────────────────────── |
| 42 | +OP_QUANTUM_GATE = 0x10 |
| 43 | +OP_MEASURE = 0x11 |
| 44 | +OP_RESET = 0x12 |
| 45 | +OP_READ_RESULT = 0x13 |
| 46 | +OP_RECORD_OUTPUT = 0x14 |
| 47 | + |
| 48 | +# ── Integer Arithmetic ─────────────────────────────────────────────────────── |
| 49 | +OP_ADD = 0x20 |
| 50 | +OP_SUB = 0x21 |
| 51 | +OP_MUL = 0x22 |
| 52 | +OP_UDIV = 0x23 |
| 53 | +OP_SDIV = 0x24 |
| 54 | +OP_UREM = 0x25 |
| 55 | +OP_SREM = 0x26 |
| 56 | + |
| 57 | +# ── Bitwise / Shift ───────────────────────────────────────────────────────── |
| 58 | +OP_AND = 0x28 |
| 59 | +OP_OR = 0x29 |
| 60 | +OP_XOR = 0x2A |
| 61 | +OP_SHL = 0x2B |
| 62 | +OP_LSHR = 0x2C |
| 63 | +OP_ASHR = 0x2D |
| 64 | + |
| 65 | +# ── Comparison ─────────────────────────────────────────────────────────────── |
| 66 | +OP_ICMP = 0x30 |
| 67 | +OP_FCMP = 0x31 |
| 68 | + |
| 69 | +# ── Float Arithmetic ───────────────────────────────────────────────────────── |
| 70 | +OP_FADD = 0x38 |
| 71 | +OP_FSUB = 0x39 |
| 72 | +OP_FMUL = 0x3A |
| 73 | +OP_FDIV = 0x3B |
| 74 | + |
| 75 | +# ── Type Conversion ────────────────────────────────────────────────────────── |
| 76 | +OP_ZEXT = 0x40 |
| 77 | +OP_SEXT = 0x41 |
| 78 | +OP_TRUNC = 0x42 |
| 79 | +OP_FPEXT = 0x43 |
| 80 | +OP_FPTRUNC = 0x44 |
| 81 | +OP_INTTOPTR = 0x45 |
| 82 | +OP_FPTOSI = 0x46 |
| 83 | +OP_SITOFP = 0x47 |
| 84 | + |
| 85 | +# ── SSA / Data Movement ───────────────────────────────────────────────────── |
| 86 | +OP_PHI = 0x50 |
| 87 | +OP_SELECT = 0x51 |
| 88 | +OP_MOV = 0x52 |
| 89 | +OP_CONST = 0x53 |
| 90 | + |
| 91 | +# ── ICmp condition codes (sub-opcode, placed in bits[15:8] via << 8) ───────── |
| 92 | +# Reference: https://llvm.org/docs/LangRef.html#icmp-instruction |
| 93 | +ICMP_EQ = 0 |
| 94 | +ICMP_NE = 1 |
| 95 | +ICMP_SLT = 2 |
| 96 | +ICMP_SLE = 3 |
| 97 | +ICMP_SGT = 4 |
| 98 | +ICMP_SGE = 5 |
| 99 | +ICMP_ULT = 6 |
| 100 | +ICMP_ULE = 7 |
| 101 | +ICMP_UGT = 8 |
| 102 | +ICMP_UGE = 9 |
| 103 | + |
| 104 | +# ── FCmp condition codes ───────────────────────────────────────────────────── |
| 105 | +# Reference: https://llvm.org/docs/LangRef.html#fcmp-instruction |
| 106 | +FCMP_FALSE = 0 |
| 107 | +FCMP_OEQ = 1 |
| 108 | +FCMP_OGT = 2 |
| 109 | +FCMP_OGE = 3 |
| 110 | +FCMP_OLT = 4 |
| 111 | +FCMP_OLE = 5 |
| 112 | +FCMP_ONE = 6 |
| 113 | +FCMP_ORD = 7 |
| 114 | +FCMP_UNO = 8 |
| 115 | +FCMP_UEQ = 9 |
| 116 | +FCMP_UGT = 10 |
| 117 | +FCMP_UGE = 11 |
| 118 | +FCMP_ULT = 12 |
| 119 | +FCMP_ULE = 13 |
| 120 | +FCMP_UNE = 14 |
| 121 | +FCMP_TRUE = 15 |
| 122 | + |
| 123 | +# ── Register type tags ─────────────────────────────────────────────────────── |
| 124 | +REG_TYPE_BOOL = 0 |
| 125 | +REG_TYPE_I32 = 1 |
| 126 | +REG_TYPE_I64 = 2 |
| 127 | +REG_TYPE_F32 = 3 |
| 128 | +REG_TYPE_F64 = 4 |
| 129 | +REG_TYPE_PTR = 5 |
| 130 | + |
| 131 | +# ── Sentinel values ────────────────────────────────────────────────────────── |
| 132 | +VOID_RETURN = 0xFFFFFFFF # Function does not have a return value. |
0 commit comments