com64.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  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. 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. }
  233. }
  234. if(typev[n->type->etype]) {
  235. if(machcap(n))
  236. return 1;
  237. switch(n->op) {
  238. default:
  239. diag(n, "unknown vlong %O", n->op);
  240. case OFUNC:
  241. n->complex = FNX;
  242. case ORETURN:
  243. case OAS:
  244. case OIND:
  245. return 1;
  246. case OADD:
  247. a = nodaddv;
  248. goto setbop;
  249. case OSUB:
  250. a = nodsubv;
  251. goto setbop;
  252. case OMUL:
  253. case OLMUL:
  254. a = nodmulv;
  255. goto setbop;
  256. case ODIV:
  257. a = noddivv;
  258. goto setbop;
  259. case OLDIV:
  260. a = noddivvu;
  261. goto setbop;
  262. case OMOD:
  263. a = nodmodv;
  264. goto setbop;
  265. case OLMOD:
  266. a = nodmodvu;
  267. goto setbop;
  268. case OASHL:
  269. a = nodlshv;
  270. goto setbop;
  271. case OASHR:
  272. a = nodrshav;
  273. goto setbop;
  274. case OLSHR:
  275. a = nodrshlv;
  276. goto setbop;
  277. case OAND:
  278. a = nodandv;
  279. goto setbop;
  280. case OOR:
  281. a = nodorv;
  282. goto setbop;
  283. case OXOR:
  284. a = nodxorv;
  285. goto setbop;
  286. case OPOSTINC:
  287. a = nodvpp;
  288. goto setvinc;
  289. case OPOSTDEC:
  290. a = nodvmm;
  291. goto setvinc;
  292. case OPREINC:
  293. a = nodppv;
  294. goto setvinc;
  295. case OPREDEC:
  296. a = nodmmv;
  297. goto setvinc;
  298. case ONEG:
  299. a = nodnegv;
  300. goto setfnx;
  301. case OCOM:
  302. a = nodcomv;
  303. goto setfnx;
  304. case OCAST:
  305. switch(l->type->etype) {
  306. case TCHAR:
  307. a = nodsc2v;
  308. goto setfnxl;
  309. case TUCHAR:
  310. a = noduc2v;
  311. goto setfnxl;
  312. case TSHORT:
  313. a = nodsh2v;
  314. goto setfnxl;
  315. case TUSHORT:
  316. a = noduh2v;
  317. goto setfnxl;
  318. case TINT:
  319. a = nodsi2v;
  320. goto setfnx;
  321. case TUINT:
  322. a = nodui2v;
  323. goto setfnx;
  324. case TLONG:
  325. a = nodsl2v;
  326. goto setfnx;
  327. case TULONG:
  328. a = nodul2v;
  329. goto setfnx;
  330. case TFLOAT:
  331. a = nodf2v;
  332. goto setfnx;
  333. case TDOUBLE:
  334. a = nodd2v;
  335. goto setfnx;
  336. case TIND:
  337. a = nodp2v;
  338. goto setfnx;
  339. }
  340. diag(n, "unknown %T->vlong cast", l->type);
  341. return 1;
  342. case OASADD:
  343. a = nodaddv;
  344. goto setasop;
  345. case OASSUB:
  346. a = nodsubv;
  347. goto setasop;
  348. case OASMUL:
  349. case OASLMUL:
  350. a = nodmulv;
  351. goto setasop;
  352. case OASDIV:
  353. a = noddivv;
  354. goto setasop;
  355. case OASLDIV:
  356. a = noddivvu;
  357. goto setasop;
  358. case OASMOD:
  359. a = nodmodv;
  360. goto setasop;
  361. case OASLMOD:
  362. a = nodmodvu;
  363. goto setasop;
  364. case OASASHL:
  365. a = nodlshv;
  366. goto setasop;
  367. case OASASHR:
  368. a = nodrshav;
  369. goto setasop;
  370. case OASLSHR:
  371. a = nodrshlv;
  372. goto setasop;
  373. case OASAND:
  374. a = nodandv;
  375. goto setasop;
  376. case OASOR:
  377. a = nodorv;
  378. goto setasop;
  379. case OASXOR:
  380. a = nodxorv;
  381. goto setasop;
  382. }
  383. }
  384. if(typefd[n->type->etype] && l && l->op == OFUNC) {
  385. switch(n->op) {
  386. case OASADD:
  387. case OASSUB:
  388. case OASMUL:
  389. case OASLMUL:
  390. case OASDIV:
  391. case OASLDIV:
  392. case OASMOD:
  393. case OASLMOD:
  394. case OASASHL:
  395. case OASASHR:
  396. case OASLSHR:
  397. case OASAND:
  398. case OASOR:
  399. case OASXOR:
  400. if(l->right && typev[l->right->etype]) {
  401. diag(n, "sorry float <asop> vlong not implemented\n");
  402. }
  403. }
  404. }
  405. if(n->op == OCAST) {
  406. if(l->type && typev[l->type->etype]) {
  407. if(machcap(n))
  408. return 1;
  409. switch(n->type->etype) {
  410. case TDOUBLE:
  411. a = nodv2d;
  412. goto setfnx;
  413. case TFLOAT:
  414. a = nodv2f;
  415. goto setfnx;
  416. case TLONG:
  417. a = nodv2sl;
  418. goto setfnx;
  419. case TULONG:
  420. a = nodv2ul;
  421. goto setfnx;
  422. case TINT:
  423. a = nodv2si;
  424. goto setfnx;
  425. case TUINT:
  426. a = nodv2ui;
  427. goto setfnx;
  428. case TSHORT:
  429. a = nodv2sh;
  430. goto setfnx;
  431. case TUSHORT:
  432. a = nodv2uh;
  433. goto setfnx;
  434. case TCHAR:
  435. a = nodv2sc;
  436. goto setfnx;
  437. case TUCHAR:
  438. a = nodv2uc;
  439. goto setfnx;
  440. case TIND: // small pun here
  441. a = nodv2ul;
  442. goto setfnx;
  443. }
  444. diag(n, "unknown vlong->%T cast", n->type);
  445. return 1;
  446. }
  447. }
  448. return 0;
  449. setbop:
  450. n->left = a;
  451. n->right = new(OLIST, l, r);
  452. n->complex = FNX;
  453. n->op = OFUNC;
  454. return 1;
  455. setfnxl:
  456. l = new(OCAST, l, 0);
  457. l->type = types[TLONG];
  458. l->complex = l->left->complex;
  459. setfnx:
  460. n->left = a;
  461. n->right = l;
  462. n->complex = FNX;
  463. n->op = OFUNC;
  464. return 1;
  465. setvinc:
  466. n->left = a;
  467. l = new(OADDR, l, Z);
  468. l->type = typ(TIND, l->left->type);
  469. n->right = new(OLIST, l, r);
  470. n->complex = FNX;
  471. n->op = OFUNC;
  472. return 1;
  473. setbool:
  474. if(machcap(n))
  475. return 1;
  476. n->left = a;
  477. n->right = new(OLIST, l, r);
  478. n->complex = FNX;
  479. n->op = OFUNC;
  480. n->type = types[TLONG];
  481. return 1;
  482. setasop:
  483. if(l->op == OFUNC) {
  484. l = l->right;
  485. goto setasop;
  486. }
  487. t = new(OCONST, 0, 0);
  488. t->vconst = etconv[l->type->etype];
  489. t->type = types[TLONG];
  490. t->addable = 20;
  491. r = new(OLIST, t, r);
  492. t = new(OADDR, a, 0);
  493. t->type = typ(TIND, a->type);
  494. r = new(OLIST, t, r);
  495. t = new(OADDR, l, 0);
  496. t->type = typ(TIND, l->type);
  497. r = new(OLIST, t, r);
  498. n->left = nodvasop;
  499. n->right = r;
  500. n->complex = FNX;
  501. n->op = OFUNC;
  502. return 1;
  503. }
  504. void
  505. bool64(Node *n)
  506. {
  507. Node *n1;
  508. if(typev[n->type->etype]) {
  509. n1 = new(OXXX, 0, 0);
  510. *n1 = *n;
  511. n->right = n1;
  512. n->left = nodtestv;
  513. n->complex = FNX;
  514. n->addable = 0;
  515. n->op = OFUNC;
  516. n->type = types[TLONG];
  517. }
  518. }
  519. /*
  520. * more machine depend stuff.
  521. * this is common for 8,16,32,64 bit machines.
  522. * this is common for ieee machines.
  523. */
  524. double
  525. convvtof(vlong v)
  526. {
  527. double d;
  528. d = v; /* BOTCH */
  529. return d;
  530. }
  531. vlong
  532. convftov(double d)
  533. {
  534. vlong v;
  535. v = d; /* BOTCH */
  536. return v;
  537. }
  538. double
  539. convftox(double d, int et)
  540. {
  541. if(!typefd[et])
  542. diag(Z, "bad type in castftox %s", tnames[et]);
  543. return d;
  544. }
  545. vlong
  546. convvtox(vlong c, int et)
  547. {
  548. int n;
  549. n = 8 * ewidth[et];
  550. c &= MASK(n);
  551. if(!typeu[et])
  552. if(c & SIGN(n))
  553. c |= ~MASK(n);
  554. return c;
  555. }