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}