simpl.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #include "all.h"
  2. static void
  3. blit(Ref sd[2], int sz, Fn *fn)
  4. {
  5. struct { int st, ld, cls, size; } *p, tbl[] = {
  6. { Ostorel, Oload, Kl, 8 },
  7. { Ostorew, Oload, Kw, 4 },
  8. { Ostoreh, Oloaduh, Kw, 2 },
  9. { Ostoreb, Oloadub, Kw, 1 }
  10. };
  11. Ref r, r1, ro;
  12. int off, fwd, n;
  13. fwd = sz >= 0;
  14. sz = abs(sz);
  15. off = fwd ? sz : 0;
  16. for (p=tbl; sz; p++)
  17. for (n=p->size; sz>=n; sz-=n) {
  18. off -= fwd ? n : 0;
  19. r = newtmp("blt", Kl, fn);
  20. r1 = newtmp("blt", Kl, fn);
  21. ro = getcon(off, fn);
  22. emit(p->st, 0, R, r, r1);
  23. emit(Oadd, Kl, r1, sd[1], ro);
  24. r1 = newtmp("blt", Kl, fn);
  25. emit(p->ld, p->cls, r, r1, R);
  26. emit(Oadd, Kl, r1, sd[0], ro);
  27. off += fwd ? 0 : n;
  28. }
  29. }
  30. static void
  31. ins(Ins **pi, int *new, Blk *b, Fn *fn)
  32. {
  33. ulong ni;
  34. Ins *i;
  35. i = *pi;
  36. /* simplify more instructions here;
  37. * copy 0 into xor, mul 2^n into shift,
  38. * bit rotations, ... */
  39. switch (i->op) {
  40. case Oblit1:
  41. assert(i > b->ins);
  42. assert((i-1)->op == Oblit0);
  43. if (!*new) {
  44. curi = &insb[NIns];
  45. ni = &b->ins[b->nins] - (i+1);
  46. curi -= ni;
  47. icpy(curi, i+1, ni);
  48. *new = 1;
  49. }
  50. blit((i-1)->arg, rsval(i->arg[0]), fn);
  51. *pi = i-1;
  52. break;
  53. default:
  54. if (*new)
  55. emiti(*i);
  56. break;
  57. }
  58. }
  59. void
  60. simpl(Fn *fn)
  61. {
  62. Blk *b;
  63. Ins *i;
  64. int new;
  65. for (b=fn->start; b; b=b->link) {
  66. new = 0;
  67. for (i=&b->ins[b->nins]; i!=b->ins;) {
  68. --i;
  69. ins(&i, &new, b, fn);
  70. }
  71. if (new) {
  72. b->nins = &insb[NIns] - curi;
  73. idup(&b->ins, curi, b->nins);
  74. }
  75. }
  76. }