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-2016 by Digital Mars, All Rights Reserved 7 * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) 8 * License: backendlicense.txt 9 * Source: $(DMDSRC backend/_oper.d) 10 */ 11 12 module ddmd.backend.oper; 13 14 extern (C++): 15 @nogc: 16 nothrow: 17 18 alias int OPER; 19 enum 20 { 21 OPunde, // place holder for undefined operator 22 23 OPadd, 24 OPmin, 25 OPmul, 26 OPdiv, 27 OPmod, 28 OPshr, // unsigned right shift 29 OPshl, 30 OPand, 31 OPxor, 32 OPor, 33 OPashr, // signed right shift 34 OPnot, 35 OPbool, // "booleanize" 36 OPcom, 37 OPcond, 38 OPcomma, 39 OPoror, 40 OPandand, 41 OPbit, // ref to bit field 42 OPind, // *E 43 OPaddr, // &E 44 OPneg, // unary - 45 OPuadd, // unary + 46 OPvoid, // where casting to void is not a no-op 47 OPabs, // absolute value 48 OPrndtol, // round to short, long, long long (inline 8087 only) 49 OPrint, // round to int 50 51 OPsqrt, // square root 52 OPsin, // sine 53 OPcos, // cosine 54 OPscale, // ldexp 55 OPyl2x, // y * log2(x) 56 OPyl2xp1, // y * log2(x + 1) 57 OPcmpxchg, // cmpxchg 58 59 OPstrlen, // strlen() 60 OPstrcpy, // strcpy() 61 OPstrcat, // strcat() 62 OPstrcmp, // strcmp() 63 OPmemcpy, 64 OPmemcmp, 65 OPmemset, 66 OPsetjmp, // setjmp() 67 68 OPremquo, // / and % in one operation 69 70 OPbsf, // bit scan forward 71 OPbsr, // bit scan reverse 72 OPbt, // bit test 73 OPbtc, // bit test and complement 74 OPbtr, // bit test and reset 75 OPbts, // bit test and set 76 OPbswap, // swap bytes 77 OProl, // rotate left 78 OPror, // rotate right 79 OPbtst, // bit test 80 OPpopcnt, // count of number of bits set to 1 81 82 OPstreq, // structure assignment 83 84 OPnegass, // x = -x 85 OPpostinc, // x++ 86 OPpostdec, // x-- 87 88 OPeq, 89 OPaddass, 90 OPminass, 91 OPmulass, 92 OPdivass, 93 OPmodass, 94 OPshrass, 95 OPshlass, 96 OPandass, 97 OPxorass, 98 OPorass, 99 100 OPashrass, 101 102 // relational operators (in same order as corresponding tokens) 103 RELOPMIN, 104 OPle = RELOPMIN, 105 OPgt, 106 OPlt, 107 OPge, 108 OPeqeq, 109 OPne, 110 111 OPunord, // !<>= 112 OPlg, // <> 113 OPleg, // <>= 114 OPule, // !> 115 OPul, // !>= 116 OPuge, // !< 117 OPug, // !<= 118 OPue, // !<> 119 OPngt, 120 OPnge, 121 OPnlt, 122 OPnle, 123 OPord, 124 OPnlg, 125 OPnleg, 126 OPnule, 127 OPnul, 128 OPnuge, 129 OPnug, 130 RELOPMAX, 131 OPnue = RELOPMAX, 132 133 //**************** End of relational operators ***************** 134 135 /* 8,16,32,64 integral type of unspecified sign 136 s,u signed/unsigned 137 f,d,ld float/double/long double 138 np,fp,vp,f16p near pointer/far pointer/handle pointer/far16 pointer 139 cvp const handle pointer 140 */ 141 142 CNVOPMIN, 143 OPb_8 = CNVOPMIN, // convert bit to byte 144 OPd_s32, 145 OPs32_d, 146 OPd_s16, 147 OPs16_d, 148 OPd_u16, 149 OPu16_d, 150 OPd_u32, 151 OPu32_d, 152 OPd_s64, 153 OPs64_d, 154 OPd_u64, 155 OPu64_d, 156 OPd_f, 157 OPf_d, 158 OPs16_32, // short to long 159 OPu16_32, // unsigned short to long 160 OP32_16, // long to short 161 OPu8_16, // unsigned char to short 162 OPs8_16, // signed char to short 163 OP16_8, // short to 8 bits 164 OPu32_64, // unsigned long to long long 165 OPs32_64, // long to long long 166 OP64_32, // long long to long 167 OPu64_128, 168 OPs64_128, 169 OP128_64, 170 171 // segmented 172 OPvp_fp, 173 OPcvp_fp, // const handle * => far * 174 OPoffset, // get offset of far pointer 175 OPnp_fp, // convert near pointer to far 176 OPnp_f16p, // from 0:32 to 16:16 177 OPf16p_np, // from 16:16 to 0:32 178 179 OPld_d, 180 OPd_ld, 181 CNVOPMAX, 182 OPld_u64 = CNVOPMAX, 183 184 //**************** End of conversion operators ***************** 185 186 OPc_r, // complex to real 187 OPc_i, // complex to imaginary 188 OPmsw, // top 32 bits of 64 bit word (32 bit code gen) 189 // top 16 bits of 32 bit word (16 bit code gen) 190 191 OPparam, // function parameter separator 192 OPcall, // binary function call 193 OPucall, // unary function call 194 OPcallns, // binary function call, no side effects 195 OPucallns, // unary function call, no side effects 196 197 OPsizeof, // for forward-ref'd structs 198 OPstrctor, // call ctor on struct param 199 OPstrthis, // 'this' pointer for OPstrctor 200 OPstrpar, // structure func param 201 OPconst, // constant 202 OPrelconst, // constant that contains an address 203 OPvar, // variable 204 OPreg, // register (used in inline asm operand expressions) 205 OPcolon, // : as in ?: 206 OPcolon2, // alternate version with different EH semantics 207 OPstring, // address of string 208 OPnullptr, // null pointer 209 OPasm, // in-line assembly code 210 OPinfo, // attach info (used to attach ctor/dtor 211 // info for exception handling) 212 OPhalt, // insert HLT instruction 213 OPctor, 214 OPdtor, 215 OPmark, 216 OPdctor, // D constructor 217 OPddtor, // D destructor 218 219 OPpair, // build register pair, E1 is lsb, E2 = msb 220 OPrpair, // build reversed register pair, E1 is msb, E2 = lsb 221 OPframeptr, // load pointer to base of frame 222 OPgot, // load pointer to global offset table 223 OPvector, // SIMD vector operations 224 OPvecsto, // SIMD vector store operations 225 226 OPinp, // input from I/O port 227 OPoutp, // output to I/O port 228 229 // C++ operators 230 OPnew, // operator new 231 OPanew, // operator new[] 232 OPdelete, // operator delete 233 OPadelete, // operator delete[] 234 OPbrack, // [] subscript 235 OParrow, // for -> overloading 236 OParrowstar, // for ->* overloading 237 OPpreinc, // ++x overloading 238 OPpredec, // --x overloading 239 240 OPva_start, // va_start intrinsic (dmd) 241 242 OPMAX // 1 past last operator 243 } 244 245 /* Convert from token to assignment operator */ 246 //int asgtoktoop(int tok) { return tok + OPeq - TKeq; } 247 248 249 /************************************ 250 * Determine things about relational operators. 251 */ 252 253 //OPER rel_toktoop(int tk) { return tk - TKle + RELOPMIN; } 254 255 extern __gshared ubyte[RELOPMAX - RELOPMIN + 1] 256 _rel_not, 257 _rel_swap, 258 _rel_integral, 259 _rel_exception, 260 _rel_unord; 261 262 int rel_not(int op) { return _rel_not [op - RELOPMIN]; } 263 int rel_swap(int op) { return _rel_swap [op - RELOPMIN]; } 264 int rel_integral(int op) { return _rel_integral [op - RELOPMIN]; } 265 int rel_exception(int op) { return _rel_exception[op - RELOPMIN]; } 266 int rel_unord(int op) { return _rel_unord [op - RELOPMIN]; } 267 268 /**************************************** 269 * Conversion operators. 270 * Convert from conversion operator to conversion index 271 * parallel array invconvtab[] in cgelem.c) 272 */ 273 int convidx(OPER op) { return op - CNVOPMIN; } 274 275 276 /********************************** 277 * Various types of operators: 278 * OTbinary binary 279 * OTunary unary 280 * OTleaf leaf 281 * OTcommut commutative (e1 op e2) == (e2 op e1) 282 * (assoc == !=) 283 * OTassoc associative (e1 op (e2 op e3)) == ((e1 op e2) op e3) 284 * (also commutative) 285 * OTassign assignment = op= i++ i-- i=-i str= 286 * OTpost post inc or post dec operator 287 * OTeop0e if (e op 0) => e 288 * OTeop00 if (e op 0) => 0 289 * OTeop1e if (e op 1) => e 290 * OTsideff there are side effects to the operator (assign call 291 * post ?: && ||) 292 * OTconv type conversion operator that could appear on lhs of 293 * assignment operator 294 * OTlogical logical operator (result is 0 or 1) 295 * OTwid high order bits of operation are irrelevant 296 * OTopeq an op= operator 297 * OTop an operator that has a corresponding op= 298 * OTcall function call 299 * OTrtol operators that evaluate right subtree first then left 300 * OTrel == != < <= > >= operators 301 * OTrel2 < <= > >= operators 302 * OTdef definition operator (assign call post asm) 303 * OTae potential common subexpression operator 304 * OTboolnop operation is a nop if boolean result is desired 305 */ 306 307 // Workaround 2.066.x bug by resolving the TYMAX value before using it as dimension. 308 static if (__VERSION__ <= 2066): 309 private enum computeEnumValue = OPMAX; 310 311 extern __gshared ubyte[OPMAX] optab1; 312 extern __gshared ubyte[OPMAX] optab2; 313 extern __gshared ubyte[OPMAX] optab3; 314 extern __gshared ubyte[OPMAX] opcost; 315 316 /* optab1[] */ /* Use byte arrays to avoid index scaling */ 317 enum 318 { 319 _OTbinary = 1, 320 _OTunary = 2, 321 _OTcommut = 4, 322 _OTassoc = 8, 323 _OTsideff = 0x10, 324 _OTeop0e = 0x20, 325 _OTeop00 = 0x40, 326 _OTeop1e = 0x80, 327 } 328 329 /* optab2[] */ 330 enum 331 { 332 _OTlogical = 1, 333 _OTwid = 2, 334 _OTcall = 4, 335 _OTrtol = 8, 336 _OTassign = 0x10, 337 _OTdef = 0x20, 338 _OTae = 0x40, 339 } 340 341 // optab3[] 342 enum 343 { 344 _OTboolnop = 1, 345 } 346 347 ubyte OTbinary(int op) { return optab1[op] & _OTbinary; } 348 ubyte OTunary(int op) { return optab1[op] & _OTunary; } 349 bool OTleaf(int op) { return !(optab1[op] & (_OTunary|_OTbinary)); } 350 ubyte OTcommut(int op) { return optab1[op] & _OTcommut; } 351 ubyte OTassoc(int op) { return optab1[op] & _OTassoc; } 352 ubyte OTassign(int op) { return optab2[op]&_OTassign; } 353 bool OTpost(int op) { return op == OPpostinc || op == OPpostdec; } 354 ubyte OTeop0e(int op) { return optab1[op] & _OTeop0e; } 355 ubyte OTeop00(int op) { return optab1[op] & _OTeop00; } 356 ubyte OTeop1e(int op) { return optab1[op] & _OTeop1e; } 357 ubyte OTsideff(int op) { return optab1[op] & _OTsideff; } 358 bool OTconv(int op) { return op >= CNVOPMIN && op <= CNVOPMAX; } 359 ubyte OTlogical(int op) { return optab2[op] & _OTlogical; } 360 ubyte OTwid(int op) { return optab2[op] & _OTwid; } 361 bool OTopeq(int op) { return op >= OPaddass && op <= OPashrass; } 362 bool OTop(int op) { return op >= OPadd && op <= OPor; } 363 ubyte OTcall(int op) { return optab2[op] & _OTcall; } 364 ubyte OTrtol(int op) { return optab2[op] & _OTrtol; } 365 bool OTrel(int op) { return op >= OPle && op <= OPnue; } 366 bool OTrel2(int op) { return op >= OPle && op <= OPge; } 367 ubyte OTdef(int op) { return optab2[op] & _OTdef; } 368 ubyte OTae(int op) { return optab2[op] & _OTae; } 369 ubyte OTboolnop(int op) { return optab3[op] & _OTboolnop; } 370 bool OTcalldef(int op) { return OTcall(op) || op == OPstrcpy || op == OPstrcat || op == OPmemcpy; } 371 372 /* Convert op= to op */ 373 int opeqtoop(int opx) { return opx - OPaddass + OPadd; } 374 375 /* Convert op to op= */ 376 int optoopeq(int opx) { return opx - OPadd + OPaddass; } 377 378 /*************************** 379 * Determine properties of an elem. 380 * EBIN binary node? 381 * EUNA unary node? 382 * EOP operator node (unary or binary)? 383 * ERTOL right to left evaluation (left to right is default) 384 * Eunambig unambiguous definition elem? 385 */ 386 387 //#define EBIN(e) (OTbinary((e)->Eoper)) 388 //#define EUNA(e) (OTunary((e)->Eoper)) 389 390 /* ERTOL(e) is moved to el.c */ 391 392 //#define Elvalue(e) ((e)->E1) 393 //#define Eunambig(e) (OTassign((e)->Eoper) && (e)->E1->Eoper == OPvar) 394 395 //#define EOP(e) (!OTleaf((e)->Eoper)) 396