1 /*
   2  * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package com.oracle.graal.lir.hsail;
  25 
  26 import static com.oracle.graal.api.code.ValueUtil.*;
  27 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
  28 
  29 import com.oracle.graal.lir.*;
  30 import com.oracle.graal.api.code.*;
  31 import com.oracle.graal.api.meta.*;
  32 import com.oracle.graal.asm.hsail.*;
  33 
  34 /**
  35  * Represents an address value used in HSAIL code.
  36  */
  37 public final class HSAILAddressValue extends CompositeValue {
  38 
  39     private static final long serialVersionUID = 1802222435353022623L;
  40     @Component({REG, LIRInstruction.OperandFlag.ILLEGAL}) private AllocatableValue base;
  41     private final long displacement;
  42 
  43     /**
  44      * Creates an {@link HSAILAddressValue} with given base register and no displacement.
  45      * 
  46      * @param kind the kind of the value being addressed
  47      * @param base the base register
  48      */
  49     public HSAILAddressValue(Kind kind, AllocatableValue base) {
  50         this(kind, base, 0);
  51     }
  52 
  53     /**
  54      * Creates an {@link HSAILAddressValue} with given base register and a displacement. This is the
  55      * most general constructor.
  56      * 
  57      * @param kind the kind of the value being addressed
  58      * @param base the base register
  59      * @param displacement the displacement
  60      */
  61     public HSAILAddressValue(Kind kind, AllocatableValue base, long displacement) {
  62         super(kind);
  63         this.base = base;
  64         this.displacement = displacement;
  65         assert !isStackSlot(base);
  66     }
  67 
  68     public HSAILAddress toAddress() {
  69         Register baseReg = base == Value.ILLEGAL ? Register.None : asRegister(base);
  70         return new HSAILAddress(baseReg, displacement);
  71     }
  72 
  73     @Override
  74     public String toString() {
  75         StringBuilder s = new StringBuilder();
  76         s.append(getKind().getJavaName()).append("[");
  77         String sep = "";
  78         if (isLegal(base)) {
  79             s.append(base);
  80             sep = " + ";
  81         }
  82         if (displacement < 0) {
  83             s.append(" - ").append(-displacement);
  84         } else if (displacement > 0) {
  85             s.append(sep).append(displacement);
  86         }
  87         s.append("]");
  88         return s.toString();
  89     }
  90 
  91     @Override
  92     public boolean equals(Object obj) {
  93         if (obj instanceof HSAILAddressValue) {
  94             HSAILAddressValue addr = (HSAILAddressValue) obj;
  95             return getKind() == addr.getKind() && displacement == addr.displacement && base.equals(addr.base);
  96         }
  97         return false;
  98     }
  99 
 100     @Override
 101     public int hashCode() {
 102         return base.hashCode() ^ ((int) displacement << 4) ^ (getKind().ordinal() << 12);
 103     }
 104 }