001/* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013 014/* NOTE: this is a mechanically generated file, see class JavaDoc 015 for details */ 016 017package org.jikesrvm.compilers.opt.ir; 018 019import org.jikesrvm.VM; 020 021/** 022 * An Operator represents the operator of an {@link Instruction}. 023 * For each operator in the IR, we create exactly one Operator instance 024 * to represent it. These instances are all stored in static fields 025 * of {@link Operators}. Since only one instance is created for each 026 * semantic operator, they can be compared using <code>==</code>. 027 * 028 * @see Operators 029 * @see Instruction 030 */ 031public abstract class Operator { 032 033 034 /* 035 * The following are used to encode operator traits in OperatorList.dat. 036 * Had to make a few of them public (yuck) to let us get at them 037 * from InstructionFormat.java. 038 */ 039 /** operator has no interesting traits */ 040 public static final int none = 0x00000000; 041 /** operator is a simple move operation from one "register" to another */ 042 protected static final int move = 0x00000001; 043 /** operator is an intraprocedural branch of some form */ 044 protected static final int branch = 0x00000002; 045 /** operator is some kind of call (interprocedural branch) */ 046 protected static final int call = 0x00000004; 047 /** modifer for branches/calls */ 048 protected static final int conditional = 0x00000008; 049 /** modifier for branches/calls, mostly on MIR */ 050 protected static final int indirect = 0x00000010; 051 /** an explicit load of a value from memory */ 052 protected static final int load = 0x00000020; 053 /** operator is modeled as a load by memory system, mostly on MIR */ 054 protected static final int memAsLoad = 0x00000040; 055 /** an explicit store of a value to memory */ 056 protected static final int store = 0x00000080; 057 /** operator is modeled as a store by memory system, mostly on MIR */ 058 protected static final int memAsStore = 0x00000100; 059 /** is an exception throw */ 060 protected static final int ethrow = 0x00000200; 061 /** an immediate PEI (null_check, int_zero_check, but _not_ call); */ 062 protected static final int immedPEI = 0x00000400; 063 /** operator is some kind of compare (val,val)-> cond */ 064 protected static final int compare = 0x00000800; 065 /** an explicit memory allocation */ 066 protected static final int alloc = 0x00001000; 067 /** a return instruction (interprocedural branch) */ 068 protected static final int ret = 0x00002000; 069 /** operator has a variable number of uses */ 070 public static final int varUses = 0x00004000; 071 /** operator has a variable number of defs */ 072 public static final int varDefs = 0x00008000; 073 /** 074 * operator is a potential thread switch point for some reason 075 * other than being a call/immedPEI 076 */ 077 protected static final int tsp = 0x00010000; 078 /** operator is an acquire (monitorenter/lock) HIR only */ 079 protected static final int acquire = 0x00020000; 080 /** operator is a relase (monitorexit/unlock) HIR only */ 081 protected static final int release = 0x00040000; 082 /** operator either directly or indirectly may casue dynamic linking */ 083 protected static final int dynLink = 0x00080000; 084 /** operator is a yield point */ 085 protected static final int yieldPoint = 0x00100000; 086 /** operator pops floating-point stack after performing defs */ 087 protected static final int fpPop = 0x00200000; 088 /** operator pushs floating-point stack before performing defs */ 089 protected static final int fpPush = 0x00400000; 090 /** operator is commutative */ 091 protected static final int commutative = 0x00800000; 092 093 /** 094 * The operators opcode. 095 * This value serves as a unique id suitable for use in switches 096 */ 097 final char opcode; 098 099 /** 100 * Encoding of the operator's InstructionFormat. 101 * This field is only meant to be directly referenced 102 * from the mechanically generated InstructionFormat 103 * classes defined in the instructionFormats package. 104 * {@link Instruction} contains an explanation 105 * of the role of InstructionFormats in the IR. 106 */ 107 public final byte format; 108 109 /** 110 * encoding of operator traits (characteristics) 111 */ 112 private final int traits; 113 114 /** 115 * How many operands of the operator are (pure) defs? 116 */ 117 private final int numberDefs; 118 119 /** 120 * How many operands of the operator are both defs and uses? 121 * Only non-zero on IA32, 390. 122 */ 123 private final int numberDefUses; 124 125 /** 126 * How many operands of the operator are pure uses? 127 * Only contains a valid value for non-variableLength operators 128 */ 129 private final int numberUses; 130 131 /** 132 * Physical registers that are implicitly defined by the operator. 133 */ 134 public final int implicitDefs; 135 136 /** 137 * Physical registers that are implicitly used by the operator. 138 */ 139 public final int implicitUses; 140 141 protected Operator(char opcode, byte format, int traits, 142 int numDefs, int numDefUses, int numUses, 143 int iDefs, int iUses) { 144 this.opcode = opcode; 145 this.format = format; 146 this.traits = traits; 147 this.numberDefs = numDefs; 148 this.numberDefUses = numDefUses; 149 this.numberUses = numUses; 150 this.implicitDefs = iDefs; 151 this.implicitUses = iUses; 152 } 153 154 public static Operator lookupOpcode(int opcode) { 155 if (VM.BuildForIA32) { 156 return org.jikesrvm.compilers.opt.ir.ia32.ArchOperator.lookupOpcode(opcode); 157 } else { 158 if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC); 159 return org.jikesrvm.compilers.opt.ir.ppc.ArchOperator.lookupOpcode(opcode); 160 } 161 } 162 163 public final char getOpcode() { 164 return opcode; 165 } 166 167 /** 168 * Returns the string representation of this operator. 169 * 170 * @return the name of the operator 171 */ 172 @Override 173 public String toString() { 174 if (VM.BuildForIA32) { 175 return org.jikesrvm.compilers.opt.ir.ia32.ArchOperatorNames.toString(this); 176 } else { 177 if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC); 178 return org.jikesrvm.compilers.opt.ir.ppc.ArchOperatorNames.toString(this); 179 } 180 } 181 182 /** 183 * Returns the number of operands that are defs. 184 * By convention, operands are ordered in instructions 185 * such that all defs are first, followed by all 186 * combined defs/uses, followed by all pure uses. 187 * 188 * @return number of operands that are pure defs 189 */ 190 public int getNumberOfPureDefs() { 191 if (VM.VerifyAssertions) VM._assert(!hasVarDefs()); 192 return numberDefs; 193 } 194 195 /** 196 * Returns the number of operands that are pure defs 197 * and are not in the variable-length part of the operand list. 198 * By convention, operands are ordered in instructions 199 * such that all defs are first, followed by all 200 * combined defs/uses, followed by all pure uses. 201 * 202 * @return how many non-variable operands are pure defs 203 */ 204 public int getNumberOfFixedPureDefs() { 205 return numberDefs; 206 } 207 208 /** 209 * Returns the number of operands that are pure uses 210 * and are not in the variable-length part of the operand list. 211 * By convention, operands are ordered in instructions 212 * such that all defs are first, followed by all 213 * combined defs/uses, followed by all pure uses. 214 * 215 * @return how many non-variable operands are pure uses 216 */ 217 public int getNumberOfFixedPureUses() { 218 return numberUses; 219 } 220 221 /** 222 * Returns the number of operands that are defs 223 * and uses. 224 * By convention, operands are ordered in instructions 225 * such that all defs are first, followed by all 226 * combined defs/uses, followed by all pure uses. 227 * 228 * @return number of operands that are combined defs and uses 229 */ 230 public int getNumberOfDefUses() { 231 return numberDefUses; 232 } 233 234 /** 235 * Returns the number of operands that are pure uses. 236 * By convention, operands are ordered in instructions 237 * such that all defs are first, followed by all 238 * combined defs/uses, followed by all pure uses. 239 * 240 * @return number of operands that are pure uses 241 */ 242 public int getNumberOfPureUses() { 243 return numberUses; 244 } 245 246 /** 247 * Returns the number of operands that are defs 248 * (either pure defs or combined def/uses). 249 * By convention, operands are ordered in instructions 250 * such that all defs are first, followed by all 251 * combined defs/uses, followed by all pure uses. 252 * 253 * @return number of operands that are defs 254 */ 255 public int getNumberOfDefs() { 256 if (VM.VerifyAssertions) VM._assert(!hasVarDefs()); 257 return numberDefs + numberDefUses; 258 } 259 260 /** 261 * Returns the number of operands that are uses 262 * (either combined def/uses or pure uses). 263 * By convention, operands are ordered in instructions 264 * such that all defs are first, followed by all 265 * combined defs/uses, followed by all pure uses. 266 * 267 * @return how many operands are uses 268 */ 269 public int getNumberOfUses() { 270 if (VM.VerifyAssertions) VM._assert(!hasVarUses()); 271 return numberDefUses + numberUses; 272 } 273 274 /** 275 * Returns the number of operands that are pure uses 276 * and are not in the variable-length part of the operand list. 277 * By convention, operands are ordered in instructions 278 * such that all defs are first, followed by all 279 * combined defs/uses, followed by all pure uses. 280 * 281 * @return how many non-variable operands are pure uses 282 */ 283 public int getNumberOfPureFixedUses() { 284 return numberUses; 285 } 286 287 /** 288 * Returns the number of operands that are uses 289 * (either combined use/defs or pure uses) 290 * and are not in the variable-length part of the operand list. 291 * By convention, operands are ordered in instructions 292 * such that all defs are first, followed by all 293 * combined defs/uses, followed by all pure uses. 294 * 295 * @return number of non-variable operands are uses 296 */ 297 public int getNumberOfFixedUses() { 298 return numberDefUses + numberUses; 299 } 300 301 /** 302 * Returns the number of physical registers that are 303 * implicitly defined by this operator. 304 * 305 * @return number of implicit defs 306 */ 307 public int getNumberOfImplicitDefs() { 308 return Integer.bitCount(implicitDefs); 309 } 310 311 /** 312 * Returns the number of physical registers that are 313 * implicitly used by this operator. 314 * 315 * @return number of implicit uses 316 */ 317 public int getNumberOfImplicitUses() { 318 return Integer.bitCount(implicitUses); 319 } 320 321 /** 322 * Does the operator represent a simple move (the value is unchanged) 323 * from one "register" location to another "register" location? 324 * 325 * @return <code>true</code> if the operator is a simple move 326 * or <code>false</code> if it is not. 327 */ 328 public boolean isMove() { 329 return (traits & move) != 0; 330 } 331 332 /** 333 * Is the operator an intraprocedural branch? 334 * 335 * @return <code>true</code> if the operator is am 336 * intraprocedural branch or <code>false</code> if it is not. 337 */ 338 public boolean isBranch() { 339 return (traits & branch) != 0; 340 } 341 342 /** 343 * Is the operator a conditional intraprocedural branch? 344 * 345 * @return <code>true</code> if the operator is a conditoonal 346 * intraprocedural branch or <code>false</code> if it is not. 347 */ 348 public boolean isConditionalBranch() { 349 return (traits & (branch | conditional)) == (branch | conditional); 350 } 351 352 /** 353 * Is the operator an unconditional intraprocedural branch? 354 * We consider various forms of switches to be unconditional 355 * intraprocedural branches, even though they are multi-way branches 356 * and we may not no exactly which target will be taken. 357 * This turns out to be the right thing to do, since some 358 * arm of the switch will always be taken (unlike conditional branches). 359 * 360 * @return <code>true</code> if the operator is an unconditional 361 * intraprocedural branch or <code>false</code> if it is not. 362 */ 363 public boolean isUnconditionalBranch() { 364 return (traits & (branch | conditional)) == branch; 365 } 366 367 /** 368 * Is the operator a direct intraprocedural branch? 369 * In the HIR and LIR we consider switches to be direct branches, 370 * because their targets are known precisely. 371 * 372 * @return <code>true</code> if the operator is a direct 373 * intraprocedural branch or <code>false</code> if it is not. 374 */ 375 public boolean isDirectBranch() { 376 return (traits & (branch | indirect)) == branch; 377 } 378 379 /** 380 * Is the operator an indirect intraprocedural branch? 381 * 382 * @return <code>true</code> if the operator is an indirect 383 * interprocedural branch or <code>false</code> if it is not. 384 */ 385 public boolean isIndirectBranch() { 386 return (traits & (branch | indirect)) == (branch | indirect); 387 } 388 389 /** 390 * Is the operator a call (one kind of interprocedural branch)? 391 * 392 * @return <code>true</code> if the operator is a call 393 * or <code>false</code> if it is not. 394 */ 395 public boolean isCall() { 396 return (traits & call) != 0; 397 } 398 399 /** 400 * Is the operator a conditional call? 401 * We only allow conditional calls in the MIR, since they 402 * tend to only be directly implementable on some architecutres. 403 * 404 * @return <code>true</code> if the operator is a 405 * conditional call or <code>false</code> if it is not. 406 */ 407 public boolean isConditionalCall() { 408 return (traits & (call | conditional)) == (call | conditional); 409 } 410 411 /** 412 * Is the operator an unconditional call? 413 * Really only an interesting question in the MIR, since 414 * it is by definition true for all HIR and LIR calls. 415 * 416 * @return <code>true</code> if the operator is an unconditional 417 * call or <code>false</code> if it is not. 418 */ 419 public boolean isUnconditionalCall() { 420 return (traits & (call | conditional)) == call; 421 } 422 423 /** 424 * Is the operator a direct call? 425 * Only interesting on the MIR. In the HIR and LIR we pretend that 426 * all calls are "direct" even though most of them aren't. 427 * 428 * @return <code>true</code> if the operator is a direct call 429 * or <code>false</code> if it is not. 430 */ 431 public boolean isDirectCall() { 432 return (traits & (call | indirect)) == call; 433 } 434 435 /** 436 * Is the operator an indirect call? 437 * Only interesting on the MIR. In the HIR and LIR we pretend that 438 * all calls are "direct" even though most of them aren't. 439 * 440 * @return <code>true</code> if the operator is an indirect call 441 * or <code>false</code> if it is not. 442 */ 443 public boolean isIndirectCall() { 444 return (traits & (call | indirect)) == (call | indirect); 445 } 446 447 /** 448 * Is the operator an explicit load of a finite set of values from 449 * a finite set of memory locations (load, load multiple, _not_ call)? 450 * 451 * @return <code>true</code> if the operator is an explicit load 452 * or <code>false</code> if it is not. 453 */ 454 public boolean isExplicitLoad() { 455 return (traits & load) != 0; 456 } 457 458 /** 459 * Should the operator be treated as a load from some unknown location(s) 460 * for the purposes of scheduling and/or modeling the memory subsystem? 461 * 462 * @return <code>true</code> if the operator is an implicit load 463 * or <code>false</code> if it is not. 464 */ 465 public boolean isImplicitLoad() { 466 return (traits & (load | memAsLoad | call)) != 0; 467 } 468 469 /** 470 * Is the operator an explicit store of a finite set of values to 471 * a finite set of memory locations (store, store multiple, _not_ call)? 472 * 473 * @return <code>true</code> if the operator is an explicit store 474 * or <code>false</code> if it is not. 475 */ 476 public boolean isExplicitStore() { 477 return (traits & store) != 0; 478 } 479 480 /** 481 * Should the operator be treated as a store to some unknown location(s) 482 * for the purposes of scheduling and/or modeling the memory subsystem? 483 * 484 * @return <code>true</code> if the operator is an implicit store 485 * or <code>false</code> if it is not. 486 */ 487 public boolean isImplicitStore() { 488 return (traits & (store | memAsStore | call)) != 0; 489 } 490 491 /** 492 * Is the operator a throw of a Java exception? 493 * 494 * @return <code>true</code> if the operator is a throw 495 * or <code>false</code> if it is not. 496 */ 497 public boolean isThrow() { 498 return (traits & ethrow) != 0; 499 } 500 501 /** 502 * Is the operator a PEI (Potentially Excepting Instruction)? 503 * 504 * @return <code>true</code> if the operator is a PEI 505 * or <code>false</code> if it is not. 506 */ 507 public boolean isPEI() { 508 return (traits & (ethrow | immedPEI)) != 0; 509 } 510 511 /** 512 * Is the operator a potential GC point? 513 * 514 * @return <code>true</code> if the operator is a potential 515 * GC point or <code>false</code> if it is not. 516 */ 517 public boolean isGCPoint() { 518 return isPEI() || ((traits & (alloc | tsp)) != 0); 519 } 520 521 /** 522 * is the operator a potential thread switch point? 523 * 524 * @return <code>true</code> if the operator is a potential 525 * threadswitch point or <code>false</code> if it is not. 526 */ 527 public boolean isTSPoint() { 528 return isGCPoint(); 529 } 530 531 /** 532 * Is the operator a compare (val,val) => condition? 533 * 534 * @return <code>true</code> if the operator is a compare 535 * or <code>false</code> if it is not. 536 */ 537 public boolean isCompare() { 538 return (traits & compare) != 0; 539 } 540 541 /** 542 * Is the operator an actual memory allocation instruction 543 * (NEW, NEWARRAY, etc)? 544 * 545 * @return <code>true</code> if the operator is an allocation 546 * or <code>false</code> if it is not. 547 */ 548 public boolean isAllocation() { 549 return (traits & alloc) != 0; 550 } 551 552 /** 553 * Is the operator a return (interprocedural branch)? 554 * 555 * @return <code>true</code> if the operator is a return 556 * or <code>false</code> if it is not. 557 */ 558 public boolean isReturn() { 559 return (traits & ret) != 0; 560 } 561 562 /** 563 * Can the operator have a variable number of uses? 564 * 565 * @return <code>true</code> if the operator has a variable number 566 * of uses or <code>false</code> if it does not. 567 */ 568 public boolean hasVarUses() { 569 return (traits & varUses) != 0; 570 } 571 572 /** 573 * Can the operator have a variable number of uses? 574 * 575 * @return <code>true</code> if the operator has a variable number 576 * of uses or <code>false</code> if it does not. 577 */ 578 public boolean hasVarDefs() { 579 return (traits & varDefs) != 0; 580 } 581 582 /** 583 * Can the operator have a variable number of uses or defs? 584 * 585 * @return <code>true</code> if the operator has a variable number 586 * of uses or defs or <code>false</code> if it does not. 587 */ 588 public boolean hasVarUsesOrDefs() { 589 return (traits & (varUses | varDefs)) != 0; 590 } 591 592 /** 593 * Is the operator an acquire (monitorenter/lock)? 594 * 595 * @return <code>true</code> if the operator is an acquire 596 * or <code>false</code> if it is not. 597 */ 598 public boolean isAcquire() { 599 return (traits & acquire) != 0; 600 } 601 602 /** 603 * Is the operator a release (monitorexit/unlock)? 604 * 605 * @return <code>true</code> if the operator is a release 606 * or <code>false</code> if it is not. 607 */ 608 public boolean isRelease() { 609 return (traits & release) != 0; 610 } 611 612 /** 613 * Could the operator either directly or indirectly 614 * cause dynamic class loading? 615 * 616 * @return <code>true</code> if the operator is a dynamic linking point 617 * or <code>false</code> if it is not. 618 */ 619 public boolean isDynamicLinkingPoint() { 620 return (traits & dynLink) != 0; 621 } 622 623 /** 624 * Is the operator a yield point? 625 * 626 * @return <code>true</code> if the operator is a yield point 627 * or <code>false</code> if it is not. 628 */ 629 public boolean isYieldPoint() { 630 return (traits & yieldPoint) != 0; 631 } 632 633 /** 634 * Does the operator pop the floating-point stack? 635 * 636 * @return <code>true</code> if the operator pops the floating-point 637 * stack. 638 * or <code>false</code> if not. 639 */ 640 public boolean isFpPop() { 641 return (traits & fpPop) != 0; 642 } 643 644 /** 645 * Does the operator push on the floating-point stack? 646 * 647 * @return <code>true</code> if the operator pushes on the floating-point 648 * stack. 649 * or <code>false</code> if not. 650 */ 651 public boolean isFpPush() { 652 return (traits & fpPush) != 0; 653 } 654 655 /** 656 * Is the operator commutative? 657 * 658 * @return <code>true</code> if the operator is commutative. 659 * or <code>false</code> if not. 660 */ 661 public boolean isCommutative() { 662 return (traits & commutative) != 0; 663 } 664 665 /** 666 * @return whether this is a operator a call to a routine that will save volatile 667 * registers 668 */ 669 public boolean isCallSaveVolatile() { 670 if (VM.BuildForIA32) { 671 return this == org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.CALL_SAVE_VOLATILE; 672 } else { 673 if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC); 674 return this == org.jikesrvm.compilers.opt.ir.ppc.ArchOperators.CALL_SAVE_VOLATILE; 675 } 676 } 677 678 /** @return is this the IA32 ADVISE_ESP operator? */ 679 public boolean isAdviseESP() { 680 return VM.BuildForIA32 && 681 this == org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.ADVISE_ESP; 682 } 683 684 /** @return is this the IA32 FNINIT operator? */ 685 public boolean isFNInit() { 686 return VM.BuildForIA32 && 687 this == org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_FNINIT; 688 } 689 690 /** @return is this the IA32 FCLEAR operator? */ 691 public boolean isFClear() { 692 return VM.BuildForIA32 && 693 this == org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_FCLEAR; 694 } 695 696 /** 697 * @return Instruction template used by the assembler to 698 * generate binary code. Only valid on MIR operators. 699 */ 700 public abstract int instTemplate(); 701}