sched.c 13 KB

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