mkswitch.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*
  2. Generates contents of opcode switch from ip_spec.t
  3. Call is:
  4. mkswitch prefix ip_spec.t cases [ functions ]
  5. Note:
  6. The u flag has been implemented by just copying and adjusting the
  7. code for 2, which is almost identical to that for 4. When this has
  8. stabilized, combine.
  9. */
  10. /* $Id$ */
  11. #include <stdio.h>
  12. extern FILE *popen();
  13. char *progname;
  14. FILE *ifp; /* Input File Pointer */
  15. FILE *ofp; /* Output File Pointer */
  16. FILE *ffp = 0; /* Function File Pointer */
  17. char *Prefix; /* Prefix for function name */
  18. main(argc, argv)
  19. int argc;
  20. char **argv;
  21. {
  22. char mnem[8]; /* Mnemonic */
  23. char flgs[8]; /* Flags */
  24. char command[32];
  25. progname = argv[0];
  26. if (argc < 4 || argc >5) {
  27. fatal("usage is: %s prefix ip_spec.t cases [ functions ]\n",
  28. argv[0]);
  29. }
  30. Prefix = argv[1];
  31. if ((ifp = fopen(argv[2], "r")) == 0) {
  32. fatal("cannot open '%s' for reading\n", argv[2]);
  33. }
  34. if ((ofp = fopen(argv[3], "w")) == 0) {
  35. fatal("cannot open '%s' for writing\n", argv[3]);
  36. }
  37. if (argc == 5) { /* Need to store functions */
  38. sprintf(command, "sort | uniq > %s", argv[4]);
  39. if ((ffp = popen(command, "w")) == 0) {
  40. fatal("cannot popen '%s'\n", command);
  41. }
  42. }
  43. /* Start reading the input file */
  44. while (fscanf(ifp, "%s %s", mnem, flgs) >= 0) {
  45. int i;
  46. char *p;
  47. char *base;
  48. int cnt, first;
  49. /* check flags */
  50. for (p = flgs; *p; p++) {
  51. if (!in("-ms2u4eNPwo", *p)) {
  52. fatal("bad flags ip_spec: %s\n", flgs);
  53. }
  54. }
  55. if ( in(flgs, '-')
  56. + in(flgs, 'm')
  57. + in(flgs, 's')
  58. + in(flgs, '2')
  59. + in(flgs, 'u')
  60. + in(flgs, '4')
  61. != 1
  62. ) {
  63. fatal("duplicate or missing opcode flag ip_spec: %s\n",
  64. flgs);
  65. }
  66. if ( in(flgs, 'N')
  67. + in(flgs, 'P')
  68. > 1
  69. ) {
  70. fatal("duplicate restriction flags ip_spec: %s\n", flgs);
  71. }
  72. /* capitalize mnemonic */
  73. for (p = mnem; *p; p++) {
  74. *p += ('A' - 'a');
  75. }
  76. /* scan rest of line */
  77. if ( in(flgs, '-')
  78. || in(flgs, '2')
  79. || in(flgs, 'u')
  80. || in(flgs, '4')
  81. ) {
  82. fscanf(ifp, " %d \n", &first);
  83. }
  84. else {
  85. fscanf(ifp, " %d %d \n", &cnt, &first);
  86. }
  87. /* determine base */
  88. if (in(flgs, 'e')) /* Escaped (secondary) opcode */
  89. base = "SEC_BASE";
  90. else
  91. if (in(flgs, '4')) /* Escaped (tertiary) opcode */
  92. base = "TERT_BASE";
  93. else
  94. base = "PRIM_BASE";
  95. /* analyse the opcode */
  96. if (in(flgs, '-')) { /* No arguments */
  97. NoArgs(base, first, mnem);
  98. } else if (in(flgs, 'm')) { /* Mini */
  99. for (i = 0; i<cnt; i++) {
  100. Mini(i, flgs, base, first, mnem);
  101. }
  102. } else if (in(flgs, 's')) { /* Shortie */
  103. for (i = 0; i<cnt; i++) {
  104. Shortie(i, flgs, base, first, mnem);
  105. }
  106. } else if (in(flgs, '2')) { /* Two byte signed */
  107. TwoSgn(flgs, base, first, mnem);
  108. } else if (in(flgs, 'u')) { /* Two byte unsigned */
  109. TwoUns(flgs, base, first, mnem);
  110. } else if (in(flgs, '4')) { /* Four byte signed */
  111. FourSgn(flgs, base, first, mnem);
  112. } else {
  113. fatal("no opcode flag in ip_spec %s\n", flgs);
  114. }
  115. }
  116. exit(0);
  117. }
  118. NoArgs(base, first, mnem)
  119. char *base;
  120. int first;
  121. char *mnem;
  122. {
  123. fprintf(ofp, "\t\tcase %s+%d:\t%s%sz(); break;\n",
  124. base, first, Prefix, mnem);
  125. if (ffp) {
  126. fprintf(ffp, "%s%sz() {", Prefix, mnem);
  127. fprintf(ffp, "LOG((\"@ %s%sz()\"));}\n", Prefix, mnem);
  128. }
  129. }
  130. Mini(i, flgs, base, first, mnem)
  131. int i;
  132. char *flgs;
  133. char *base;
  134. int first;
  135. char *mnem;
  136. {
  137. char arg[16];
  138. int newi = in(flgs, 'N') ? (-i-1) : in(flgs, 'o') ? (i+1) : i;
  139. switch (newi) {
  140. case -1:
  141. sprintf(arg, "%s",
  142. in(flgs, 'w') ? "-wsize" : "-1L");
  143. break;
  144. case 0:
  145. sprintf(arg, "0L");
  146. break;
  147. case 1:
  148. sprintf(arg, "%s",
  149. in(flgs, 'w') ? "wsize" : "1L");
  150. break;
  151. default:
  152. sprintf(arg, "%dL%s",
  153. newi, in(flgs, 'w') ? "*wsize" : "");
  154. break;
  155. }
  156. fprintf(ofp, "\t\tcase %s+%d:\t%s%sm(%s); break;\n",
  157. base, first+i, Prefix, mnem, arg);
  158. if (ffp) {
  159. fprintf(ffp, "%s%sm(arg) long arg; {",
  160. Prefix, mnem);
  161. fprintf(ffp, "LOG((\"@ %s%sm(%%d)\", arg));}\n",
  162. Prefix, mnem);
  163. }
  164. }
  165. Shortie(i, flgs, base, first, mnem)
  166. int i;
  167. char *flgs;
  168. char *base;
  169. int first;
  170. char *mnem;
  171. {
  172. char arg[16];
  173. int newi = in(flgs, 'N') ? (-i-1) : in(flgs, 'o') ? (i+1) : i;
  174. sprintf(arg, "%dL, %s", newi, (in(flgs, 'w') ? "wsize" : "1L"));
  175. fprintf(ofp, "\t\tcase %s+%d:\t%s%ss(%s); break;\n",
  176. base, first+i, Prefix, mnem, arg);
  177. if (ffp) {
  178. fprintf(ffp, "%s%ss(hob, wfac) long hob; size wfac; {",
  179. Prefix, mnem);
  180. fprintf(ffp, "LOG((\"@ %s%ss(%%d)\", hob, wfac));",
  181. Prefix, mnem);
  182. fprintf(ffp, " newPC(PC+1);}\n");
  183. }
  184. }
  185. TwoSgn(flgs, base, first, mnem)
  186. char *flgs;
  187. char *base;
  188. int first;
  189. char *mnem;
  190. {
  191. char *xy = in(flgs, 'P') ? "p2" : in(flgs, 'N') ? "n2" : "l2";
  192. fprintf(ofp, "\t\tcase %s+%d:\t%s%s%s(%s); break;\n",
  193. base, first, Prefix, mnem, xy,
  194. in(flgs, 'w') ? "wsize" : "1L");
  195. if (ffp) {
  196. fprintf(ffp, "%s%s%s(arg) long arg; {", Prefix, mnem, xy);
  197. fprintf(ffp, "LOG((\"@ %s%s%s(%%d)\", arg));",
  198. Prefix, mnem, xy);
  199. fprintf(ffp, " newPC(PC+2);}\n");
  200. }
  201. }
  202. TwoUns(flgs, base, first, mnem)
  203. char *flgs;
  204. char *base;
  205. int first;
  206. char *mnem;
  207. {
  208. char *xy = "u";
  209. fprintf(ofp, "\t\tcase %s+%d:\t%s%s%s(%s); break;\n",
  210. base, first, Prefix, mnem, xy,
  211. in(flgs, 'w') ? "wsize" : "1L");
  212. if (ffp) {
  213. fprintf(ffp, "%s%s%s(arg) long arg; {", Prefix, mnem, xy);
  214. fprintf(ffp, "LOG((\"@ %s%s%s(%%d)\", arg));",
  215. Prefix, mnem, xy);
  216. fprintf(ffp, " newPC(PC+2);}\n");
  217. }
  218. }
  219. FourSgn(flgs, base, first, mnem)
  220. char *flgs;
  221. char *base;
  222. int first;
  223. char *mnem;
  224. {
  225. char *xy = in(flgs, 'P') ? "p4" : in(flgs, 'N') ? "n4" : "l4";
  226. fprintf(ofp, "\t\tcase %s+%d:\t%s%s%s(%s); break;\n",
  227. base, first, Prefix, mnem, xy,
  228. in(flgs, 'w') ? "wsize" : "1L");
  229. if (ffp) {
  230. fprintf(ffp, "%s%s%s(arg) long arg; {", Prefix, mnem, xy);
  231. fprintf(ffp, "LOG((\"@ %s%s%s(%%d)\", arg));",
  232. Prefix, mnem, xy);
  233. fprintf(ffp, " newPC(PC+4);}\n");
  234. }
  235. }
  236. int
  237. in(flgs, c)
  238. char *flgs;
  239. char c;
  240. {
  241. while (*flgs)
  242. if (c == *flgs++)
  243. return 1;
  244. return 0;
  245. }
  246. fatal(fmt, str)
  247. char *fmt;
  248. char *str;
  249. {
  250. fprintf(stderr, "%s, (fatal error): ", progname);
  251. fprintf(stderr, fmt, str);
  252. fprintf(stderr, "\n");
  253. exit(1);
  254. }