1 /** 2 * Compiler implementation of the 3 * $(LINK2 http://www.dlang.org, D programming language). 4 * 5 * Copyright: Copyright (C) 1985-1998 by Symantec 6 * Copyright (C) 2000-2020 by The D Language Foundation, All Rights Reserved 7 * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) 8 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 9 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/oper.d, backend/oper.d) 10 */ 11 12 module dmd.backend.oper; 13 14 // Online documentation: https://dlang.org/phobos/dmd_backend_oper.html 15 16 extern (C++): 17 @nogc: 18 nothrow: 19 20 alias OPER = int; 21 enum 22 { 23 OPunde, // place holder for undefined operator 24 25 OPadd, 26 OPmin, 27 OPmul, 28 OPdiv, 29 OPmod, 30 OPshr, // unsigned right shift 31 OPshl, 32 OPand, 33 OPxor, 34 OPor, 35 OPashr, // signed right shift 36 OPnot, 37 OPbool, // "booleanize" 38 OPcom, 39 OPcond, 40 OPcomma, 41 OPoror, 42 OPandand, 43 OPbit, // ref to bit field 44 OPind, // *E 45 OPaddr, // &E 46 OPneg, // unary - 47 OPuadd, // unary + 48 OPvoid, // where casting to void is not a no-op 49 OPabs, // absolute value 50 OPrndtol, // round to short, long, long long (inline 8087 only) 51 OPrint, // round to int 52 53 OPsqrt, // square root 54 OPsin, // sine 55 OPcos, // cosine 56 OPscale, // ldexp 57 OPyl2x, // y * log2(x) 58 OPyl2xp1, // y * log2(x + 1) 59 OPcmpxchg, // cmpxchg 60 61 OPstrlen, // strlen() 62 OPstrcpy, // strcpy() 63 OPstrcat, // strcat() 64 OPstrcmp, // strcmp() 65 OPmemcpy, 66 OPmemcmp, 67 OPmemset, 68 OPsetjmp, // setjmp() 69 70 OPremquo, // / and % in one operation 71 72 OPbsf, // bit scan forward 73 OPbsr, // bit scan reverse 74 OPbt, // bit test 75 OPbtc, // bit test and complement 76 OPbtr, // bit test and reset 77 OPbts, // bit test and set 78 OPbswap, // swap bytes 79 OProl, // rotate left 80 OPror, // rotate right 81 OPbtst, // bit test 82 OPpopcnt, // count of number of bits set to 1 83 84 OPstreq, // structure assignment 85 86 OPnegass, // x = -x 87 OPpostinc, // x++ 88 OPpostdec, // x-- 89 90 OPeq, 91 OPaddass, 92 OPminass, 93 OPmulass, 94 OPdivass, 95 OPmodass, 96 OPshrass, 97 OPshlass, 98 OPandass, 99 OPxorass, 100 OPorass, 101 102 OPashrass, 103 104 // relational operators (in same order as corresponding tokens) 105 RELOPMIN, 106 OPle = RELOPMIN, 107 OPgt, 108 OPlt, 109 OPge, 110 OPeqeq, 111 OPne, 112 113 OPunord, // !<>= 114 OPlg, // <> 115 OPleg, // <>= 116 OPule, // !> 117 OPul, // !>= 118 OPuge, // !< 119 OPug, // !<= 120 OPue, // !<> 121 OPngt, 122 OPnge, 123 OPnlt, 124 OPnle, 125 OPord, 126 OPnlg, 127 OPnleg, 128 OPnule, 129 OPnul, 130 OPnuge, 131 OPnug, 132 RELOPMAX, 133 OPnue = RELOPMAX, 134 135 //**************** End of relational operators ***************** 136 137 /* 8,16,32,64 integral type of unspecified sign 138 s,u signed/unsigned 139 f,d,ld float/double/long double 140 np,fp,vp,f16p near pointer/far pointer/handle pointer/far16 pointer 141 cvp const handle pointer 142 */ 143 144 CNVOPMIN, 145 OPb_8 = CNVOPMIN, // convert bit to byte 146 OPd_s32, 147 OPs32_d, 148 OPd_s16, 149 OPs16_d, 150 OPd_u16, 151 OPu16_d, 152 OPd_u32, 153 OPu32_d, 154 OPd_s64, 155 OPs64_d, 156 OPd_u64, 157 OPu64_d, 158 OPd_f, 159 OPf_d, 160 OPs16_32, // short to long 161 OPu16_32, // unsigned short to long 162 OP32_16, // long to short 163 OPu8_16, // unsigned char to short 164 OPs8_16, // signed char to short 165 OP16_8, // short to 8 bits 166 OPu32_64, // unsigned long to long long 167 OPs32_64, // long to long long 168 OP64_32, // long long to long 169 OPu64_128, 170 OPs64_128, 171 OP128_64, 172 173 // segmented 174 OPvp_fp, 175 OPcvp_fp, // const handle * => far * 176 OPoffset, // get offset of far pointer 177 OPnp_fp, // convert near pointer to far 178 OPnp_f16p, // from 0:32 to 16:16 179 OPf16p_np, // from 16:16 to 0:32 180 181 OPld_d, 182 OPd_ld, 183 CNVOPMAX, 184 OPld_u64 = CNVOPMAX, 185 186 //**************** End of conversion operators ***************** 187 188 OPc_r, // complex to real 189 OPc_i, // complex to imaginary 190 OPmsw, // top 32 bits of 64 bit word (32 bit code gen) 191 // top 16 bits of 32 bit word (16 bit code gen) 192 193 OPparam, // function parameter separator 194 OPcall, // binary function call 195 OPucall, // unary function call 196 OPcallns, // binary function call, no side effects 197 OPucallns, // unary function call, no side effects 198 199 OPsizeof, // for forward-ref'd structs 200 OPstrctor, // call ctor on struct param 201 OPstrthis, // 'this' pointer for OPstrctor 202 OPstrpar, // structure func param 203 OPconst, // constant 204 OPrelconst, // constant that contains an address 205 OPvar, // variable 206 OPreg, // register (used in inline asm operand expressions) 207 OPcolon, // : as in ?: 208 OPcolon2, // alternate version with different EH semantics 209 OPstring, // address of string 210 OPnullptr, // null pointer 211 OPasm, // in-line assembly code 212 OPinfo, // attach info (used to attach ctor/dtor 213 // info for exception handling) 214 OPhalt, // insert HLT instruction 215 OPctor, 216 OPdtor, 217 OPmark, 218 OPdctor, // D constructor 219 OPddtor, // D destructor 220 221 OPpair, // build register pair, E1 is lsb, E2 = msb 222 OPrpair, // build reversed register pair, E1 is msb, E2 = lsb 223 OPframeptr, // load pointer to base of frame 224 OPgot, // load pointer to global offset table 225 OPvector, // SIMD vector operations 226 OPvecsto, // SIMD vector store operations 227 OPvecfill, // fill SIMD vector with E1 228 229 OPinp, // input from I/O port 230 OPoutp, // output to I/O port 231 232 // C++ operators 233 OPnew, // operator new 234 OPanew, // operator new[] 235 OPdelete, // operator delete 236 OPadelete, // operator delete[] 237 OPbrack, // [] subscript 238 OParrow, // for -> overloading 239 OParrowstar, // for ->* overloading 240 OPpreinc, // ++x overloading 241 OPpredec, // --x overloading 242 243 OPva_start, // va_start intrinsic (dmd) 244 OPprefetch, // prefetch intrinsic (dmd) 245 246 OPMAX // 1 past last operator 247 } 248 249 250 /************************************ 251 * Determine things about relational operators. 252 */ 253 254 OPER rel_not(OPER op) { return _rel_not [op - RELOPMIN]; } 255 OPER rel_swap(OPER op) { return _rel_swap [op - RELOPMIN]; } 256 OPER rel_integral(OPER op) { return _rel_integral [op - RELOPMIN]; } 257 OPER rel_exception(OPER op) { return _rel_exception[op - RELOPMIN]; } 258 OPER rel_unord(OPER op) { return _rel_unord [op - RELOPMIN]; } 259 260 /**************************************** 261 * Conversion operators. 262 * Convert from conversion operator to conversion index 263 * parallel array invconvtab[] in cgelem.c 264 * Params: 265 * op = conversion operator 266 */ 267 int convidx(OPER op) { return op - CNVOPMIN; } 268 269 270 /********************************** 271 * Various types of operators: 272 * OTbinary binary 273 * OTunary unary 274 * OTleaf leaf 275 * OTcommut commutative (e1 op e2) == (e2 op e1) 276 * (assoc == !=) 277 * OTassoc associative (e1 op (e2 op e3)) == ((e1 op e2) op e3) 278 * (also commutative) 279 * OTassign assignment = op= i++ i-- i=-i str= 280 * OTpost post inc or post dec operator 281 * OTeop0e if (e op 0) => e 282 * OTeop00 if (e op 0) => 0 283 * OTeop1e if (e op 1) => e 284 * OTsideff there are side effects to the operator (assign call 285 * post ?: && ||) 286 * OTconv type conversion operator that could appear on lhs of 287 * assignment operator 288 * OTlogical logical operator (result is 0 or 1) 289 * OTwid high order bits of operation are irrelevant 290 * OTopeq an op= operator 291 * OTop an operator that has a corresponding op= 292 * OTcall function call 293 * OTrtol operators that evaluate right subtree first then left 294 * OTrel == != < <= > >= operators 295 * OTrel2 < <= > >= operators 296 * OTdef definition operator (assign call post asm) 297 * OTae potential common subexpression operator 298 * OTboolnop operation is a nop if boolean result is desired 299 */ 300 301 /* optab1[] */ /* Use byte arrays to avoid index scaling */ 302 enum 303 { 304 _OTbinary = 1, 305 _OTunary = 2, 306 _OTcommut = 4, 307 _OTassoc = 8, 308 _OTsideff = 0x10, 309 _OTeop0e = 0x20, 310 _OTeop00 = 0x40, 311 _OTeop1e = 0x80, 312 } 313 314 /* optab2[] */ 315 enum 316 { 317 _OTlogical = 1, 318 _OTwid = 2, 319 _OTcall = 4, 320 _OTrtol = 8, 321 _OTassign = 0x10, 322 _OTdef = 0x20, 323 _OTae = 0x40, 324 } 325 326 // optab3[] 327 enum 328 { 329 _OTboolnop = 1, 330 } 331 332 ubyte OTbinary(OPER op) { return optab1[op] & _OTbinary; } 333 ubyte OTunary(OPER op) { return optab1[op] & _OTunary; } 334 bool OTleaf(OPER op) { return !(optab1[op] & (_OTunary|_OTbinary)); } 335 ubyte OTcommut(OPER op) { return optab1[op] & _OTcommut; } 336 ubyte OTassoc(OPER op) { return optab1[op] & _OTassoc; } 337 ubyte OTassign(OPER op) { return optab2[op]&_OTassign; } 338 bool OTpost(OPER op) { return op == OPpostinc || op == OPpostdec; } 339 ubyte OTeop0e(OPER op) { return optab1[op] & _OTeop0e; } 340 ubyte OTeop00(OPER op) { return optab1[op] & _OTeop00; } 341 ubyte OTeop1e(OPER op) { return optab1[op] & _OTeop1e; } 342 ubyte OTsideff(OPER op) { return optab1[op] & _OTsideff; } 343 bool OTconv(OPER op) { return op >= CNVOPMIN && op <= CNVOPMAX; } 344 ubyte OTlogical(OPER op) { return optab2[op] & _OTlogical; } 345 ubyte OTwid(OPER op) { return optab2[op] & _OTwid; } 346 bool OTopeq(OPER op) { return op >= OPaddass && op <= OPashrass; } 347 bool OTop(OPER op) { return op >= OPadd && op <= OPor; } 348 ubyte OTcall(OPER op) { return optab2[op] & _OTcall; } 349 ubyte OTrtol(OPER op) { return optab2[op] & _OTrtol; } 350 bool OTrel(OPER op) { return op >= OPle && op <= OPnue; } 351 bool OTrel2(OPER op) { return op >= OPle && op <= OPge; } 352 ubyte OTdef(OPER op) { return optab2[op] & _OTdef; } 353 ubyte OTae(OPER op) { return optab2[op] & _OTae; } 354 ubyte OTboolnop(OPER op) { return optab3[op] & _OTboolnop; } 355 bool OTcalldef(OPER op) { return OTcall(op) || op == OPstrcpy || op == OPstrcat || op == OPmemcpy; } 356 357 /* Convert op= to op */ 358 OPER opeqtoop(OPER opx) { return opx - OPaddass + OPadd; } 359 360 /* Convert op to op= */ 361 OPER optoopeq(OPER opx) { return opx - OPadd + OPaddass; } 362 363 OPER swaprel(OPER); 364 365 /*************************** 366 * Determine properties of an elem. 367 * EBIN binary node? 368 * EUNA unary node? 369 * EOP operator node (unary or binary)? 370 * ERTOL right to left evaluation (left to right is default) 371 * Eunambig unambiguous definition elem? 372 */ 373 374 //#define EBIN(e) (OTbinary((e)->Eoper)) 375 //#define EUNA(e) (OTunary((e)->Eoper)) 376 377 /* ERTOL(e) is moved to el.c */ 378 379 //#define Elvalue(e) ((e)->E1) 380 //#define Eunambig(e) (OTassign((e)->Eoper) && (e)->E1->Eoper == OPvar) 381 382 //#define EOP(e) (!OTleaf((e)->Eoper)) 383 384 extern (D): 385 386 extern (C) immutable ubyte[OPMAX] optab1 = 387 () { 388 ubyte[OPMAX] tab; 389 foreach (i; Ebinary) { tab[i] |= _OTbinary; } 390 foreach (i; Eunary) { tab[i] |= _OTunary; } 391 foreach (i; Ecommut) { tab[i] |= _OTcommut; } 392 foreach (i; Eassoc) { tab[i] |= _OTassoc; } 393 foreach (i; Esideff) { tab[i] |= _OTsideff; } 394 foreach (i; Eeop0e) { tab[i] |= _OTeop0e; } 395 foreach (i; Eeop00) { tab[i] |= _OTeop00; } 396 foreach (i; Eeop1e) { tab[i] |= _OTeop1e; } 397 return tab; 398 } (); 399 400 immutable ubyte[OPMAX] optab2 = 401 () { 402 ubyte[OPMAX] tab; 403 foreach (i; Elogical) { tab[i] |= _OTlogical; } 404 foreach (i; Ewid) { tab[i] |= _OTwid; } 405 foreach (i; Ecall) { tab[i] |= _OTcall; } 406 foreach (i; Ertol) { tab[i] |= _OTrtol; } 407 foreach (i; Eassign) { tab[i] |= _OTassign; } 408 foreach (i; Edef) { tab[i] |= _OTdef; } 409 foreach (i; Eae) { tab[i] |= _OTae; } 410 return tab; 411 } (); 412 413 immutable ubyte[OPMAX] optab3 = 414 () { 415 ubyte[OPMAX] tab; 416 foreach (i; Eboolnop) { tab[i] |= _OTboolnop; } 417 return tab; 418 } (); 419 420 private enum RELMAX = RELOPMAX - RELOPMIN + 1; 421 422 immutable ubyte[RELMAX] _rel_exception = 423 () { 424 ubyte[RELMAX] tab; 425 foreach (i; Eexception) { tab[cast(int)i - RELOPMIN] = 1; } 426 return tab; 427 } (); 428 429 immutable ubyte[RELMAX] _rel_unord = 430 () { 431 ubyte[RELMAX] tab; 432 foreach (i; Eunord) { tab[cast(int)i - RELOPMIN] = 1; } 433 return tab; 434 } (); 435 436 /// Logical negation 437 immutable ubyte[RELMAX] _rel_not = 438 () { 439 ubyte[RELMAX] tab; 440 foreach (op; RELOPMIN .. RELOPMAX + 1) 441 { 442 OPER opnot; 443 switch (op) 444 { 445 case OPeqeq: opnot = OPne; break; 446 case OPne: opnot = OPeqeq; break; 447 case OPgt: opnot = OPngt; break; 448 case OPge: opnot = OPnge; break; 449 case OPlt: opnot = OPnlt; break; 450 case OPle: opnot = OPnle; break; 451 452 case OPunord: opnot = OPord; break; 453 case OPlg: opnot = OPnlg; break; 454 case OPleg: opnot = OPnleg; break; 455 case OPule: opnot = OPnule; break; 456 case OPul: opnot = OPnul; break; 457 case OPuge: opnot = OPnuge; break; 458 case OPug: opnot = OPnug; break; 459 case OPue: opnot = OPnue; break; 460 461 case OPngt: opnot = OPgt; break; 462 case OPnge: opnot = OPge; break; 463 case OPnlt: opnot = OPlt; break; 464 case OPnle: opnot = OPle; break; 465 case OPord: opnot = OPunord; break; 466 case OPnlg: opnot = OPlg; break; 467 case OPnleg: opnot = OPleg; break; 468 case OPnule: opnot = OPule; break; 469 case OPnul: opnot = OPul; break; 470 case OPnuge: opnot = OPuge; break; 471 case OPnug: opnot = OPug; break; 472 case OPnue: opnot = OPue; break; 473 474 default: 475 assert(0); 476 } 477 tab[cast(int)op - RELOPMIN] = cast(ubyte)opnot; 478 } 479 480 foreach (op; RELOPMIN .. RELOPMAX + 1) 481 { 482 OPER opnot = tab[cast(int)op - RELOPMIN]; 483 assert(op == tab[cast(int)opnot - RELOPMIN]); // symmetry check 484 } 485 return tab; 486 } (); 487 488 489 /// Operand swap 490 immutable ubyte[RELMAX] _rel_swap = 491 () { 492 ubyte[RELMAX] tab; 493 foreach (op; RELOPMIN .. RELOPMAX + 1) 494 { 495 OPER opswap; 496 switch (op) 497 { 498 case OPeqeq: opswap = op; break; 499 case OPne: opswap = op; break; 500 case OPgt: opswap = OPlt; break; 501 case OPge: opswap = OPle; break; 502 case OPlt: opswap = OPgt; break; 503 case OPle: opswap = OPge; break; 504 505 case OPunord: opswap = op; break; 506 case OPlg: opswap = op; break; 507 case OPleg: opswap = op; break; 508 case OPule: opswap = OPuge; break; 509 case OPul: opswap = OPug; break; 510 case OPuge: opswap = OPule; break; 511 case OPug: opswap = OPul; break; 512 case OPue: opswap = op; break; 513 514 case OPngt: opswap = OPnlt; break; 515 case OPnge: opswap = OPnle; break; 516 case OPnlt: opswap = OPngt; break; 517 case OPnle: opswap = OPnge; break; 518 case OPord: opswap = op; break; 519 case OPnlg: opswap = op; break; 520 case OPnleg: opswap = op; break; 521 case OPnule: opswap = OPnuge; break; 522 case OPnul: opswap = OPnug; break; 523 case OPnuge: opswap = OPnule; break; 524 case OPnug: opswap = OPnul; break; 525 case OPnue: opswap = op; break; 526 527 default: 528 assert(0); 529 } 530 tab[cast(int)op - RELOPMIN] = cast(ubyte)opswap; 531 } 532 533 foreach (op; RELOPMIN .. RELOPMAX + 1) 534 { 535 OPER opswap = tab[cast(int)op - RELOPMIN]; 536 assert(op == tab[cast(int)opswap - RELOPMIN]); // symmetry check 537 } 538 return tab; 539 } (); 540 541 /// If operands are integral types 542 immutable ubyte[RELMAX] _rel_integral = 543 () { 544 ubyte[RELMAX] tab; 545 foreach (op; RELOPMIN .. RELOPMAX + 1) 546 { 547 OPER opintegral; 548 switch (op) 549 { 550 case OPeqeq: opintegral = op; break; 551 case OPne: opintegral = op; break; 552 case OPgt: opintegral = op; break; 553 case OPge: opintegral = op; break; 554 case OPlt: opintegral = op; break; 555 case OPle: opintegral = op; break; 556 557 case OPunord: opintegral = cast(OPER)0; break; 558 case OPlg: opintegral = OPne; break; 559 case OPleg: opintegral = cast(OPER)1; break; 560 case OPule: opintegral = OPle; break; 561 case OPul: opintegral = OPlt; break; 562 case OPuge: opintegral = OPge; break; 563 case OPug: opintegral = OPgt; break; 564 case OPue: opintegral = OPeqeq; break; 565 566 case OPngt: opintegral = OPle; break; 567 case OPnge: opintegral = OPlt; break; 568 case OPnlt: opintegral = OPge; break; 569 case OPnle: opintegral = OPgt; break; 570 case OPord: opintegral = cast(OPER)1; break; 571 case OPnlg: opintegral = OPeqeq; break; 572 case OPnleg: opintegral = cast(OPER)0; break; 573 case OPnule: opintegral = OPgt; break; 574 case OPnul: opintegral = OPge; break; 575 case OPnuge: opintegral = OPlt; break; 576 case OPnug: opintegral = OPle; break; 577 case OPnue: opintegral = OPne; break; 578 579 default: 580 assert(0); 581 } 582 tab[cast(int)op - RELOPMIN] = cast(ubyte)opintegral; 583 } 584 return tab; 585 } (); 586 587 /************************************* 588 * Determine the cost of evaluating an operator. 589 * 590 * Used for reordering elem trees to minimize register usage. 591 */ 592 593 immutable ubyte[OPMAX] opcost = 594 () { 595 ubyte[OPMAX] tab; 596 foreach (op; 0 .. OPMAX) 597 { 598 ubyte c = 0; // default cost 599 foreach (o; Eunary) 600 { 601 if (o == op) 602 { 603 c += 2; 604 break; 605 } 606 } 607 608 foreach (o; Ebinary) 609 { 610 if (o == op) 611 { 612 c += 7; 613 break; 614 } 615 } 616 617 foreach (o; Elogical) 618 { 619 if (o == op) 620 { 621 c += 3; 622 break; 623 } 624 } 625 626 switch (op) 627 { 628 case OPvar: c += 1; break; 629 case OPmul: c += 3; break; 630 case OPdiv: 631 case OPmod: c += 4; break; 632 case OProl: 633 case OPror: 634 case OPshl: 635 case OPashr: 636 case OPshr: c += 2; break; 637 case OPcall: 638 case OPucall: 639 case OPcallns: 640 case OPucallns: 641 c += 10; break; // very high cost for function calls 642 default: 643 break; 644 } 645 tab[op] = c; 646 } 647 return tab; 648 } (); 649 650 extern (C++) __gshared const(char)*[OPMAX] debtab = 651 [ 652 OPunde: "unde", 653 OPadd: "+", 654 OPmul: "*", 655 OPand: "&", 656 OPmin: "-", 657 OPnot: "!", 658 OPcom: "~", 659 OPcond: "?", 660 OPcomma: ",", 661 OPremquo: "/%", 662 OPdiv: "/", 663 OPmod: "%", 664 OPxor: "^", 665 OPstring: "string", 666 OPrelconst: "relconst", 667 OPinp: "inp", 668 OPoutp: "outp", 669 OPasm: "asm", 670 OPinfo: "info", 671 OPdctor: "dctor", 672 OPddtor: "ddtor", 673 OPctor: "ctor", 674 OPdtor: "dtor", 675 OPmark: "mark", 676 OPvoid: "void", 677 OPhalt: "halt", 678 OPnullptr: "nullptr", 679 OPpair: "pair", 680 OPrpair: "rpair", 681 682 OPor: "|", 683 OPoror: "||", 684 OPandand: "&&", 685 OProl: "<<|", 686 OPror: ">>|", 687 OPshl: "<<", 688 OPshr: ">>>", 689 OPashr: ">>", 690 OPbit: "bit", 691 OPind: "*", 692 OPaddr: "&", 693 OPneg: "-", 694 OPuadd: "+", 695 OPabs: "abs", 696 OPsqrt: "sqrt", 697 OPsin: "sin", 698 OPcos: "cos", 699 OPscale: "scale", 700 OPyl2x: "yl2x", 701 OPyl2xp1: "yl2xp1", 702 OPcmpxchg: "cas", 703 OPrint: "rint", 704 OPrndtol: "rndtol", 705 OPstrlen: "strlen", 706 OPstrcpy: "strcpy", 707 OPmemcpy: "memcpy", 708 OPmemset: "memset", 709 OPstrcat: "strcat", 710 OPstrcmp: "strcmp", 711 OPmemcmp: "memcmp", 712 OPsetjmp: "setjmp", 713 OPnegass: "negass", 714 OPpreinc: "U++", 715 OPpredec: "U--", 716 OPstreq: "streq", 717 OPpostinc: "++", 718 OPpostdec: "--", 719 OPeq: "=", 720 OPaddass: "+=", 721 OPminass: "-=", 722 OPmulass: "*=", 723 OPdivass: "/=", 724 OPmodass: "%=", 725 OPshrass: ">>>=", 726 OPashrass: ">>=", 727 OPshlass: "<<=", 728 OPandass: "&=", 729 OPxorass: "^=", 730 OPorass: "|=", 731 732 OPle: "<=", 733 OPgt: ">", 734 OPlt: "<", 735 OPge: ">=", 736 OPeqeq: "==", 737 OPne: "!=", 738 739 OPunord: "!<>=", 740 OPlg: "<>", 741 OPleg: "<>=", 742 OPule: "!>", 743 OPul: "!>=", 744 OPuge: "!<", 745 OPug: "!<=", 746 OPue: "!<>", 747 OPngt: "~>", 748 OPnge: "~>=", 749 OPnlt: "~<", 750 OPnle: "~<=", 751 OPord: "~!<>=", 752 OPnlg: "~<>", 753 OPnleg: "~<>=", 754 OPnule: "~!>", 755 OPnul: "~!>=", 756 OPnuge: "~!<", 757 OPnug: "~!<=", 758 OPnue: "~!<>", 759 760 OPvp_fp: "vptrfptr", 761 OPcvp_fp: "cvptrfptr", 762 OPoffset: "offset", 763 OPnp_fp: "ptrlptr", 764 OPnp_f16p: "tofar16", 765 OPf16p_np: "fromfar16", 766 767 OPs16_32: "s16_32", 768 OPu16_32: "u16_32", 769 OPd_s32: "d_s32", 770 OPb_8: "b_8", 771 OPs32_d: "s32_d", 772 OPd_s16: "d_s16", 773 OPs16_d: "s16_d", 774 OPd_u16: "d_u16", 775 OPu16_d: "u16_d", 776 OPd_u32: "d_u32", 777 OPu32_d: "u32_d", 778 OP32_16: "32_16", 779 OPd_f: "d_f", 780 OPf_d: "f_d", 781 OPd_ld: "d_ld", 782 OPld_d: "ld_d", 783 OPc_r: "c_r", 784 OPc_i: "c_i", 785 OPu8_16: "u8_16", 786 OPs8_16: "s8_16", 787 OP16_8: "16_8", 788 OPu32_64: "u32_64", 789 OPs32_64: "s32_64", 790 OP64_32: "64_32", 791 OPu64_128: "u64_128", 792 OPs64_128: "s64_128", 793 OP128_64: "128_64", 794 OPmsw: "msw", 795 796 OPd_s64: "d_s64", 797 OPs64_d: "s64_d", 798 OPd_u64: "d_u64", 799 OPu64_d: "u64_d", 800 OPld_u64: "ld_u64", 801 OPparam: "param", 802 OPsizeof: "sizeof", 803 OParrow: "->", 804 OParrowstar: "->*", 805 OPcolon: "colon", 806 OPcolon2: "colon2", 807 OPbool: "bool", 808 OPcall: "call", 809 OPucall: "ucall", 810 OPcallns: "callns", 811 OPucallns: "ucallns", 812 OPstrpar: "strpar", 813 OPstrctor: "strctor", 814 OPstrthis: "strthis", 815 OPconst: "const", 816 OPvar: "var", 817 OPreg: "reg", 818 OPnew: "new", 819 OPanew: "new[]", 820 OPdelete: "delete", 821 OPadelete: "delete[]", 822 OPbrack: "brack", 823 OPframeptr: "frameptr", 824 OPgot: "got", 825 826 OPbsf: "bsf", 827 OPbsr: "bsr", 828 OPbtst: "btst", 829 OPbt: "bt", 830 OPbtc: "btc", 831 OPbtr: "btr", 832 OPbts: "bts", 833 834 OPbswap: "bswap", 835 OPpopcnt: "popcnt", 836 OPvector: "vector", 837 OPvecsto: "vecsto", 838 OPvecfill: "vecfill", 839 OPva_start: "va_start", 840 OPprefetch: "prefetch", 841 ]; 842 843 private: 844 845 /**** 846 * Different categories of operators. 847 */ 848 849 enum Ebinary = 850 [ 851 OPadd,OPmul,OPand,OPmin,OPcond,OPcomma,OPdiv,OPmod,OPxor, 852 OPor,OPoror,OPandand,OPshl,OPshr,OPashr,OPstreq,OPstrcpy,OPstrcat,OPstrcmp, 853 OPpostinc,OPpostdec,OPeq,OPaddass,OPminass,OPmulass,OPdivass, 854 OPmodass,OPshrass,OPashrass,OPshlass,OPandass,OPxorass,OPorass, 855 OPle,OPgt,OPlt,OPge,OPeqeq,OPne,OPparam,OPcall,OPcallns,OPcolon,OPcolon2, 856 OPbit,OPbrack,OParrowstar,OPmemcpy,OPmemcmp,OPmemset, 857 OPunord,OPlg,OPleg,OPule,OPul,OPuge,OPug,OPue,OPngt,OPnge, 858 OPnlt,OPnle,OPord,OPnlg,OPnleg,OPnule,OPnul,OPnuge,OPnug,OPnue, 859 OPinfo,OPpair,OPrpair, 860 OPbt,OPbtc,OPbtr,OPbts,OPror,OProl,OPbtst, 861 OPremquo,OPcmpxchg, 862 OPoutp,OPscale,OPyl2x,OPyl2xp1, 863 OPvecsto,OPprefetch 864 ]; 865 866 enum Eunary = 867 [ 868 OPnot,OPcom,OPind,OPaddr,OPneg,OPuadd, 869 OPabs,OPrndtol,OPrint, 870 OPpreinc,OPpredec, 871 OPbool,OPstrlen, 872 OPb_8,OPs16_32,OPu16_32,OPd_s32,OPd_u32, 873 OPs32_d,OPu32_d,OPd_s16,OPs16_d,OP32_16, 874 OPd_f,OPf_d,OPu8_16,OPs8_16,OP16_8, 875 OPd_ld, OPld_d,OPc_r,OPc_i, 876 OPu32_64,OPs32_64,OP64_32,OPmsw, 877 OPd_s64,OPs64_d,OPd_u64,OPu64_d,OPld_u64, 878 OP128_64,OPs64_128,OPu64_128, 879 OPucall,OPucallns,OPstrpar,OPstrctor,OPu16_d,OPd_u16, 880 OParrow,OPnegass, 881 OPctor,OPdtor,OPsetjmp,OPvoid, 882 OPbsf,OPbsr,OPbswap,OPpopcnt, 883 OPddtor, 884 OPvector,OPvecfill, 885 OPva_start, 886 OPsqrt,OPsin,OPcos,OPinp, 887 OPvp_fp,OPcvp_fp,OPnp_fp,OPnp_f16p,OPf16p_np,OPoffset, 888 ]; 889 890 enum Ecommut = 891 [ 892 OPadd,OPand,OPor,OPxor,OPmul,OPeqeq,OPne,OPle,OPlt,OPge,OPgt, 893 OPunord,OPlg,OPleg,OPule,OPul,OPuge,OPug,OPue,OPngt,OPnge, 894 OPnlt,OPnle,OPord,OPnlg,OPnleg,OPnule,OPnul,OPnuge,OPnug,OPnue, 895 ]; 896 897 enum Eassoc = [ OPadd,OPand,OPor,OPxor,OPmul ]; 898 899 enum Esideff = 900 [ 901 OPasm,OPucall,OPstrcpy,OPmemcpy,OPmemset,OPstrcat, 902 OPcall,OPeq,OPstreq,OPpostinc,OPpostdec, 903 OPaddass,OPminass,OPmulass,OPdivass,OPmodass,OPandass, 904 OPorass,OPxorass,OPshlass,OPshrass,OPashrass, 905 OPnegass,OPctor,OPdtor,OPmark,OPvoid, 906 OPbtc,OPbtr,OPbts, 907 OPhalt,OPdctor,OPddtor, 908 OPcmpxchg, 909 OPva_start, 910 OPinp,OPoutp,OPvecsto,OPprefetch, 911 ]; 912 913 enum Eeop0e = 914 [ 915 OPadd,OPmin,OPxor,OPor,OPshl,OPshr,OPashr,OPpostinc,OPpostdec,OPaddass, 916 OPminass,OPshrass,OPashrass,OPshlass,OPxorass,OPorass, 917 OPror,OProl, 918 ]; 919 920 enum Eeop00 = [ OPmul,OPand,OPmulass,OPandass ]; 921 922 enum Eeop1e = [ OPmul,OPdiv,OPmulass,OPdivass ]; 923 924 enum Elogical = 925 [ 926 OPeqeq,OPne,OPle,OPlt,OPgt,OPge,OPandand,OPoror,OPnot,OPbool, 927 OPunord,OPlg,OPleg,OPule,OPul,OPuge,OPug,OPue,OPngt,OPnge, 928 OPnlt,OPnle,OPord,OPnlg,OPnleg,OPnule,OPnul,OPnuge,OPnug,OPnue, 929 OPbt,OPbtst, 930 ]; 931 932 enum Ewid = 933 [ 934 OPadd,OPmin,OPand,OPor,OPxor,OPcom,OPneg,OPmul,OPaddass,OPnegass, 935 OPminass,OPandass,OPorass,OPxorass,OPmulass,OPshlass,OPshl,OPshrass, 936 OPashrass, 937 ]; 938 939 enum Ecall = [ OPcall,OPucall,OPcallns,OPucallns ]; 940 941 enum Ertol = 942 [ 943 OPeq,OPstreq,OPstrcpy,OPmemcpy,OPpostinc,OPpostdec,OPaddass, 944 OPminass,OPmulass,OPdivass,OPmodass,OPandass, 945 OPorass,OPxorass,OPshlass,OPshrass,OPashrass, 946 OPcall,OPcallns,OPinfo,OPmemset, 947 OPvecsto,OPcmpxchg, 948 ]; 949 950 enum Eassign = 951 [ 952 OPstreq,OPeq,OPaddass,OPminass,OPmulass,OPdivass,OPmodass, 953 OPshrass,OPashrass,OPshlass,OPandass,OPxorass,OPorass,OPpostinc,OPpostdec, 954 OPnegass,OPvecsto,OPcmpxchg, 955 ]; 956 957 enum Edef = 958 [ 959 OPstreq,OPeq,OPaddass,OPminass,OPmulass,OPdivass,OPmodass, 960 OPshrass,OPashrass,OPshlass,OPandass,OPxorass,OPorass, 961 OPpostinc,OPpostdec, 962 OPcall,OPucall,OPasm,OPstrcpy,OPmemcpy,OPmemset,OPstrcat, 963 OPnegass, 964 OPbtc,OPbtr,OPbts, 965 OPvecsto,OPcmpxchg, 966 ]; 967 968 enum Eae = 969 [ 970 OPvar,OPconst,OPrelconst,OPneg, 971 OPabs,OPrndtol,OPrint, 972 OPstrlen,OPstrcmp,OPind,OPaddr, 973 OPnot,OPbool,OPcom,OPadd,OPmin,OPmul,OPand,OPor,OPmemcmp, 974 OPxor,OPdiv,OPmod,OPshl,OPshr,OPashr,OPeqeq,OPne,OPle,OPlt,OPge,OPgt, 975 OPunord,OPlg,OPleg,OPule,OPul,OPuge,OPug,OPue,OPngt,OPnge, 976 OPnlt,OPnle,OPord,OPnlg,OPnleg,OPnule,OPnul,OPnuge,OPnug,OPnue, 977 OPs16_32,OPu16_32,OPd_s32,OPd_u32,OPu16_d,OPd_u16, 978 OPs32_d,OPu32_d,OPd_s16,OPs16_d,OP32_16, 979 OPd_f,OPf_d,OPu8_16,OPs8_16,OP16_8, 980 OPd_ld,OPld_d,OPc_r,OPc_i, 981 OPu32_64,OPs32_64,OP64_32,OPmsw, 982 OPd_s64,OPs64_d,OPd_u64,OPu64_d,OPld_u64, 983 OP128_64,OPs64_128,OPu64_128, 984 OPsizeof, 985 OPcallns,OPucallns,OPpair,OPrpair, 986 OPbsf,OPbsr,OPbt,OPbswap,OPb_8,OPbtst,OPpopcnt, 987 OPgot,OPremquo, 988 OPnullptr, 989 OProl,OPror, 990 OPsqrt,OPsin,OPcos,OPscale, 991 OPvp_fp,OPcvp_fp,OPnp_fp,OPnp_f16p,OPf16p_np,OPoffset,OPvecfill, 992 ]; 993 994 enum Eboolnop = 995 [ 996 OPuadd,OPbool,OPs16_32,OPu16_32, 997 OPs16_d, 998 OPf_d,OPu8_16,OPs8_16, 999 OPd_ld, OPld_d, 1000 OPu32_64,OPs32_64,/*OP64_32,OPmsw,*/ 1001 OPs64_128,OPu64_128, 1002 OPu16_d,OPb_8, 1003 OPnullptr, 1004 OPnp_fp,OPvp_fp,OPcvp_fp, 1005 OPvecfill, 1006 ]; 1007 1008 /** if invalid exception can be generated by operator */ 1009 enum Eexception = 1010 [ 1011 OPgt,OPge,OPlt,OPle, 1012 OPlg,OPleg, 1013 OPngt,OPnge,OPnlt,OPnle,OPnlg,OPnleg, 1014 ]; 1015 1016 /** result of unordered operands */ 1017 enum Eunord = 1018 [ 1019 OPne, 1020 OPunord,OPule,OPul,OPuge,OPug,OPue, 1021 OPngt,OPnge,OPnlt,OPnle,OPnlg,OPnleg, 1022 ];