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