com64.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. #include "cc.h"
  2. /*
  3. * this is machine depend, but it is totally
  4. * common on all of the 64-bit symulating machines.
  5. */
  6. #define FNX 100 /* botch -- redefinition */
  7. Node* nodaddv;
  8. Node* nodsubv;
  9. Node* nodmulv;
  10. Node* noddivv;
  11. Node* noddivvu;
  12. Node* nodmodv;
  13. Node* nodmodvu;
  14. Node* nodlshv;
  15. Node* nodrshav;
  16. Node* nodrshlv;
  17. Node* nodandv;
  18. Node* nodorv;
  19. Node* nodxorv;
  20. Node* nodnegv;
  21. Node* nodcomv;
  22. Node* nodtestv;
  23. Node* nodeqv;
  24. Node* nodnev;
  25. Node* nodlev;
  26. Node* nodltv;
  27. Node* nodgev;
  28. Node* nodgtv;
  29. Node* nodhiv;
  30. Node* nodhsv;
  31. Node* nodlov;
  32. Node* nodlsv;
  33. Node* nodf2v;
  34. Node* nodd2v;
  35. Node* nodp2v;
  36. Node* nodsi2v;
  37. Node* nodui2v;
  38. Node* nodsl2v;
  39. Node* nodul2v;
  40. Node* nodsh2v;
  41. Node* noduh2v;
  42. Node* nodsc2v;
  43. Node* noduc2v;
  44. Node* nodv2f;
  45. Node* nodv2d;
  46. Node* nodv2ui;
  47. Node* nodv2si;
  48. Node* nodv2ul;
  49. Node* nodv2sl;
  50. Node* nodv2uh;
  51. Node* nodv2sh;
  52. Node* nodv2uc;
  53. Node* nodv2sc;
  54. Node* nodvpp;
  55. Node* nodppv;
  56. Node* nodvmm;
  57. Node* nodmmv;
  58. Node* nodvasop;
  59. char etconv[NTYPE]; /* for _vasop */
  60. Init initetconv[] =
  61. {
  62. TCHAR, 1, 0,
  63. TUCHAR, 2, 0,
  64. TSHORT, 3, 0,
  65. TUSHORT, 4, 0,
  66. TLONG, 5, 0,
  67. TULONG, 6, 0,
  68. TVLONG, 7, 0,
  69. TUVLONG, 8, 0,
  70. TINT, 9, 0,
  71. TUINT, 10, 0,
  72. -1, 0, 0,
  73. };
  74. Node*
  75. fvn(char *name, int type)
  76. {
  77. Node *n;
  78. n = new(ONAME, Z, Z);
  79. n->sym = slookup(name);
  80. if(fntypes[type] == 0)
  81. fntypes[type] = typ(TFUNC, types[type]);
  82. n->type = fntypes[type];
  83. n->etype = type;
  84. n->class = CGLOBL;
  85. n->addable = 10;
  86. n->complex = 0;
  87. return n;
  88. }
  89. void
  90. com64init(void)
  91. {
  92. Init *p;
  93. nodaddv = fvn("_addv", TVLONG);
  94. nodsubv = fvn("_subv", TVLONG);
  95. nodmulv = fvn("_mulv", TVLONG);
  96. noddivv = fvn("_divv", TVLONG);
  97. noddivvu = fvn("_divvu", TVLONG);
  98. nodmodv = fvn("_modv", TVLONG);
  99. nodmodvu = fvn("_modvu", TVLONG);
  100. nodlshv = fvn("_lshv", TVLONG);
  101. nodrshav = fvn("_rshav", TVLONG);
  102. nodrshlv = fvn("_rshlv", TVLONG);
  103. nodandv = fvn("_andv", TVLONG);
  104. nodorv = fvn("_orv", TVLONG);
  105. nodxorv = fvn("_xorv", TVLONG);
  106. nodnegv = fvn("_negv", TVLONG);
  107. nodcomv = fvn("_comv", TVLONG);
  108. nodtestv = fvn("_testv", TLONG);
  109. nodeqv = fvn("_eqv", TLONG);
  110. nodnev = fvn("_nev", TLONG);
  111. nodlev = fvn("_lev", TLONG);
  112. nodltv = fvn("_ltv", TLONG);
  113. nodgev = fvn("_gev", TLONG);
  114. nodgtv = fvn("_gtv", TLONG);
  115. nodhiv = fvn("_hiv", TLONG);
  116. nodhsv = fvn("_hsv", TLONG);
  117. nodlov = fvn("_lov", TLONG);
  118. nodlsv = fvn("_lsv", TLONG);
  119. nodf2v = fvn("_f2v", TVLONG);
  120. nodd2v = fvn("_d2v", TVLONG);
  121. nodp2v = fvn("_p2v", TVLONG);
  122. nodsi2v = fvn("_si2v", TVLONG);
  123. nodui2v = fvn("_ui2v", TVLONG);
  124. nodsl2v = fvn("_sl2v", TVLONG);
  125. nodul2v = fvn("_ul2v", TVLONG);
  126. nodsh2v = fvn("_sh2v", TVLONG);
  127. noduh2v = fvn("_uh2v", TVLONG);
  128. nodsc2v = fvn("_sc2v", TVLONG);
  129. noduc2v = fvn("_uc2v", TVLONG);
  130. nodv2f = fvn("_v2f", TFLOAT);
  131. nodv2d = fvn("_v2d", TDOUBLE);
  132. nodv2sl = fvn("_v2sl", TLONG);
  133. nodv2ul = fvn("_v2ul", TULONG);
  134. nodv2si = fvn("_v2si", TINT);
  135. nodv2ui = fvn("_v2ui", TUINT);
  136. nodv2sh = fvn("_v2sh", TSHORT);
  137. nodv2uh = fvn("_v2ul", TUSHORT);
  138. nodv2sc = fvn("_v2sc", TCHAR);
  139. nodv2uc = fvn("_v2uc", TUCHAR);
  140. nodvpp = fvn("_vpp", TVLONG);
  141. nodppv = fvn("_ppv", TVLONG);
  142. nodvmm = fvn("_vmm", TVLONG);
  143. nodmmv = fvn("_mmv", TVLONG);
  144. nodvasop = fvn("_vasop", TVLONG);
  145. for(p = initetconv; p->code >= 0; p++)
  146. etconv[p->code] = p->value;
  147. }
  148. int
  149. com64(Node *n)
  150. {
  151. Node *l, *r, *a, *t;
  152. int lv, rv;
  153. if(n->type == 0)
  154. return 0;
  155. l = n->left;
  156. r = n->right;
  157. lv = 0;
  158. if(l && l->type && typev[l->type->etype])
  159. lv = 1;
  160. rv = 0;
  161. if(r && r->type && typev[r->type->etype])
  162. rv = 1;
  163. if(lv) {
  164. switch(n->op) {
  165. case OEQ:
  166. a = nodeqv;
  167. goto setbool;
  168. case ONE:
  169. a = nodnev;
  170. goto setbool;
  171. case OLE:
  172. a = nodlev;
  173. goto setbool;
  174. case OLT:
  175. a = nodltv;
  176. goto setbool;
  177. case OGE:
  178. a = nodgev;
  179. goto setbool;
  180. case OGT:
  181. a = nodgtv;
  182. goto setbool;
  183. case OHI:
  184. a = nodhiv;
  185. goto setbool;
  186. case OHS:
  187. a = nodhsv;
  188. goto setbool;
  189. case OLO:
  190. a = nodlov;
  191. goto setbool;
  192. case OLS:
  193. a = nodlsv;
  194. goto setbool;
  195. case OANDAND:
  196. case OOROR:
  197. if(rv) {
  198. r = new(OFUNC, nodtestv, r);
  199. n->right = r;
  200. r->complex = FNX;
  201. r->op = OFUNC;
  202. r->type = types[TLONG];
  203. }
  204. case OCOND:
  205. case ONOT:
  206. l = new(OFUNC, nodtestv, l);
  207. n->left = l;
  208. l->complex = FNX;
  209. l->op = OFUNC;
  210. l->type = types[TLONG];
  211. n->complex = FNX;
  212. return 1;
  213. }
  214. }
  215. if(rv) {
  216. switch(n->op) {
  217. case OANDAND:
  218. case OOROR:
  219. r = new(OFUNC, nodtestv, r);
  220. n->right = r;
  221. r->complex = FNX;
  222. r->op = OFUNC;
  223. r->type = types[TLONG];
  224. return 1;
  225. }
  226. }
  227. if(typev[n->type->etype]) {
  228. switch(n->op) {
  229. default:
  230. diag(n, "unknown vlong %O", n->op);
  231. case OFUNC:
  232. n->complex = FNX;
  233. case ORETURN:
  234. case OAS:
  235. case OIND:
  236. return 1;
  237. case OADD:
  238. a = nodaddv;
  239. goto setbop;
  240. case OSUB:
  241. a = nodsubv;
  242. goto setbop;
  243. case OMUL:
  244. case OLMUL:
  245. a = nodmulv;
  246. goto setbop;
  247. case ODIV:
  248. a = noddivv;
  249. goto setbop;
  250. case OLDIV:
  251. a = noddivvu;
  252. goto setbop;
  253. case OMOD:
  254. a = nodmodv;
  255. goto setbop;
  256. case OLMOD:
  257. a = nodmodvu;
  258. goto setbop;
  259. case OASHL:
  260. a = nodlshv;
  261. goto setbop;
  262. case OASHR:
  263. a = nodrshav;
  264. goto setbop;
  265. case OLSHR:
  266. a = nodrshlv;
  267. goto setbop;
  268. case OAND:
  269. a = nodandv;
  270. goto setbop;
  271. case OOR:
  272. a = nodorv;
  273. goto setbop;
  274. case OXOR:
  275. a = nodxorv;
  276. goto setbop;
  277. case OPOSTINC:
  278. a = nodvpp;
  279. goto setvinc;
  280. case OPOSTDEC:
  281. a = nodvmm;
  282. goto setvinc;
  283. case OPREINC:
  284. a = nodppv;
  285. goto setvinc;
  286. case OPREDEC:
  287. a = nodmmv;
  288. goto setvinc;
  289. case ONEG:
  290. a = nodnegv;
  291. goto setfnx;
  292. case OCOM:
  293. a = nodcomv;
  294. goto setfnx;
  295. case OCAST:
  296. switch(l->type->etype) {
  297. case TCHAR:
  298. a = nodsc2v;
  299. goto setfnxl;
  300. case TUCHAR:
  301. a = noduc2v;
  302. goto setfnxl;
  303. case TSHORT:
  304. a = nodsh2v;
  305. goto setfnxl;
  306. case TUSHORT:
  307. a = noduh2v;
  308. goto setfnxl;
  309. case TINT:
  310. a = nodsi2v;
  311. goto setfnx;
  312. case TUINT:
  313. a = nodui2v;
  314. goto setfnx;
  315. case TLONG:
  316. a = nodsl2v;
  317. goto setfnx;
  318. case TULONG:
  319. a = nodul2v;
  320. goto setfnx;
  321. case TFLOAT:
  322. a = nodf2v;
  323. goto setfnx;
  324. case TDOUBLE:
  325. a = nodd2v;
  326. goto setfnx;
  327. case TIND:
  328. a = nodp2v;
  329. goto setfnx;
  330. }
  331. diag(n, "unknown %T->vlong cast", l->type);
  332. return 1;
  333. case OASADD:
  334. a = nodaddv;
  335. goto setasop;
  336. case OASSUB:
  337. a = nodsubv;
  338. goto setasop;
  339. case OASMUL:
  340. case OASLMUL:
  341. a = nodmulv;
  342. goto setasop;
  343. case OASDIV:
  344. a = noddivv;
  345. goto setasop;
  346. case OASLDIV:
  347. a = noddivvu;
  348. goto setasop;
  349. case OASMOD:
  350. a = nodmodv;
  351. goto setasop;
  352. case OASLMOD:
  353. a = nodmodvu;
  354. goto setasop;
  355. case OASASHL:
  356. a = nodlshv;
  357. goto setasop;
  358. case OASASHR:
  359. a = nodrshav;
  360. goto setasop;
  361. case OASLSHR:
  362. a = nodrshlv;
  363. goto setasop;
  364. case OASAND:
  365. a = nodandv;
  366. goto setasop;
  367. case OASOR:
  368. a = nodorv;
  369. goto setasop;
  370. case OASXOR:
  371. a = nodxorv;
  372. goto setasop;
  373. }
  374. }
  375. if(typefd[n->type->etype] && l && l->op == OFUNC) {
  376. switch(n->op) {
  377. case OASADD:
  378. case OASSUB:
  379. case OASMUL:
  380. case OASLMUL:
  381. case OASDIV:
  382. case OASLDIV:
  383. case OASMOD:
  384. case OASLMOD:
  385. case OASASHL:
  386. case OASASHR:
  387. case OASLSHR:
  388. case OASAND:
  389. case OASOR:
  390. case OASXOR:
  391. if(l->right && typev[l->right->etype]) {
  392. diag(n, "sorry float <asop> vlong not implemented\n");
  393. }
  394. }
  395. }
  396. if(n->op == OCAST) {
  397. if(l->type && typev[l->type->etype]) {
  398. switch(n->type->etype) {
  399. case TDOUBLE:
  400. a = nodv2d;
  401. goto setfnx;
  402. case TFLOAT:
  403. a = nodv2f;
  404. goto setfnx;
  405. case TLONG:
  406. a = nodv2sl;
  407. goto setfnx;
  408. case TULONG:
  409. a = nodv2ul;
  410. goto setfnx;
  411. case TINT:
  412. a = nodv2si;
  413. goto setfnx;
  414. case TUINT:
  415. a = nodv2ui;
  416. goto setfnx;
  417. case TSHORT:
  418. a = nodv2sh;
  419. goto setfnx;
  420. case TUSHORT:
  421. a = nodv2uh;
  422. goto setfnx;
  423. case TCHAR:
  424. a = nodv2sc;
  425. goto setfnx;
  426. case TUCHAR:
  427. a = nodv2uc;
  428. goto setfnx;
  429. case TIND: // small pun here
  430. a = nodv2ul;
  431. goto setfnx;
  432. }
  433. diag(n, "unknown vlong->%T cast", n->type);
  434. return 1;
  435. }
  436. }
  437. return 0;
  438. setbop:
  439. n->left = a;
  440. n->right = new(OLIST, l, r);
  441. n->complex = FNX;
  442. n->op = OFUNC;
  443. return 1;
  444. setfnxl:
  445. l = new(OCAST, l, 0);
  446. l->type = types[TLONG];
  447. l->complex = l->left->complex;
  448. setfnx:
  449. n->left = a;
  450. n->right = l;
  451. n->complex = FNX;
  452. n->op = OFUNC;
  453. return 1;
  454. setvinc:
  455. n->left = a;
  456. l = new(OADDR, l, Z);
  457. l->type = typ(TIND, l->left->type);
  458. n->right = new(OLIST, l, r);
  459. n->complex = FNX;
  460. n->op = OFUNC;
  461. return 1;
  462. setbool:
  463. n->left = a;
  464. n->right = new(OLIST, l, r);
  465. n->complex = FNX;
  466. n->op = OFUNC;
  467. n->type = types[TLONG];
  468. return 1;
  469. setasop:
  470. if(l->op == OFUNC) {
  471. l = l->right;
  472. goto setasop;
  473. }
  474. t = new(OCONST, 0, 0);
  475. t->vconst = etconv[l->type->etype];
  476. t->type = types[TLONG];
  477. t->addable = 20;
  478. r = new(OLIST, t, r);
  479. t = new(OADDR, a, 0);
  480. t->type = typ(TIND, a->type);
  481. r = new(OLIST, t, r);
  482. t = new(OADDR, l, 0);
  483. t->type = typ(TIND, l->type);
  484. r = new(OLIST, t, r);
  485. n->left = nodvasop;
  486. n->right = r;
  487. n->complex = FNX;
  488. n->op = OFUNC;
  489. return 1;
  490. }
  491. void
  492. bool64(Node *n)
  493. {
  494. Node *n1;
  495. if(typev[n->type->etype]) {
  496. n1 = new(OXXX, 0, 0);
  497. *n1 = *n;
  498. n->right = n1;
  499. n->left = nodtestv;
  500. n->complex = FNX;
  501. n->addable = 0;
  502. n->op = OFUNC;
  503. n->type = types[TLONG];
  504. }
  505. }
  506. /*
  507. * more machine depend stuff.
  508. * this is common for 8,16,32,64 bit machines.
  509. * this is common for ieee machines.
  510. */
  511. double
  512. convvtof(vlong v)
  513. {
  514. double d;
  515. d = v; /* BOTCH */
  516. return d;
  517. }
  518. vlong
  519. convftov(double d)
  520. {
  521. vlong v;
  522. v = d; /* BOTCH */
  523. return v;
  524. }
  525. double
  526. convftox(double d, int et)
  527. {
  528. if(!typefd[et])
  529. diag(Z, "bad type in castftox %s", tnames[et]);
  530. return d;
  531. }
  532. vlong
  533. convvtox(vlong c, int et)
  534. {
  535. int n;
  536. n = 8 * ewidth[et];
  537. c &= MASK(n);
  538. if(!typeu[et])
  539. if(c & SIGN(n))
  540. c |= ~MASK(n);
  541. return c;
  542. }