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 */
013package org.jikesrvm.compilers.opt.ir.operand;
014
015import org.jikesrvm.compilers.opt.OptimizingCompilerException;
016import org.vmmagic.unboxed.Address;
017import org.jikesrvm.runtime.Magic;
018
019/**
020 * Encodes the condition codes for branches.
021 *
022 * @see Operand
023 */
024public final class ConditionOperand extends Operand {
025
026  /* signed integer arithmetic */
027  /** Integer equal == */
028  public static final int EQUAL               = 0;
029  /** Integer not equal != */
030  public static final int NOT_EQUAL           = 1;
031  /** Signed integer < */
032  public static final int LESS                = 2;
033  /** Signed integer >= */
034  public static final int GREATER_EQUAL       = 3;
035  /** Signed integer > */
036  public static final int GREATER             = 4;
037  /** Signed integer <= */
038  public static final int LESS_EQUAL          = 5;
039
040  /* unsigned integer arithmetic */
041  /** Unsigned integer > - >U */
042  public static final int HIGHER             = 6;
043  /** Unsigned integer < - <U */
044  public static final int LOWER              = 7;
045  /** Unsigned integer >= - >=U */
046  public static final int HIGHER_EQUAL       = 8;
047  /** Unsigned integer <= - <=U */
048  public static final int LOWER_EQUAL        = 9;
049
050  /* floating-point arithmethic */
051  // branches that fall through when unordered
052  /** Branch if == (equivalent to CMPG_EQUAL)  - ==F */
053  public static final int CMPL_EQUAL         = 10;
054  /** Branch if > - >F */
055  public static final int CMPL_GREATER       = 11;
056  /** Branch if < - <F */
057  public static final int CMPG_LESS          = 12;
058  /** Branch if >= - >=F */
059  public static final int CMPL_GREATER_EQUAL = 13;
060  /** Branch if <= - <=F */
061  public static final int CMPG_LESS_EQUAL    = 14;
062
063  // branches that are taken when unordered
064  /** Branch if != (equivalent to CMPG_NOT_EQUAL) - !=FU */
065  public static final int CMPL_NOT_EQUAL     = 15;
066  /** Branch if < or unordered - <FU */
067  public static final int CMPL_LESS          = 16;
068  /** Brach if >= or unordered - >=FU */
069  public static final int CMPG_GREATER_EQUAL = 17;
070  /** Branch if > or unordered - >FU */
071  public static final int CMPG_GREATER       = 18;
072  /** Branch if <= or unordered - <=FU */
073  public static final int CMPL_LESS_EQUAL    = 19;
074
075  /* integer arithmetic flag operations */
076  /** Would a+b produce a carry? */
077  public static final int CARRY_FROM_ADD        = 20;
078  /** Would a+b not produce a carry? */
079  public static final int NO_CARRY_FROM_ADD     = 21;
080
081  /** Would a+b cause an overflow? */
082  public static final int OVERFLOW_FROM_ADD     = 22;
083  /** Would a+b not cause an overflow? */
084  public static final int NO_OVERFLOW_FROM_ADD  = 23;
085
086  /** Would a-b produce a borrow? */
087  public static final int BORROW_FROM_SUB       = 24;
088  /** Would a-b not produce a borrow? */
089  public static final int NO_BORROW_FROM_SUB    = 25;
090  /** Would b-a produce a borrow? */
091  public static final int BORROW_FROM_RSUB      = 26;
092  /** Would b-a not produce a borrow? */
093  public static final int NO_BORROW_FROM_RSUB   = 27;
094
095  /** Would a-b cause an overflow? */
096  public static final int OVERFLOW_FROM_SUB     = 28;
097  /** Would a-b not cause an overflow? */
098  public static final int NO_OVERFLOW_FROM_SUB  = 29;
099  /** Would b-a cause an overflow? */
100  public static final int OVERFLOW_FROM_RSUB    = 30;
101  /** Would b-a not cause an overflow? */
102  public static final int NO_OVERFLOW_FROM_RSUB = 31;
103
104  /** Would is bit b set in a? */
105  public static final int BIT_TEST              = 32;
106  /** Would is bit b not set in a? */
107  public static final int NO_BIT_TEST           = 33;
108  /** Would is bit a set in b? */
109  public static final int RBIT_TEST             = 34;
110  /** Would is bit a not set in b? */
111  public static final int NO_RBIT_TEST          = 35;
112
113  /** Would a*b cause an overflow? */
114  public static final int OVERFLOW_FROM_MUL     = 36;
115  /** Would a*b not cause an overflow? */
116  public static final int NO_OVERFLOW_FROM_MUL  = 37;
117
118  /* Results from evaluations */
119  /** Evaluation result is false */
120  public static final int FALSE = 0;
121  /** Evaluation result is true */
122  public static final int TRUE = 1;
123  /** Evaluation result is unknown */
124  public static final int UNKNOWN = 2;
125
126  /**
127   * Value of this operand.
128   */
129  public int value;
130
131  /**
132   * @param code the condition code
133   */
134  private ConditionOperand(int code) {
135    value = code;
136  }
137
138  /**
139   * Create the condition code operand for EQUAL
140   *
141   * @return a new condition code operand
142   */
143  public static ConditionOperand EQUAL() {
144    return new ConditionOperand(EQUAL);
145  }
146
147  /**
148   * Create the condition code operand for NOT_EQUAL
149   *
150   * @return a newly created condition code operand
151   */
152  public static ConditionOperand NOT_EQUAL() {
153    return new ConditionOperand(NOT_EQUAL);
154  }
155
156  /**
157   * Create the condition code operand for LESS
158   *
159   * @return a newly created condition code operand
160   */
161  public static ConditionOperand LESS() {
162    return new ConditionOperand(LESS);
163  }
164
165  /**
166   * Create the condition code operand for GREATER_EQUAL
167   *
168   * @return a newly created condition code operand
169   */
170  public static ConditionOperand GREATER_EQUAL() {
171    return new ConditionOperand(GREATER_EQUAL);
172  }
173
174  /**
175   * Create the condition code operand for GREATER
176   *
177   * @return a newly created condition code operand
178   */
179  public static ConditionOperand GREATER() {
180    return new ConditionOperand(GREATER);
181  }
182
183  /**
184   * Create the condition code operand for LESS_EQUAL
185   *
186   * @return a newly created condition code operand
187   */
188  public static ConditionOperand LESS_EQUAL() {
189    return new ConditionOperand(LESS_EQUAL);
190  }
191
192  /**
193   * Create the condition code operand for HIGHER
194   *
195   * @return a newly created condition code operand
196   */
197  public static ConditionOperand HIGHER() {
198    return new ConditionOperand(HIGHER);
199  }
200
201  /**
202   * Create the condition code operand for LOWER
203   *
204   * @return a newly created condition code operand
205   */
206  public static ConditionOperand LOWER() {
207    return new ConditionOperand(LOWER);
208  }
209
210  /**
211   * Create the condition code operand for HIGHER_EQUAL
212   *
213   * @return a newly created condition code operand
214   */
215  public static ConditionOperand HIGHER_EQUAL() {
216    return new ConditionOperand(HIGHER_EQUAL);
217  }
218
219  /**
220   * Create the condition code operand for LOWER_EQUAL
221   *
222   * @return a newly created condition code operand
223   */
224  public static ConditionOperand LOWER_EQUAL() {
225    return new ConditionOperand(LOWER_EQUAL);
226  }
227
228  /**
229   * Create the condition code operand for CMPL_EQUAL
230   *
231   * @return a newly created condition code operand
232   */
233  public static ConditionOperand CMPL_EQUAL() {
234    return new ConditionOperand(CMPL_EQUAL);
235  }
236
237  /**
238   * Create the condition code operand for CMPL_NOT_EQUAL
239   *
240   * @return a newly created condition code operand
241   */
242  public static ConditionOperand CMPL_NOT_EQUAL() {
243    return new ConditionOperand(CMPL_NOT_EQUAL);
244  }
245
246  /**
247   * Create the condition code operand for CMPL_GREATER
248   *
249   * @return a newly created condition code operand
250   */
251  public static ConditionOperand CMPL_GREATER() {
252    return new ConditionOperand(CMPL_GREATER);
253  }
254
255  /**
256   * Create the condition code operand for CMPL_GREATER_EQUAL
257   *
258   * @return a newly created condition code operand
259   */
260  public static ConditionOperand CMPL_GREATER_EQUAL() {
261    return new ConditionOperand(CMPL_GREATER_EQUAL);
262  }
263
264  /**
265   * Create the condition code operand for CMPG_LESS
266   *
267   * @return a newly created condition code operand
268   */
269  public static ConditionOperand CMPG_LESS() {
270    return new ConditionOperand(CMPG_LESS);
271 }
272
273  /**
274   * Create the condition code operand for CARRY_FROM_ADD
275   *
276   * @return a newly created condition code operand
277   */
278  public static ConditionOperand CARRY_FROM_ADD() {
279    return new ConditionOperand(CARRY_FROM_ADD);
280  }
281
282  /**
283   * Create the condition code operand for OVERFLOW_FROM_ADD
284   *
285   * @return a newly created condition code operand
286   */
287  public static ConditionOperand OVERFLOW_FROM_ADD() {
288    return new ConditionOperand(OVERFLOW_FROM_ADD);
289  }
290
291  /**
292   * Create the condition code operand for BORROW_FROM_SUB
293   *
294   * @return a newly created condition code operand
295   */
296  public static ConditionOperand BORROW_FROM_SUB() {
297    return new ConditionOperand(BORROW_FROM_SUB);
298  }
299
300  /**
301   * Create the condition code operand for OVERFLOW_FROM_SUB
302   *
303   * @return a newly created condition code operand
304   */
305  public static ConditionOperand OVERFLOW_FROM_SUB() {
306    return new ConditionOperand(OVERFLOW_FROM_SUB);
307  }
308
309  /**
310   * Create the condition code operand for BIT_TEST
311   *
312   * @return a newly created condition code operand
313   */
314  public static ConditionOperand BIT_TEST() {
315    return new ConditionOperand(BIT_TEST);
316  }
317
318  /**
319   * Create the condition code operand for OVERFLOW_FROM_ADD
320   *
321   * @return a newly created condition code operand
322   */
323  public static ConditionOperand OVERFLOW_FROM_MUL() {
324    return new ConditionOperand(OVERFLOW_FROM_MUL);
325  }
326
327  /**
328   * Is x higher (unsigned >) than y?
329   * @param x first value for comparison
330   * @param y second value for comparison
331   * @return {@code true} if x is higher (unsigned >)
332   *  than y, {@code false} otherwise
333   */
334  private static boolean higher(int x, int y) {
335    return (x & 0xFFFFFFFFL) > ((long)y & 0xFFFFFFFF);
336  }
337
338  /**
339   * Is x lower (unsigned <) than y?
340   * @param x first value for comparison
341   * @param y second value for comparison
342   * @return {@code true} if x is lower (unsigned <)
343   *  than y, {@code false} otherwise
344   */
345  private static boolean lower(int x, int y) {
346    return (x & 0xFFFFFFFFL) < ((long)y & 0xFFFFFFFF);
347  }
348
349  /**
350   * Is x higher equal (unsigned &gt;=) than y?
351   * @param x first value for comparison
352   * @param y second value for comparison
353   * @return {@code true} if x is higher equal (unsigned &gt;=)
354   *  than y, {@code false} otherwise
355   */
356  private static boolean higher_equal(int x, int y) {
357    return (x & 0xFFFFFFFFL) >= ((long)y & 0xFFFFFFFF);
358  }
359
360  /**
361   * Is x lower equal (unsigned &lt;=) than y?
362   * @param x first value for comparison
363   * @param y second value for comparison
364   * @return {@code true} if x is lower equal (unsigned &lt;=)
365   *  than y, {@code false} otherwise
366   */
367  private static boolean lower_equal(int x, int y) {
368    return (x & 0xFFFFFFFFL) <= ((long)y & 0xFFFFFFFF);
369  }
370
371  /**
372   * Would {@code x + y} produce a carry?
373   * @param x first summand
374   * @param y second summand
375   * @return {@code true} if the addition would produce
376   *   a carry, {@code false} otherwise
377   */
378  private static boolean carry_from_add(int x, int y) {
379    int sum = x + y;
380    return lower(sum, x);
381  }
382
383  /**
384   * Would {@code x - y} produce a borrow?
385   * @param x minuend
386   * @param y subtrahend
387   * @return {@code true} if the subtraction would produce
388   *   a borrow, {@code false} otherwise
389   */
390  private static boolean borrow_from_sub(int x, int y) {
391    return lower(x, y);
392  }
393
394  /**
395   * Would {@code x + y} overflow a register?
396   * @param x first summand
397   * @param y second summand
398   * @return {@code true} if the addition would overflow,
399   *   {@code false} otherwise
400   */
401  private static boolean overflow_from_add(int x, int y) {
402    if (y >= 0)
403      return x > (Integer.MAX_VALUE - y);
404    else
405      return x < (Integer.MIN_VALUE - y);
406  }
407
408  /**
409   * Would {@code x - y} overflow a register?
410   * @param x minuend
411   * @param y subtrahend
412   * @return {@code true} if the subtraction would overflow,
413   *   {@code false} otherwise
414   */
415  private static boolean overflow_from_sub(int x, int y) {
416    if (y >= 0)
417      return x < (Integer.MIN_VALUE + y);
418    else
419      return x > (Integer.MAX_VALUE + y);
420  }
421
422  /**
423   * Would {@code x * y} overflow a register?
424   * @param x first factor
425   * @param y second factor
426   * @return {@code true} if the multiplication would overflow,
427   *   {@code false} otherwise
428   */
429  private static boolean overflow_from_mul(int x, int y) {
430    int z = x * y;
431    long z2 = ((long)x) * ((long)y);
432    return z != z2;
433  }
434
435  /**
436   * Is bit y of x set?
437   *
438   * @param x the number to check
439   * @param y the bit position (0 is least significant bit)
440   * @return whether bit position y of x is set (LSB is 0)
441   */
442  private static boolean bit_test(int x, int y) {
443    return (x & (1 << y)) != 0;
444  }
445
446  /**
447   * Is the condition code EQUAL?
448   *
449   * @return <code>true</code> if it is or <code>false</code> if it is not
450   */
451  public boolean isEQUAL() {
452    return value == EQUAL;
453  }
454
455  /**
456   * Is the condition code NOT_EQUAL?
457   *
458   * @return <code>true</code> if it is or <code>false</code> if it is not
459   */
460  public boolean isNOT_EQUAL() {
461    return value == NOT_EQUAL;
462  }
463
464  /**
465   * Is the condition code LESS EQUAL?
466   *
467   * @return <code>true</code> if it is or <code>false</code> if it is not
468   */
469  public boolean isLESS_EQUAL() {
470    return value == LESS_EQUAL;
471  }
472
473  /**
474   * Is the condition code GREATER_EQUAL?
475   *
476   * @return <code>true</code> if it is or <code>false</code> if it is not
477   */
478  public boolean isGREATER_EQUAL() {
479    return value == GREATER_EQUAL;
480  }
481
482  /**
483   * Is the condition code GREATER?
484   *
485   * @return <code>true</code> if it is or <code>false</code> if it is not
486   */
487  public boolean isGREATER() {
488    return value == GREATER;
489  }
490
491  /**
492   * Is the condition code LESS?
493   *
494   * @return <code>true</code> if it is or <code>false</code> if it is not
495   */
496  public boolean isLESS() {
497    return value == LESS;
498  }
499
500  /**
501   * Is the condition code HIGHER?
502   *
503   * @return <code>true</code> if it is or <code>false</code> if it is not
504   */
505  public boolean isHIGHER() {
506    return value == HIGHER;
507  }
508
509  /**
510   * Is the condition code LOWER?
511   *
512   * @return <code>true</code> if it is or <code>false</code> if it is not
513   */
514  public boolean isLOWER() {
515    return value == LOWER;
516  }
517
518  /**
519   * Is the condition code HIGHER_EQUAL?
520   *
521   * @return <code>true</code> if it is or <code>false</code> if it is not
522   */
523  public boolean isHIGHER_EQUAL() {
524    return value == HIGHER_EQUAL;
525  }
526
527  /**
528   * Is the condition code LOWER_EQUAL?
529   *
530   * @return <code>true</code> if it is or <code>false</code> if it is not
531   */
532  public boolean isLOWER_EQUAL() {
533    return value == LOWER_EQUAL;
534  }
535
536  /**
537   * Is the condition code an unsigned comparison?
538   * @return <code>true</code> if it is or <code>false</code> if it is not
539   */
540  public boolean isUNSIGNED() {
541    switch (value) {
542      case HIGHER:
543      case LOWER:
544      case HIGHER_EQUAL:
545      case LOWER_EQUAL:
546        return true;
547      default:
548        return false;
549    }
550  }
551
552  /**
553   * Is the condition code a flag operation?
554   * @return <code>true</code> if it is or <code>false</code> if it is not
555   */
556  public boolean isFLAG_OPERATION() {
557    switch (value) {
558      case CARRY_FROM_ADD:
559      case NO_CARRY_FROM_ADD:
560      case OVERFLOW_FROM_ADD:
561      case NO_OVERFLOW_FROM_ADD:
562      case BORROW_FROM_SUB:
563      case NO_BORROW_FROM_SUB:
564      case OVERFLOW_FROM_SUB:
565      case NO_OVERFLOW_FROM_SUB:
566      case BORROW_FROM_RSUB:
567      case NO_BORROW_FROM_RSUB:
568      case OVERFLOW_FROM_RSUB:
569      case NO_OVERFLOW_FROM_RSUB:
570      case BIT_TEST:
571      case NO_BIT_TEST:
572      case RBIT_TEST:
573      case NO_RBIT_TEST:
574      case OVERFLOW_FROM_MUL:
575      case NO_OVERFLOW_FROM_MUL:
576        return true;
577      default:
578        return false;
579    }
580  }
581
582  /**
583   * Is the condition code a flag operation following an add?
584   * @return <code>true</code> if it is or <code>false</code> if it is not
585   */
586  public boolean isFLAG_OPERATION_FROM_ADD() {
587    switch (value) {
588      case CARRY_FROM_ADD:
589      case NO_CARRY_FROM_ADD:
590      case OVERFLOW_FROM_ADD:
591      case NO_OVERFLOW_FROM_ADD:
592        return true;
593      default:
594        return false;
595    }
596  }
597
598  /**
599   * Is the condition code a flag operation following a subtract?
600   * @return <code>true</code> if it is or <code>false</code> if it is not
601   */
602  public boolean isFLAG_OPERATION_FROM_SUB() {
603    switch (value) {
604      case BORROW_FROM_SUB:
605      case NO_BORROW_FROM_SUB:
606      case OVERFLOW_FROM_SUB:
607      case NO_OVERFLOW_FROM_SUB:
608        return true;
609      default:
610        return false;
611    }
612  }
613
614  /**
615   * Is the condition code a flag operation following a reversed subtract?
616   * @return <code>true</code> if it is or <code>false</code> if it is not
617   */
618  public boolean isFLAG_OPERATION_FROM_RSUB() {
619    switch (value) {
620      case BORROW_FROM_RSUB:
621      case NO_BORROW_FROM_RSUB:
622      case OVERFLOW_FROM_RSUB:
623      case NO_OVERFLOW_FROM_RSUB:
624        return true;
625      default:
626        return false;
627    }
628  }
629
630  /**
631   * Is the condition code a flag operation following a bit test?
632   * @return <code>true</code> if it is or <code>false</code> if it is not
633   */
634  public boolean isBIT_TEST() {
635    switch (value) {
636      case BIT_TEST:
637      case NO_BIT_TEST:
638        return true;
639      default:
640        return false;
641    }
642  }
643
644  /**
645   * Is the condition code a flag operation following a reversed bit test?
646   * @return <code>true</code> if it is or <code>false</code> if it is not
647   */
648  public boolean isRBIT_TEST() {
649    switch (value) {
650      case RBIT_TEST:
651      case NO_RBIT_TEST:
652        return true;
653      default:
654        return false;
655    }
656  }
657
658  /**
659   * Is the condition code a floating point compare?
660   * @return <code>true</code> if it is or <code>false</code> if it is not
661   */
662  public boolean isFLOATINGPOINT() {
663    switch (value) {
664      case CMPL_EQUAL:
665      case CMPL_GREATER:
666      case CMPG_LESS:
667      case CMPL_GREATER_EQUAL:
668      case CMPG_LESS_EQUAL:
669      case CMPL_NOT_EQUAL:
670      case CMPL_LESS:
671      case CMPG_GREATER_EQUAL:
672      case CMPG_GREATER:
673      case CMPL_LESS_EQUAL:
674        return true;
675      default:
676        return false;
677    }
678  }
679
680  /**
681   * Will this floating point compare branch if the results are
682   * unordered?
683   * @return <code>true</code> if it is or <code>false</code> if it is not
684   */
685  public boolean branchIfUnordered() {
686    switch (value) {
687      case CMPL_EQUAL:
688      case CMPL_GREATER:
689      case CMPG_LESS:
690      case CMPL_GREATER_EQUAL:
691      case CMPG_LESS_EQUAL:
692        return false;
693      case CMPL_NOT_EQUAL:
694      case CMPL_LESS:
695      case CMPG_GREATER_EQUAL:
696      case CMPG_GREATER:
697      case CMPL_LESS_EQUAL:
698        return true;
699      default:
700        throw new OptimizingCompilerException("invalid condition " + this);
701    }
702  }
703
704  /**
705   * Convert this integer compare to a floating point cmpl
706   * compare. Used during BC2IR.
707   */
708  public void translateCMPL() {
709    switch (value) {
710      case EQUAL:
711        value = CMPL_EQUAL;
712        break;
713      case NOT_EQUAL:
714        value = CMPL_NOT_EQUAL;
715        break;
716      case LESS:
717        value = CMPL_LESS;
718        break;
719      case GREATER_EQUAL:
720        value = CMPL_GREATER_EQUAL;
721        break;
722      case GREATER:
723        value = CMPL_GREATER;
724        break;
725      case LESS_EQUAL:
726        value = CMPL_LESS_EQUAL;
727        break;
728      default:
729        throw new OptimizingCompilerException("invalid condition " + this);
730    }
731  }
732
733  /**
734   * Convert this integer compare to a floating point cmpg
735   * compare. Used during BC2IR.
736   */
737  public void translateCMPG() {
738    switch (value) {
739      case EQUAL:
740        value = CMPL_EQUAL;
741        break;
742      case NOT_EQUAL:
743        value = CMPL_NOT_EQUAL;
744        break;
745      case LESS:
746        value = CMPG_LESS;
747        break;
748      case GREATER_EQUAL:
749        value = CMPG_GREATER_EQUAL;
750        break;
751      case GREATER:
752        value = CMPG_GREATER;
753        break;
754      case LESS_EQUAL:
755        value = CMPG_LESS_EQUAL;
756        break;
757      default:
758        throw new OptimizingCompilerException("invalid condition " + this);
759    }
760  }
761
762  /**
763   * Convert this floating point compare to the equivalent unsigned
764   * integer compare. Used during IA-32 BURS.<p>
765   *
766   * NB this doesn't respect ordered/unordered operation, so it
767   * should only be used when it's safe to.
768   *
769   * @return this
770   */
771  public ConditionOperand translateUNSIGNED() {
772    switch (value) {
773      case CMPL_EQUAL:         value = EQUAL;         break;
774      case CMPL_GREATER:       value = HIGHER;       break;
775      case CMPG_LESS:          value = LOWER;        break;
776      case CMPL_GREATER_EQUAL: value = HIGHER_EQUAL; break;
777      case CMPG_LESS_EQUAL:    value = LOWER_EQUAL;  break;
778      case CMPL_NOT_EQUAL:     value = NOT_EQUAL;     break;
779      case CMPL_LESS:          value = LOWER;        break;
780      case CMPG_GREATER_EQUAL: value = HIGHER_EQUAL; break;
781      case CMPG_GREATER:       value = HIGHER;       break;
782      case CMPL_LESS_EQUAL:    value = LOWER_EQUAL;  break;
783      default:
784        throw new OptimizingCompilerException("invalid condition " + this);
785    }
786    return this;
787  }
788
789  @Override
790  public Operand copy() {
791    return new ConditionOperand(value);
792  }
793
794  @Override
795  public boolean similar(Operand op) {
796    return (op instanceof ConditionOperand) && (((ConditionOperand) op).value == value);
797  }
798
799  /**
800   * Given two operands, evaluate the condition on them.
801   *
802   * @param v1 first operand to condition
803   * @param v2 second operand to condition
804   * @return <code>TRUE</code> if (v1 cond v2) or
805   *         <code>FALSE</code> if !(v1 cond v2) or
806   *         <code>UNKNOWN</code>
807   */
808  public int evaluate(Operand v1, Operand v2) {
809    if (v1.isAddressConstant()) {
810      if (v2.isAddressConstant()) {
811        return evaluate(v1.asAddressConstant().value, v2.asAddressConstant().value);
812      } else if (v2.isNullConstant()) {
813        return evaluate(v1.asAddressConstant().value, Address.zero());
814      } else if (v2.isIntConstant()) {
815        return evaluate(v1.asAddressConstant().value, Address.fromIntSignExtend(v2.asIntConstant().value));
816      } else if (v2.isObjectConstant() && !v2.isMovableObjectConstant()) {
817        return evaluate(v1.asAddressConstant().value,
818            Magic.objectAsAddress(v2.asObjectConstant().value));
819      }
820    } else if (v1.isIntConstant()) {
821      if (v2.isIntConstant()) {
822        return evaluate(v1.asIntConstant().value, v2.asIntConstant().value);
823      } else if (v2.isNullConstant()) {
824        return evaluate(v1.asIntConstant().value, 0);
825      } else if (v2.isAddressConstant()) {
826        return evaluate(Address.fromIntSignExtend(v1.asIntConstant().value), v2.asAddressConstant().value);
827      } else if (v2.isObjectConstant() && !v2.isMovableObjectConstant()) {
828        return evaluate(Address.fromIntSignExtend(v1.asIntConstant().value),
829            Magic.objectAsAddress(v2.asObjectConstant().value));
830      }
831    } else if (v1.isLongConstant()) {
832      if (v2.isLongConstant()) {
833        return evaluate(v1.asLongConstant().value, v2.asLongConstant().value);
834      }
835    } else if (v1.isFloatConstant()) {
836      if (v2.isFloatConstant()) {
837        return evaluate(v1.asFloatConstant().value, v2.asFloatConstant().value);
838      }
839    } else if (v1.isDoubleConstant()) {
840      if (v2.isDoubleConstant()) {
841        return evaluate(v1.asDoubleConstant().value, v2.asDoubleConstant().value);
842      }
843    } else if (v1.isObjectConstant()) {
844      if (v2.isObjectConstant()) {
845        if (!v1.isMovableObjectConstant() && !v2.isMovableObjectConstant()) {
846          return evaluate(Magic.objectAsAddress(v1.asObjectConstant().value),
847              Magic.objectAsAddress(v2.asObjectConstant().value));
848        } else if (isEQUAL()) {
849          return (v1.asObjectConstant().value == v2.asObjectConstant().value) ? TRUE : FALSE;
850        } else if (isNOT_EQUAL()) {
851          return (v1.asObjectConstant().value != v2.asObjectConstant().value) ? TRUE : FALSE;
852        }
853      }
854      if (v2.isNullConstant() || (v2.isIntConstant() && v2.asIntConstant().value == 0)) {
855        return evaluate(1,0);
856      }
857      if (!v1.isMovableObjectConstant()) {
858        if (v2.isIntConstant()) {
859          return evaluate(Magic.objectAsAddress(v1.asObjectConstant().value),
860              Address.fromIntSignExtend(v2.asIntConstant().value));
861        } else if (v2.isAddressConstant()) {
862          return evaluate(Magic.objectAsAddress(v1.asObjectConstant().value),
863              v2.asAddressConstant().value);
864        } else if (v2.isNullConstant()) {
865          return evaluate(Magic.objectAsAddress(v1.asObjectConstant().value),
866              Address.zero());
867        }
868      }
869    } else if (v1.isNullConstant()) {
870      if (v2.isNullConstant()) {
871        return evaluate(0, 0);
872      } else if (v2.isIntConstant()) {
873        return evaluate(0, v2.asIntConstant().value);
874      } else if (v2.isAddressConstant()) {
875        return evaluate(Address.zero(), v2.asAddressConstant().value);
876      } else if (v2.isObjectConstant()) {
877        if (!v2.isMovableObjectConstant()) {
878          return evaluate(Address.zero(),
879              Magic.objectAsAddress(v2.asObjectConstant().value));
880        } else if (isEQUAL()) {
881          return FALSE;
882        } else if (isNOT_EQUAL()) {
883          return TRUE;
884        }
885      }
886    } else if (v1.similar(v2) && !isFLOATINGPOINT()) {
887      // comparisons of identical operands can be evaluated, except
888      // for floating point NaN cases
889      switch (value) {
890        case EQUAL:
891        case GREATER_EQUAL:
892        case LESS_EQUAL:
893        case HIGHER_EQUAL:
894        case LOWER_EQUAL:
895          return TRUE;
896        case NOT_EQUAL:
897        case LESS:
898        case GREATER:
899        case HIGHER:
900        case LOWER:
901        case BORROW_FROM_SUB:
902        case NO_BORROW_FROM_SUB:
903        case BORROW_FROM_RSUB:
904        case NO_BORROW_FROM_RSUB:
905        case OVERFLOW_FROM_SUB:
906        case NO_OVERFLOW_FROM_SUB:
907        case OVERFLOW_FROM_RSUB:
908        case NO_OVERFLOW_FROM_RSUB:
909          return FALSE;
910        case CARRY_FROM_ADD:
911        case NO_CARRY_FROM_ADD:
912        case OVERFLOW_FROM_ADD:
913        case NO_OVERFLOW_FROM_ADD:
914        case BIT_TEST:
915        case NO_BIT_TEST:
916        case RBIT_TEST:
917        case NO_RBIT_TEST:
918        case OVERFLOW_FROM_MUL:
919        case NO_OVERFLOW_FROM_MUL:
920          return UNKNOWN;
921        default:
922          throw new OptimizingCompilerException("invalid condition " + this);
923      }
924    }
925    return UNKNOWN;
926  }
927
928  /**
929   * Given two ints, evaluate the condition on them.
930   *
931   * @param v1 first operand to condition
932   * @param v2 second operand to condition
933   * @return <code>TRUE</code> if (v1 cond v2) or
934   *         <code>FALSE</code> if !(v1 cond v2) or
935   *         <code>UNKNOWN</code>
936   */
937  public int evaluate(int v1, int v2) {
938    switch (value) {
939      case EQUAL:          return (v1 == v2) ? TRUE : FALSE;
940      case NOT_EQUAL:      return (v1 != v2) ? TRUE : FALSE;
941      case GREATER:        return (v1 > v2)  ? TRUE : FALSE;
942      case LESS:           return (v1 < v2) ? TRUE : FALSE;
943      case GREATER_EQUAL:  return (v1 >= v2)  ? TRUE : FALSE;
944      case LESS_EQUAL:     return (v1 <= v2)  ? TRUE : FALSE;
945      case LOWER:          return lower(v1, v2) ? TRUE : FALSE;
946      case LOWER_EQUAL:    return lower_equal(v1, v2) ? TRUE : FALSE;
947      case HIGHER:         return higher(v1, v2) ? TRUE : FALSE;
948      case HIGHER_EQUAL:   return higher_equal(v1, v2) ? TRUE : FALSE;
949      case CARRY_FROM_ADD:        return carry_from_add(v1, v2) ? TRUE : FALSE;
950      case NO_CARRY_FROM_ADD:     return carry_from_add(v1, v2) ? FALSE : TRUE;
951      case OVERFLOW_FROM_ADD:     return overflow_from_add(v1, v2) ? TRUE : FALSE;
952      case NO_OVERFLOW_FROM_ADD:  return overflow_from_add(v1, v2) ? FALSE : TRUE;
953      case BORROW_FROM_SUB:       return borrow_from_sub(v1, v2) ? TRUE : FALSE;
954      case NO_BORROW_FROM_SUB:    return borrow_from_sub(v1, v2) ? FALSE : TRUE;
955      case BORROW_FROM_RSUB:      return borrow_from_sub(v2, v1) ? TRUE : FALSE;
956      case NO_BORROW_FROM_RSUB:   return borrow_from_sub(v2, v1) ? FALSE : TRUE;
957      case OVERFLOW_FROM_SUB:     return overflow_from_sub(v1, v2) ? TRUE : FALSE;
958      case NO_OVERFLOW_FROM_SUB:  return overflow_from_sub(v1, v2) ? FALSE : TRUE;
959      case OVERFLOW_FROM_RSUB:    return overflow_from_sub(v2, v1) ? TRUE : FALSE;
960      case NO_OVERFLOW_FROM_RSUB: return overflow_from_sub(v2, v1) ? FALSE : TRUE;
961      case BIT_TEST:              return bit_test(v1, v2) ? TRUE : FALSE;
962      case NO_BIT_TEST:           return bit_test(v1, v2) ? FALSE : TRUE;
963      case RBIT_TEST:             return bit_test(v2, v1) ? TRUE : FALSE;
964      case NO_RBIT_TEST:          return bit_test(v2, v1) ? FALSE : TRUE;
965      case OVERFLOW_FROM_MUL:     return overflow_from_mul(v1, v2) ? TRUE : FALSE;
966      case NO_OVERFLOW_FROM_MUL:  return overflow_from_mul(v1, v2) ? FALSE : TRUE;
967    }
968    throw new OptimizingCompilerException("invalid condition " + this);
969  }
970
971  /**
972   * Given two longs, evaluate the condition on them.
973   *
974   * @param v1 first operand to condition
975   * @param v2 second operand to condition
976   * @return <code>TRUE</code> if (v1 cond v2) or
977   *         <code>FALSE</code> if !(v1 cond v2) or
978   *         <code>UNKNOWN</code>
979   */
980  public int evaluate(long v1, long v2) {
981    switch (value) {
982      case EQUAL:         return (v1 == v2) ? TRUE : FALSE;
983      case NOT_EQUAL:     return (v1 != v2) ? TRUE : FALSE;
984      case GREATER:       return (v1 > v2)  ? TRUE : FALSE;
985      case LESS:          return (v1 < v2)  ? TRUE : FALSE;
986      case GREATER_EQUAL: return (v1 >= v2) ? TRUE : FALSE;
987      case LESS_EQUAL:    return (v1 <= v2) ? TRUE : FALSE;
988    }
989    throw new OptimizingCompilerException("invalid condition " + this);
990  }
991
992  /**
993   * Given two floats, evaluate the condition on them.
994   *
995   * @param v1 first operand to condition
996   * @param v2 second operand to condition
997   * @return <code>true</code> if (v1 cond v2) or
998   *         <code>false</code> otherwise
999   */
1000  public int evaluate(float v1, float v2) {
1001    switch (value) {
1002      // Return FALSE when UNORDERED
1003      case CMPL_EQUAL:               return (v1 == v2) ? TRUE : FALSE;
1004      case CMPL_GREATER:             return (v1 > v2)  ? TRUE : FALSE;
1005      case CMPG_LESS:                return (v1 < v2)  ? TRUE : FALSE;
1006      case CMPL_GREATER_EQUAL:        return (v1 >= v2) ? TRUE : FALSE;
1007      case CMPG_LESS_EQUAL:          return (v1 <= v2) ? TRUE : FALSE;
1008      // Return TRUE when UNORDERED
1009      case CMPL_NOT_EQUAL:           return (v1 == v2) ? FALSE : TRUE;
1010      case CMPL_LESS:                return (v1 >= v2) ? FALSE : TRUE;
1011      case CMPG_GREATER_EQUAL:       return (v1 < v2)  ? FALSE : TRUE;
1012      case CMPG_GREATER:             return (v1 <= v2) ? FALSE : TRUE;
1013      case CMPL_LESS_EQUAL:          return (v1 > v2)  ? FALSE : TRUE;
1014    }
1015    throw new OptimizingCompilerException("invalid condition " + this);
1016  }
1017
1018  /**
1019   * Given two doubles, evaluate the condition on them.
1020   *
1021   * @param v1 first operand to condition
1022   * @param v2 second operand to condition
1023   * @return <code>true</code> if (v1 cond v2) or
1024   *         <code>false</code> otherwise
1025   */
1026  public int evaluate(double v1, double v2) {
1027    switch (value) {
1028      // Return FALSE when UNORDERED
1029      case CMPL_EQUAL:               return (v1 == v2) ? TRUE : FALSE;
1030      case CMPL_GREATER:             return (v1 > v2)  ? TRUE : FALSE;
1031      case CMPG_LESS:                return (v1 < v2)  ? TRUE : FALSE;
1032      case CMPL_GREATER_EQUAL:        return (v1 >= v2) ? TRUE : FALSE;
1033      case CMPG_LESS_EQUAL:          return (v1 <= v2) ? TRUE : FALSE;
1034        // Return TRUE when UNORDERED
1035      case CMPL_NOT_EQUAL:           return (v1 == v2) ? FALSE : TRUE;
1036      case CMPL_LESS:                return (v1 >= v2) ? FALSE : TRUE;
1037      case CMPG_GREATER_EQUAL:       return (v1 < v2)  ? FALSE : TRUE;
1038      case CMPG_GREATER:             return (v1 <= v2) ? FALSE : TRUE;
1039      case CMPL_LESS_EQUAL:          return (v1 > v2)  ? FALSE : TRUE;
1040    }
1041    throw new OptimizingCompilerException("invalid condition " + this);
1042  }
1043
1044  /**
1045   * Given two Addresses, evaluate the condition on them.
1046   *
1047   * @param v1 first operand to condition
1048   * @param v2 second operand to condition
1049   * @return <code>TRUE</code> if (v1 cond v2) or
1050   *         <code>FALSE</code> if !(v1 cond v2) or
1051   *         <code>UNKNOWN</code>
1052   */
1053  public int evaluate(Address v1, Address v2) {
1054    switch (value) {
1055      case EQUAL:         return (v1.EQ(v2)) ? TRUE : FALSE;
1056      case NOT_EQUAL:     return (v1.NE(v2)) ? TRUE : FALSE;
1057      case GREATER:       return (v1.toWord().toOffset().sGT(v2.toWord().toOffset())) ? TRUE : FALSE;
1058      case LESS:          return (v1.toWord().toOffset().sLT(v2.toWord().toOffset())) ? TRUE : FALSE;
1059      case GREATER_EQUAL: return (v1.toWord().toOffset().sGE(v2.toWord().toOffset())) ? TRUE : FALSE;
1060      case LESS_EQUAL:    return (v1.toWord().toOffset().sLE(v2.toWord().toOffset())) ? TRUE : FALSE;
1061      case LOWER:         return (v1.LT(v2)) ? TRUE : FALSE;
1062      case LOWER_EQUAL:   return (v1.LE(v2)) ? TRUE : FALSE;
1063      case HIGHER:        return (v1.GT(v2)) ? TRUE : FALSE;
1064      case HIGHER_EQUAL:  return (v1.GE(v2)) ? TRUE : FALSE;
1065    }
1066    throw new OptimizingCompilerException("invalid condition " + this);
1067  }
1068
1069  /**
1070   * Flip the direction of the condition.  Typical use is if you want to
1071   * change the direction of a branch. i.e. to transform:
1072   * <code>
1073   * if (condition) goto A
1074   * goto B
1075   * A:
1076   * </code>
1077   * into:
1078   * <code>
1079   * if (!condition) goto B
1080   * A:
1081   * </code>
1082   * Note that this is not the same as calling {@link #flipOperands}.
1083   *
1084   * @return this
1085   */
1086  public ConditionOperand flipCode() {
1087    switch (value) {
1088      case EQUAL:              value = NOT_EQUAL; break;
1089      case NOT_EQUAL:          value = EQUAL; break;
1090      case LESS:               value = GREATER_EQUAL; break;
1091      case LESS_EQUAL:         value = GREATER; break;
1092      case GREATER:            value = LESS_EQUAL; break;
1093      case GREATER_EQUAL:      value = LESS; break;
1094
1095      case HIGHER:             value = LOWER_EQUAL; break;
1096      case LOWER:              value = HIGHER_EQUAL; break;
1097      case HIGHER_EQUAL:       value = LOWER; break;
1098      case LOWER_EQUAL:        value = HIGHER; break;
1099
1100      case CMPL_EQUAL:         value = CMPL_NOT_EQUAL; break;
1101      case CMPL_GREATER:       value = CMPL_LESS_EQUAL; break;
1102      case CMPG_LESS:          value = CMPG_GREATER_EQUAL; break;
1103      case CMPL_GREATER_EQUAL: value = CMPL_LESS; break;
1104      case CMPG_LESS_EQUAL:    value = CMPG_GREATER; break;
1105      case CMPL_NOT_EQUAL:     value = CMPL_EQUAL; break;
1106      case CMPL_LESS:          value = CMPL_GREATER_EQUAL; break;
1107      case CMPG_GREATER_EQUAL: value = CMPG_LESS; break;
1108      case CMPG_GREATER:       value = CMPG_LESS_EQUAL; break;
1109      case CMPL_LESS_EQUAL:    value = CMPL_GREATER; break;
1110
1111      case CARRY_FROM_ADD:        value = NO_CARRY_FROM_ADD; break;
1112      case NO_CARRY_FROM_ADD:     value = CARRY_FROM_ADD; break;
1113
1114      case OVERFLOW_FROM_ADD:     value = NO_OVERFLOW_FROM_ADD; break;
1115      case NO_OVERFLOW_FROM_ADD:  value = OVERFLOW_FROM_ADD; break;
1116
1117      case BORROW_FROM_SUB:       value = NO_BORROW_FROM_SUB; break;
1118      case NO_BORROW_FROM_SUB:    value = BORROW_FROM_SUB; break;
1119      case BORROW_FROM_RSUB:      value = NO_BORROW_FROM_RSUB; break;
1120      case NO_BORROW_FROM_RSUB:   value = BORROW_FROM_RSUB; break;
1121
1122      case OVERFLOW_FROM_SUB:     value = NO_OVERFLOW_FROM_SUB; break;
1123      case NO_OVERFLOW_FROM_SUB:  value = OVERFLOW_FROM_SUB; break;
1124      case OVERFLOW_FROM_RSUB:    value = NO_OVERFLOW_FROM_RSUB; break;
1125      case NO_OVERFLOW_FROM_RSUB: value = OVERFLOW_FROM_RSUB; break;
1126
1127      case BIT_TEST:              value = NO_BIT_TEST; break;
1128      case NO_BIT_TEST:           value = BIT_TEST; break;
1129      case RBIT_TEST:             value = NO_RBIT_TEST; break;
1130      case NO_RBIT_TEST:          value = RBIT_TEST; break;
1131
1132      case OVERFLOW_FROM_MUL:     value = NO_OVERFLOW_FROM_MUL; break;
1133      case NO_OVERFLOW_FROM_MUL:  value = OVERFLOW_FROM_MUL; break;
1134
1135      default:
1136        OptimizingCompilerException.UNREACHABLE();
1137    }
1138    return this;
1139  }
1140
1141  /**
1142   * Change the condition code to allow the order of the operands to
1143   * be flipped. i.e. So that:
1144   * <code>
1145   * if x &lt; y then goto A
1146   * </code>
1147   * becomes:
1148   * <code>
1149   * if y &gt; x then goto A
1150   * </code>
1151   * Note that this is not the same as calling {@link #flipCode}.
1152   *
1153   * @return this
1154   */
1155  public ConditionOperand flipOperands() {
1156    switch (value) {
1157      case EQUAL:              value = EQUAL; break;
1158      case NOT_EQUAL:          value = NOT_EQUAL;   break;
1159      case LESS:               value = GREATER; break;
1160      case LESS_EQUAL:         value = GREATER_EQUAL; break;
1161      case GREATER:            value = LESS; break;
1162      case GREATER_EQUAL:      value = LESS_EQUAL; break;
1163
1164      case HIGHER:             value = LOWER; break;
1165      case LOWER:              value = HIGHER; break;
1166      case HIGHER_EQUAL:       value = LOWER_EQUAL; break;
1167      case LOWER_EQUAL:        value = HIGHER_EQUAL; break;
1168
1169      case CMPL_EQUAL:         value = CMPL_EQUAL; break;
1170      case CMPL_GREATER:       value = CMPG_LESS; break;
1171      case CMPG_LESS:          value = CMPL_GREATER; break;
1172      case CMPL_GREATER_EQUAL: value = CMPG_LESS_EQUAL; break;
1173      case CMPG_LESS_EQUAL:    value = CMPL_GREATER_EQUAL; break;
1174      case CMPL_NOT_EQUAL:     value = CMPL_NOT_EQUAL; break;
1175      case CMPL_LESS:          value = CMPG_GREATER; break;
1176      case CMPG_GREATER_EQUAL: value = CMPL_LESS_EQUAL; break;
1177      case CMPG_GREATER:       value = CMPL_LESS; break;
1178      case CMPL_LESS_EQUAL:    value = CMPG_GREATER_EQUAL; break;
1179
1180      case CARRY_FROM_ADD:        break; // add is commutative
1181      case NO_CARRY_FROM_ADD:     break;
1182
1183      case OVERFLOW_FROM_ADD:     break;
1184      case NO_OVERFLOW_FROM_ADD:  break;
1185
1186      case BORROW_FROM_SUB:       value = BORROW_FROM_RSUB; break;
1187      case NO_BORROW_FROM_SUB:    value = NO_BORROW_FROM_RSUB; break;
1188      case BORROW_FROM_RSUB:      value = BORROW_FROM_SUB; break;
1189      case NO_BORROW_FROM_RSUB:   value = NO_BORROW_FROM_SUB; break;
1190
1191      case OVERFLOW_FROM_SUB:     value = OVERFLOW_FROM_RSUB; break;
1192      case NO_OVERFLOW_FROM_SUB:  value = NO_OVERFLOW_FROM_RSUB; break;
1193      case OVERFLOW_FROM_RSUB:    value = OVERFLOW_FROM_SUB; break;
1194      case NO_OVERFLOW_FROM_RSUB: value = NO_OVERFLOW_FROM_SUB; break;
1195
1196      case BIT_TEST:              value = RBIT_TEST; break;
1197      case NO_BIT_TEST:           value = NO_RBIT_TEST; break;
1198      case RBIT_TEST:             value = BIT_TEST; break;
1199      case NO_RBIT_TEST:          value = NO_BIT_TEST; break;
1200
1201      case OVERFLOW_FROM_MUL:     break; // mul is commutative
1202      case NO_OVERFLOW_FROM_MUL:  break;
1203
1204      default:
1205        OptimizingCompilerException.UNREACHABLE();
1206    }
1207    return this;
1208  }
1209
1210  /**
1211   * Returns the string representation of this operand. Postfix
1212   * meanings:
1213   * <ul><li>U - unsigned comparison</li>
1214   *     <li>F - floating point compare that doesn't branch when
1215   *         operands are unordered</li>
1216   *     <li>FU - floating point compare that does branch when
1217   *         operands are unordered</li>
1218   * </ul>
1219   *
1220   * @return a string representation of this operand.
1221   */
1222  @Override
1223  public String toString() {
1224    switch (value) {
1225      case EQUAL:              return "==";
1226      case NOT_EQUAL:          return "!=";
1227      case LESS:               return "<";
1228      case LESS_EQUAL:         return "<=";
1229      case GREATER:            return ">";
1230      case GREATER_EQUAL:      return ">=";
1231
1232      case HIGHER:             return ">U";
1233      case LOWER:              return "<U";
1234      case HIGHER_EQUAL:       return ">=U";
1235      case LOWER_EQUAL:        return "<=U";
1236
1237      case CMPL_EQUAL:         return "==F";
1238      case CMPL_GREATER:       return ">F";
1239      case CMPG_LESS:          return "<F";
1240      case CMPL_GREATER_EQUAL: return ">=F";
1241      case CMPG_LESS_EQUAL:    return "<=F";
1242
1243      case CMPL_NOT_EQUAL:     return "!=FU";
1244      case CMPL_LESS:          return "<FU";
1245      case CMPG_GREATER_EQUAL: return ">=FU";
1246      case CMPG_GREATER:       return ">FU";
1247      case CMPL_LESS_EQUAL:    return "<=FU";
1248
1249      case CARRY_FROM_ADD:        return "carry(+)";
1250      case NO_CARRY_FROM_ADD:     return "nocarry(+)";
1251
1252      case OVERFLOW_FROM_ADD:     return "overflow(+)";
1253      case NO_OVERFLOW_FROM_ADD:  return "nooverflow(+)";
1254
1255      case BORROW_FROM_SUB:       return "borrow(-)";
1256      case NO_BORROW_FROM_SUB:    return "noborrow(-)";
1257      case BORROW_FROM_RSUB:      return "borrow(r-)";
1258      case NO_BORROW_FROM_RSUB:   return "noborrow(r-)";
1259
1260      case OVERFLOW_FROM_SUB:     return "overflow(-)";
1261      case NO_OVERFLOW_FROM_SUB:  return "nooverflow(-)";
1262      case OVERFLOW_FROM_RSUB:    return "overflow(r-)";
1263      case NO_OVERFLOW_FROM_RSUB: return "nooverflow(r-)";
1264
1265      case BIT_TEST:              return "bt";
1266      case NO_BIT_TEST:           return "!bt";
1267      case RBIT_TEST:             return "rbt";
1268      case NO_RBIT_TEST:          return "!rbt";
1269
1270      case OVERFLOW_FROM_MUL:     return "overflow(*)";
1271      case NO_OVERFLOW_FROM_MUL:  return "nooverflow(*)";
1272
1273      default:                 return "UNKNOWN";
1274    }
1275  }
1276}