p1output.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. /****************************************************************
  2. Copyright 1990, 1991, 1993, 1994, 1999-2001 by AT&T, Lucent Technologies and Bellcore.
  3. Permission to use, copy, modify, and distribute this software
  4. and its documentation for any purpose and without fee is hereby
  5. granted, provided that the above copyright notice appear in all
  6. copies and that both that the copyright notice and this
  7. permission notice and warranty disclaimer appear in supporting
  8. documentation, and that the names of AT&T, Bell Laboratories,
  9. Lucent or Bellcore or any of their entities not be used in
  10. advertising or publicity pertaining to distribution of the
  11. software without specific, written prior permission.
  12. AT&T, Lucent and Bellcore disclaim all warranties with regard to
  13. this software, including all implied warranties of
  14. merchantability and fitness. In no event shall AT&T, Lucent or
  15. Bellcore be liable for any special, indirect or consequential
  16. damages or any damages whatsoever resulting from loss of use,
  17. data or profits, whether in an action of contract, negligence or
  18. other tortious action, arising out of or in connection with the
  19. use or performance of this software.
  20. ****************************************************************/
  21. #include "defs.h"
  22. #include "p1defs.h"
  23. #include "output.h"
  24. #include "names.h"
  25. static void p1_addr Argdcl((Addrp));
  26. static void p1_big_addr Argdcl((Addrp));
  27. static void p1_binary Argdcl((Exprp));
  28. static void p1_const Argdcl((Constp));
  29. static void p1_list Argdcl((struct Listblock*));
  30. static void p1_literal Argdcl((long int));
  31. static void p1_name Argdcl((Namep));
  32. static void p1_unary Argdcl((Exprp));
  33. static void p1puta Argdcl((int, Addr));
  34. static void p1putd Argdcl((int, long int));
  35. static void p1putdd Argdcl((int, int, int));
  36. static void p1putddd Argdcl((int, int, int, int));
  37. static void p1putdds Argdcl((int, int, int, char*));
  38. static void p1putds Argdcl((int, int, char*));
  39. static void p1putn Argdcl((int, int, char*));
  40. /* p1_comment -- save the text of a Fortran comment in the intermediate
  41. file. Make sure that there are no spurious "/ *" or "* /" characters by
  42. mapping them onto "/+" and "+/". str is assumed to hold no newlines and be
  43. null terminated; it may be modified by this function. */
  44. void
  45. #ifdef KR_headers
  46. p1_comment(str)
  47. char *str;
  48. #else
  49. p1_comment(char *str)
  50. #endif
  51. {
  52. register unsigned char *pointer, *ustr;
  53. if (!str)
  54. return;
  55. /* Get rid of any open or close comment combinations that may be in the
  56. Fortran input */
  57. ustr = (unsigned char *)str;
  58. for(pointer = ustr; *pointer; pointer++)
  59. if (*pointer == '*' && (pointer[1] == '/'
  60. || pointer > ustr && pointer[-1] == '/'))
  61. *pointer = '+';
  62. /* trim trailing white space */
  63. #ifdef isascii
  64. while(--pointer >= ustr && (!isascii(*pointer) || isspace(*pointer)));
  65. #else
  66. while(--pointer >= ustr && isspace(*pointer));
  67. #endif
  68. pointer[1] = 0;
  69. p1puts (P1_COMMENT, str);
  70. } /* p1_comment */
  71. /* p1_name -- Writes the address of a hash table entry into the
  72. intermediate file */
  73. static void
  74. #ifdef KR_headers
  75. p1_name(namep)
  76. Namep namep;
  77. #else
  78. p1_name(Namep namep)
  79. #endif
  80. {
  81. p1puta (P1_NAME_POINTER, (Addr) namep);
  82. namep->visused = 1;
  83. } /* p1_name */
  84. void
  85. #ifdef KR_headers
  86. p1_expr(expr)
  87. expptr expr;
  88. #else
  89. p1_expr(expptr expr)
  90. #endif
  91. {
  92. /* An opcode of 0 means a null entry */
  93. if (expr == ENULL) {
  94. p1putdd (P1_EXPR, 0, TYUNKNOWN); /* Should this be TYERROR? */
  95. return;
  96. } /* if (expr == ENULL) */
  97. switch (expr -> tag) {
  98. case TNAME:
  99. p1_name ((Namep) expr);
  100. return;
  101. case TCONST:
  102. p1_const(&expr->constblock);
  103. return;
  104. case TEXPR:
  105. /* Fall through the switch */
  106. break;
  107. case TADDR:
  108. p1_addr (&(expr -> addrblock));
  109. goto freeup;
  110. case TPRIM:
  111. warn ("p1_expr: got TPRIM");
  112. return;
  113. case TLIST:
  114. p1_list (&(expr->listblock));
  115. frchain( &(expr->listblock.listp) );
  116. return;
  117. case TERROR:
  118. return;
  119. default:
  120. erri ("p1_expr: bad tag '%d'", (int) (expr -> tag));
  121. return;
  122. }
  123. /* Now we know that the tag is TEXPR */
  124. if (is_unary_op (expr -> exprblock.opcode))
  125. p1_unary (&(expr -> exprblock));
  126. else if (is_binary_op (expr -> exprblock.opcode))
  127. p1_binary (&(expr -> exprblock));
  128. else
  129. erri ("p1_expr: bad opcode '%d'", (int) expr -> exprblock.opcode);
  130. freeup:
  131. free((char *)expr);
  132. } /* p1_expr */
  133. static void
  134. #ifdef KR_headers
  135. p1_const(cp)
  136. register Constp cp;
  137. #else
  138. p1_const(register Constp cp)
  139. #endif
  140. {
  141. int type = cp->vtype;
  142. expptr vleng = cp->vleng;
  143. union Constant *c = &cp->Const;
  144. char cdsbuf0[64], cdsbuf1[64];
  145. char *cds0, *cds1;
  146. switch (type) {
  147. case TYINT1:
  148. case TYSHORT:
  149. case TYLONG:
  150. #ifdef TYQUAD0
  151. case TYQUAD:
  152. #endif
  153. case TYLOGICAL:
  154. case TYLOGICAL1:
  155. case TYLOGICAL2:
  156. fprintf(pass1_file, "%d: %d %ld\n", P1_CONST, type, c->ci);
  157. break;
  158. #ifndef NO_LONG_LONG
  159. case TYQUAD:
  160. fprintf(pass1_file, "%d: %d %llx\n", P1_CONST, type, c->cq);
  161. break;
  162. #endif
  163. case TYREAL:
  164. case TYDREAL:
  165. fprintf(pass1_file, "%d: %d %s\n", P1_CONST, type,
  166. cp->vstg ? c->cds[0] : cds(dtos(c->cd[0]), cdsbuf0));
  167. break;
  168. case TYCOMPLEX:
  169. case TYDCOMPLEX:
  170. if (cp->vstg) {
  171. cds0 = c->cds[0];
  172. cds1 = c->cds[1];
  173. }
  174. else {
  175. cds0 = cds(dtos(c->cd[0]), cdsbuf0);
  176. cds1 = cds(dtos(c->cd[1]), cdsbuf1);
  177. }
  178. fprintf(pass1_file, "%d: %d %s %s\n", P1_CONST, type,
  179. cds0, cds1);
  180. break;
  181. case TYCHAR:
  182. if (vleng && !ISICON (vleng))
  183. err("p1_const: bad vleng\n");
  184. else
  185. fprintf(pass1_file, "%d: %d " Addrfmt "\n", P1_CONST, type,
  186. (Addr)cpexpr((expptr)cp));
  187. break;
  188. default:
  189. erri ("p1_const: bad constant type '%d'", type);
  190. break;
  191. } /* switch */
  192. } /* p1_const */
  193. void
  194. #ifdef KR_headers
  195. p1_asgoto(addrp)
  196. Addrp addrp;
  197. #else
  198. p1_asgoto(Addrp addrp)
  199. #endif
  200. {
  201. p1put (P1_ASGOTO);
  202. p1_addr (addrp);
  203. } /* p1_asgoto */
  204. void
  205. #ifdef KR_headers
  206. p1_goto(stateno)
  207. ftnint stateno;
  208. #else
  209. p1_goto(ftnint stateno)
  210. #endif
  211. {
  212. p1putd (P1_GOTO, stateno);
  213. } /* p1_goto */
  214. static void
  215. #ifdef KR_headers
  216. p1_addr(addrp)
  217. register struct Addrblock *addrp;
  218. #else
  219. p1_addr(register struct Addrblock *addrp)
  220. #endif
  221. {
  222. int stg;
  223. if (addrp == (struct Addrblock *) NULL)
  224. return;
  225. stg = addrp -> vstg;
  226. if (ONEOF(stg, M(STGINIT)|M(STGREG))
  227. || ONEOF(stg, M(STGCOMMON)|M(STGEQUIV)) &&
  228. (!ISICON(addrp->memoffset)
  229. || (addrp->uname_tag == UNAM_NAME
  230. ? addrp->memoffset->constblock.Const.ci
  231. != addrp->user.name->voffset
  232. : addrp->memoffset->constblock.Const.ci))
  233. || ONEOF(stg, M(STGBSS)|M(STGINIT)|M(STGAUTO)|M(STGARG)) &&
  234. (!ISICON(addrp->memoffset)
  235. || addrp->memoffset->constblock.Const.ci)
  236. || addrp->Field || addrp->isarray || addrp->vstg == STGLENG)
  237. {
  238. p1_big_addr (addrp);
  239. return;
  240. }
  241. /* Write out a level of indirection for non-array arguments, which have
  242. addrp -> memoffset set and are handled by p1_big_addr().
  243. Lengths are passed by value, so don't check STGLENG
  244. 28-Jun-89 (dmg) Added the check for != TYCHAR
  245. */
  246. if (oneof_stg ( addrp -> uname_tag == UNAM_NAME ? addrp -> user.name : NULL,
  247. stg, M(STGARG)|M(STGEQUIV)) && addrp->vtype != TYCHAR) {
  248. p1putdd (P1_EXPR, OPWHATSIN, addrp -> vtype);
  249. p1_expr (ENULL); /* Put dummy vleng */
  250. } /* if stg == STGARG */
  251. switch (addrp -> uname_tag) {
  252. case UNAM_NAME:
  253. p1_name (addrp -> user.name);
  254. break;
  255. case UNAM_IDENT:
  256. p1putdds(P1_IDENT, addrp->vtype, addrp->vstg,
  257. addrp->user.ident);
  258. break;
  259. case UNAM_CHARP:
  260. p1putdds(P1_CHARP, addrp->vtype, addrp->vstg,
  261. addrp->user.Charp);
  262. break;
  263. case UNAM_EXTERN:
  264. p1putd (P1_EXTERN, (long) addrp -> memno);
  265. if (addrp->vclass == CLPROC)
  266. extsymtab[addrp->memno].extype = addrp->vtype;
  267. break;
  268. case UNAM_CONST:
  269. if (addrp -> memno != BAD_MEMNO)
  270. p1_literal (addrp -> memno);
  271. else
  272. p1_const((struct Constblock *)addrp);
  273. break;
  274. case UNAM_UNKNOWN:
  275. default:
  276. erri ("p1_addr: unknown uname_tag '%d'", addrp -> uname_tag);
  277. break;
  278. } /* switch */
  279. } /* p1_addr */
  280. static void
  281. #ifdef KR_headers
  282. p1_list(listp)
  283. struct Listblock *listp;
  284. #else
  285. p1_list(struct Listblock *listp)
  286. #endif
  287. {
  288. chainp lis;
  289. int count = 0;
  290. if (listp == (struct Listblock *) NULL)
  291. return;
  292. /* Count the number of parameters in the list */
  293. for (lis = listp -> listp; lis; lis = lis -> nextp)
  294. count++;
  295. p1putddd (P1_LIST, listp -> tag, listp -> vtype, count);
  296. for (lis = listp -> listp; lis; lis = lis -> nextp)
  297. p1_expr ((expptr) lis -> datap);
  298. } /* p1_list */
  299. void
  300. #ifdef KR_headers
  301. p1_label(lab)
  302. long lab;
  303. #else
  304. p1_label(long lab)
  305. #endif
  306. {
  307. if (parstate < INDATA)
  308. earlylabs = mkchain((char *)(Addr)lab, earlylabs);
  309. else
  310. p1putd (P1_LABEL, lab);
  311. }
  312. static void
  313. #ifdef KR_headers
  314. p1_literal(memno)
  315. long memno;
  316. #else
  317. p1_literal(long memno)
  318. #endif
  319. {
  320. p1putd (P1_LITERAL, memno);
  321. } /* p1_literal */
  322. void
  323. #ifdef KR_headers
  324. p1_if(expr)
  325. expptr expr;
  326. #else
  327. p1_if(expptr expr)
  328. #endif
  329. {
  330. p1put (P1_IF);
  331. p1_expr (expr);
  332. } /* p1_if */
  333. void
  334. #ifdef KR_headers
  335. p1_elif(expr)
  336. expptr expr;
  337. #else
  338. p1_elif(expptr expr)
  339. #endif
  340. {
  341. p1put (P1_ELIF);
  342. p1_expr (expr);
  343. } /* p1_elif */
  344. void
  345. p1_else(Void)
  346. {
  347. p1put (P1_ELSE);
  348. } /* p1_else */
  349. void
  350. p1_endif(Void)
  351. {
  352. p1put (P1_ENDIF);
  353. } /* p1_endif */
  354. void
  355. p1else_end(Void)
  356. {
  357. p1put (P1_ENDELSE);
  358. } /* p1else_end */
  359. static void
  360. #ifdef KR_headers
  361. p1_big_addr(addrp)
  362. Addrp addrp;
  363. #else
  364. p1_big_addr(Addrp addrp)
  365. #endif
  366. {
  367. if (addrp == (Addrp) NULL)
  368. return;
  369. p1putn (P1_ADDR, (int)sizeof(struct Addrblock), (char *) addrp);
  370. p1_expr (addrp -> vleng);
  371. p1_expr (addrp -> memoffset);
  372. if (addrp->uname_tag == UNAM_NAME)
  373. addrp->user.name->visused = 1;
  374. } /* p1_big_addr */
  375. static void
  376. #ifdef KR_headers
  377. p1_unary(e)
  378. struct Exprblock *e;
  379. #else
  380. p1_unary(struct Exprblock *e)
  381. #endif
  382. {
  383. if (e == (struct Exprblock *) NULL)
  384. return;
  385. p1putdd (P1_EXPR, (int) e -> opcode, e -> vtype);
  386. p1_expr (e -> vleng);
  387. switch (e -> opcode) {
  388. case OPNEG:
  389. case OPNEG1:
  390. case OPNOT:
  391. case OPABS:
  392. case OPBITNOT:
  393. case OPPREINC:
  394. case OPPREDEC:
  395. case OPADDR:
  396. case OPIDENTITY:
  397. case OPCHARCAST:
  398. case OPDABS:
  399. p1_expr(e -> leftp);
  400. break;
  401. default:
  402. erri ("p1_unary: bad opcode '%d'", (int) e -> opcode);
  403. break;
  404. } /* switch */
  405. } /* p1_unary */
  406. static void
  407. #ifdef KR_headers
  408. p1_binary(e)
  409. struct Exprblock *e;
  410. #else
  411. p1_binary(struct Exprblock *e)
  412. #endif
  413. {
  414. if (e == (struct Exprblock *) NULL)
  415. return;
  416. p1putdd (P1_EXPR, e -> opcode, e -> vtype);
  417. p1_expr (e -> vleng);
  418. p1_expr (e -> leftp);
  419. p1_expr (e -> rightp);
  420. } /* p1_binary */
  421. void
  422. #ifdef KR_headers
  423. p1_head(Class, name)
  424. int Class;
  425. char *name;
  426. #else
  427. p1_head(int Class, char *name)
  428. #endif
  429. {
  430. p1putds (P1_HEAD, Class, (char*)(name ? name : ""));
  431. } /* p1_head */
  432. void
  433. #ifdef KR_headers
  434. p1_subr_ret(retexp)
  435. expptr retexp;
  436. #else
  437. p1_subr_ret(expptr retexp)
  438. #endif
  439. {
  440. p1put (P1_SUBR_RET);
  441. p1_expr (cpexpr(retexp));
  442. } /* p1_subr_ret */
  443. void
  444. #ifdef KR_headers
  445. p1comp_goto(index, count, labels)
  446. expptr index;
  447. int count;
  448. struct Labelblock **labels;
  449. #else
  450. p1comp_goto(expptr index, int count, struct Labelblock **labels)
  451. #endif
  452. {
  453. struct Constblock c;
  454. int i;
  455. register struct Labelblock *L;
  456. p1put (P1_COMP_GOTO);
  457. p1_expr (index);
  458. /* Write out a P1_LIST directly, to avoid the overhead of allocating a
  459. list before it's needed HACK HACK HACK */
  460. p1putddd (P1_LIST, TLIST, TYUNKNOWN, count);
  461. c.vtype = TYLONG;
  462. c.vleng = 0;
  463. for (i = 0; i < count; i++) {
  464. L = labels[i];
  465. L->labused = 1;
  466. c.Const.ci = L->stateno;
  467. p1_const(&c);
  468. } /* for i = 0 */
  469. } /* p1comp_goto */
  470. void
  471. #ifdef KR_headers
  472. p1_for(init, test, inc)
  473. expptr init;
  474. expptr test;
  475. expptr inc;
  476. #else
  477. p1_for(expptr init, expptr test, expptr inc)
  478. #endif
  479. {
  480. p1put (P1_FOR);
  481. p1_expr (init);
  482. p1_expr (test);
  483. p1_expr (inc);
  484. } /* p1_for */
  485. void
  486. p1for_end(Void)
  487. {
  488. p1put (P1_ENDFOR);
  489. } /* p1for_end */
  490. /* ----------------------------------------------------------------------
  491. The intermediate file actually gets written ONLY by the routines below.
  492. To change the format of the file, you need only change these routines.
  493. ----------------------------------------------------------------------
  494. */
  495. /* p1puts -- Put a typed string into the Pass 1 intermediate file. Assumes that
  496. str contains no newlines and is null-terminated. */
  497. void
  498. #ifdef KR_headers
  499. p1puts(type, str)
  500. int type;
  501. char *str;
  502. #else
  503. p1puts(int type, char *str)
  504. #endif
  505. {
  506. fprintf (pass1_file, "%d: %s\n", type, str);
  507. } /* p1puts */
  508. /* p1puta -- Put an Addr into the Pass 1 intermediate file. */
  509. static void
  510. #ifdef KR_headers
  511. p1puta(type, value)
  512. int type;
  513. Addr value;
  514. #else
  515. p1puta(int type, Addr value)
  516. #endif
  517. {
  518. fprintf (pass1_file, "%d: " Addrfmt "\n", type, value);
  519. } /* p1_puta */
  520. /* p1putd -- Put a typed integer into the Pass 1 intermediate file. */
  521. static void
  522. #ifdef KR_headers
  523. p1putd(type, value)
  524. int type;
  525. long value;
  526. #else
  527. p1putd(int type, long value)
  528. #endif
  529. {
  530. fprintf (pass1_file, "%d: %ld\n", type, value);
  531. } /* p1_putd */
  532. /* p1putdd -- Put a typed pair of integers into the intermediate file. */
  533. static void
  534. #ifdef KR_headers
  535. p1putdd(type, v1, v2)
  536. int type;
  537. int v1;
  538. int v2;
  539. #else
  540. p1putdd(int type, int v1, int v2)
  541. #endif
  542. {
  543. fprintf (pass1_file, "%d: %d %d\n", type, v1, v2);
  544. } /* p1putdd */
  545. /* p1putddd -- Put a typed triple of integers into the intermediate file. */
  546. static void
  547. #ifdef KR_headers
  548. p1putddd(type, v1, v2, v3)
  549. int type;
  550. int v1;
  551. int v2;
  552. int v3;
  553. #else
  554. p1putddd(int type, int v1, int v2, int v3)
  555. #endif
  556. {
  557. fprintf (pass1_file, "%d: %d %d %d\n", type, v1, v2, v3);
  558. } /* p1putddd */
  559. union dL {
  560. double d;
  561. long L[2];
  562. };
  563. static void
  564. #ifdef KR_headers
  565. p1putn(type, count, str)
  566. int type;
  567. int count;
  568. char *str;
  569. #else
  570. p1putn(int type, int count, char *str)
  571. #endif
  572. {
  573. int i;
  574. fprintf (pass1_file, "%d: ", type);
  575. for (i = 0; i < count; i++)
  576. putc (str[i], pass1_file);
  577. putc ('\n', pass1_file);
  578. } /* p1putn */
  579. /* p1put -- Put a type marker into the intermediate file. */
  580. void
  581. #ifdef KR_headers
  582. p1put(type)
  583. int type;
  584. #else
  585. p1put(int type)
  586. #endif
  587. {
  588. fprintf (pass1_file, "%d:\n", type);
  589. } /* p1put */
  590. static void
  591. #ifdef KR_headers
  592. p1putds(type, i, str)
  593. int type;
  594. int i;
  595. char *str;
  596. #else
  597. p1putds(int type, int i, char *str)
  598. #endif
  599. {
  600. fprintf (pass1_file, "%d: %d %s\n", type, i, str);
  601. } /* p1putds */
  602. static void
  603. #ifdef KR_headers
  604. p1putdds(token, type, stg, str)
  605. int token;
  606. int type;
  607. int stg;
  608. char *str;
  609. #else
  610. p1putdds(int token, int type, int stg, char *str)
  611. #endif
  612. {
  613. fprintf (pass1_file, "%d: %d %d %s\n", token, type, stg, str);
  614. } /* p1putdds */