001/*
002 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.asm.sparc;
024
025import static jdk.internal.jvmci.sparc.SPARC.*;
026import jdk.internal.jvmci.code.*;
027import jdk.internal.jvmci.sparc.*;
028
029public class SPARCAddress extends AbstractAddress {
030
031    private final Register base;
032    private final Register index;
033    private final int displacement;
034
035    /**
036     * Creates an {@link SPARCAddress} with given base register, no scaling and a given
037     * displacement.
038     *
039     * @param base the base register
040     * @param displacement the displacement
041     */
042    public SPARCAddress(Register base, int displacement) {
043        this.base = base;
044        this.index = Register.None;
045        this.displacement = displacement;
046    }
047
048    /**
049     * Creates an {@link SPARCAddress} with given base register, no scaling and a given index.
050     *
051     * @param base the base register
052     * @param index the index register
053     */
054    public SPARCAddress(Register base, Register index) {
055        this.base = base;
056        this.index = index;
057        this.displacement = 0;
058    }
059
060    @Override
061    public String toString() {
062        StringBuilder s = new StringBuilder();
063        s.append("[");
064        String sep = "";
065        if (!getBase().equals(Register.None)) {
066            s.append(getBase());
067            sep = " + ";
068        }
069        if (!getIndex().equals(Register.None)) {
070            s.append(sep).append(getIndex());
071            sep = " + ";
072        } else {
073            if (getDisplacement() < 0) {
074                s.append(" - ").append(-getDisplacement());
075            } else if (getDisplacement() > 0) {
076                s.append(sep).append(getDisplacement());
077            }
078        }
079        s.append("]");
080        return s.toString();
081    }
082
083    /**
084     * @return Base register that defines the start of the address computation. If not present, is
085     *         denoted by {@link Register#None}.
086     */
087    public Register getBase() {
088        return base;
089    }
090
091    /**
092     * @return Index register, the value of which is added to {@link #getBase}. If not present, is
093     *         denoted by {@link Register#None}.
094     */
095    public Register getIndex() {
096        return index;
097    }
098
099    /**
100     * @return true if this address has an index register
101     */
102    public boolean hasIndex() {
103        return !getIndex().equals(Register.None);
104    }
105
106    /**
107     * This method adds the stack-bias to the displacement if the base register is either
108     * {@link SPARC#sp} or {@link SPARC#fp}.
109     *
110     * @return Optional additive displacement.
111     */
112    public int getDisplacement() {
113        if (hasIndex()) {
114            throw new InternalError("address has index register");
115        }
116        // TODO Should we also hide the register save area size here?
117        if (getBase().equals(sp) || getBase().equals(fp)) {
118            return displacement + STACK_BIAS;
119        }
120        return displacement;
121    }
122}