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.classloader.TypeReference;
016import org.jikesrvm.util.Bits;
017
018/**
019 * Represents a constant int operand.
020 *
021 * @see Operand
022 */
023public 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  @Override
054  public TypeReference getType() {
055    if ((value == 0) || (value == 1)) {
056      return TypeReference.Boolean;
057    } else if (-128 <= value && value <= 127) {
058      return TypeReference.Byte;
059    } else if (-32768 <= value && value <= 32767) {
060      return TypeReference.Short;
061    } else {
062      return TypeReference.Int;
063    }
064  }
065
066  /**
067   * @return <code>true</code>
068   */
069  @Override
070  public boolean isIntLike() {
071    return true;
072  }
073
074  /**
075   * @return <code>true</code>
076   */
077  @Override
078  public boolean isInt() {
079    return true;
080  }
081
082  @Override
083  public Operand copy() {
084    return new IntConstantOperand(value);
085  }
086
087  /**
088   * @return the lower 8 bits (as an int) of value
089   */
090  public int lower8() {
091    return Bits.lower8(value);
092  }
093
094  /**
095   * @return the lower 16 bits (as an int) of value
096   */
097  public int lower16() {
098    return Bits.lower16(value);
099  }
100
101  /**
102   * @return the upper 16 bits (as an int) of value
103   */
104  public int upper16() {
105    return Bits.upper16(value);
106  }
107
108  /**
109   * @return the upper 24 bits (as an int) of value
110   */
111  public int upper24() {
112    return Bits.upper24(value);
113  }
114
115  @Override
116  public boolean similar(Operand op) {
117    return (op instanceof IntConstantOperand) && (value == ((IntConstantOperand) op).value);
118  }
119
120  @Override
121  public boolean equals(Object o) {
122    return (o instanceof IntConstantOperand) && (value == ((IntConstantOperand) o).value);
123  }
124
125  @Override
126  public int hashCode() {
127    return value;
128  }
129
130  /**
131   * Returns the string representation of this operand.
132   *
133   * @return a string representation of this operand.
134   */
135  @Override
136  public String toString() {
137    if (value > 0xffff || value < -0xffff) {
138      return "0x" + Integer.toHexString(value);
139    } else {
140      return Integer.toString(value);
141    }
142  }
143}