com64.c 9.9 KB

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