diff options
Diffstat (limited to 'all.h')
-rw-r--r-- | all.h | 334 |
1 files changed, 107 insertions, 227 deletions
diff --git a/all.h b/all.h index 124a8d2..c0e08fe 100644 --- a/all.h +++ b/all.h @@ -8,13 +8,14 @@ #define MAKESURE(what, x) typedef char make_sure_##what[(x)?1:-1] #define die(...) die_(__FILE__, __VA_ARGS__) +typedef unsigned char uchar; typedef unsigned int uint; typedef unsigned long ulong; typedef unsigned long long bits; typedef struct BSet BSet; typedef struct Ref Ref; -typedef struct OpDesc OpDesc; +typedef struct Op Op; typedef struct Ins Ins; typedef struct Phi Phi; typedef struct Blk Blk; @@ -27,6 +28,7 @@ typedef struct Fn Fn; typedef struct Typ Typ; typedef struct Seg Seg; typedef struct Dat Dat; +typedef struct Target Target; enum { NString = 32, @@ -38,61 +40,29 @@ enum { NBit = CHAR_BIT * sizeof(bits), }; -#define BIT(n) ((bits)1 << (n)) - -enum Reg { - RXX, - - RAX, /* caller-save */ - RCX, - RDX, - RSI, - RDI, - R8, - R9, - R10, - R11, - - RBX, /* callee-save */ - R12, - R13, - R14, - R15, - - RBP, /* globally live */ - RSP, -#define RGLOB (BIT(RBP)|BIT(RSP)) - - XMM0, /* sse */ - XMM1, - XMM2, - XMM3, - XMM4, - XMM5, - XMM6, - XMM7, - XMM8, - XMM9, - XMM10, - XMM11, - XMM12, - XMM13, - XMM14, - XMM15, - - Tmp0, /* first non-reg temporary */ - - NRGlob = 2, - NIReg = R15 - RAX + 1 + NRGlob, - NFReg = XMM14 - XMM0 + 1, /* XMM15 is reserved */ - NISave = R11 - RAX + 1, - NFSave = NFReg, - NRSave = NISave + NFSave, - NRClob = R15 - RBX + 1, +struct Target { + int gpr0; /* first general purpose reg */ + int ngpr; + int fpr0; /* first floating point reg */ + int nfpr; + bits rglob; /* globally live regs (e.g., sp, fp) */ + int nrglob; + int *rsave; /* caller-save */ + int nrsave[2]; + bits (*retregs)(Ref, int[2]); + bits (*argregs)(Ref, int[2]); + int (*memargs)(int); + void (*abi)(Fn *); + void (*isel)(Fn *); + void (*emitfn)(Fn *, FILE *); }; -MAKESURE(NBit_is_enough, NBit >= (int)Tmp0); +#define BIT(n) ((bits)1 << (n)) +enum { + RXX = 0, + Tmp0 = NBit, /* first non-reg temporary */ +}; struct BSet { uint nt; @@ -139,51 +109,81 @@ static inline int isreg(Ref r) return rtype(r) == RTmp && r.val < Tmp0; } -enum ICmp { -#define ICMPS(X) \ - X(ule) \ - X(ult) \ - X(sle) \ - X(slt) \ - X(sgt) \ - X(sge) \ - X(ugt) \ - X(uge) \ - X(eq) \ - X(ne) /* make sure icmpop() below works! */ - -#define X(c) IC##c, - ICMPS(X) -#undef X - NICmp, +enum CmpI { + Cieq, + Cine, + Cisge, + Cisgt, + Cisle, + Cislt, + Ciuge, + Ciugt, + Ciule, + Ciult, + NCmpI, +}; - ICxnp = NICmp, /* x64 specific */ - ICxp, - NXICmp +enum CmpF { + Cfeq, + Cfge, + Cfgt, + Cfle, + Cflt, + Cfne, + Cfo, + Cfuo, + NCmpF, + NCmp = NCmpI + NCmpF, }; -static inline int icmpop(int c) -{ - return c >= ICeq ? c : ICuge - c; -} +enum O { + Oxxx, +#define O(op, x, y) O##op, + #include "ops.h" + NOp, +}; -enum FCmp { -#define FCMPS(X) \ - X(le) \ - X(lt) \ - X(gt) \ - X(ge) \ - X(ne) \ - X(eq) \ - X(o) \ - X(uo) - -#define X(c) FC##c, - FCMPS(X) +enum J { + Jxxx, +#define JMPS(X) \ + X(ret0) X(retw) X(retl) X(rets) \ + X(retd) X(retc) X(jmp) X(jnz) \ + X(jfieq) X(jfine) X(jfisge) X(jfisgt) \ + X(jfisle) X(jfislt) X(jfiuge) X(jfiugt) \ + X(jfiule) X(jfiult) X(jffeq) X(jffge) \ + X(jffgt) X(jffle) X(jfflt) X(jffne) \ + X(jffo) X(jffuo) +#define X(j) J##j, + JMPS(X) #undef X - NFCmp + NJmp +}; + +enum { + Ocmpw = Oceqw, + Ocmpw1 = Ocultw, + Ocmpl = Oceql, + Ocmpl1 = Ocultl, + Ocmps = Oceqs, + Ocmps1 = Ocuos, + Ocmpd = Oceqd, + Ocmpd1 = Ocuod, + Oalloc = Oalloc4, + Oalloc1 = Oalloc16, + Oflag = Oflagieq, + Oflag1 = Oflagfuo, + NPubOp = Onop, + Jjf = Jjfieq, + Jjf1 = Jjffuo, }; +#define isstore(o) (Ostoreb <= o && o <= Ostored) +#define isload(o) (Oloadsb <= o && o <= Oload) +#define isext(o) (Oextsb <= o && o <= Oextuw) +#define ispar(o) (Opar <= o && o <= Opare) +#define isarg(o) (Oarg <= o && o <= Oarge) +#define isret(j) (Jret0 <= j && j <= Jretc) + enum Class { Kx = -1, /* "top" class (see usecheck() and clsmerge()) */ Kw, @@ -195,124 +195,10 @@ enum Class { #define KWIDE(k) ((k)&1) #define KBASE(k) ((k)>>1) -enum Op { - Oxxx, - - /* public instructions */ - Oadd, - Osub, - Odiv, - Orem, - Oudiv, - Ourem, - Omul, - Oand, - Oor, - Oxor, - Osar, - Oshr, - Oshl, - Ocmpw, - Ocmpw1 = Ocmpw + NICmp-1, - Ocmpl, - Ocmpl1 = Ocmpl + NICmp-1, - Ocmps, - Ocmps1 = Ocmps + NFCmp-1, - Ocmpd, - Ocmpd1 = Ocmpd + NFCmp-1, - - Ostoreb, - Ostoreh, - Ostorew, - Ostorel, - Ostores, - Ostored, -#define isstore(o) (Ostoreb <= o && o <= Ostored) - Oloadsb, /* must match Oext and Tmp.width */ - Oloadub, - Oloadsh, - Oloaduh, - Oloadsw, - Oloaduw, - Oload, -#define isload(o) (Oloadsb <= o && o <= Oload) - Oextsb, - Oextub, - Oextsh, - Oextuh, - Oextsw, - Oextuw, -#define isext(o) (Oextsb <= o && o <= Oextuw) - - Oexts, - Otruncd, - Ostosi, - Odtosi, - Oswtof, - Osltof, - Ocast, - - Oalloc, - Oalloc1 = Oalloc + NAlign-1, - - Ovastart, - Ovaarg, - - Ocopy, - NPubOp, - - /* function instructions */ - Opar = NPubOp, - Oparc, - Opare, -#define ispar(o) (Opar <= o && o <= Opare) - Oarg, - Oargc, - Oarge, -#define isarg(o) (Oarg <= o && o <= Oarge) - Ocall, - Ovacall, - - /* reserved instructions */ - Onop, - Oaddr, - Oswap, - Osign, - Osalloc, - Oxidiv, - Oxdiv, - Oxcmp, - Oxset, - Oxsetnp = Oxset + ICxnp, - Oxsetp = Oxset + ICxp, - Oxtest, - NOp -}; - -enum Jmp { - Jxxx, - Jret0, - Jretw, - Jretl, - Jrets, - Jretd, - Jretc, -#define isret(j) (Jret0 <= j && j <= Jretc) - Jjmp, - Jjnz, - Jxjc, - Jxjnp = Jxjc + ICxnp, - Jxjp = Jxjc + ICxp, - NJmp -}; - -struct OpDesc { +struct Op { char *name; - int nmem; short argcls[2][4]; - uint sflag:1; /* sets the zero flag */ - uint lflag:1; /* leaves flags */ - uint cfold:1; /* can fold */ + int canfold; }; struct Ins { @@ -437,7 +323,7 @@ struct Con { typedef struct Addr Addr; -struct Addr { /* x64 addressing */ +struct Addr { /* amd64 addressing */ Con offset; Ref base; Ref index; @@ -508,8 +394,8 @@ struct Dat { char export; }; - /* main.c */ +extern Target T; extern char debug['Z'+1]; /* util.c */ @@ -524,6 +410,8 @@ void die_(char *, char *, ...) __attribute__((noreturn)); void *emalloc(size_t); void *alloc(size_t); void freeall(void); +int argcls(Ins *, int); +int iscmp(int, int *, int *); void emit(int, int, Ref, Ref, Ref); void emiti(Ins); void idup(Ins **, Ins *, ulong); @@ -531,12 +419,15 @@ Ins *icpy(Ins *, Ins *, ulong); void *vnew(ulong, size_t, Pool); void vfree(void *); void vgrow(void *, ulong); +int cmpop(int); +int cmpneg(int); int clsmerge(short *, short); int phicls(int, Tmp *); Ref newtmp(char *, int, Fn *); void chuse(Ref, int, Fn *); Ref getcon(int64_t, Fn *); void addcon(Con *, Con *); +void blit(Ref, uint, Ref, uint, Fn *); void dumpts(BSet *, Tmp *, FILE *); void bsinit(BSet *, uint); @@ -559,7 +450,7 @@ bshas(BSet *bs, uint elt) } /* parse.c */ -extern OpDesc opdesc[NOp]; +extern Op optab[NOp]; void parse(FILE *, char *, void (Dat *), void (Fn *)); void printfn(Fn *, FILE *); void printref(Ref, Fn *, FILE *); @@ -611,16 +502,6 @@ void fold(Fn *); void liveon(BSet *, Blk *, Blk *); void filllive(Fn *); -/* abi: sysv.c */ -extern int rsave[/* NRSave */]; -extern int rclob[/* NRClob */]; -bits retregs(Ref, int[2]); -bits argregs(Ref, int[2]); -void abi(Fn *); - -/* isel.c */ -void isel(Fn *); - /* spill.c */ void fillcost(Fn *); void spill(Fn *); @@ -628,10 +509,9 @@ void spill(Fn *); /* rega.c */ void rega(Fn *); -/* emit.c */ -extern char *locprefix; -extern char *symprefix; -void emitfn(Fn *, FILE *); -void emitdat(Dat *, FILE *); -int stashfp(int64_t, int); -void emitfin(FILE *); +/* gas.c */ +extern char *gasloc; +extern char *gassym; +void gasemitdat(Dat *, FILE *); +int gasstashfp(int64_t, int); +void gasemitfin(FILE *); |