1e887ea33SDavid du Colombier #include "../cc/cc.h" 2e887ea33SDavid du Colombier #include "../6c/6.out.h" 3e887ea33SDavid du Colombier 4e887ea33SDavid du Colombier /* 5e887ea33SDavid du Colombier * 6c/amd64 6e887ea33SDavid du Colombier * Intel 386 with AMD64 extensions 7e887ea33SDavid du Colombier */ 8e887ea33SDavid du Colombier #define SZ_CHAR 1 9e887ea33SDavid du Colombier #define SZ_SHORT 2 10e887ea33SDavid du Colombier #define SZ_INT 4 11e887ea33SDavid du Colombier #define SZ_LONG 4 12e887ea33SDavid du Colombier #define SZ_IND 8 13e887ea33SDavid du Colombier #define SZ_FLOAT 4 14e887ea33SDavid du Colombier #define SZ_VLONG 8 15e887ea33SDavid du Colombier #define SZ_DOUBLE 8 16e887ea33SDavid du Colombier #define FNX 100 17e887ea33SDavid du Colombier 18e887ea33SDavid du Colombier typedef struct Adr Adr; 19e887ea33SDavid du Colombier typedef struct Prog Prog; 20e887ea33SDavid du Colombier typedef struct Case Case; 21e887ea33SDavid du Colombier typedef struct C1 C1; 22e887ea33SDavid du Colombier typedef struct Var Var; 23e887ea33SDavid du Colombier typedef struct Reg Reg; 24e887ea33SDavid du Colombier typedef struct Rgn Rgn; 25e887ea33SDavid du Colombier typedef struct Renv Renv; 26e887ea33SDavid du Colombier 27e887ea33SDavid du Colombier EXTERN struct 28e887ea33SDavid du Colombier { 29e887ea33SDavid du Colombier Node* regtree; 30e887ea33SDavid du Colombier Node* basetree; 31e887ea33SDavid du Colombier short scale; 32e887ea33SDavid du Colombier short reg; 33e887ea33SDavid du Colombier short ptr; 34e887ea33SDavid du Colombier } idx; 35e887ea33SDavid du Colombier 36e887ea33SDavid du Colombier struct Adr 37e887ea33SDavid du Colombier { 38e887ea33SDavid du Colombier vlong offset; 39e887ea33SDavid du Colombier double dval; 40e887ea33SDavid du Colombier char sval[NSNAME]; 41e887ea33SDavid du Colombier 42e887ea33SDavid du Colombier Sym* sym; 43e887ea33SDavid du Colombier uchar type; 44e887ea33SDavid du Colombier uchar index; 45e887ea33SDavid du Colombier uchar etype; 46e887ea33SDavid du Colombier uchar scale; /* doubles as width in DATA op */ 47e887ea33SDavid du Colombier }; 48e887ea33SDavid du Colombier #define A ((Adr*)0) 49e887ea33SDavid du Colombier 50e887ea33SDavid du Colombier #define INDEXED 9 51e887ea33SDavid du Colombier struct Prog 52e887ea33SDavid du Colombier { 53e887ea33SDavid du Colombier Adr from; 54e887ea33SDavid du Colombier Adr to; 55e887ea33SDavid du Colombier Prog* link; 56e887ea33SDavid du Colombier long lineno; 57e887ea33SDavid du Colombier short as; 58e887ea33SDavid du Colombier }; 59e887ea33SDavid du Colombier #define P ((Prog*)0) 60e887ea33SDavid du Colombier 61e887ea33SDavid du Colombier struct Case 62e887ea33SDavid du Colombier { 63e887ea33SDavid du Colombier Case* link; 64e887ea33SDavid du Colombier vlong val; 65e887ea33SDavid du Colombier long label; 66e887ea33SDavid du Colombier char def; 67e887ea33SDavid du Colombier char isv; 68e887ea33SDavid du Colombier }; 69e887ea33SDavid du Colombier #define C ((Case*)0) 70e887ea33SDavid du Colombier 71e887ea33SDavid du Colombier struct C1 72e887ea33SDavid du Colombier { 73e887ea33SDavid du Colombier vlong val; 74e887ea33SDavid du Colombier long label; 75e887ea33SDavid du Colombier }; 76e887ea33SDavid du Colombier 77e887ea33SDavid du Colombier struct Var 78e887ea33SDavid du Colombier { 79e887ea33SDavid du Colombier vlong offset; 80e887ea33SDavid du Colombier Sym* sym; 81e887ea33SDavid du Colombier char name; 82e887ea33SDavid du Colombier char etype; 83e887ea33SDavid du Colombier }; 84e887ea33SDavid du Colombier 85e887ea33SDavid du Colombier struct Reg 86e887ea33SDavid du Colombier { 87e887ea33SDavid du Colombier long pc; 88e887ea33SDavid du Colombier long rpo; /* reverse post ordering */ 89e887ea33SDavid du Colombier 90e887ea33SDavid du Colombier Bits set; 91e887ea33SDavid du Colombier Bits use1; 92e887ea33SDavid du Colombier Bits use2; 93e887ea33SDavid du Colombier 94e887ea33SDavid du Colombier Bits refbehind; 95e887ea33SDavid du Colombier Bits refahead; 96e887ea33SDavid du Colombier Bits calbehind; 97e887ea33SDavid du Colombier Bits calahead; 98e887ea33SDavid du Colombier Bits regdiff; 99e887ea33SDavid du Colombier Bits act; 100e887ea33SDavid du Colombier 101e887ea33SDavid du Colombier long regu; 102e887ea33SDavid du Colombier long loop; /* could be shorter */ 103e887ea33SDavid du Colombier 104e887ea33SDavid du Colombier Reg* log5; 105e887ea33SDavid du Colombier long active; 106e887ea33SDavid du Colombier 107e887ea33SDavid du Colombier Reg* p1; 108e887ea33SDavid du Colombier Reg* p2; 109e887ea33SDavid du Colombier Reg* p2link; 110e887ea33SDavid du Colombier Reg* s1; 111e887ea33SDavid du Colombier Reg* s2; 112e887ea33SDavid du Colombier Reg* link; 113e887ea33SDavid du Colombier Prog* prog; 114e887ea33SDavid du Colombier }; 115e887ea33SDavid du Colombier #define R ((Reg*)0) 116e887ea33SDavid du Colombier 117e887ea33SDavid du Colombier struct Renv 118e887ea33SDavid du Colombier { 119e887ea33SDavid du Colombier int safe; 120e887ea33SDavid du Colombier Node base; 121e887ea33SDavid du Colombier Node* saved; 122e887ea33SDavid du Colombier Node* scope; 123e887ea33SDavid du Colombier }; 124e887ea33SDavid du Colombier 125*40d01547SDavid du Colombier #define NRGN 1000 126e887ea33SDavid du Colombier struct Rgn 127e887ea33SDavid du Colombier { 128e887ea33SDavid du Colombier Reg* enter; 129e887ea33SDavid du Colombier short cost; 130e887ea33SDavid du Colombier short varno; 131e887ea33SDavid du Colombier short regno; 132e887ea33SDavid du Colombier }; 133e887ea33SDavid du Colombier 134e887ea33SDavid du Colombier EXTERN long breakpc; 135e887ea33SDavid du Colombier EXTERN long nbreak; 136e887ea33SDavid du Colombier EXTERN Case* cases; 137e887ea33SDavid du Colombier EXTERN Node constnode; 138e887ea33SDavid du Colombier EXTERN Node fconstnode; 139e887ea33SDavid du Colombier EXTERN Node vconstnode; 140e887ea33SDavid du Colombier EXTERN long continpc; 141e887ea33SDavid du Colombier EXTERN long curarg; 142e887ea33SDavid du Colombier EXTERN long cursafe; 143e887ea33SDavid du Colombier EXTERN Prog* firstp; 144e887ea33SDavid du Colombier EXTERN Prog* lastp; 145e887ea33SDavid du Colombier EXTERN long maxargsafe; 146e887ea33SDavid du Colombier EXTERN int mnstring; 147e887ea33SDavid du Colombier EXTERN Node* nodrat; 148e887ea33SDavid du Colombier EXTERN Node* nodret; 149e887ea33SDavid du Colombier EXTERN Node* nodsafe; 150e887ea33SDavid du Colombier EXTERN long nrathole; 151e887ea33SDavid du Colombier EXTERN long nstring; 152e887ea33SDavid du Colombier EXTERN Prog* p; 153e887ea33SDavid du Colombier EXTERN long pc; 154e887ea33SDavid du Colombier EXTERN Node lregnode; 155e887ea33SDavid du Colombier EXTERN Node qregnode; 156e887ea33SDavid du Colombier EXTERN char string[NSNAME]; 157e887ea33SDavid du Colombier EXTERN Sym* symrathole; 158e887ea33SDavid du Colombier EXTERN Node znode; 159e887ea33SDavid du Colombier EXTERN Prog zprog; 160*40d01547SDavid du Colombier EXTERN int reg[D_XREG]; 161e887ea33SDavid du Colombier EXTERN long exregoffset; 162e887ea33SDavid du Colombier EXTERN long exfregoffset; 163e887ea33SDavid du Colombier EXTERN uchar typechlpv[NTYPE]; 164e887ea33SDavid du Colombier 165e887ea33SDavid du Colombier #define BLOAD(r) band(bnot(r->refbehind), r->refahead) 166e887ea33SDavid du Colombier #define BSTORE(r) band(bnot(r->calbehind), r->calahead) 167e887ea33SDavid du Colombier #define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z]) 168e887ea33SDavid du Colombier #define STORE(r) (~r->calbehind.b[z] & r->calahead.b[z]) 169e887ea33SDavid du Colombier 170e887ea33SDavid du Colombier #define bset(a,n) ((a).b[(n)/32]&(1L<<(n)%32)) 171e887ea33SDavid du Colombier 172e887ea33SDavid du Colombier #define CLOAD 5 173e887ea33SDavid du Colombier #define CREF 5 174e887ea33SDavid du Colombier #define CINF 1000 175e887ea33SDavid du Colombier #define LOOP 3 176e887ea33SDavid du Colombier 177e887ea33SDavid du Colombier EXTERN Rgn region[NRGN]; 178e887ea33SDavid du Colombier EXTERN Rgn* rgp; 179e887ea33SDavid du Colombier EXTERN int nregion; 180e887ea33SDavid du Colombier EXTERN int nvar; 181e887ea33SDavid du Colombier 182e887ea33SDavid du Colombier EXTERN Bits externs; 183e887ea33SDavid du Colombier EXTERN Bits params; 184e887ea33SDavid du Colombier EXTERN Bits consts; 185e887ea33SDavid du Colombier EXTERN Bits addrs; 186e887ea33SDavid du Colombier 187e887ea33SDavid du Colombier EXTERN long regbits; 188e887ea33SDavid du Colombier EXTERN long exregbits; 189e887ea33SDavid du Colombier 190e887ea33SDavid du Colombier EXTERN int change; 191e887ea33SDavid du Colombier EXTERN int suppress; 192e887ea33SDavid du Colombier 193e887ea33SDavid du Colombier EXTERN Reg* firstr; 194e887ea33SDavid du Colombier EXTERN Reg* lastr; 195e887ea33SDavid du Colombier EXTERN Reg zreg; 196e887ea33SDavid du Colombier EXTERN Reg* freer; 197e887ea33SDavid du Colombier EXTERN Var var[NVAR]; 198e887ea33SDavid du Colombier EXTERN long* idom; 199e887ea33SDavid du Colombier EXTERN Reg** rpo2r; 200e887ea33SDavid du Colombier EXTERN long maxnr; 201e887ea33SDavid du Colombier 202e887ea33SDavid du Colombier extern char* anames[]; 203e887ea33SDavid du Colombier 204e887ea33SDavid du Colombier /* 205e887ea33SDavid du Colombier * sgen.c 206e887ea33SDavid du Colombier */ 207e887ea33SDavid du Colombier void codgen(Node*, Node*); 208e887ea33SDavid du Colombier void gen(Node*); 209e887ea33SDavid du Colombier void noretval(int); 210e887ea33SDavid du Colombier void usedset(Node*, int); 211e887ea33SDavid du Colombier void xcom(Node*); 212e887ea33SDavid du Colombier void indx(Node*); 213e887ea33SDavid du Colombier int bcomplex(Node*, Node*); 214e887ea33SDavid du Colombier 215e887ea33SDavid du Colombier /* 216e887ea33SDavid du Colombier * cgen.c 217e887ea33SDavid du Colombier */ 218e887ea33SDavid du Colombier void zeroregm(Node*); 219e887ea33SDavid du Colombier void cgen(Node*, Node*); 220e887ea33SDavid du Colombier void reglcgen(Node*, Node*, Node*); 221e887ea33SDavid du Colombier void lcgen(Node*, Node*); 222e887ea33SDavid du Colombier void bcgen(Node*, int); 223e887ea33SDavid du Colombier void boolgen(Node*, int, Node*); 224e887ea33SDavid du Colombier void sugen(Node*, Node*, long); 225e887ea33SDavid du Colombier int needreg(Node*, int); 226e887ea33SDavid du Colombier int hardconst(Node*); 227e887ea33SDavid du Colombier int immconst(Node*); 228e887ea33SDavid du Colombier 229e887ea33SDavid du Colombier /* 230e887ea33SDavid du Colombier * cgen64.c 231e887ea33SDavid du Colombier */ 232e887ea33SDavid du Colombier int vaddr(Node*, int); 233e887ea33SDavid du Colombier void loadpair(Node*, Node*); 234e887ea33SDavid du Colombier int cgen64(Node*, Node*); 235e887ea33SDavid du Colombier void testv(Node*, int); 236e887ea33SDavid du Colombier 237e887ea33SDavid du Colombier /* 238e887ea33SDavid du Colombier * txt.c 239e887ea33SDavid du Colombier */ 240e887ea33SDavid du Colombier void ginit(void); 241e887ea33SDavid du Colombier void gclean(void); 242e887ea33SDavid du Colombier void nextpc(void); 243e887ea33SDavid du Colombier void gargs(Node*, Node*, Node*); 244e887ea33SDavid du Colombier void garg1(Node*, Node*, Node*, int, Node**); 245e887ea33SDavid du Colombier Node* nodconst(long); 246e887ea33SDavid du Colombier Node* nodfconst(double); 247e887ea33SDavid du Colombier Node* nodgconst(vlong, Type*); 248e887ea33SDavid du Colombier int nodreg(Node*, Node*, int); 249e887ea33SDavid du Colombier int isreg(Node*, int); 250e887ea33SDavid du Colombier void regret(Node*, Node*); 251e887ea33SDavid du Colombier void regalloc(Node*, Node*, Node*); 252e887ea33SDavid du Colombier void regfree(Node*); 253e887ea33SDavid du Colombier void regialloc(Node*, Node*, Node*); 254e887ea33SDavid du Colombier void regsalloc(Node*, Node*); 255e887ea33SDavid du Colombier void regaalloc1(Node*, Node*); 256e887ea33SDavid du Colombier void regaalloc(Node*, Node*); 257e887ea33SDavid du Colombier void regind(Node*, Node*); 258e887ea33SDavid du Colombier void gprep(Node*, Node*); 259e887ea33SDavid du Colombier void naddr(Node*, Adr*); 260e887ea33SDavid du Colombier void gcmp(int, Node*, vlong); 261e887ea33SDavid du Colombier void gmove(Node*, Node*); 262e887ea33SDavid du Colombier void gins(int a, Node*, Node*); 263e887ea33SDavid du Colombier void gopcode(int, Type*, Node*, Node*); 264e887ea33SDavid du Colombier int samaddr(Node*, Node*); 265e887ea33SDavid du Colombier void gbranch(int); 266e887ea33SDavid du Colombier void patch(Prog*, long); 267e887ea33SDavid du Colombier int sconst(Node*); 268e887ea33SDavid du Colombier void gpseudo(int, Sym*, Node*); 269e887ea33SDavid du Colombier 270e887ea33SDavid du Colombier /* 271e887ea33SDavid du Colombier * swt.c 272e887ea33SDavid du Colombier */ 273e887ea33SDavid du Colombier int swcmp(const void*, const void*); 274e887ea33SDavid du Colombier void doswit(Node*); 275e887ea33SDavid du Colombier void swit1(C1*, int, long, Node*); 276e887ea33SDavid du Colombier void casf(void); 277e887ea33SDavid du Colombier void bitload(Node*, Node*, Node*, Node*, Node*); 278e887ea33SDavid du Colombier void bitstore(Node*, Node*, Node*, Node*, Node*); 279e887ea33SDavid du Colombier long outstring(char*, long); 280e887ea33SDavid du Colombier void nullwarn(Node*, Node*); 281e887ea33SDavid du Colombier void gextern(Sym*, Node*, long, long); 282e887ea33SDavid du Colombier void outcode(void); 283e887ea33SDavid du Colombier void ieeedtod(Ieee*, double); 284e887ea33SDavid du Colombier 285e887ea33SDavid du Colombier /* 286e887ea33SDavid du Colombier * list 287e887ea33SDavid du Colombier */ 288e887ea33SDavid du Colombier void listinit(void); 289e887ea33SDavid du Colombier int Pconv(Fmt*); 290e887ea33SDavid du Colombier int Aconv(Fmt*); 291e887ea33SDavid du Colombier int Dconv(Fmt*); 292e887ea33SDavid du Colombier int Sconv(Fmt*); 293e887ea33SDavid du Colombier int Rconv(Fmt*); 294e887ea33SDavid du Colombier int Xconv(Fmt*); 295e887ea33SDavid du Colombier int Bconv(Fmt*); 296e887ea33SDavid du Colombier 297e887ea33SDavid du Colombier /* 298e887ea33SDavid du Colombier * reg.c 299e887ea33SDavid du Colombier */ 300e887ea33SDavid du Colombier Reg* rega(void); 301e887ea33SDavid du Colombier int rcmp(const void*, const void*); 302e887ea33SDavid du Colombier void regopt(Prog*); 303e887ea33SDavid du Colombier void addmove(Reg*, int, int, int); 304e887ea33SDavid du Colombier Bits mkvar(Reg*, Adr*); 305e887ea33SDavid du Colombier void prop(Reg*, Bits, Bits); 306e887ea33SDavid du Colombier void loopit(Reg*, long); 307e887ea33SDavid du Colombier void synch(Reg*, Bits); 308e887ea33SDavid du Colombier ulong allreg(ulong, Rgn*); 309e887ea33SDavid du Colombier void paint1(Reg*, int); 310e887ea33SDavid du Colombier ulong paint2(Reg*, int); 311e887ea33SDavid du Colombier void paint3(Reg*, int, long, int); 312e887ea33SDavid du Colombier void addreg(Adr*, int); 313e887ea33SDavid du Colombier 314e887ea33SDavid du Colombier /* 315e887ea33SDavid du Colombier * peep.c 316e887ea33SDavid du Colombier */ 317e887ea33SDavid du Colombier void peep(void); 318e887ea33SDavid du Colombier void excise(Reg*); 319e887ea33SDavid du Colombier Reg* uniqp(Reg*); 320e887ea33SDavid du Colombier Reg* uniqs(Reg*); 321e887ea33SDavid du Colombier int regtyp(Adr*); 322e887ea33SDavid du Colombier int anyvar(Adr*); 323e887ea33SDavid du Colombier int subprop(Reg*); 324e887ea33SDavid du Colombier int copyprop(Reg*); 325e887ea33SDavid du Colombier int copy1(Adr*, Adr*, Reg*, int); 326e887ea33SDavid du Colombier int copyu(Prog*, Adr*, Adr*); 327e887ea33SDavid du Colombier 328e887ea33SDavid du Colombier int copyas(Adr*, Adr*); 329e887ea33SDavid du Colombier int copyau(Adr*, Adr*); 330e887ea33SDavid du Colombier int copysub(Adr*, Adr*, Adr*, int); 331e887ea33SDavid du Colombier int copysub1(Prog*, Adr*, Adr*, int); 332e887ea33SDavid du Colombier 333e887ea33SDavid du Colombier long RtoB(int); 334e887ea33SDavid du Colombier long FtoB(int); 335e887ea33SDavid du Colombier int BtoR(long); 336e887ea33SDavid du Colombier int BtoF(long); 337e887ea33SDavid du Colombier 338e887ea33SDavid du Colombier #define isregtype(t) ((t)>= D_AX && (t)<=D_R15) 339e887ea33SDavid du Colombier 340e887ea33SDavid du Colombier /* 341e887ea33SDavid du Colombier * bound 342e887ea33SDavid du Colombier */ 343e887ea33SDavid du Colombier void comtarg(void); 344e887ea33SDavid du Colombier 345e887ea33SDavid du Colombier /* 346e887ea33SDavid du Colombier * com64 347e887ea33SDavid du Colombier */ 348e887ea33SDavid du Colombier int cond(int); 349e887ea33SDavid du Colombier int com64(Node*); 350e887ea33SDavid du Colombier void com64init(void); 351e887ea33SDavid du Colombier void bool64(Node*); 352e887ea33SDavid du Colombier long lo64v(Node*); 353e887ea33SDavid du Colombier long hi64v(Node*); 354e887ea33SDavid du Colombier Node* lo64(Node*); 355e887ea33SDavid du Colombier Node* hi64(Node*); 356e887ea33SDavid du Colombier 357e887ea33SDavid du Colombier /* 358e887ea33SDavid du Colombier * div/mul 359e887ea33SDavid du Colombier */ 360e887ea33SDavid du Colombier void sdivgen(Node*, Node*, Node*, Node*); 361e887ea33SDavid du Colombier void udivgen(Node*, Node*, Node*, Node*); 362e887ea33SDavid du Colombier void sdiv2(long, int, Node*, Node*); 363e887ea33SDavid du Colombier void smod2(long, int, Node*, Node*); 364e887ea33SDavid du Colombier void mulgen(Type*, Node*, Node*); 365e887ea33SDavid du Colombier void genmuladd(Node*, Node*, int, Node*); 366e887ea33SDavid du Colombier void shiftit(Type*, Node*, Node*); 367e887ea33SDavid du Colombier 368e887ea33SDavid du Colombier #pragma varargck type "A" int 369e887ea33SDavid du Colombier #pragma varargck type "B" Bits 370e887ea33SDavid du Colombier #pragma varargck type "D" Adr* 371e887ea33SDavid du Colombier #pragma varargck type "P" Prog* 372e887ea33SDavid du Colombier #pragma varargck type "R" int 373e887ea33SDavid du Colombier #pragma varargck type "S" char* 374e887ea33SDavid du Colombier 375e887ea33SDavid du Colombier #define D_X7 (D_X0+7) 376e887ea33SDavid du Colombier 377e887ea33SDavid du Colombier void fgopcode(int, Node*, Node*, int, int); 378