/compiler4/sim/sim.c

https://github.com/pandora2000/aiueo · C · 526 lines · 429 code · 24 blank · 73 comment · 177 complexity · 6289309e02d7f206d87f425700b98304 MD5 · raw file

  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <stdbool.h>
  6. #include <unistd.h>
  7. #include <ctype.h>
  8. #include "ssim.h"
  9. const int rareg = 20;//return address
  10. const int greg1 = 2;
  11. const int greg2 = 3;
  12. const int fgreg1 = 0;
  13. const int fgreg2 = 1;
  14. const int spreg = 0;
  15. const int hpreg = 1;
  16. const int sp_offset = 2048;
  17. const int hp_offset = 4096;
  18. bool cmpne;
  19. bool cmpg;
  20. bool cmpl;
  21. FILE *out_fp;
  22. /*stdinからfloatを読む*/
  23. float read_float()
  24. {
  25. char s[100];
  26. int a, i;
  27. bool f;
  28. for (i = 0, f = false; true; )
  29. {
  30. a = fgetc(stdin);
  31. if (f) {
  32. if (a == EOF || isspace(a))
  33. {
  34. s[i] = '\0';
  35. return atof(s);
  36. }
  37. else
  38. {
  39. s[i++] = (char) a;
  40. }
  41. }
  42. else
  43. {
  44. if (!(a == EOF || isspace(a)))
  45. {
  46. f = true;
  47. s[i++] = (char) a;
  48. }
  49. }
  50. }
  51. }
  52. /*stdinからintを読む*/
  53. int read_int()
  54. {
  55. char s[100];
  56. int a, i;
  57. bool f;
  58. for (i = 0, f = false; true; )
  59. {
  60. a = fgetc(stdin);
  61. if (f)
  62. {
  63. if (a == EOF || isspace(a))
  64. {
  65. s[i] = '\0';
  66. return atoi(s);
  67. }
  68. else
  69. {
  70. s[i++] = (char) a;
  71. }
  72. }
  73. else
  74. {
  75. if (!(a == EOF || isspace(a)))
  76. {
  77. f = true;
  78. s[i++] = (char) a;
  79. }
  80. }
  81. }
  82. }
  83. void print_int(int n)
  84. {
  85. static int counter = 0;
  86. if(counter == 0)
  87. {
  88. fprintf(out_fp, "P3\n%d ", n);
  89. }
  90. else if((counter % 3) == 2)
  91. {
  92. fprintf(out_fp, "%d\n", n);
  93. }
  94. else
  95. {
  96. fprintf(out_fp, "%d ", n);
  97. }
  98. ++counter;
  99. }
  100. void simulate_extfunc(int n)
  101. {
  102. int i, a, b, c;
  103. float d;
  104. if(n == 0)
  105. {
  106. //imul
  107. regs[greg1] = regs[greg1] * regs[greg2];
  108. }
  109. else if(n == 1)
  110. {
  111. //fiszero
  112. regs[greg1] = fregs[fgreg1] == 0.0 ? 1 : 0;
  113. }
  114. else if(n == 2)
  115. {
  116. //fispos
  117. regs[greg1] = fregs[fgreg1] > 0.0 ? 1 : 0;
  118. }
  119. else if(n == 3)
  120. {
  121. //fneg
  122. fregs[fgreg1] = - fregs[fgreg1];
  123. }
  124. else if(n == 4)
  125. {
  126. //fsqr
  127. fregs[fgreg1] = fregs[fgreg1] * fregs[fgreg1];
  128. }
  129. else if(n == 5)
  130. {
  131. //sqrt
  132. fregs[fgreg1] = sqrtf(fregs[fgreg1]);
  133. }
  134. else if(n == 6)
  135. {
  136. //read_float
  137. d = read_float();
  138. printf("read_float: %f\n", d);
  139. fregs[fgreg1] = d;
  140. }
  141. else if(n == 7)
  142. {
  143. //cos
  144. fregs[fgreg1] = cosf(fregs[fgreg1]);
  145. }
  146. else if(n == 8)
  147. {
  148. //sin
  149. fregs[fgreg1] = sinf(fregs[fgreg1]);
  150. }
  151. else if(n == 9)
  152. {
  153. //read_int
  154. a = read_int();
  155. printf("read_int: %d\n", a);
  156. regs[greg1] = a;
  157. }
  158. else if(n == 10)
  159. {
  160. //fisneg
  161. regs[greg1] = fregs[fgreg1] < 0.0 ? 1 : 0;
  162. }
  163. else if(n == 11)
  164. {
  165. //fabs
  166. fregs[fgreg1] = fregs[fgreg1] < 0.0 ? - fregs[fgreg1] : fregs[fgreg1];
  167. }
  168. else if(n == 12)
  169. {
  170. //fless
  171. regs[greg1] = fregs[fgreg1] < fregs[fgreg2] ? 1 : 0;
  172. }
  173. else if(n == 13)
  174. {
  175. //fhalf
  176. fregs[fgreg1] = fregs[fgreg1] * 0.5;
  177. }
  178. else if(n == 14)
  179. {
  180. //floor
  181. fregs[fgreg1] = floorf(fregs[fgreg1]);
  182. }
  183. else if(n == 15)
  184. {
  185. //atan
  186. fregs[fgreg1] = atanf(fregs[fgreg1]);
  187. }
  188. else if(n == 16)
  189. {
  190. //print_int
  191. print_int(regs[greg1]);
  192. }
  193. else if(n == 17)
  194. {
  195. //print_float
  196. print_int((int)fregs[fgreg1]);
  197. }
  198. else if(n == 18)
  199. {
  200. //float_of_int
  201. fregs[fgreg1] = (float)regs[greg1];
  202. }
  203. else if(n == 19)
  204. {
  205. //create_array
  206. a = regs[greg1];
  207. b = regs[hpreg];
  208. regs[greg1] = b;
  209. regs[hpreg] += a << 2;
  210. c = regs[greg2];
  211. for(i = 0; i < a; ++i)
  212. {
  213. memory[(b + (i << 2)) >> 2].i = c;
  214. }
  215. }
  216. else
  217. {
  218. //create_float_array
  219. a = regs[greg1];
  220. b = regs[hpreg];
  221. regs[greg1] = b;
  222. regs[hpreg] += a << 3;
  223. d = fregs[fgreg1];
  224. for(i = 0; i < a; ++i)
  225. {
  226. memory[(b + (i << 3)) >> 2].f = d;
  227. }
  228. }
  229. }
  230. int simulate_blanch_extfunc(int n)
  231. {
  232. simulate_extfunc(-1 - n);
  233. return regs[rareg];
  234. }
  235. int simulate_instruction(instruction_fast *fist, int pc)
  236. {
  237. int npc = pc + 1, nm, a1, a2, a3, a4, t;
  238. static long long clk = 0;
  239. nm = fist->name;
  240. a1 = fist->args[0];
  241. a2 = fist->args[1];
  242. a3 = fist->args[2];
  243. a4 = fist->args[3];
  244. //print_regs();
  245. //print_fregs();
  246. if(clk > 620000 && memory[2].i == 271504)
  247. {
  248. /*
  249. print_regs();
  250. //print_fregs();
  251. //printf("%lld %d\n", clk, pc);
  252. print_label(pc);
  253. print_instruction(pc);
  254. */
  255. }
  256. if(clk > 621000)
  257. {
  258. //print_regs();
  259. //print_fregs();
  260. //printf("%lld %d\n", clk, pc);
  261. //print_label(pc);
  262. //print_instruction(pc);
  263. }
  264. ++clk;
  265. if(nm == 0)
  266. {
  267. //nop
  268. }
  269. else if(nm == 1)
  270. {
  271. //add
  272. t = a2 < 0 ? a4 : regs[a2];
  273. regs[a3] = regs[a1] + t;
  274. }
  275. else if(nm == 2)
  276. {
  277. //sub
  278. t = a2 < 0 ? a4 : regs[a2];
  279. regs[a3] = regs[a1] - t;
  280. }
  281. else if(nm == 3)
  282. {
  283. //cmp
  284. t = a2 < 0 ? a4 : regs[a2];
  285. cmpne = regs[a1] != t;
  286. cmpg = regs[a1] > t;
  287. cmpl = regs[a1] < t;
  288. }
  289. else if(nm == 4)
  290. {
  291. //bne
  292. if(cmpne)
  293. {
  294. simulate_instruction(&fprog.insts[npc], npc);
  295. if(a1 < 0)
  296. {
  297. return simulate_blanch_extfunc(a1);
  298. }
  299. return a1;
  300. }
  301. }
  302. else if(nm == 5)
  303. {
  304. //ld
  305. t = a2 < 0 ? a4 : regs[a2];
  306. regs[a3] = memory[(regs[a1] + t) >> 2].i;
  307. }
  308. else if(nm == 6)
  309. {
  310. //ldd
  311. t = a2 < 0 ? a4 : regs[a2];
  312. fregs[a3] = memory[(regs[a1] + t) >> 2].f;
  313. }
  314. else if(nm == 7)
  315. {
  316. //st
  317. t = a3 < 0 ? a4 : regs[a3];
  318. memory[(regs[a2] + t) >> 2].i = regs[a1];
  319. }
  320. else if(nm == 8)
  321. {
  322. //set
  323. t = a1 < 0 ? a4 : a1;
  324. regs[a2] = t;
  325. }
  326. else if(nm == 9)
  327. {
  328. //retl
  329. simulate_instruction(&fprog.insts[npc], npc);
  330. return regs[rareg];
  331. }
  332. else if(nm == 10)
  333. {
  334. //b
  335. simulate_instruction(&fprog.insts[npc], npc);
  336. if(a1 < 0)
  337. {
  338. return simulate_blanch_extfunc(a1);
  339. }
  340. return a1;
  341. }
  342. else if(nm == 11)
  343. {
  344. //mov
  345. regs[a2] = regs[a1];
  346. }
  347. else if(nm == 12)
  348. {
  349. //std
  350. t = a3 < 0 ? a4 : regs[a3];
  351. memory[(regs[a2] + t) >> 2].f = fregs[a1];
  352. }
  353. else if(nm == 13)
  354. {
  355. //call
  356. simulate_instruction(&fprog.insts[npc], npc);
  357. if(a1 < 0)
  358. {
  359. simulate_extfunc(-1 - a1);
  360. return npc + 1;
  361. }
  362. regs[rareg] = npc + 1;
  363. return a1;
  364. }
  365. else if(nm == 14)
  366. {
  367. //bl
  368. if(cmpl)
  369. {
  370. simulate_instruction(&fprog.insts[npc], npc);
  371. if(a1 < 0)
  372. {
  373. return simulate_blanch_extfunc(a1);
  374. }
  375. return a1;
  376. }
  377. }
  378. else if(nm == 15)
  379. {
  380. //fmovs
  381. if((a1 & 1) == 0)
  382. {
  383. fregs[a2] = fregs[a1];
  384. }
  385. }
  386. else if(nm == 16)
  387. {
  388. //faddd
  389. fregs[a3] = fregs[a1] + fregs[a2];
  390. }
  391. else if(nm == 17)
  392. {
  393. //fmuld
  394. fregs[a3] = fregs[a1] * fregs[a2];
  395. }
  396. else if(nm == 18)
  397. {
  398. //fdivd
  399. fregs[a3] = fregs[a1] / fregs[a2];
  400. }
  401. else if(nm == 19)
  402. {
  403. //fsubd
  404. fregs[a3] = fregs[a1] - fregs[a2];
  405. }
  406. else if(nm == 20)
  407. {
  408. //sll
  409. t = a2 < 0 ? a4 : regs[a2];
  410. regs[a3] = regs[a1] << t;
  411. }
  412. else if(nm == 21)
  413. {
  414. //bg
  415. if(cmpg)
  416. {
  417. simulate_instruction(&fprog.insts[npc], npc);
  418. if(a1 < 0)
  419. {
  420. return simulate_blanch_extfunc(a1);
  421. }
  422. return a1;
  423. }
  424. }
  425. else if(nm == 22)
  426. {
  427. //fcmpd
  428. cmpg = fregs[a1] > fregs[a2];
  429. }
  430. else if(nm == 23)
  431. {
  432. //fbg
  433. if(cmpg)
  434. {
  435. simulate_instruction(&fprog.insts[npc], npc);
  436. if(a1 < 0)
  437. {
  438. return simulate_blanch_extfunc(a1);
  439. }
  440. return a1;
  441. }
  442. }
  443. else
  444. {
  445. //bp
  446. print_regs();
  447. }
  448. return npc;
  449. }
  450. void simulate(char *ofname)
  451. {
  452. int pc = labeltoi("min_caml_start");
  453. //int i;
  454. //char str[1000];
  455. /*
  456. for(i = 0; i < prog.label_count; ++i)
  457. {
  458. printf("%s: %d\n", prog.labels[i].name, prog.labels[i].index);
  459. }
  460. */
  461. out_fp = fopen(ofname, "w");
  462. regs[spreg] = sp_offset << 2;
  463. regs[hpreg] = hp_offset << 2;
  464. init_memory();
  465. //print_memory();
  466. //printf("pc: %d\n", pc);
  467. while(true)
  468. {
  469. if((pc = simulate_instruction(&fprog.insts[pc], pc)) == prog.inst_count)
  470. {
  471. break;
  472. }
  473. }
  474. fclose(out_fp);
  475. }
  476. int main(int argc, char *argv[])
  477. {
  478. int result;
  479. FILE *fp;
  480. char ofname[1000] = "result";
  481. while ((result = getopt(argc, argv, "o:")) != -1)
  482. {
  483. switch (result)
  484. {
  485. case 'o':
  486. strcpy(ofname, optarg);
  487. break;
  488. }
  489. }
  490. argc -= optind;
  491. argv += optind;
  492. fp = fopen(argv[0], "r");
  493. init_reg_count();
  494. init_freg_count();
  495. init_extval();
  496. init_extfunc();
  497. init_inst_kind_count();
  498. parse(fp);
  499. simulate(ofname);
  500. //print_memory();
  501. return 0;
  502. }