#[macro_export]
macro_rules! opcodes {
($mac:ident) => {
$mac! {
(0x00, Target, "TARGET", "Mark a valid jump destination.",
0, {}),
(0x01, Jump1, "JUMP1", "Unconditionally jump to a basic block by u8 label index (narrow form).",
0, {label: u8}),
(0x02, JumpI1, "JUMPI1", "Jump to a basic block by u8 label index if the top of the stack is non-zero (narrow form).",
-1_i8, {label: u8}),
(0x03, Jump2, "JUMP2", "Unconditionally jump to a basic block by u16 label index (wide form).",
0, {label: u16}),
(0x04, JumpI2, "JUMPI2", "Jump to a basic block by u16 label index if the top of the stack is non-zero (wide form).",
-1_i8, {label: u16}),
(0x05, Lidx, "LIDX", "Copy the current loop index (offset-adjusted) into a register.",
0, {reg: $crate::Register}),
(0x06, LVal, "LVAL", "Copy the current loop value into a register.",
0, {reg: $crate::Register}),
(0x07, Next, "NEXT", "Advance the loop index; jump back or exit the current loop.",
0, {}),
(0x08, Range, "RANGE", "Start a range loop over [start, start + count).",
-2_i8, {}),
(0x09, Iter, "ITER", "Start a vec iteration over a slice of a register's vec.",
-2_i8, {reg: $crate::Register}),
(0x0A, Load, "LOAD", "Push the value of an int register onto the stack.",
1, {reg: $crate::Register}),
(0x0B, Stow, "STOW", "Pop the top of the stack into an int register.",
-1_i8, {reg: $crate::Register}),
(0x0C, Drop, "DROP", "Reset a register to Int(0).",
0, {reg: $crate::Register}),
(0x0E, Input, "INPUT", "Pop a calldata slot index and load that slot into a register.",
-1_i8, {reg: $crate::Register}),
(0x0F, Output, "OUTPUT", "Pop an output slot index and write the register to it.",
-1_i8, {reg: $crate::Register}),
(0x10, Pop, "POP", "Discard the top of the stack.",
-1_i8, {}),
(0x11, Push1, "PUSH1", "Push a 1-byte big-endian signed constant, sign-extended to i64.",
1, {val: [u8; 1]}),
(0x12, Push2, "PUSH2", "Push a 2-byte big-endian signed constant, sign-extended to i64.",
1, {val: [u8; 2]}),
(0x13, Push3, "PUSH3", "Push a 3-byte big-endian signed constant, sign-extended to i64.",
1, {val: [u8; 3]}),
(0x14, Push4, "PUSH4", "Push a 4-byte big-endian signed constant, sign-extended to i64.",
1, {val: [u8; 4]}),
(0x15, Push5, "PUSH5", "Push a 5-byte big-endian signed constant, sign-extended to i64.",
1, {val: [u8; 5]}),
(0x16, Push6, "PUSH6", "Push a 6-byte big-endian signed constant, sign-extended to i64.",
1, {val: [u8; 6]}),
(0x17, Push7, "PUSH7", "Push a 7-byte big-endian signed constant, sign-extended to i64.",
1, {val: [u8; 7]}),
(0x18, Push8, "PUSH8", "Push a full 8-byte big-endian signed constant (i64).",
1, {val: [u8; 8]}),
(0x1A, Sclr, "SCLR", "Clear the entire value stack.",
i8::MIN, {}),
(0x1B, Swap, "SWAP", "Swap the top two stack elements.",
0, {}),
(0x1C, Copy, "COPY", "Duplicate the top of the stack.",
1, {}),
(0x20, Add, "ADD", "Pop b and a; push a + b.",
-1_i8, {}),
(0x21, Sub, "SUB", "Pop b and a; push a - b.",
-1_i8, {}),
(0x22, Mul, "MUL", "Pop b and a; push a * b.",
-1_i8, {}),
(0x23, Div, "DIV", "Pop b and a; push a / b (truncating integer division).",
-1_i8, {}),
(0x24, Modulo, "MOD", "Pop b and a; push a % b.",
-1_i8, {}),
(0x25, Sqr, "SQR", "Pop a; push a * a.",
0, {}),
(0x26, Abs, "ABS", "Pop a; push |a|.",
0, {}),
(0x27, Neg, "NEG", "Pop a; push -a.",
0, {}),
(0x28, Min, "MIN", "Pop b and a; push min(a, b).",
-1_i8, {}),
(0x29, Max, "MAX", "Pop b and a; push max(a, b).",
-1_i8, {}),
(0x2A, Inc, "INC", "Pop a; push a + 1.",
0, {}),
(0x2B, Dec, "DEC", "Pop a; push a - 1.",
0, {}),
(0x2C, BitLen, "BITLEN", "Pop a; push floor(log2(a))+1. If a <= 0, push 0.",
0, {}),
(0x30, Eq, "EQ", "Pop b and a; push 1 if a == b, else 0.",
-1_i8, {}),
(0x31, Lt, "LT", "Pop b and a; push 1 if a < b, else 0.",
-1_i8, {}),
(0x32, Gt, "GT", "Pop b and a; push 1 if a > b, else 0.",
-1_i8, {}),
(0x33, Lte, "LTE", "Pop b and a; push 1 if a <= b, else 0.",
-1_i8, {}),
(0x34, Gte, "GTE", "Pop b and a; push 1 if a >= b, else 0.",
-1_i8, {}),
(0x36, Not, "NOT", "Pop a; push 1 if a == 0, else 0.",
0, {}),
(0x37, And, "AND", "Pop b and a; push 1 if both are non-zero, else 0.",
-1_i8, {}),
(0x38, Or, "OR", "Pop b and a; push 1 if either is non-zero, else 0.",
-1_i8, {}),
(0x39, Xor, "XOR", "Pop b and a; push 1 if exactly one is non-zero, else 0.",
-1_i8, {}),
(0x3A, BAnd, "BAND", "Pop b and a; push a & b.",
-1_i8, {}),
(0x3B, BOr, "BOR", "Pop b and a; push a | b.",
-1_i8, {}),
(0x3C, BXor, "BXOR", "Pop b and a; push a ^ b.",
-1_i8, {}),
(0x3D, BNot, "BNOT", "Pop a; push ~a.",
0, {}),
(0x3E, Shl, "SHL", "Pop b and a; push a << b.",
-1_i8, {}),
(0x3F, Shr, "SHR", "Pop b and a; push a >> b (arithmetic right shift, sign-preserving).",
-1_i8, {}),
(0x40, Bqmx, "BQMX", "Pop size; allocate a binary QUBO model ([0, 1] domain) into a register.",
-1_i8, {reg: $crate::Register}),
(0x41, Sqmx, "SQMX", "Pop size; allocate a spin Ising model ([-1, 1] domain) into a register.",
-1_i8, {reg: $crate::Register}),
(0x42, Xqmx, "XQMX", "Pop k then size; allocate a discrete model with signed centered domain [-k, k-1] into a register. Errors when k < 2.",
-2_i8, {reg: $crate::Register}),
(0x43, Bsmx, "BSMX", "Pop size; allocate a binary sample ([0, 1] domain) into a register.",
-1_i8, {reg: $crate::Register}),
(0x44, Ssmx, "SSMX", "Pop size; allocate a spin sample ([-1, 1] domain) into a register.",
-1_i8, {reg: $crate::Register}),
(0x45, Xsmx, "XSMX", "Pop k then size; allocate a discrete sample with signed centered domain [-k, k-1] into a register. Errors when k < 2.",
-2_i8, {reg: $crate::Register}),
(0x4A, Vec, "VEC", "Create an empty vec (element type inferred on first push) in a register.",
0, {reg: $crate::Register}),
(0x4B, VecI, "VECI", "Create an empty `vec<int>` in a register.",
0, {reg: $crate::Register}),
(0x4C, VecX, "VECX", "Create an empty `vec<xqmx>` in a register.",
0, {reg: $crate::Register}),
(0x50, VecPush, "VECPUSH", "Pop a value; append it to the register's vec.",
-1_i8, {reg: $crate::Register}),
(0x51, VecGet, "VECGET", "Pop index; push `vec[index]` from the register's vec.",
0, {reg: $crate::Register}),
(0x52, VecSet, "VECSET", "Pop value and index; set `vec[index]` in the register's vec.",
-2_i8, {reg: $crate::Register}),
(0x53, VecLen, "VECLEN", "Push the length of the register's vec onto the stack.",
1, {reg: $crate::Register}),
(0x54, Slack, "SLACK", "Pop capacity and `start_index`; append slack variable indices and power-of-two coefficients to two register vecs.",
-2_i8, {indices: $crate::Register, coeffs: $crate::Register}),
(0x5A, IdxGrid, "IDXGRID", "Pop cols, col, row; push the flat grid index row * cols + col.",
-2_i8, {}),
(0x5B, IdxTriu, "IDXTRIU", "Pop j and i (i <= j); push the upper-triangular index for (i, j).",
-1_i8, {}),
(0x60, GetLine, "GETLINE", "Pop i; push `linear[i]` from the register's model (0 if absent).",
0, {reg: $crate::Register}),
(0x61, SetLine, "SETLINE", "Pop value and i; set `linear[i]` in the register's model.",
-2_i8, {reg: $crate::Register}),
(0x62, AddLine, "ADDLINE", "Pop delta and i; add delta to `linear[i]` in the register's model.",
-2_i8, {reg: $crate::Register}),
(0x63, GetQuad, "GETQUAD", "Pop j and i; push `quadratic[i, j]` from the register's model (0 if absent).",
-1_i8, {reg: $crate::Register}),
(0x64, SetQuad, "SETQUAD", "Pop value, j, and i; set `quadratic[i, j]` in the register's model.",
-3_i8, {reg: $crate::Register}),
(0x65, AddQuad, "ADDQUAD", "Pop delta, j, and i; add delta to `quadratic[i, j]` in the register's model.",
-3_i8, {reg: $crate::Register}),
(0x66, Resize, "RESIZE", "Pop cols and rows; set the grid dimensions of the register's model.",
-2_i8, {reg: $crate::Register}),
(0x67, RowFind, "ROWFIND", "Pop value and row; push the first column where the value matches, or -1.",
-1_i8, {reg: $crate::Register}),
(0x68, ColFind, "COLFIND", "Pop value and col; push the first row where the value matches, or -1.",
-1_i8, {reg: $crate::Register}),
(0x69, RowSum, "ROWSUM", "Pop row; push the sum of all linear values in that grid row.",
0, {reg: $crate::Register}),
(0x6A, ColSum, "COLSUM", "Pop col; push the sum of all linear values in that grid column.",
0, {reg: $crate::Register}),
(0x70, OneHotR, "ONEHOTR", "Pop penalty and row; add a one-hot constraint over the grid row.",
-2_i8, {reg: $crate::Register}),
(0x71, OneHotC, "ONEHOTC", "Pop penalty and col; add a one-hot constraint over the grid column.",
-2_i8, {reg: $crate::Register}),
(0x72, Exclude, "EXCLUDE", "Pop penalty, j, and i; add a mutual-exclusion constraint between variables i and j.",
-3_i8, {reg: $crate::Register}),
(0x73, Implies, "IMPLIES", "Pop penalty, j, and i; add an implication constraint from variable i to variable j.",
-3_i8, {reg: $crate::Register}),
(0x74, Equality, "EQUALITY", "Pop penalty and target; expand weighted equality constraint into QUBO terms on a model.",
-2_i8, {model: $crate::Register, indices: $crate::Register, coeffs: $crate::Register}),
(0x75, AtLeast, "ATLEAST", "Pop penalty and k; allocate slack variables and apply at-least-k constraint.",
-2_i8, {model: $crate::Register, indices: $crate::Register}),
(0x76, AtLeastW, "ATLEASTW", "Pop penalty and k; allocate slack variables and apply weighted at-least-k constraint.",
-2_i8, {model: $crate::Register, indices: $crate::Register, coeffs: $crate::Register}),
(0x77, Reduce, "REDUCE", "Pop `P_aux`, `var_b`, `var_a`; allocate auxiliary variable and add Rosenberg enforcement terms; push aux index.",
-2_i8, {model: $crate::Register}),
(0x7F, Energy, "ENERGY", "Compute the Hamiltonian energy of a sample against a model; push the result.",
1, {model: $crate::Register, sample: $crate::Register}),
(0xF0, Nop, "NOP", "No operation.",
0, {}),
(0xFF, Halt, "HALT", "Stop execution.",
0, {}),
}
};
}