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