/* Plan 9 cmd/6c/gc.h shape, trimmed. */ #ifndef SIX_GC_H #define SIX_GC_H #include "ww.h" #include "6.out.h" typedef struct Prog Prog; typedef struct Adr Adr; /* one operand: register, immediate, indirect, or symbolic. */ struct Adr { int type; /* D_AX, D_CONST, D_INDIR, ... */ int reg; /* base register for D_INDIR */ long long offset; /* immediate value or memory displacement */ const char *sym; /* symbol name for D_EXTERN/D_BRANCH */ }; struct Prog { int as; /* opcode (A_MOVQ, ...) */ Adr from; /* source operand */ Adr to; /* destination operand (Plan 9 order) */ int line; const char *label; /* if non-NULL, this prog is preceded by label: */ Prog *link; }; /* per-fn codegen state */ typedef struct Cg Cg; struct Cg { Arena *a; Prog *head, *tail; const char *fnname; const char *cur_mod; /* current fn's `// MODULE: foo` directive, * NULL when the fn lives in the primary * file (no MODULE: stamp). Drives bare-IDENT * call mangling — `frob()` from within * lib/foo binds to `foo.frob` regardless * of which other modules also export `frob`. * Set by cgfn before walking the body. */ int cur_source; /* lexical source-file scope of the current * declaration; selects its own import bindings. */ int framesize; /* bytes of locals; 16-byte aligned */ int curoff; /* current top of locals */ Scope *locals; /* (name → offset) tracked via Sym */ int labelseq; int sep_mode; /* #22 M3 `-c`: separate-compile / primary-only * codegen. Emit code+DATA ONLY for this * package's own (imported==0) decls; treat every * `.wwi`-sourced (imported==1) dep decl as an * external — body-less fns already skip, value * globals/defs are gated so they don't duplicate * the dep's real definition (link collision). * Off on the combined path (every existing * invocation) so M3 is a pure addition. */ int sep_isdep; /* #99: this unit is a sep DEPENDENCY, not the * root/link-entry unit. The compiler's explicit * --entry flag clears this independently of -I: * every package action may emit export data. Gates * the bare-`main` carve-out: a dep's `fn main` must * mangle on its path like any decl; only the root * entry stays bare. */ }; /* cgen.c */ void cg_init(Cg*, Arena*); void cg_file(Cg*, FILE *out, Node *file); Prog *newprog(Cg*, int op); void emit(Cg*, Prog*); /* txt.c */ void txt_emit(FILE*, Prog *head); /* wwi.c — non-zero return: check_exported_type rejected a dangling export. */ int wwi_emit(Checker *c, FILE *of, Node *file); #endif