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