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)-&gt; 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) =&gt; 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}