SPARCAddress.java revision 12651:6ef01bd40ce2
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 */
23package org.graalvm.compiler.asm.sparc;
24
25import static jdk.vm.ci.sparc.SPARC.STACK_BIAS;
26import static jdk.vm.ci.sparc.SPARC.fp;
27import static jdk.vm.ci.sparc.SPARC.sp;
28import jdk.vm.ci.code.Register;
29import jdk.vm.ci.sparc.SPARC;
30
31import org.graalvm.compiler.asm.AbstractAddress;
32
33public 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}
127