pub const FILE = @import("std").c.FILE; pub const bits = u64; pub const Target = extern struct { name: [16:0]u8, apple: u8, /// First general-purpose register. gpr0: c_int, ngpr: c_int, /// First floating-point register. fpr0: c_int, nfpr: c_int, /// Globally live registers, e.g. sp, fp. rglob: bits, nrglob: c_int, /// Caller-save. rsave: [*c]c_int, nrsave: [2]c_int, retregs: *const fn (Ref, [*c]c_int) callconv(.C) bits, argregs: *const fn (Ref, [*c]c_int) callconv(.C) bits, memargs: *const fn (c_int) callconv(.C) c_int, abi0: *const fn (?*Fn) callconv(.C) void, abi1: *const fn (?*Fn) callconv(.C) void, isel: *const fn (?*Fn) callconv(.C) void, emitfn: *const fn (?*Fn, *FILE) callconv(.C) void, emitfin: *const fn (*FILE) callconv(.C) void, asloc: [4]u8, assym: [4]u8, }; pub const BSet = extern struct { nt: c_uint, t: [*c]bits, }; pub const Ref = extern struct { // type: u3, // val: u29, ref: u32, }; pub const Ins = extern struct { // op: u30, // cls: u2, op: u32, to: Ref, arg: [2]Ref, }; pub const Phi = extern struct { to: Ref, arg: ?*Ref, blk: [*c]?*Blk, narg: c_uint, cls: c_int, link: ?*Phi, }; pub const Blk = extern struct { phi: ?*Phi, ins: ?*Ins, nins: c_uint, jmp: extern struct { type: c_short, arg: Ref, }, s1: ?*Blk, s2: ?*Blk, link: ?*Blk, id: c_uint, visit: c_uint, idom: ?*Blk, dom: ?*Blk, dlink: ?*Blk, fron: [*c]?*Blk, nfron: c_uint, pred: [*c]?*Blk, npred: c_uint, in: [1]BSet, out: [1]BSet, gen: [1]BSet, nlive: [2]c_int, loop: c_int, name: [80]u8, }; pub const Use = extern struct { type: enum(c_uint) { UXXX, UPhi, UIns, UJmp }, bid: c_uint, u: extern union { ins: ?*Ins, phi: ?*Phi, }, }; pub const Sym = extern struct { type: enum (c_uint) { SGlo, SThr }, id: u32, }; pub const Alias = extern struct { type: enum (c_uint) { ABot = 0, ALoc = 1, // stack local ACon = 2, AEsc = 3, // stack escaping ASym = 4, AUnk = 6, }, base: c_int, offset: i64, u: extern union { sym: Sym, loc: extern struct { sz: c_int, m: bits, }, }, slot: [*c]Alias, }; pub const Tmp = extern struct { name: [80]u8, def: ?*Ins, use: [*c]Use, ndef: c_uint, nuse: c_uint, bid: c_uint, cost: c_uint, slot: c_int, cls: c_short, hint: extern struct { r: c_int, w: c_int, m: bits, }, phi: c_int, alias: Alias, width: c_uint, visit: c_int, }; pub const Con = extern struct { type: enum (c_uint) { CUndef, CBits, CAddr }, sym: Sym, bits: extern union { i: i64, d: f64, s: f32, }, flt: u8, }; pub const Addr = extern struct { offset: Con, base: Ref, index: Ref, scale: c_int, }; pub const Mem = Addr; pub const Lnk = extern struct { @"export": u8, thread: u8, @"align": u8, sec: [*c]u8, secf: [*c]u8, }; pub const Fn = extern struct { start: ?*Blk, tmp: [*c]Tmp, con: [*c]Con, mem: ?*Mem, ntmp: c_int, ncon: c_int, nmem: c_int, nblk: c_uint, retty: c_int, retr: Ref, rpo: [*c]?*Blk, reg: bits, slot: c_int, vararg: u8, dynalloc: u8, name: [80]u8, lnk: Lnk, }; pub const Dat = extern struct { type: enum(c_uint) { DStart, DEnd, DB, DH, DW, DL, DZ }, name: [*:0]u8, lnk: [*c]Lnk, u: extern union { num: i64, fltd: f64, flts: f32, str: [*c]u8, ref: extern struct { name: [*:0]u8, off: i64, }, }, isref: u8, isstr: u8, }; pub extern const T_arm64_apple: Target; pub extern const T_amd64_apple: Target; pub extern const T_arm64: Target; pub extern const T_rv64: Target; pub extern const T_amd64_sysv: Target; pub export const targets = [_]*Target{ &T_amd64_sysv, &T_amd64_apple, &T_arm64, &T_arm64_apple, &T_rv64, }; pub export var T: Target = undefined; pub export var debug = [_]bool{ false } ** ('Z' + 1); // util.c pub extern fn freeall() void; // parse.c pub extern fn parse(in: *FILE, path: [*:0]const u8, out: *FILE, *const fn (*Dat, *FILE) callconv(.C) void, *const fn (*Fn, *FILE) callconv(.C) void) void; pub extern fn printfn(fun: *Fn, out: *FILE) void; // cfg.c pub extern fn fillpreds(fun: *Fn) void; pub extern fn fillrpo(fun: *Fn) void; pub extern fn fillloop(fun: *Fn) void; pub extern fn simpljmp(fun: *Fn) void; // mem.c pub extern fn promote(fun: *Fn) void; pub extern fn coalesce(fun: *Fn) void; // alias.c pub extern fn fillalias(fun: *Fn) void; // load.c pub extern fn loadopt(fun: *Fn) void; // ssa.c pub extern fn filluse(fun: *Fn) void; pub extern fn ssa(fun: *Fn) void; pub extern fn ssacheck(fun: *Fn) void; // copy.c pub extern fn copy(fun: *Fn) void; // fold.c pub extern fn fold(fun: *Fn) void; // simpl.c pub extern fn simpl(fun: *Fn) void; // live.c pub extern fn filllive(fun: *Fn) void; // spill.c pub extern fn fillcost(fun: *Fn) void; pub extern fn spill(fun: *Fn) void; // rega.c pub extern fn rega(fun: *Fn) void; // emit.c pub extern fn emitdat(dat: *Dat, out: *FILE) void; pub extern fn emitdbgfile(fun: [*:0]const u8, out: *FILE) void;