sched.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1. #include "l.h"
  2. enum
  3. {
  4. E_ICC = 1<<0,
  5. E_FCC = 1<<1,
  6. E_MEM = 1<<2,
  7. E_MEMSP = 1<<3, /* uses offset and size */
  8. E_MEMSB = 1<<4, /* uses offset and size */
  9. E_LR = 1<<5,
  10. E_CR = 1<<6,
  11. E_CTR = 1<<7,
  12. E_XER = 1<<8,
  13. E_CR0 = 0xF<<0,
  14. E_CR1 = 0xF<<4,
  15. ANYMEM = E_MEM|E_MEMSP|E_MEMSB,
  16. ALL = ~0,
  17. };
  18. typedef struct Sch Sch;
  19. typedef struct Dep Dep;
  20. struct Dep
  21. {
  22. ulong ireg;
  23. ulong freg;
  24. ulong cc;
  25. ulong cr;
  26. };
  27. struct Sch
  28. {
  29. Prog p;
  30. Dep set;
  31. Dep used;
  32. long soffset;
  33. char size;
  34. char comp;
  35. };
  36. void regused(Sch*, Prog*);
  37. int depend(Sch*, Sch*);
  38. int conflict(Sch*, Sch*);
  39. int offoverlap(Sch*, Sch*);
  40. void dumpbits(Sch*, Dep*);
  41. void
  42. sched(Prog *p0, Prog *pe)
  43. {
  44. Prog *p, *q;
  45. Sch sch[NSCHED], *s, *t, *u, *se, stmp;
  46. if(!debug['Q'])
  47. return;
  48. /*
  49. * build side structure
  50. */
  51. s = sch;
  52. for(p=p0;; p=p->link) {
  53. memset(s, 0, sizeof(*s));
  54. s->p = *p;
  55. regused(s, p);
  56. if(debug['X']) {
  57. Bprint(&bso, "%P\tset", &s->p);
  58. dumpbits(s, &s->set);
  59. Bprint(&bso, "; used");
  60. dumpbits(s, &s->used);
  61. if(s->comp)
  62. Bprint(&bso, "; compound");
  63. if(s->p.mark & LOAD)
  64. Bprint(&bso, "; load");
  65. if(s->p.mark & BRANCH)
  66. Bprint(&bso, "; branch");
  67. if(s->p.mark & FCMP)
  68. Bprint(&bso, "; fcmp");
  69. Bprint(&bso, "\n");
  70. }
  71. s++;
  72. if(p == pe)
  73. break;
  74. }
  75. se = s;
  76. for(s=se-1; s>=sch; s--) {
  77. /*
  78. * load delay. interlocked.
  79. */
  80. if(s->p.mark & LOAD) {
  81. if(s >= se-1)
  82. continue;
  83. if(!conflict(s, (s+1)))
  84. continue;
  85. /*
  86. * s is load, s+1 is immediate use of result
  87. * t is the trial instruction to insert between s and s+1
  88. */
  89. for(t=s-1; t>=sch; t--) {
  90. if(t->p.mark & BRANCH)
  91. goto no2;
  92. if(t->p.mark & FCMP)
  93. if((s+1)->p.mark & BRANCH)
  94. goto no2;
  95. if(t->p.mark & LOAD)
  96. if(conflict(t, (s+1)))
  97. goto no2;
  98. for(u=t+1; u<=s; u++)
  99. if(depend(u, t))
  100. goto no2;
  101. goto out2;
  102. no2:;
  103. }
  104. if(debug['X'])
  105. Bprint(&bso, "?l%P\n", &s->p);
  106. continue;
  107. out2:
  108. if(debug['X']) {
  109. Bprint(&bso, "!l%P\n", &t->p);
  110. Bprint(&bso, "%P\n", &s->p);
  111. }
  112. stmp = *t;
  113. memmove(t, t+1, (uchar*)s - (uchar*)t);
  114. *s = stmp;
  115. s--;
  116. continue;
  117. }
  118. /*
  119. * fop2 delay.
  120. */
  121. if(s->p.mark & FCMP) {
  122. if(s >= se-1)
  123. continue;
  124. if(!((s+1)->p.mark & BRANCH))
  125. continue;
  126. /* t is the trial instruction to use */
  127. for(t=s-1; t>=sch; t--) {
  128. for(u=t+1; u<=s; u++)
  129. if(depend(u, t))
  130. goto no3;
  131. goto out3;
  132. no3:;
  133. }
  134. if(debug['X'])
  135. Bprint(&bso, "?f%P\n", &s->p);
  136. continue;
  137. out3:
  138. if(debug['X']) {
  139. Bprint(&bso, "!f%P\n", &t->p);
  140. Bprint(&bso, "%P\n", &s->p);
  141. }
  142. stmp = *t;
  143. memmove(t, t+1, (uchar*)s - (uchar*)t);
  144. *s = stmp;
  145. s--;
  146. continue;
  147. }
  148. }
  149. /*
  150. * put it all back
  151. */
  152. for(s=sch, p=p0; s<se; s++, p=q) {
  153. q = p->link;
  154. if(q != s->p.link) {
  155. *p = s->p;
  156. p->link = q;
  157. }
  158. }
  159. if(debug['X'])
  160. Bprint(&bso, "\n");
  161. }
  162. void
  163. regused(Sch *s, Prog *realp)
  164. {
  165. int c, ar, ad, ld, sz, nr, upd;
  166. ulong m;
  167. Prog *p;
  168. p = &s->p;
  169. s->comp = compound(p);
  170. if(s->comp) {
  171. s->set.ireg |= 1<<REGTMP;
  172. s->used.ireg |= 1<<REGTMP;
  173. }
  174. ar = 0; /* dest is really reference */
  175. ad = 0; /* source/dest is really address */
  176. ld = 0; /* opcode is load instruction */
  177. sz = 32*4; /* size of load/store for overlap computation */
  178. nr = 0; /* source/dest is not really reg */
  179. upd = 0; /* move with update; changes reg */
  180. /*
  181. * flags based on opcode
  182. */
  183. switch(p->as) {
  184. case ATEXT:
  185. curtext = realp;
  186. autosize = p->to.offset + 8;
  187. ad = 1;
  188. break;
  189. case ABL:
  190. s->set.cc |= E_LR;
  191. ar = 1;
  192. ad = 1;
  193. break;
  194. case ABR:
  195. ar = 1;
  196. ad = 1;
  197. break;
  198. case ACMP:
  199. case ACMPU:
  200. case ACMPW:
  201. case ACMPWU:
  202. s->set.cc |= E_ICC;
  203. if(p->reg == 0)
  204. s->set.cr |= E_CR0;
  205. else
  206. s->set.cr |= (0xF<<((p->reg&7)*4));
  207. ar = 1;
  208. break;
  209. case AFCMPO:
  210. case AFCMPU:
  211. s->set.cc |= E_FCC;
  212. if(p->reg == 0)
  213. s->set.cr |= E_CR0;
  214. else
  215. s->set.cr |= (0xF<<((p->reg&7)*4));
  216. ar = 1;
  217. break;
  218. case ACRAND:
  219. case ACRANDN:
  220. case ACREQV:
  221. case ACRNAND:
  222. case ACRNOR:
  223. case ACROR:
  224. case ACRORN:
  225. case ACRXOR:
  226. s->used.cr |= 1<<p->from.reg;
  227. s->set.cr |= 1<<p->to.reg;
  228. nr = 1;
  229. break;
  230. case ABCL: /* tricky */
  231. s->used.cc |= E_FCC|E_ICC;
  232. s->used.cr = ALL;
  233. s->set.cc |= E_LR;
  234. ar = 1;
  235. break;
  236. case ABC: /* tricky */
  237. s->used.cc |= E_FCC|E_ICC;
  238. s->used.cr = ALL;
  239. ar = 1;
  240. break;
  241. case ABEQ:
  242. case ABGE:
  243. case ABGT:
  244. case ABLE:
  245. case ABLT:
  246. case ABNE:
  247. case ABVC:
  248. case ABVS:
  249. s->used.cc |= E_ICC;
  250. s->used.cr |= E_CR0;
  251. ar = 1;
  252. break;
  253. case ALSW:
  254. case AMOVMW:
  255. /* could do better */
  256. sz = 32*4;
  257. ld = 1;
  258. break;
  259. case AMOVBU:
  260. case AMOVBZU:
  261. upd = 1;
  262. sz = 1;
  263. ld = 1;
  264. break;
  265. case AMOVB:
  266. case AMOVBZ:
  267. sz = 1;
  268. ld = 1;
  269. break;
  270. case AMOVHU:
  271. case AMOVHZU:
  272. upd = 1;
  273. sz = 2;
  274. ld = 1;
  275. break;
  276. case AMOVH:
  277. case AMOVHBR:
  278. case AMOVHZ:
  279. sz = 2;
  280. ld = 1;
  281. break;
  282. case AFMOVSU:
  283. case AMOVWU:
  284. case AMOVWZU:
  285. upd = 1;
  286. sz = 4;
  287. ld = 1;
  288. break;
  289. case AFMOVS:
  290. case AMOVW:
  291. case AMOVWZ:
  292. case AMOVWBR:
  293. case ALWAR:
  294. sz = 4;
  295. ld = 1;
  296. break;
  297. case AFMOVDU:
  298. upd = 1;
  299. sz = 8;
  300. ld = 1;
  301. break;
  302. case AFMOVD:
  303. sz = 8;
  304. ld = 1;
  305. break;
  306. case AFMOVDCC:
  307. sz = 8;
  308. ld = 1;
  309. s->set.cc |= E_FCC;
  310. s->set.cr |= E_CR1;
  311. break;
  312. case AMOVFL:
  313. case AMOVCRFS:
  314. case AMTFSB0:
  315. case AMTFSB0CC:
  316. case AMTFSB1:
  317. case AMTFSB1CC:
  318. s->set.ireg = ALL;
  319. s->set.freg = ALL;
  320. s->set.cc = ALL;
  321. s->set.cr = ALL;
  322. break;
  323. case AADDCC:
  324. case AADDVCC:
  325. case AADDCCC:
  326. case AADDCVCC:
  327. case AADDMECC:
  328. case AADDMEVCC:
  329. case AADDECC:
  330. case AADDEVCC:
  331. case AADDZECC:
  332. case AADDZEVCC:
  333. case AANDCC:
  334. case AANDNCC:
  335. case ACNTLZWCC:
  336. case ADIVWCC:
  337. case ADIVWVCC:
  338. case ADIVWUCC:
  339. case ADIVWUVCC:
  340. case AEQVCC:
  341. case AEXTSBCC:
  342. case AEXTSHCC:
  343. case AMULHWCC:
  344. case AMULHWUCC:
  345. case AMULLWCC:
  346. case AMULLWVCC:
  347. case ANANDCC:
  348. case ANEGCC:
  349. case ANEGVCC:
  350. case ANORCC:
  351. case AORCC:
  352. case AORNCC:
  353. case AREMCC:
  354. case AREMVCC:
  355. case AREMUCC:
  356. case AREMUVCC:
  357. case ARLWMICC:
  358. case ARLWNMCC:
  359. case ASLWCC:
  360. case ASRAWCC:
  361. case ASRWCC:
  362. case ASTWCCC:
  363. case ASUBCC:
  364. case ASUBVCC:
  365. case ASUBCCC:
  366. case ASUBCVCC:
  367. case ASUBMECC:
  368. case ASUBMEVCC:
  369. case ASUBECC:
  370. case ASUBEVCC:
  371. case ASUBZECC:
  372. case ASUBZEVCC:
  373. case AXORCC:
  374. s->set.cc |= E_ICC;
  375. s->set.cr |= E_CR0;
  376. break;
  377. case AFABSCC:
  378. case AFADDCC:
  379. case AFADDSCC:
  380. case AFCTIWCC:
  381. case AFCTIWZCC:
  382. case AFDIVCC:
  383. case AFDIVSCC:
  384. case AFMADDCC:
  385. case AFMADDSCC:
  386. case AFMSUBCC:
  387. case AFMSUBSCC:
  388. case AFMULCC:
  389. case AFMULSCC:
  390. case AFNABSCC:
  391. case AFNEGCC:
  392. case AFNMADDCC:
  393. case AFNMADDSCC:
  394. case AFNMSUBCC:
  395. case AFNMSUBSCC:
  396. case AFRSPCC:
  397. case AFSUBCC:
  398. case AFSUBSCC:
  399. s->set.cc |= E_FCC;
  400. s->set.cr |= E_CR1;
  401. break;
  402. }
  403. /*
  404. * flags based on 'to' field
  405. */
  406. c = p->to.class;
  407. if(c == 0) {
  408. c = aclass(&p->to) + 1;
  409. p->to.class = c;
  410. }
  411. c--;
  412. switch(c) {
  413. default:
  414. print("unknown class %d %D\n", c, &p->to);
  415. case C_NONE:
  416. case C_ZCON:
  417. case C_SCON:
  418. case C_UCON:
  419. case C_LCON:
  420. case C_ADDCON:
  421. case C_ANDCON:
  422. case C_SBRA:
  423. case C_LBRA:
  424. break;
  425. case C_CREG:
  426. c = p->to.reg;
  427. if(c == NREG)
  428. s->set.cr = ALL;
  429. else
  430. s->set.cr |= (0xF << ((p->from.reg&7)*4));
  431. s->set.cc = ALL;
  432. break;
  433. case C_SPR:
  434. case C_FPSCR:
  435. case C_MSR:
  436. case C_XER:
  437. s->set.ireg = ALL;
  438. s->set.freg = ALL;
  439. s->set.cc = ALL;
  440. s->set.cr = ALL;
  441. break;
  442. case C_LR:
  443. s->set.cc |= E_LR;
  444. break;
  445. case C_CTR:
  446. s->set.cc |= E_CTR;
  447. break;
  448. case C_ZOREG:
  449. case C_SOREG:
  450. case C_LOREG:
  451. c = p->to.reg;
  452. s->used.ireg |= 1<<c;
  453. if(upd)
  454. s->set.ireg |= 1<<c;
  455. if(ad)
  456. break;
  457. s->size = sz;
  458. s->soffset = regoff(&p->to);
  459. m = ANYMEM;
  460. if(c == REGSB)
  461. m = E_MEMSB;
  462. if(c == REGSP)
  463. m = E_MEMSP;
  464. if(ar)
  465. s->used.cc |= m;
  466. else
  467. s->set.cc |= m;
  468. break;
  469. case C_SACON:
  470. case C_LACON:
  471. s->used.ireg |= 1<<REGSP;
  472. if(upd)
  473. s->set.ireg |= 1<<c;
  474. break;
  475. case C_SECON:
  476. case C_LECON:
  477. s->used.ireg |= 1<<REGSB;
  478. if(upd)
  479. s->set.ireg |= 1<<c;
  480. break;
  481. case C_REG:
  482. if(nr)
  483. break;
  484. if(ar)
  485. s->used.ireg |= 1<<p->to.reg;
  486. else
  487. s->set.ireg |= 1<<p->to.reg;
  488. break;
  489. case C_FREG:
  490. if(ar)
  491. s->used.freg |= 1<<p->to.reg;
  492. else
  493. s->set.freg |= 1<<p->to.reg;
  494. break;
  495. case C_SAUTO:
  496. case C_LAUTO:
  497. s->used.ireg |= 1<<REGSP;
  498. if(upd)
  499. s->set.ireg |= 1<<c;
  500. if(ad)
  501. break;
  502. s->size = sz;
  503. s->soffset = regoff(&p->to);
  504. if(ar)
  505. s->used.cc |= E_MEMSP;
  506. else
  507. s->set.cc |= E_MEMSP;
  508. break;
  509. case C_SEXT:
  510. case C_LEXT:
  511. s->used.ireg |= 1<<REGSB;
  512. if(upd)
  513. s->set.ireg |= 1<<c;
  514. if(ad)
  515. break;
  516. s->size = sz;
  517. s->soffset = regoff(&p->to);
  518. if(ar)
  519. s->used.cc |= E_MEMSB;
  520. else
  521. s->set.cc |= E_MEMSB;
  522. break;
  523. }
  524. /*
  525. * flags based on 'from' field
  526. */
  527. c = p->from.class;
  528. if(c == 0) {
  529. c = aclass(&p->from) + 1;
  530. p->from.class = c;
  531. }
  532. c--;
  533. switch(c) {
  534. default:
  535. print("unknown class %d %D\n", c, &p->from);
  536. case C_NONE:
  537. case C_ZCON:
  538. case C_SCON:
  539. case C_UCON:
  540. case C_LCON:
  541. case C_ADDCON:
  542. case C_ANDCON:
  543. case C_SBRA:
  544. case C_LBRA:
  545. c = p->from.reg;
  546. if(c != NREG)
  547. s->used.ireg |= 1<<c;
  548. break;
  549. case C_CREG:
  550. c = p->from.reg;
  551. if(c == NREG)
  552. s->used.cr = ALL;
  553. else
  554. s->used.cr |= (0xF << ((p->from.reg&7)*4));
  555. s->used.cc = ALL;
  556. break;
  557. case C_SPR:
  558. case C_FPSCR:
  559. case C_MSR:
  560. case C_XER:
  561. s->set.ireg = ALL;
  562. s->set.freg = ALL;
  563. s->set.cc = ALL;
  564. s->set.cr = ALL;
  565. break;
  566. case C_LR:
  567. s->used.cc |= E_LR;
  568. break;
  569. case C_CTR:
  570. s->used.cc |= E_CTR;
  571. break;
  572. case C_ZOREG:
  573. case C_SOREG:
  574. case C_LOREG:
  575. c = p->from.reg;
  576. s->used.ireg |= 1<<c;
  577. if(ld)
  578. p->mark |= LOAD;
  579. if(ad)
  580. break;
  581. s->size = sz;
  582. s->soffset = regoff(&p->from);
  583. m = ANYMEM;
  584. if(c == REGSB)
  585. m = E_MEMSB;
  586. if(c == REGSP)
  587. m = E_MEMSP;
  588. s->used.cc |= m;
  589. break;
  590. case C_SACON:
  591. case C_LACON:
  592. s->used.ireg |= 1<<REGSP;
  593. break;
  594. case C_SECON:
  595. case C_LECON:
  596. s->used.ireg |= 1<<REGSB;
  597. break;
  598. case C_REG:
  599. if(nr)
  600. break;
  601. s->used.ireg |= 1<<p->from.reg;
  602. break;
  603. case C_FREG:
  604. s->used.freg |= 1<<p->from.reg;
  605. break;
  606. case C_SAUTO:
  607. case C_LAUTO:
  608. s->used.ireg |= 1<<REGSP;
  609. if(ld)
  610. p->mark |= LOAD;
  611. if(ad)
  612. break;
  613. s->size = sz;
  614. s->soffset = regoff(&p->from);
  615. s->used.cc |= E_MEMSP;
  616. break;
  617. case C_SEXT:
  618. case C_LEXT:
  619. s->used.ireg |= 1<<REGSB;
  620. if(ld)
  621. p->mark |= LOAD;
  622. if(ad)
  623. break;
  624. s->size = sz;
  625. s->soffset = regoff(&p->from);
  626. s->used.cc |= E_MEMSB;
  627. break;
  628. }
  629. c = p->reg;
  630. if(c != NREG) {
  631. if(p->from.type == D_FREG || p->to.type == D_FREG)
  632. s->used.freg |= 1<<c;
  633. else
  634. s->used.ireg |= 1<<c;
  635. }
  636. }
  637. /*
  638. * test to see if 2 instrictions can be
  639. * interchanged without changing semantics
  640. */
  641. int
  642. depend(Sch *sa, Sch *sb)
  643. {
  644. ulong x;
  645. if(sa->set.ireg & (sb->set.ireg|sb->used.ireg))
  646. return 1;
  647. if(sb->set.ireg & sa->used.ireg)
  648. return 1;
  649. if(sa->set.freg & (sb->set.freg|sb->used.freg))
  650. return 1;
  651. if(sb->set.freg & sa->used.freg)
  652. return 1;
  653. if(sa->set.cr & (sb->set.cr|sb->used.cr))
  654. return 1;
  655. if(sb->set.cr & sa->used.cr)
  656. return 1;
  657. x = (sa->set.cc & (sb->set.cc|sb->used.cc)) |
  658. (sb->set.cc & sa->used.cc);
  659. if(x) {
  660. /*
  661. * allow SB and SP to pass each other.
  662. * allow SB to pass SB iff doffsets are ok
  663. * anything else conflicts
  664. */
  665. if(x != E_MEMSP && x != E_MEMSB)
  666. return 1;
  667. x = sa->set.cc | sb->set.cc |
  668. sa->used.cc | sb->used.cc;
  669. if(x & E_MEM)
  670. return 1;
  671. if(offoverlap(sa, sb))
  672. return 1;
  673. }
  674. return 0;
  675. }
  676. int
  677. offoverlap(Sch *sa, Sch *sb)
  678. {
  679. if(sa->soffset < sb->soffset) {
  680. if(sa->soffset+sa->size > sb->soffset)
  681. return 1;
  682. return 0;
  683. }
  684. if(sb->soffset+sb->size > sa->soffset)
  685. return 1;
  686. return 0;
  687. }
  688. /*
  689. * test 2 adjacent instructions
  690. * and find out if inserted instructions
  691. * are desired to prevent stalls.
  692. * first instruction is a load instruction.
  693. */
  694. int
  695. conflict(Sch *sa, Sch *sb)
  696. {
  697. if(sa->set.ireg & sb->used.ireg)
  698. return 1;
  699. if(sa->set.freg & sb->used.freg)
  700. return 1;
  701. if(sa->set.cr & sb->used.cr)
  702. return 1;
  703. return 0;
  704. }
  705. int
  706. compound(Prog *p)
  707. {
  708. Optab *o;
  709. o = oplook(p);
  710. if(o->size != 4)
  711. return 1;
  712. if(p->to.type == D_REG && p->to.reg == REGSB)
  713. return 1;
  714. return 0;
  715. }
  716. void
  717. dumpbits(Sch *s, Dep *d)
  718. {
  719. int i;
  720. for(i=0; i<32; i++)
  721. if(d->ireg & (1<<i))
  722. Bprint(&bso, " R%d", i);
  723. for(i=0; i<32; i++)
  724. if(d->freg & (1<<i))
  725. Bprint(&bso, " F%d", i);
  726. for(i=0; i<32; i++)
  727. if(d->cr & (1<<i))
  728. Bprint(&bso, " C%d", i);
  729. for(i=0; i<32; i++)
  730. switch(d->cc & (1<<i)) {
  731. default:
  732. break;
  733. case E_ICC:
  734. Bprint(&bso, " ICC");
  735. break;
  736. case E_FCC:
  737. Bprint(&bso, " FCC");
  738. break;
  739. case E_LR:
  740. Bprint(&bso, " LR");
  741. break;
  742. case E_CR:
  743. Bprint(&bso, " CR");
  744. break;
  745. case E_CTR:
  746. Bprint(&bso, " CTR");
  747. break;
  748. case E_XER:
  749. Bprint(&bso, " XER");
  750. break;
  751. case E_MEM:
  752. Bprint(&bso, " MEM%d", s->size);
  753. break;
  754. case E_MEMSB:
  755. Bprint(&bso, " SB%d", s->size);
  756. break;
  757. case E_MEMSP:
  758. Bprint(&bso, " SP%d", s->size);
  759. break;
  760. }
  761. }