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