mul.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "gc.h"
  10. typedef struct Malg Malg;
  11. typedef struct Mparam Mparam;
  12. struct Malg
  13. {
  14. char vals[10];
  15. };
  16. struct Mparam
  17. {
  18. uint32_t value;
  19. char alg;
  20. char neg;
  21. char shift;
  22. char arg;
  23. char off;
  24. };
  25. static Mparam multab[32];
  26. static int mulptr;
  27. static Malg malgs[] =
  28. {
  29. {0, 100},
  30. {-1, 1, 100},
  31. {-9, -5, -3, 3, 5, 9, 100},
  32. {6, 10, 12, 18, 20, 24, 36, 40, 72, 100},
  33. {-8, -4, -2, 2, 4, 8, 100},
  34. };
  35. /*
  36. * return position of lowest 1
  37. */
  38. int
  39. lowbit(uint32_t v)
  40. {
  41. int s, i;
  42. uint32_t m;
  43. s = 0;
  44. m = 0xFFFFFFFFUL;
  45. for(i = 16; i > 0; i >>= 1) {
  46. m >>= i;
  47. if((v & m) == 0) {
  48. v >>= i;
  49. s += i;
  50. }
  51. }
  52. return s;
  53. }
  54. void
  55. genmuladd(Node *d, Node *s, int m, Node *a)
  56. {
  57. Node nod;
  58. nod.op = OINDEX;
  59. nod.left = a;
  60. nod.right = s;
  61. nod.scale = m;
  62. nod.type = types[TIND];
  63. nod.xoffset = 0;
  64. xcom(&nod);
  65. gopcode(OADDR, d->type, &nod, d);
  66. }
  67. void
  68. mulparam(uint32_t m, Mparam *mp)
  69. {
  70. int c, i, j, n, o, q, s;
  71. int bc, bi, bn, bo, bq, bs, bt;
  72. char *p;
  73. int32_t u;
  74. uint32_t t;
  75. bc = bq = 10;
  76. bi = bn = bo = bs = bt = 0;
  77. for(i = 0; i < nelem(malgs); i++) {
  78. for(p = malgs[i].vals, j = 0; (o = p[j]) < 100; j++)
  79. for(s = 0; s < 2; s++) {
  80. c = 10;
  81. q = 10;
  82. u = m - o;
  83. if(u == 0)
  84. continue;
  85. if(s) {
  86. o = -o;
  87. if(o > 0)
  88. continue;
  89. u = -u;
  90. }
  91. n = lowbit(u);
  92. t = (uint32_t)u >> n;
  93. switch(i) {
  94. case 0:
  95. if(t == 1) {
  96. c = s + 1;
  97. q = 0;
  98. break;
  99. }
  100. switch(t) {
  101. case 3:
  102. case 5:
  103. case 9:
  104. c = s + 1;
  105. if(n)
  106. c++;
  107. q = 0;
  108. break;
  109. }
  110. if(s)
  111. break;
  112. switch(t) {
  113. case 15:
  114. case 25:
  115. case 27:
  116. case 45:
  117. case 81:
  118. c = 2;
  119. if(n)
  120. c++;
  121. q = 1;
  122. break;
  123. }
  124. break;
  125. case 1:
  126. if(t == 1) {
  127. c = 3;
  128. q = 3;
  129. break;
  130. }
  131. switch(t) {
  132. case 3:
  133. case 5:
  134. case 9:
  135. c = 3;
  136. q = 2;
  137. break;
  138. }
  139. break;
  140. case 2:
  141. if(t == 1) {
  142. c = 3;
  143. q = 2;
  144. break;
  145. }
  146. break;
  147. case 3:
  148. if(s)
  149. break;
  150. if(t == 1) {
  151. c = 3;
  152. q = 1;
  153. break;
  154. }
  155. break;
  156. case 4:
  157. if(t == 1) {
  158. c = 3;
  159. q = 0;
  160. break;
  161. }
  162. break;
  163. }
  164. if(c < bc || (c == bc && q > bq)) {
  165. bc = c;
  166. bi = i;
  167. bn = n;
  168. bo = o;
  169. bq = q;
  170. bs = s;
  171. bt = t;
  172. }
  173. }
  174. }
  175. mp->value = m;
  176. if(bc <= 3) {
  177. mp->alg = bi;
  178. mp->shift = bn;
  179. mp->off = bo;
  180. mp->neg = bs;
  181. mp->arg = bt;
  182. }
  183. else
  184. mp->alg = -1;
  185. }
  186. int
  187. m0(int a)
  188. {
  189. switch(a) {
  190. case -2:
  191. case 2:
  192. return 2;
  193. case -3:
  194. case 3:
  195. return 2;
  196. case -4:
  197. case 4:
  198. return 4;
  199. case -5:
  200. case 5:
  201. return 4;
  202. case 6:
  203. return 2;
  204. case -8:
  205. case 8:
  206. return 8;
  207. case -9:
  208. case 9:
  209. return 8;
  210. case 10:
  211. return 4;
  212. case 12:
  213. return 2;
  214. case 15:
  215. return 2;
  216. case 18:
  217. return 8;
  218. case 20:
  219. return 4;
  220. case 24:
  221. return 2;
  222. case 25:
  223. return 4;
  224. case 27:
  225. return 2;
  226. case 36:
  227. return 8;
  228. case 40:
  229. return 4;
  230. case 45:
  231. return 4;
  232. case 72:
  233. return 8;
  234. case 81:
  235. return 8;
  236. }
  237. diag(Z, "bad m0");
  238. return 0;
  239. }
  240. int
  241. m1(int a)
  242. {
  243. switch(a) {
  244. case 15:
  245. return 4;
  246. case 25:
  247. return 4;
  248. case 27:
  249. return 8;
  250. case 45:
  251. return 8;
  252. case 81:
  253. return 8;
  254. }
  255. diag(Z, "bad m1");
  256. return 0;
  257. }
  258. int
  259. m2(int a)
  260. {
  261. switch(a) {
  262. case 6:
  263. return 2;
  264. case 10:
  265. return 2;
  266. case 12:
  267. return 4;
  268. case 18:
  269. return 2;
  270. case 20:
  271. return 4;
  272. case 24:
  273. return 8;
  274. case 36:
  275. return 4;
  276. case 40:
  277. return 8;
  278. case 72:
  279. return 8;
  280. }
  281. diag(Z, "bad m2");
  282. return 0;
  283. }
  284. void
  285. shiftit(Type *t, Node *s, Node *d)
  286. {
  287. int32_t c;
  288. c = (int32_t)s->vconst & 31;
  289. switch(c) {
  290. case 0:
  291. break;
  292. case 1:
  293. gopcode(OADD, t, d, d);
  294. break;
  295. default:
  296. gopcode(OASHL, t, s, d);
  297. }
  298. }
  299. static int
  300. mulgen1(uint32_t v, Node *n)
  301. {
  302. int i, o;
  303. Mparam *p;
  304. Node nod, nods;
  305. for(i = 0; i < nelem(multab); i++) {
  306. p = &multab[i];
  307. if(p->value == v)
  308. goto found;
  309. }
  310. p = &multab[mulptr];
  311. if(++mulptr == nelem(multab))
  312. mulptr = 0;
  313. mulparam(v, p);
  314. found:
  315. // print("v=%.lx a=%d n=%d s=%d g=%d o=%d \n", p->value, p->alg, p->neg, p->shift, p->arg, p->off);
  316. if(p->alg < 0)
  317. return 0;
  318. nods = *nodconst(p->shift);
  319. o = OADD;
  320. if(p->alg > 0) {
  321. regalloc(&nod, n, Z);
  322. if(p->off < 0)
  323. o = OSUB;
  324. }
  325. switch(p->alg) {
  326. case 0:
  327. switch(p->arg) {
  328. case 1:
  329. shiftit(n->type, &nods, n);
  330. break;
  331. case 15:
  332. case 25:
  333. case 27:
  334. case 45:
  335. case 81:
  336. genmuladd(n, n, m1(p->arg), n);
  337. /* fall thru */
  338. case 3:
  339. case 5:
  340. case 9:
  341. genmuladd(n, n, m0(p->arg), n);
  342. shiftit(n->type, &nods, n);
  343. break;
  344. default:
  345. goto bad;
  346. }
  347. if(p->neg == 1)
  348. gins(ANEGL, Z, n);
  349. break;
  350. case 1:
  351. switch(p->arg) {
  352. case 1:
  353. gmove(n, &nod);
  354. shiftit(n->type, &nods, &nod);
  355. break;
  356. case 3:
  357. case 5:
  358. case 9:
  359. genmuladd(&nod, n, m0(p->arg), n);
  360. shiftit(n->type, &nods, &nod);
  361. break;
  362. default:
  363. goto bad;
  364. }
  365. if(p->neg)
  366. gopcode(o, n->type, &nod, n);
  367. else {
  368. gopcode(o, n->type, n, &nod);
  369. gmove(&nod, n);
  370. }
  371. break;
  372. case 2:
  373. genmuladd(&nod, n, m0(p->off), n);
  374. shiftit(n->type, &nods, n);
  375. goto comop;
  376. case 3:
  377. genmuladd(&nod, n, m0(p->off), n);
  378. shiftit(n->type, &nods, n);
  379. genmuladd(n, &nod, m2(p->off), n);
  380. break;
  381. case 4:
  382. genmuladd(&nod, n, m0(p->off), nodconst(0));
  383. shiftit(n->type, &nods, n);
  384. goto comop;
  385. default:
  386. diag(Z, "bad mul alg");
  387. break;
  388. comop:
  389. if(p->neg) {
  390. gopcode(o, n->type, n, &nod);
  391. gmove(&nod, n);
  392. }
  393. else
  394. gopcode(o, n->type, &nod, n);
  395. }
  396. if(p->alg > 0)
  397. regfree(&nod);
  398. return 1;
  399. bad:
  400. diag(Z, "mulgen botch");
  401. return 1;
  402. }
  403. void
  404. mulgen(Type *t, Node *r, Node *n)
  405. {
  406. if(!mulgen1(r->vconst, n))
  407. gopcode(OMUL, t, r, n);
  408. }