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     *
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      public String toString() {
089        String s = "";
090        switch (size) {
091          case 1:
092            s = ">B";
093            break;
094          case 2:
095            s = ">W";
096            break;
097          case 4:
098            s = ">DW";
099            break;
100          case 8:
101            s = ">QW";
102            break;
103          default:
104            OptimizingCompilerException.UNREACHABLE();
105        }
106        return "<" + (isFromTop() ? "FrameTop" : "FrameBottom") + (getOffset() < 0 ? "" : "+") + getOffset() + s;
107      }
108    
109      public boolean similar(Operand op) {
110        if (op instanceof StackLocationOperand) {
111          StackLocationOperand o2 = (StackLocationOperand) op;
112          return ((o2.isFromTop() == isFromTop()) && (o2.getOffset() == getOffset()) && (o2.getSize() == getSize()));
113        } else {
114          return false;
115        }
116      }
117    
118      public Operand copy() {
119        return new StackLocationOperand(isFromTop(), getOffset(), getSize());
120      }
121    }