1 /*
   2  * Copyright (c) 2013, 2015, 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 package org.graalvm.compiler.asm.sparc;
  24 
  25 import static jdk.vm.ci.sparc.SPARC.STACK_BIAS;
  26 import static jdk.vm.ci.sparc.SPARC.fp;
  27 import static jdk.vm.ci.sparc.SPARC.sp;
  28 import jdk.vm.ci.code.Register;
  29 import jdk.vm.ci.sparc.SPARC;
  30 
  31 import org.graalvm.compiler.asm.AbstractAddress;
  32 
  33 public class SPARCAddress extends AbstractAddress {
  34 
  35     private final Register base;
  36     private final Register index;
  37     private final int displacement;
  38 
  39     /**
  40      * Creates an {@link SPARCAddress} with given base register, no scaling and a given
  41      * displacement.
  42      *
  43      * @param base the base register
  44      * @param displacement the displacement
  45      */
  46     public SPARCAddress(Register base, int displacement) {
  47         this.base = base;
  48         this.index = Register.None;
  49         this.displacement = displacement;
  50     }
  51 
  52     /**
  53      * Creates an {@link SPARCAddress} with given base register, no scaling and a given index.
  54      *
  55      * @param base the base register
  56      * @param index the index register
  57      */
  58     public SPARCAddress(Register base, Register index) {
  59         this.base = base;
  60         this.index = index;
  61         this.displacement = 0;
  62     }
  63 
  64     @Override
  65     public String toString() {
  66         StringBuilder s = new StringBuilder();
  67         s.append("[");
  68         String sep = "";
  69         if (!getBase().equals(Register.None)) {
  70             s.append(getBase());
  71             sep = " + ";
  72         }
  73         if (!getIndex().equals(Register.None)) {
  74             s.append(sep).append(getIndex());
  75             sep = " + ";
  76         } else {
  77             if (getDisplacement() < 0) {
  78                 s.append(" - ").append(-getDisplacement());
  79             } else if (getDisplacement() > 0) {
  80                 s.append(sep).append(getDisplacement());
  81             }
  82         }
  83         s.append("]");
  84         return s.toString();
  85     }
  86 
  87     /**
  88      * @return Base register that defines the start of the address computation. If not present, is
  89      *         denoted by {@link Register#None}.
  90      */
  91     public Register getBase() {
  92         return base;
  93     }
  94 
  95     /**
  96      * @return Index register, the value of which is added to {@link #getBase}. If not present, is
  97      *         denoted by {@link Register#None}.
  98      */
  99     public Register getIndex() {
 100         return index;
 101     }
 102 
 103     /**
 104      * @return true if this address has an index register
 105      */
 106     public boolean hasIndex() {
 107         return !getIndex().equals(Register.None);
 108     }
 109 
 110     /**
 111      * This method adds the stack-bias to the displacement if the base register is either
 112      * {@link SPARC#sp} or {@link SPARC#fp}.
 113      *
 114      * @return Optional additive displacement.
 115      */
 116     public int getDisplacement() {
 117         if (hasIndex()) {
 118             throw new InternalError("address has index register");
 119         }
 120         // TODO Should we also hide the register save area size here?
 121         if (getBase().equals(sp) || getBase().equals(fp)) {
 122             return displacement + STACK_BIAS;
 123         }
 124         return displacement;
 125     }
 126 }