// Mirrors cmd/w6a/a.h and cmd/w6c/6.out.h. package main; // Registers + operand kinds must stay numerically aligned with the // 6.out.h C enum so that ww-cgen output (which reads them via // `D_AX(SB)` etc.) lands on the same integers when read by ww-w6a. def D_NONE: i32 = 0; def D_AX: i32 = 1; def D_CX: i32 = 2; def D_DX: i32 = 3; def D_BX: i32 = 4; def D_SP: i32 = 5; def D_BP: i32 = 6; def D_SI: i32 = 7; def D_DI: i32 = 8; def D_R8: i32 = 9; def D_R9: i32 = 10; def D_R10: i32 = 11; def D_R11: i32 = 12; def D_R12: i32 = 13; def D_R13: i32 = 14; def D_R14: i32 = 15; def D_R15: i32 = 16; def D_X0: i32 = 17; def D_X1: i32 = 18; def D_X2: i32 = 19; def D_X3: i32 = 20; def D_X4: i32 = 21; def D_X5: i32 = 22; def D_X6: i32 = 23; def D_X7: i32 = 24; def D_X8: i32 = 25; def D_X9: i32 = 26; def D_X10: i32 = 27; def D_X11: i32 = 28; def D_X12: i32 = 29; def D_X13: i32 = 30; def D_X14: i32 = 31; def D_X15: i32 = 32; def D_PSP: i32 = 33; def D_PFP: i32 = 34; def D_PSB: i32 = 35; def D_CONST: i32 = 36; def D_BRANCH: i32 = 37; def D_EXTERN: i32 = 38; def D_INDIR: i32 = 39; def A_NOP: i32 = 0; def A_TEXT: i32 = 1; def A_DATA: i32 = 2; def A_GLOBL: i32 = 3; def A_END: i32 = 4; def A_MOVQ: i32 = 5; def A_MOVL: i32 = 6; def A_MOVB: i32 = 7; def A_MOVZBQ: i32 = 8; def A_MOVSXD: i32 = 9; def A_MOVW: i32 = 62; def A_MOVZWQ: i32 = 63; def A_MOVSWQ: i32 = 64; def A_MOVSBQ: i32 = 65; def A_MOVSD: i32 = 10; def A_ADDSD: i32 = 11; def A_SUBSD: i32 = 12; def A_MULSD: i32 = 13; def A_DIVSD: i32 = 14; def A_UCOMISD: i32 = 15; def A_CVTTSD2SI: i32 = 16; def A_CVTSI2SD: i32 = 17; def A_MOVSS: i32 = 18; def A_ADDSS: i32 = 19; def A_SUBSS: i32 = 20; def A_MULSS: i32 = 21; def A_DIVSS: i32 = 22; def A_UCOMISS: i32 = 23; def A_CVTTSS2SI: i32 = 24; def A_CVTSI2SS: i32 = 25; def A_CVTSD2SS: i32 = 26; def A_CVTSS2SD: i32 = 27; def A_ADDQ: i32 = 28; def A_SUBQ: i32 = 29; def A_IMULQ: i32 = 30; def A_IDIVQ: i32 = 31; def A_DIVQ: i32 = 32; def A_NEGQ: i32 = 33; def A_NOTQ: i32 = 34; def A_ANDQ: i32 = 35; def A_ORQ: i32 = 36; def A_XORQ: i32 = 37; def A_SHLQ: i32 = 38; def A_SHRQ: i32 = 39; def A_CMPQ: i32 = 40; def A_PUSHQ: i32 = 41; def A_POPQ: i32 = 42; def A_LEAQ: i32 = 43; def A_CALL: i32 = 44; def A_RET: i32 = 45; def A_JMP: i32 = 46; def A_JE: i32 = 47; def A_JNE: i32 = 48; def A_JL: i32 = 49; def A_JLE: i32 = 50; def A_JG: i32 = 51; def A_JGE: i32 = 52; def A_JB: i32 = 53; def A_JBE: i32 = 54; def A_JA: i32 = 55; def A_JAE: i32 = 56; def A_JZ: i32 = 57; def A_JNZ: i32 = 58; // 67 (next free above A_CQO=66): appended so the existing A_MOV*/ // A_SYSCALL/A_DATAW/A_DATAR/A_CQO numbers stay put. Jump on // parity (PF=1): UCOMISD unordered (#97). def A_JP: i32 = 67; // #136: arithmetic right-shift, sign-extends MSB. SHR injects // zeros and is wrong for signed operands; cgen routes signed // `>>` / `>>=` through SAR after this opcode landed. def A_SARQ: i32 = 68; def A_SYSCALL: i32 = 59; // Writable data + reloc-only data. Mirror cmd/w6c/6.out.h. // A_DATAW: bytes land in .data (RW) instead of .text. // A_DATAR: record an R_X86_64_64 reloc at a .data slot, patched // to a target symbol's runtime VA at link time. def A_DATAW: i32 = 60; def A_DATAR: i32 = 61; // REX.W 99 — sign-extend RAX into RDX:RAX. Pairs with IDIVQ for // signed division; pendant to the MOVQ $0, DX zero-fill that pairs // with DIVQ. def A_CQO: i32 = 66; type aoperand = struct { atype: i32, // D_NONE / D_AX..D_R15 / D_CONST / D_INDIR / D_EXTERN / D_BRANCH reg: i32, offset: i64, asym: str, }; // `from` and `to` are pointer-to-aoperand (rather than embedded). // The C cgen doesn't support chained-dot through embedded value // fields, so allocating each operand once per prog lets us write // `p.to.atype` directly. type aprog = struct { as_: i32, from: *aoperand, to: *aoperand, line: i32, label: str, link: *aprog, bytes: *u8, // payload for A_DATA nbytes: u64, }; type asym = struct { name: str, defined: i32, istext: i32, isdata: i32, // mutually exclusive with istext; DATAW symbols isglobal: i32, hasreloc: i32, // referenced by a relocation — must be in the symtab addr: u64, // offset within its section (.text or .data) idx: i32, snext: *asym, }; type areloc = struct { off: u64, section: i32, // 0 = .text, 1 = .data kind: i32, asy: *asym, addend: i64, rnext: *areloc, }; type afixup = struct { off: u64, // where the rel32 lands in .text label: str, fnext: *afixup, }; type asm_ = struct { file: str, src: *u8, srclen: u64, pos: u64, line: i32, head: *aprog, tail: *aprog, text: *u8, textcap: u64, textlen: u64, // Writable .data. Empty unless any DATAW directive was seen; // obj.ww emits the extra section conditionally so .o output // stays byte-identical for inputs that don't use DATAW (test // 991 byte-diff invariant). data: *u8, datacap: u64, datalen: u64, syms: *asym, relocs: *areloc, fixups: *afixup, errs: i32, };