asm.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747
  1. #include "l.h"
  2. #define KMASK 0xF0000000
  3. #define LPUT(c)\
  4. {\
  5. cbp[0] = (c)>>24;\
  6. cbp[1] = (c)>>16;\
  7. cbp[2] = (c)>>8;\
  8. cbp[3] = (c);\
  9. cbp += 4;\
  10. cbc -= 4;\
  11. if(cbc <= 0)\
  12. cflush();\
  13. }
  14. #define CPUT(c)\
  15. {\
  16. cbp[0] = (c);\
  17. cbp++;\
  18. cbc--;\
  19. if(cbc <= 0)\
  20. cflush();\
  21. }
  22. void strnput(char*, int);
  23. long
  24. entryvalue(void)
  25. {
  26. char *a;
  27. Sym *s;
  28. a = INITENTRY;
  29. if(*a >= '0' && *a <= '9')
  30. return atolwhex(a);
  31. s = lookup(a, 0);
  32. if(s->type == 0)
  33. return INITTEXT;
  34. if(dlm && s->type == SDATA)
  35. return s->value+INITDAT;
  36. if(s->type != STEXT && s->type != SLEAF)
  37. diag("entry not text: %s", s->name);
  38. return s->value;
  39. }
  40. void
  41. asmb(void)
  42. {
  43. Prog *p;
  44. long t;
  45. Optab *o;
  46. if(debug['v'])
  47. Bprint(&bso, "%5.2f asm\n", cputime());
  48. Bflush(&bso);
  49. seek(cout, HEADR, 0);
  50. pc = INITTEXT;
  51. for(p = firstp; p != P; p = p->link) {
  52. if(p->as == ATEXT) {
  53. curtext = p;
  54. autosize = p->to.offset + 4;
  55. if(p->from3.type == D_CONST) {
  56. for(; pc < p->pc; pc++)
  57. CPUT(0);
  58. }
  59. }
  60. if(p->pc != pc) {
  61. diag("phase error %lux sb %lux",
  62. p->pc, pc);
  63. if(!debug['a'])
  64. prasm(curp);
  65. pc = p->pc;
  66. }
  67. curp = p;
  68. o = oplook(p); /* could probably avoid this call */
  69. if(asmout(p, o, 0)) {
  70. p = p->link;
  71. pc += 4;
  72. }
  73. pc += o->size;
  74. }
  75. if(debug['a'])
  76. Bprint(&bso, "\n");
  77. Bflush(&bso);
  78. cflush();
  79. curtext = P;
  80. switch(HEADTYPE) {
  81. case 0:
  82. case 1:
  83. case 2:
  84. case 5:
  85. seek(cout, HEADR+textsize, 0);
  86. break;
  87. case 3:
  88. seek(cout, rnd(HEADR+textsize, 4), 0);
  89. break;
  90. case 4:
  91. seek(cout, rnd(HEADR+textsize, 4096), 0);
  92. break;
  93. }
  94. if(dlm){
  95. char buf[8];
  96. write(cout, buf, INITDAT-textsize);
  97. textsize = INITDAT;
  98. }
  99. for(t = 0; t < datsize; t += sizeof(buf)-100) {
  100. if(datsize-t > sizeof(buf)-100)
  101. datblk(t, sizeof(buf)-100);
  102. else
  103. datblk(t, datsize-t);
  104. }
  105. symsize = 0;
  106. lcsize = 0;
  107. if(!debug['s']) {
  108. if(debug['v'])
  109. Bprint(&bso, "%5.2f sym\n", cputime());
  110. Bflush(&bso);
  111. switch(HEADTYPE) {
  112. case 0:
  113. case 1:
  114. case 2:
  115. case 5:
  116. seek(cout, HEADR+textsize+datsize, 0);
  117. break;
  118. case 3:
  119. seek(cout, rnd(HEADR+textsize, 4)+datsize, 0);
  120. break;
  121. case 4:
  122. seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0);
  123. break;
  124. }
  125. if(!debug['s'])
  126. asmsym();
  127. if(debug['v'])
  128. Bprint(&bso, "%5.2f sp\n", cputime());
  129. Bflush(&bso);
  130. if(!debug['s'])
  131. asmlc();
  132. if(dlm)
  133. asmdyn();
  134. if(HEADTYPE == 0 || HEADTYPE == 1) /* round up file length for boot image */
  135. if((symsize+lcsize) & 1)
  136. CPUT(0);
  137. cflush();
  138. }
  139. else if(dlm){
  140. asmdyn();
  141. cflush();
  142. }
  143. seek(cout, 0L, 0);
  144. switch(HEADTYPE) {
  145. case 0:
  146. lput(0x1030107); /* magic and sections */
  147. lput(textsize); /* sizes */
  148. lput(datsize);
  149. lput(bsssize);
  150. lput(symsize); /* nsyms */
  151. lput(entryvalue()); /* va of entry */
  152. lput(0L);
  153. lput(lcsize);
  154. break;
  155. case 1:
  156. lput(0x4a6f7921); /* Joy! */
  157. lput(0x70656666); /* peff */
  158. lput(0x70777063); /* pwpc */
  159. lput(1);
  160. lput(0);
  161. lput(0);
  162. lput(0);
  163. lput(0);
  164. lput(0x30002); /*YY*/
  165. lput(0);
  166. lput(~0);
  167. lput(0);
  168. lput(textsize+datsize);
  169. lput(textsize+datsize);
  170. lput(textsize+datsize);
  171. lput(0xd0); /* header size */
  172. lput(0x10400);
  173. lput(~0);
  174. lput(0);
  175. lput(0xc);
  176. lput(0xc);
  177. lput(0xc);
  178. lput(0xc0);
  179. lput(0x01010400);
  180. lput(~0);
  181. lput(0);
  182. lput(0x38);
  183. lput(0x38);
  184. lput(0x38);
  185. lput(0x80);
  186. lput(0x04040400);
  187. lput(0);
  188. lput(1);
  189. lput(0);
  190. lput(~0);
  191. lput(0);
  192. lput(~0);
  193. lput(0);
  194. lput(0);
  195. lput(0);
  196. lput(0);
  197. lput(0);
  198. lput(0);
  199. lput(0);
  200. lput(0);
  201. lput(0);
  202. lput(0);
  203. lput(0);
  204. lput(0x3100); /* load address */
  205. lput(0);
  206. lput(0);
  207. lput(0); /* whew! */
  208. break;
  209. case 2:
  210. if(dlm)
  211. lput(0x80000000 | (4*21*21+7)); /* magic */
  212. else
  213. lput(4*21*21+7); /* magic */
  214. lput(textsize); /* sizes */
  215. lput(datsize);
  216. lput(bsssize);
  217. lput(symsize); /* nsyms */
  218. lput(entryvalue()); /* va of entry */
  219. lput(0L);
  220. lput(lcsize);
  221. break;
  222. case 3:
  223. break;
  224. case 4:
  225. lput((0x1DFL<<16)|3L); /* magic and sections */
  226. lput(time(0)); /* time and date */
  227. lput(rnd(HEADR+textsize, 4096)+datsize);
  228. lput(symsize); /* nsyms */
  229. lput((0x48L<<16)|15L); /* size of optional hdr and flags */
  230. lput((0413<<16)|01L); /* magic and version */
  231. lput(textsize); /* sizes */
  232. lput(datsize);
  233. lput(bsssize);
  234. lput(entryvalue()); /* va of entry */
  235. lput(INITTEXT); /* va of base of text */
  236. lput(INITDAT); /* va of base of data */
  237. lput(INITDAT); /* address of TOC */
  238. lput((1L<<16)|1); /* sn(entry) | sn(text) */
  239. lput((2L<<16)|1); /* sn(data) | sn(toc) */
  240. lput((0L<<16)|3); /* sn(loader) | sn(bss) */
  241. lput((3L<<16)|3); /* maxalign(text) | maxalign(data) */
  242. lput(('1'<<24)|('L'<<16)|0); /* type field, and reserved */
  243. lput(0); /* max stack allowed */
  244. lput(0); /* max data allowed */
  245. lput(0); lput(0); lput(0); /* reserved */
  246. strnput(".text", 8); /* text segment */
  247. lput(INITTEXT); /* address */
  248. lput(INITTEXT);
  249. lput(textsize);
  250. lput(HEADR);
  251. lput(0L);
  252. lput(HEADR+textsize+datsize+symsize);
  253. lput(lcsize); /* line number size */
  254. lput(0x20L); /* flags */
  255. strnput(".data", 8); /* data segment */
  256. lput(INITDAT); /* address */
  257. lput(INITDAT);
  258. lput(datsize);
  259. lput(rnd(HEADR+textsize, 4096));/* sizes */
  260. lput(0L);
  261. lput(0L);
  262. lput(0L);
  263. lput(0x40L); /* flags */
  264. strnput(".bss", 8); /* bss segment */
  265. lput(INITDAT+datsize); /* address */
  266. lput(INITDAT+datsize);
  267. lput(bsssize);
  268. lput(0L);
  269. lput(0L);
  270. lput(0L);
  271. lput(0L);
  272. lput(0x80L); /* flags */
  273. break;
  274. case 5:
  275. strnput("\177ELF", 4); /* e_ident */
  276. CPUT(1); /* class = 32 bit */
  277. CPUT(2); /* data = MSB */
  278. CPUT(1); /* version = CURRENT */
  279. strnput("", 9);
  280. lput((2L<<16)|20L); /* type = EXEC; machine = PowerPC */
  281. lput(1L); /* version = CURRENT */
  282. lput(entryvalue() & ~KMASK); /* entry vaddr */
  283. lput(52L); /* offset to first phdr */
  284. if(debug['S']){
  285. lput(HEADR+textsize+datsize+symsize); /* offset to first shdr */
  286. lput(0L); /* flags = PPC */
  287. lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/
  288. lput((3L<<16)|40L); /* # Phdrs & Shdr size */
  289. lput((3L<<16)|2L); /* # Shdrs & shdr string size */
  290. }
  291. else{
  292. lput(0L);
  293. lput(0L); /* flags = PPC */
  294. lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/
  295. lput((3L<<16)|0L); /* # Phdrs & Shdr size */
  296. lput((3L<<16)|0L); /* # Shdrs & shdr string size */
  297. }
  298. lput(1L); /* text - type = PT_LOAD */
  299. lput(HEADR); /* file offset */
  300. lput(INITTEXT & ~KMASK); /* vaddr */
  301. lput(INITTEXT); /* paddr */
  302. lput(textsize); /* file size */
  303. lput(textsize); /* memory size */
  304. lput(0x05L); /* protections = RX */
  305. lput(0x10000L); /* alignment */
  306. lput(1L); /* data - type = PT_LOAD */
  307. lput(HEADR+textsize); /* file offset */
  308. lput(INITDAT & ~KMASK); /* vaddr */
  309. lput(INITDAT); /* paddr */
  310. lput(datsize); /* file size */
  311. lput(datsize); /* memory size */
  312. lput(0x07L); /* protections = RWX */
  313. lput(0x10000L); /* alignment */
  314. lput(0L); /* data - type = PT_NULL */
  315. lput(HEADR+textsize+datsize); /* file offset */
  316. lput(0L);
  317. lput(0L);
  318. lput(symsize); /* symbol table size */
  319. lput(lcsize); /* line number size */
  320. lput(0x04L); /* protections = R */
  321. lput(0x04L); /* alignment code?? */
  322. cflush();
  323. if(!debug['S'])
  324. break;
  325. seek(cout, HEADR+textsize+datsize+symsize, 0);
  326. lput(1); /* Section name (string tbl index) */
  327. lput(1); /* Section type */
  328. lput(2|4); /* Section flags */
  329. lput(INITTEXT & ~KMASK); /* Section virtual addr at execution */
  330. lput(HEADR); /* Section file offset */
  331. lput(textsize); /* Section size in bytes */
  332. lput(0); /* Link to another section */
  333. lput(0); /* Additional section information */
  334. lput(0x10000L); /* Section alignment */
  335. lput(0); /* Entry size if section holds table */
  336. lput(7); /* Section name (string tbl index) */
  337. lput(1); /* Section type */
  338. lput(2|1); /* Section flags */
  339. lput(INITDAT & ~KMASK); /* Section virtual addr at execution */
  340. lput(HEADR+textsize); /* Section file offset */
  341. lput(datsize); /* Section size in bytes */
  342. lput(0); /* Link to another section */
  343. lput(0); /* Additional section information */
  344. lput(0x10000L); /* Section alignment */
  345. lput(0); /* Entry size if section holds table */
  346. /* string section header */
  347. lput(12); /* Section name (string tbl index) */
  348. lput(3); /* Section type */
  349. lput(1 << 5); /* Section flags */
  350. lput(0); /* Section virtual addr at execution */
  351. lput(HEADR+textsize+datsize+symsize+3*40); /* Section file offset */
  352. lput(14); /* Section size in bytes */
  353. lput(0); /* Link to another section */
  354. lput(0); /* Additional section information */
  355. lput(1); /* Section alignment */
  356. lput(0); /* Entry size if section holds table */
  357. /* string table */
  358. cput(0);
  359. strnput(".text", 5);
  360. cput(0);
  361. strnput(".data", 5);
  362. cput(0);
  363. strnput(".strtab", 7);
  364. cput(0);
  365. cput(0);
  366. break;
  367. }
  368. cflush();
  369. }
  370. void
  371. strnput(char *s, int n)
  372. {
  373. for(; *s; s++){
  374. CPUT(*s);
  375. n--;
  376. }
  377. for(; n > 0; n--)
  378. CPUT(0);
  379. }
  380. void
  381. cput(long l)
  382. {
  383. CPUT(l);
  384. }
  385. void
  386. wput(long l)
  387. {
  388. cbp[0] = l>>8;
  389. cbp[1] = l;
  390. cbp += 2;
  391. cbc -= 2;
  392. if(cbc <= 0)
  393. cflush();
  394. }
  395. void
  396. lput(long l)
  397. {
  398. LPUT(l);
  399. }
  400. void
  401. cflush(void)
  402. {
  403. int n;
  404. n = sizeof(buf.cbuf) - cbc;
  405. if(n)
  406. write(cout, buf.cbuf, n);
  407. cbp = buf.cbuf;
  408. cbc = sizeof(buf.cbuf);
  409. }
  410. void
  411. asmsym(void)
  412. {
  413. Prog *p;
  414. Auto *a;
  415. Sym *s;
  416. int h;
  417. s = lookup("etext", 0);
  418. if(s->type == STEXT)
  419. putsymb(s->name, 'T', s->value, s->version);
  420. for(h=0; h<NHASH; h++)
  421. for(s=hash[h]; s!=S; s=s->link)
  422. switch(s->type) {
  423. case SCONST:
  424. putsymb(s->name, 'D', s->value, s->version);
  425. continue;
  426. case SDATA:
  427. putsymb(s->name, 'D', s->value+INITDAT, s->version);
  428. continue;
  429. case SBSS:
  430. putsymb(s->name, 'B', s->value+INITDAT, s->version);
  431. continue;
  432. case SFILE:
  433. putsymb(s->name, 'f', s->value, s->version);
  434. continue;
  435. }
  436. for(p=textp; p!=P; p=p->cond) {
  437. s = p->from.sym;
  438. if(s->type != STEXT && s->type != SLEAF)
  439. continue;
  440. /* filenames first */
  441. for(a=p->to.autom; a; a=a->link)
  442. if(a->type == D_FILE)
  443. putsymb(a->sym->name, 'z', a->aoffset, 0);
  444. else
  445. if(a->type == D_FILE1)
  446. putsymb(a->sym->name, 'Z', a->aoffset, 0);
  447. if(s->type == STEXT)
  448. putsymb(s->name, 'T', s->value, s->version);
  449. else
  450. putsymb(s->name, 'L', s->value, s->version);
  451. /* frame, auto and param after */
  452. putsymb(".frame", 'm', p->to.offset+4, 0);
  453. for(a=p->to.autom; a; a=a->link)
  454. if(a->type == D_AUTO)
  455. putsymb(a->sym->name, 'a', -a->aoffset, 0);
  456. else
  457. if(a->type == D_PARAM)
  458. putsymb(a->sym->name, 'p', a->aoffset, 0);
  459. }
  460. if(debug['v'] || debug['n'])
  461. Bprint(&bso, "symsize = %lud\n", symsize);
  462. Bflush(&bso);
  463. }
  464. void
  465. putsymb(char *s, int t, long v, int ver)
  466. {
  467. int i, f;
  468. if(t == 'f')
  469. s++;
  470. LPUT(v);
  471. if(ver)
  472. t += 'a' - 'A';
  473. CPUT(t+0x80); /* 0x80 is variable length */
  474. if(t == 'Z' || t == 'z') {
  475. CPUT(s[0]);
  476. for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
  477. CPUT(s[i]);
  478. CPUT(s[i+1]);
  479. }
  480. CPUT(0);
  481. CPUT(0);
  482. i++;
  483. }
  484. else {
  485. for(i=0; s[i]; i++)
  486. CPUT(s[i]);
  487. CPUT(0);
  488. }
  489. symsize += 4 + 1 + i + 1;
  490. if(debug['n']) {
  491. if(t == 'z' || t == 'Z') {
  492. Bprint(&bso, "%c %.8lux ", t, v);
  493. for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
  494. f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
  495. Bprint(&bso, "/%x", f);
  496. }
  497. Bprint(&bso, "\n");
  498. return;
  499. }
  500. if(ver)
  501. Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
  502. else
  503. Bprint(&bso, "%c %.8lux %s\n", t, v, s);
  504. }
  505. }
  506. #define MINLC 4
  507. void
  508. asmlc(void)
  509. {
  510. long oldpc, oldlc;
  511. Prog *p;
  512. long v, s;
  513. oldpc = INITTEXT;
  514. oldlc = 0;
  515. for(p = firstp; p != P; p = p->link) {
  516. if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
  517. if(p->as == ATEXT)
  518. curtext = p;
  519. if(debug['L'])
  520. Bprint(&bso, "%6lux %P\n",
  521. p->pc, p);
  522. continue;
  523. }
  524. if(debug['L'])
  525. Bprint(&bso, "\t\t%6ld", lcsize);
  526. v = (p->pc - oldpc) / MINLC;
  527. while(v) {
  528. s = 127;
  529. if(v < 127)
  530. s = v;
  531. CPUT(s+128); /* 129-255 +pc */
  532. if(debug['L'])
  533. Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
  534. v -= s;
  535. lcsize++;
  536. }
  537. s = p->line - oldlc;
  538. oldlc = p->line;
  539. oldpc = p->pc + MINLC;
  540. if(s > 64 || s < -64) {
  541. CPUT(0); /* 0 vv +lc */
  542. CPUT(s>>24);
  543. CPUT(s>>16);
  544. CPUT(s>>8);
  545. CPUT(s);
  546. if(debug['L']) {
  547. if(s > 0)
  548. Bprint(&bso, " lc+%ld(%d,%ld)\n",
  549. s, 0, s);
  550. else
  551. Bprint(&bso, " lc%ld(%d,%ld)\n",
  552. s, 0, s);
  553. Bprint(&bso, "%6lux %P\n",
  554. p->pc, p);
  555. }
  556. lcsize += 5;
  557. continue;
  558. }
  559. if(s > 0) {
  560. CPUT(0+s); /* 1-64 +lc */
  561. if(debug['L']) {
  562. Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
  563. Bprint(&bso, "%6lux %P\n",
  564. p->pc, p);
  565. }
  566. } else {
  567. CPUT(64-s); /* 65-128 -lc */
  568. if(debug['L']) {
  569. Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
  570. Bprint(&bso, "%6lux %P\n",
  571. p->pc, p);
  572. }
  573. }
  574. lcsize++;
  575. }
  576. while(lcsize & 1) {
  577. s = 129;
  578. CPUT(s);
  579. lcsize++;
  580. }
  581. if(debug['v'] || debug['L'])
  582. Bprint(&bso, "lcsize = %ld\n", lcsize);
  583. Bflush(&bso);
  584. }
  585. void
  586. datblk(long s, long n)
  587. {
  588. Prog *p;
  589. char *cast;
  590. long l, fl, j, d;
  591. int i, c;
  592. memset(buf.dbuf, 0, n+100);
  593. for(p = datap; p != P; p = p->link) {
  594. curp = p;
  595. l = p->from.sym->value + p->from.offset - s;
  596. c = p->reg;
  597. i = 0;
  598. if(l < 0) {
  599. if(l+c <= 0)
  600. continue;
  601. while(l < 0) {
  602. l++;
  603. i++;
  604. }
  605. }
  606. if(l >= n)
  607. continue;
  608. if(p->as != AINIT && p->as != ADYNT) {
  609. for(j=l+(c-i)-1; j>=l; j--)
  610. if(buf.dbuf[j]) {
  611. print("%P\n", p);
  612. diag("multiple initialization");
  613. break;
  614. }
  615. }
  616. switch(p->to.type) {
  617. default:
  618. diag("unknown mode in initialization\n%P", p);
  619. break;
  620. case D_FCONST:
  621. switch(c) {
  622. default:
  623. case 4:
  624. fl = ieeedtof(&p->to.ieee);
  625. cast = (char*)&fl;
  626. for(; i<c; i++) {
  627. buf.dbuf[l] = cast[fnuxi8[i+4]];
  628. l++;
  629. }
  630. break;
  631. case 8:
  632. cast = (char*)&p->to.ieee;
  633. for(; i<c; i++) {
  634. buf.dbuf[l] = cast[fnuxi8[i]];
  635. l++;
  636. }
  637. break;
  638. }
  639. break;
  640. case D_SCONST:
  641. for(; i<c; i++) {
  642. buf.dbuf[l] = p->to.sval[i];
  643. l++;
  644. }
  645. break;
  646. case D_CONST:
  647. d = p->to.offset;
  648. if(p->to.sym) {
  649. if(p->to.sym->type == SUNDEF){
  650. ckoff(p->to.sym, d);
  651. d += p->to.sym->value;
  652. }
  653. if(p->to.sym->type == STEXT ||
  654. p->to.sym->type == SLEAF)
  655. d += p->to.sym->value;
  656. if(p->to.sym->type == SDATA)
  657. d += p->to.sym->value + INITDAT;
  658. if(p->to.sym->type == SBSS)
  659. d += p->to.sym->value + INITDAT;
  660. if(dlm)
  661. dynreloc(p->to.sym, l+s+INITDAT, 1, 0, 0);
  662. }
  663. cast = (char*)&d;
  664. switch(c) {
  665. default:
  666. diag("bad nuxi %d %d\n%P", c, i, curp);
  667. break;
  668. case 1:
  669. for(; i<c; i++) {
  670. buf.dbuf[l] = cast[inuxi1[i]];
  671. l++;
  672. }
  673. break;
  674. case 2:
  675. for(; i<c; i++) {
  676. buf.dbuf[l] = cast[inuxi2[i]];
  677. l++;
  678. }
  679. break;
  680. case 4:
  681. for(; i<c; i++) {
  682. buf.dbuf[l] = cast[inuxi4[i]];
  683. l++;
  684. }
  685. break;
  686. }
  687. break;
  688. }
  689. }
  690. write(cout, buf.dbuf, n);
  691. }