all.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. #include <assert.h>
  2. #include <inttypes.h>
  3. #include <limits.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #define MAKESURE(what, x) typedef char make_sure_##what[(x)?1:-1]
  8. #define die(...) die_(__FILE__, __VA_ARGS__)
  9. typedef unsigned char uchar;
  10. typedef unsigned int uint;
  11. typedef unsigned long ulong;
  12. typedef unsigned long long bits;
  13. typedef struct BSet BSet;
  14. typedef struct Ref Ref;
  15. typedef struct Op Op;
  16. typedef struct Ins Ins;
  17. typedef struct Phi Phi;
  18. typedef struct Blk Blk;
  19. typedef struct Use Use;
  20. typedef struct Sym Sym;
  21. typedef struct Num Num;
  22. typedef struct Alias Alias;
  23. typedef struct Tmp Tmp;
  24. typedef struct Con Con;
  25. typedef struct Addr Mem;
  26. typedef struct Fn Fn;
  27. typedef struct Typ Typ;
  28. typedef struct Field Field;
  29. typedef struct Dat Dat;
  30. typedef struct Lnk Lnk;
  31. typedef struct Target Target;
  32. enum {
  33. NString = 80,
  34. NIns = 1 << 20,
  35. NAlign = 3,
  36. NField = 32,
  37. NBit = CHAR_BIT * sizeof(bits),
  38. };
  39. struct Target {
  40. char name[16];
  41. char apple;
  42. int gpr0; /* first general purpose reg */
  43. int ngpr;
  44. int fpr0; /* first floating point reg */
  45. int nfpr;
  46. bits rglob; /* globally live regs (e.g., sp, fp) */
  47. int nrglob;
  48. int *rsave; /* caller-save */
  49. int nrsave[2];
  50. bits (*retregs)(Ref, int[2]);
  51. bits (*argregs)(Ref, int[2]);
  52. int (*memargs)(int);
  53. void (*abi0)(Fn *);
  54. void (*abi1)(Fn *);
  55. void (*isel)(Fn *);
  56. void (*emitfn)(Fn *, FILE *);
  57. void (*emitfin)(FILE *);
  58. char asloc[4];
  59. char assym[4];
  60. };
  61. #define BIT(n) ((bits)1 << (n))
  62. enum {
  63. RXX = 0,
  64. Tmp0 = NBit, /* first non-reg temporary */
  65. };
  66. struct BSet {
  67. uint nt;
  68. bits *t;
  69. };
  70. struct Ref {
  71. uint type:3;
  72. uint val:29;
  73. };
  74. enum {
  75. RTmp,
  76. RCon,
  77. RInt,
  78. RType, /* last kind to come out of the parser */
  79. RSlot,
  80. RCall,
  81. RMem,
  82. };
  83. #define R (Ref){RTmp, 0}
  84. #define UNDEF (Ref){RCon, 0} /* represents uninitialized data */
  85. #define CON_Z (Ref){RCon, 1}
  86. #define TMP(x) (Ref){RTmp, x}
  87. #define CON(x) (Ref){RCon, x}
  88. #define SLOT(x) (Ref){RSlot, (x)&0x1fffffff}
  89. #define TYPE(x) (Ref){RType, x}
  90. #define CALL(x) (Ref){RCall, x}
  91. #define MEM(x) (Ref){RMem, x}
  92. #define INT(x) (Ref){RInt, (x)&0x1fffffff}
  93. static inline int req(Ref a, Ref b)
  94. {
  95. return a.type == b.type && a.val == b.val;
  96. }
  97. static inline int rtype(Ref r)
  98. {
  99. if (req(r, R))
  100. return -1;
  101. return r.type;
  102. }
  103. static inline int rsval(Ref r)
  104. {
  105. return ((int)r.val ^ 0x10000000) - 0x10000000;
  106. }
  107. enum CmpI {
  108. Cieq,
  109. Cine,
  110. Cisge,
  111. Cisgt,
  112. Cisle,
  113. Cislt,
  114. Ciuge,
  115. Ciugt,
  116. Ciule,
  117. Ciult,
  118. NCmpI,
  119. };
  120. enum CmpF {
  121. Cfeq,
  122. Cfge,
  123. Cfgt,
  124. Cfle,
  125. Cflt,
  126. Cfne,
  127. Cfo,
  128. Cfuo,
  129. NCmpF,
  130. NCmp = NCmpI + NCmpF,
  131. };
  132. enum O {
  133. Oxxx,
  134. #define O(op, x, y) O##op,
  135. #include "ops.h"
  136. NOp,
  137. };
  138. enum J {
  139. Jxxx,
  140. #define JMPS(X) \
  141. X(retw) X(retl) X(rets) X(retd) \
  142. X(retsb) X(retub) X(retsh) X(retuh) \
  143. X(retc) X(ret0) X(jmp) X(jnz) \
  144. X(jfieq) X(jfine) X(jfisge) X(jfisgt) \
  145. X(jfisle) X(jfislt) X(jfiuge) X(jfiugt) \
  146. X(jfiule) X(jfiult) X(jffeq) X(jffge) \
  147. X(jffgt) X(jffle) X(jfflt) X(jffne) \
  148. X(jffo) X(jffuo) X(hlt)
  149. #define X(j) J##j,
  150. JMPS(X)
  151. #undef X
  152. NJmp
  153. };
  154. enum {
  155. Ocmpw = Oceqw,
  156. Ocmpw1 = Ocultw,
  157. Ocmpl = Oceql,
  158. Ocmpl1 = Ocultl,
  159. Ocmps = Oceqs,
  160. Ocmps1 = Ocuos,
  161. Ocmpd = Oceqd,
  162. Ocmpd1 = Ocuod,
  163. Oalloc = Oalloc4,
  164. Oalloc1 = Oalloc16,
  165. Oflag = Oflagieq,
  166. Oflag1 = Oflagfuo,
  167. NPubOp = Onop,
  168. Jjf = Jjfieq,
  169. Jjf1 = Jjffuo,
  170. };
  171. #define INRANGE(x, l, u) ((unsigned)(x) - l <= u - l) /* linear in x */
  172. #define isstore(o) INRANGE(o, Ostoreb, Ostored)
  173. #define isload(o) INRANGE(o, Oloadsb, Oload)
  174. #define isext(o) INRANGE(o, Oextsb, Oextuw)
  175. #define ispar(o) INRANGE(o, Opar, Opare)
  176. #define isarg(o) INRANGE(o, Oarg, Oargv)
  177. #define isret(j) INRANGE(j, Jretw, Jret0)
  178. #define isparbh(o) INRANGE(o, Oparsb, Oparuh)
  179. #define isargbh(o) INRANGE(o, Oargsb, Oarguh)
  180. #define isretbh(j) INRANGE(j, Jretsb, Jretuh)
  181. enum {
  182. Kx = -1, /* "top" class (see usecheck() and clsmerge()) */
  183. Kw,
  184. Kl,
  185. Ks,
  186. Kd
  187. };
  188. #define KWIDE(k) ((k)&1)
  189. #define KBASE(k) ((k)>>1)
  190. struct Op {
  191. char *name;
  192. short argcls[2][4];
  193. uint canfold:1;
  194. uint hasid:1;
  195. uint idval:1; /* identity value 0/1 */
  196. };
  197. struct Ins {
  198. uint op:30;
  199. uint cls:2;
  200. Ref to;
  201. Ref arg[2];
  202. };
  203. struct Phi {
  204. Ref to;
  205. Ref *arg;
  206. Blk **blk;
  207. uint narg;
  208. int cls;
  209. Phi *link;
  210. };
  211. struct Blk {
  212. Phi *phi;
  213. Ins *ins;
  214. uint nins;
  215. struct {
  216. short type;
  217. Ref arg;
  218. } jmp;
  219. Blk *s1;
  220. Blk *s2;
  221. Blk *link;
  222. uint id;
  223. uint visit;
  224. Blk *idom;
  225. Blk *dom, *dlink;
  226. Blk **fron;
  227. uint nfron;
  228. Blk **pred;
  229. uint npred;
  230. BSet in[1], out[1], gen[1];
  231. int nlive[2];
  232. int loop;
  233. char name[NString];
  234. };
  235. struct Use {
  236. enum {
  237. UXXX,
  238. UPhi,
  239. UIns,
  240. UJmp,
  241. } type;
  242. uint bid;
  243. union {
  244. Ins *ins;
  245. Phi *phi;
  246. } u;
  247. };
  248. struct Sym {
  249. enum {
  250. SGlo,
  251. SThr,
  252. } type;
  253. uint32_t id;
  254. };
  255. struct Num {
  256. uchar n;
  257. uchar nl, nr;
  258. Ref l, r;
  259. };
  260. enum {
  261. NoAlias,
  262. MayAlias,
  263. MustAlias
  264. };
  265. struct Alias {
  266. enum {
  267. ABot = 0,
  268. ALoc = 1, /* stack local */
  269. ACon = 2,
  270. AEsc = 3, /* stack escaping */
  271. ASym = 4,
  272. AUnk = 6,
  273. #define astack(t) ((t) & 1)
  274. } type;
  275. int base;
  276. int64_t offset;
  277. union {
  278. Sym sym;
  279. struct {
  280. int sz; /* -1 if > NBit */
  281. bits m;
  282. } loc;
  283. } u;
  284. Alias *slot;
  285. };
  286. struct Tmp {
  287. char name[NString];
  288. Ins *def;
  289. Use *use;
  290. uint ndef, nuse;
  291. uint bid; /* id of a defining block */
  292. uint cost;
  293. int slot; /* -1 for unset */
  294. short cls;
  295. struct {
  296. int r; /* register or -1 */
  297. int w; /* weight */
  298. bits m; /* avoid these registers */
  299. } hint;
  300. int phi;
  301. Alias alias;
  302. enum {
  303. WFull,
  304. Wsb, /* must match Oload/Oext order */
  305. Wub,
  306. Wsh,
  307. Wuh,
  308. Wsw,
  309. Wuw
  310. } width;
  311. int visit;
  312. };
  313. struct Con {
  314. enum {
  315. CUndef,
  316. CBits,
  317. CAddr,
  318. } type;
  319. Sym sym;
  320. union {
  321. int64_t i;
  322. double d;
  323. float s;
  324. } bits;
  325. char flt; /* 1 to print as s, 2 to print as d */
  326. };
  327. typedef struct Addr Addr;
  328. struct Addr { /* amd64 addressing */
  329. Con offset;
  330. Ref base;
  331. Ref index;
  332. int scale;
  333. };
  334. struct Lnk {
  335. char export;
  336. char thread;
  337. char common;
  338. char align;
  339. char *sec;
  340. char *secf;
  341. };
  342. struct Fn {
  343. Blk *start;
  344. Tmp *tmp;
  345. Con *con;
  346. Mem *mem;
  347. int ntmp;
  348. int ncon;
  349. int nmem;
  350. uint nblk;
  351. int retty; /* index in typ[], -1 if no aggregate return */
  352. Ref retr;
  353. Blk **rpo;
  354. bits reg;
  355. int slot;
  356. char vararg;
  357. char dynalloc;
  358. char name[NString];
  359. Lnk lnk;
  360. };
  361. struct Typ {
  362. char name[NString];
  363. char isdark;
  364. char isunion;
  365. int align;
  366. uint64_t size;
  367. uint nunion;
  368. struct Field {
  369. enum {
  370. FEnd,
  371. Fb,
  372. Fh,
  373. Fw,
  374. Fl,
  375. Fs,
  376. Fd,
  377. FPad,
  378. FTyp,
  379. } type;
  380. uint len; /* or index in typ[] for FTyp */
  381. } (*fields)[NField+1];
  382. };
  383. struct Dat {
  384. enum {
  385. DStart,
  386. DEnd,
  387. DB,
  388. DH,
  389. DW,
  390. DL,
  391. DZ
  392. } type;
  393. char *name;
  394. Lnk *lnk;
  395. union {
  396. int64_t num;
  397. double fltd;
  398. float flts;
  399. char *str;
  400. struct {
  401. char *name;
  402. int64_t off;
  403. } ref;
  404. } u;
  405. char isref;
  406. char isstr;
  407. };
  408. /* main.c */
  409. extern Target T;
  410. extern char debug['Z'+1];
  411. /* util.c */
  412. typedef enum {
  413. PHeap, /* free() necessary */
  414. PFn, /* discarded after processing the function */
  415. } Pool;
  416. extern Typ *typ;
  417. extern Ins insb[NIns], *curi;
  418. uint32_t hash(char *);
  419. void die_(char *, char *, ...) __attribute__((noreturn));
  420. void *emalloc(size_t);
  421. void *alloc(size_t);
  422. void freeall(void);
  423. void *vnew(ulong, size_t, Pool);
  424. void vfree(void *);
  425. void vgrow(void *, ulong);
  426. void strf(char[NString], char *, ...);
  427. uint32_t intern(char *);
  428. char *str(uint32_t);
  429. int argcls(Ins *, int);
  430. int isreg(Ref);
  431. int iscmp(int, int *, int *);
  432. void emit(int, int, Ref, Ref, Ref);
  433. void emiti(Ins);
  434. void idup(Ins **, Ins *, ulong);
  435. Ins *icpy(Ins *, Ins *, ulong);
  436. int cmpop(int);
  437. int cmpneg(int);
  438. int clsmerge(short *, short);
  439. int phicls(int, Tmp *);
  440. Ref newtmp(char *, int, Fn *);
  441. void chuse(Ref, int, Fn *);
  442. int symeq(Sym, Sym);
  443. Ref newcon(Con *, Fn *);
  444. Ref getcon(int64_t, Fn *);
  445. int addcon(Con *, Con *, int);
  446. void salloc(Ref, Ref, Fn *);
  447. void dumpts(BSet *, Tmp *, FILE *);
  448. void runmatch(uchar *, Num *, Ref, Ref *);
  449. void bsinit(BSet *, uint);
  450. void bszero(BSet *);
  451. uint bscount(BSet *);
  452. void bsset(BSet *, uint);
  453. void bsclr(BSet *, uint);
  454. void bscopy(BSet *, BSet *);
  455. void bsunion(BSet *, BSet *);
  456. void bsinter(BSet *, BSet *);
  457. void bsdiff(BSet *, BSet *);
  458. int bsequal(BSet *, BSet *);
  459. int bsiter(BSet *, int *);
  460. static inline int
  461. bshas(BSet *bs, uint elt)
  462. {
  463. assert(elt < bs->nt * NBit);
  464. return (bs->t[elt/NBit] & BIT(elt%NBit)) != 0;
  465. }
  466. /* parse.c */
  467. extern Op optab[NOp];
  468. void parse(FILE *, char *, void (char *), void (Dat *), void (Fn *));
  469. void printfn(Fn *, FILE *);
  470. void printref(Ref, Fn *, FILE *);
  471. void err(char *, ...) __attribute__((noreturn));
  472. /* abi.c */
  473. void elimsb(Fn *);
  474. /* cfg.c */
  475. Blk *newblk(void);
  476. void edgedel(Blk *, Blk **);
  477. void fillpreds(Fn *);
  478. void fillrpo(Fn *);
  479. void filldom(Fn *);
  480. int sdom(Blk *, Blk *);
  481. int dom(Blk *, Blk *);
  482. void fillfron(Fn *);
  483. void loopiter(Fn *, void (*)(Blk *, Blk *));
  484. void fillloop(Fn *);
  485. void simpljmp(Fn *);
  486. /* mem.c */
  487. void promote(Fn *);
  488. void coalesce(Fn *);
  489. /* alias.c */
  490. void fillalias(Fn *);
  491. void getalias(Alias *, Ref, Fn *);
  492. int alias(Ref, int, int, Ref, int, int *, Fn *);
  493. int escapes(Ref, Fn *);
  494. /* load.c */
  495. int loadsz(Ins *);
  496. int storesz(Ins *);
  497. void loadopt(Fn *);
  498. /* ssa.c */
  499. void filluse(Fn *);
  500. void ssa(Fn *);
  501. void ssacheck(Fn *);
  502. /* copy.c */
  503. void copy(Fn *);
  504. /* fold.c */
  505. void fold(Fn *);
  506. /* simpl.c */
  507. void simpl(Fn *);
  508. /* live.c */
  509. void liveon(BSet *, Blk *, Blk *);
  510. void filllive(Fn *);
  511. /* spill.c */
  512. void fillcost(Fn *);
  513. void spill(Fn *);
  514. /* rega.c */
  515. void rega(Fn *);
  516. /* emit.c */
  517. void emitfnlnk(char *, Lnk *, FILE *);
  518. void emitdat(Dat *, FILE *);
  519. void emitdbgfile(char *, FILE *);
  520. void emitdbgloc(uint, uint, FILE *);
  521. int stashbits(void *, int);
  522. void elf_emitfnfin(char *, FILE *);
  523. void elf_emitfin(FILE *);
  524. void macho_emitfin(FILE *);