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 package org.jikesrvm.compilers.opt.ir.operand;
014
015 import org.jikesrvm.classloader.TypeReference;
016 import org.jikesrvm.compilers.opt.util.Bits;
017
018 /**
019 * Represents a constant int operand.
020 *
021 * @see Operand
022 */
023 public final class IntConstantOperand extends ConstantOperand {
024
025 /**
026 * Constant 0, can be copied as convenient
027 */
028 public static final IntConstantOperand zero = new IntConstantOperand(0);
029
030 /**
031 * Value of this operand.
032 */
033 public final int value;
034
035 /**
036 * Constructs a new int constant operand with the specified value.
037 * Type will be determined by value.
038 *
039 * @param v value
040 */
041 public IntConstantOperand(int v) {
042 value = v;
043 }
044
045 /**
046 * Return the {@link TypeReference} of the value represented by
047 * the operand. For int constants we speculate on the type
048 * dependenent on the constant value.
049 *
050 * @return a speculation on the type of the value represented by the
051 * operand.
052 */
053 public TypeReference getType() {
054 if ((value == 0) || (value == 1)) {
055 return TypeReference.Boolean;
056 } else if (-128 <= value && value <= 127) {
057 return TypeReference.Byte;
058 } else if (-32768 <= value && value <= 32767) {
059 return TypeReference.Short;
060 } else {
061 return TypeReference.Int;
062 }
063 }
064
065 /**
066 * Does the operand represent a value of an int-like data type?
067 *
068 * @return <code>true</code>
069 */
070 public boolean isIntLike() {
071 return true;
072 }
073
074 /**
075 * Does the operand represent a value of an int data type?
076 *
077 * @return <code>true</code>
078 */
079 public boolean isInt() {
080 return true;
081 }
082
083 /**
084 * Return a new operand that is semantically equivalent to <code>this</code>.
085 *
086 * @return a copy of <code>this</code>
087 */
088 public Operand copy() {
089 return new IntConstantOperand(value);
090 }
091
092 /**
093 * Return the lower 8 bits (as an int) of value
094 */
095 public int lower8() {
096 return Bits.lower8(value);
097 }
098
099 /**
100 * Return the lower 16 bits (as an int) of value
101 */
102 public int lower16() {
103 return Bits.lower16(value);
104 }
105
106 /**
107 * Return the upper 16 bits (as an int) of value
108 */
109 public int upper16() {
110 return Bits.upper16(value);
111 }
112
113 /**
114 * Return the upper 24 bits (as an int) of value
115 */
116 public int upper24() {
117 return Bits.upper24(value);
118 }
119
120 /**
121 * Are two operands semantically equivalent?
122 *
123 * @param op other operand
124 * @return <code>true</code> if <code>this</code> and <code>op</code>
125 * are semantically equivalent or <code>false</code>
126 * if they are not.
127 */
128 public boolean similar(Operand op) {
129 return (op instanceof IntConstantOperand) && (value == ((IntConstantOperand) op).value);
130 }
131
132 public boolean equals(Object o) {
133 return (o instanceof IntConstantOperand) && (value == ((IntConstantOperand) o).value);
134 }
135
136 public int hashCode() {
137 return value;
138 }
139
140 /**
141 * Returns the string representation of this operand.
142 *
143 * @return a string representation of this operand.
144 */
145 public String toString() {
146 if (value > 0xffff || value < -0xffff) {
147 return "0x" + Integer.toHexString(value);
148 } else {
149 return Integer.toString(value);
150 }
151 }
152 }