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;
016
017/**
018 * Represents a symbolic name for a stack location.
019 * <p>
020 * The stack location is defined by an offset from either the framepointer
021 * (top of stack frame) or stackpointer-home-location (bottom of frame).
022 */
023public final class StackLocationOperand extends Operand {
024  /**
025   * Is the offset from the top or bottom of stack frame?
026   */
027  private final boolean fromTop;
028
029  /**
030   * The offset (top/bottom of stack frame) corresponding
031   * to this stack location.
032   */
033  private final int offset;
034
035  /**
036   * Size (in bytes) reserved for the value of this operand.
037   */
038  private final byte size;
039
040  /**
041   * @param fromTop is the offset from the top of bottom of the frame?
042   * @param offset  the offset of the stack location from the top/bottom
043   *                of the frame
044   * @param size    Size (in bytes) of the stack location.
045   */
046  public StackLocationOperand(boolean fromTop, int offset, byte size) {
047    this.fromTop = fromTop;
048    this.offset = offset;
049    this.size = size;
050  }
051
052  /**
053   * @param fromTop is the offset from the top of bottom of the frame?
054   * @param offset  the offset of the stack location from the top/bottom
055   *                of the frame
056   * @param size    Size (in bytes) of the stack location.
057   */
058  public StackLocationOperand(boolean fromTop, int offset, int size) {
059    this.fromTop = fromTop;
060    this.offset = offset;
061    this.size = (byte) size;
062  }
063
064  /**
065   * @return <code>true</code> if the stack location uses the top of the
066   *         frame as its base, <code>false</code> if it uses the bottom
067   *         of the frame as its base.
068   */
069  public boolean isFromTop() {
070    return fromTop;
071  }
072
073  /**
074   * @return the offset from the frame pointer (top of stack frame)
075   *         corresponding to this stack location.
076   */
077  public int getOffset() {
078    return offset;
079  }
080
081  /**
082   * @return Size (in bytes) of this stack location.
083   */
084  public byte getSize() {
085    return size;
086  }
087
088  @Override
089  public String toString() {
090    String s = "";
091    switch (size) {
092      case 1:
093        s = ">B";
094        break;
095      case 2:
096        s = ">W";
097        break;
098      case 4:
099        s = ">DW";
100        break;
101      case 8:
102        s = ">QW";
103        break;
104      default:
105        OptimizingCompilerException.UNREACHABLE();
106    }
107    return "<" + (isFromTop() ? "FrameTop" : "FrameBottom") + (getOffset() < 0 ? "" : "+") + getOffset() + s;
108  }
109
110  @Override
111  public boolean similar(Operand op) {
112    if (op instanceof StackLocationOperand) {
113      StackLocationOperand o2 = (StackLocationOperand) op;
114      return ((o2.isFromTop() == isFromTop()) && (o2.getOffset() == getOffset()) && (o2.getSize() == getSize()));
115    } else {
116      return false;
117    }
118  }
119
120  @Override
121  public Operand copy() {
122    return new StackLocationOperand(isFromTop(), getOffset(), getSize());
123  }
124}