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