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