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