001/*
002 * Copyright (c) 2015, 2015, 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 */
023
024package com.oracle.graal.compiler.sparc;
025
026import jdk.internal.jvmci.code.*;
027import jdk.internal.jvmci.meta.*;
028
029import com.oracle.graal.asm.sparc.*;
030import com.oracle.graal.nodes.*;
031import com.oracle.graal.nodes.calc.*;
032import com.oracle.graal.nodes.memory.address.*;
033import com.oracle.graal.phases.common.AddressLoweringPhase.AddressLowering;
034
035public class SPARCAddressLowering extends AddressLowering {
036
037    private final CodeCacheProvider codeCache;
038
039    public SPARCAddressLowering(CodeCacheProvider codeCache) {
040        this.codeCache = codeCache;
041    }
042
043    @Override
044    public AddressNode lower(ValueNode address) {
045        return lower(address, 0);
046    }
047
048    @Override
049    public AddressNode lower(ValueNode base, ValueNode offset) {
050        JavaConstant immBase = asImmediate(base);
051        if (immBase != null && SPARCAssembler.isSimm13(immBase)) {
052            return lower(offset, immBase.asLong());
053        }
054
055        JavaConstant immOffset = asImmediate(offset);
056        if (immOffset != null && SPARCAssembler.isSimm13(immOffset)) {
057            return lower(base, immOffset.asLong());
058        }
059        return base.graph().unique(new SPARCIndexedAddressNode(base, offset));
060    }
061
062    private AddressNode lower(ValueNode base, long displacement) {
063        if (base instanceof AddNode) {
064            AddNode add = (AddNode) base;
065
066            JavaConstant immX = asImmediate(add.getX());
067            if (immX != null && SPARCAssembler.isSimm13(displacement + immX.asLong())) {
068                return lower(add.getY(), displacement + immX.asLong());
069            }
070
071            JavaConstant immY = asImmediate(add.getY());
072            if (immY != null && SPARCAssembler.isSimm13(displacement + immY.asLong())) {
073                return lower(add.getX(), displacement + immY.asLong());
074            }
075
076            if (displacement == 0) {
077                return lower(add.getX(), add.getY());
078            }
079        }
080
081        assert SPARCAssembler.isSimm13(displacement);
082        return base.graph().unique(new SPARCImmediateAddressNode(base, (int) displacement));
083    }
084
085    private JavaConstant asImmediate(ValueNode value) {
086        JavaConstant c = value.asJavaConstant();
087        if (c != null && c.getKind().isNumericInteger() && !codeCache.needsDataPatch(c)) {
088            return c;
089        } else {
090            return null;
091        }
092    }
093}