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.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     */
023    public final class StackLocationOperand extends Operand {
024      /**
025       * Is the offset from the top or bottom of stack frame?
026       */
027      private boolean fromTop;
028    
029      /**
030       * The offset (top/bottom of stack frame) corresponding
031       * to this stack location.
032       */
033      private int offset;
034    
035      /**
036       * Size (in bytes) reserved for the value of this operand.
037       */
038      private 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    }