simpl.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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 int
  31. ulog2_tab64[64] = {
  32. 63, 0, 1, 41, 37, 2, 16, 42,
  33. 38, 29, 32, 3, 12, 17, 43, 55,
  34. 39, 35, 30, 53, 33, 21, 4, 23,
  35. 13, 9, 18, 6, 25, 44, 48, 56,
  36. 62, 40, 36, 15, 28, 31, 11, 54,
  37. 34, 52, 20, 22, 8, 5, 24, 47,
  38. 61, 14, 27, 10, 51, 19, 7, 46,
  39. 60, 26, 50, 45, 59, 49, 58, 57,
  40. };
  41. static int
  42. ulog2(uint64_t pow2)
  43. {
  44. return ulog2_tab64[(pow2 * 0x5b31ab928877a7e) >> 58];
  45. }
  46. static int
  47. ispow2(uint64_t v)
  48. {
  49. return v && (v & (v - 1)) == 0;
  50. }
  51. static void
  52. ins(Ins **pi, int *new, Blk *b, Fn *fn)
  53. {
  54. ulong ni;
  55. Con *c;
  56. Ins *i;
  57. Ref r;
  58. int n;
  59. i = *pi;
  60. /* simplify more instructions here;
  61. * copy 0 into xor, bit rotations,
  62. * etc. */
  63. switch (i->op) {
  64. case Oblit1:
  65. assert(i > b->ins);
  66. assert((i-1)->op == Oblit0);
  67. if (!*new) {
  68. curi = &insb[NIns];
  69. ni = &b->ins[b->nins] - (i+1);
  70. curi -= ni;
  71. icpy(curi, i+1, ni);
  72. *new = 1;
  73. }
  74. blit((i-1)->arg, rsval(i->arg[0]), fn);
  75. *pi = i-1;
  76. return;
  77. case Oudiv:
  78. case Ourem:
  79. r = i->arg[1];
  80. if (KBASE(i->cls) == 0)
  81. if (rtype(r) == RCon) {
  82. c = &fn->con[r.val];
  83. if (c->type == CBits)
  84. if (ispow2(c->bits.i)) {
  85. n = ulog2(c->bits.i);
  86. if (i->op == Ourem) {
  87. i->op = Oand;
  88. i->arg[1] = getcon((1ull<<n) - 1, fn);
  89. } else {
  90. i->op = Oshr;
  91. i->arg[1] = getcon(n, fn);
  92. }
  93. }
  94. }
  95. break;
  96. }
  97. if (*new)
  98. emiti(*i);
  99. }
  100. void
  101. simpl(Fn *fn)
  102. {
  103. Blk *b;
  104. Ins *i;
  105. int new;
  106. for (b=fn->start; b; b=b->link) {
  107. new = 0;
  108. for (i=&b->ins[b->nins]; i!=b->ins;) {
  109. --i;
  110. ins(&i, &new, b, fn);
  111. }
  112. if (new)
  113. idup(b, curi, &insb[NIns]-curi);
  114. }
  115. }