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