changeset 21785:06cd28cccc64

[SPARC] Create SPARC specific address nodes.
author Roland Schatz <roland.schatz@oracle.com>
date Mon, 08 Jun 2015 19:19:51 +0200
parents f4e1d958f1c3
children ae2a39857ab4
files graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCAddressLowering.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCImmediateAddressNode.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCIndexedAddressNode.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCImmediateAddressValue.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCIndexedAddressValue.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java
diffstat 12 files changed, 487 insertions(+), 193 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCAddressLowering.java	Mon Jun 08 19:19:51 2015 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.graal.compiler.sparc;
+
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.memory.address.*;
+import com.oracle.graal.phases.common.AddressLoweringPhase.AddressLowering;
+import com.oracle.jvmci.code.*;
+import com.oracle.jvmci.meta.*;
+
+public class SPARCAddressLowering extends AddressLowering {
+
+    private final CodeCacheProvider codeCache;
+
+    public SPARCAddressLowering(CodeCacheProvider codeCache) {
+        this.codeCache = codeCache;
+    }
+
+    @Override
+    public AddressNode lower(ValueNode address) {
+        return lower(address, 0);
+    }
+
+    @Override
+    public AddressNode lower(ValueNode base, ValueNode offset) {
+        JavaConstant immBase = asImmediate(base);
+        if (immBase != null && SPARCAssembler.isSimm13(immBase)) {
+            return lower(offset, immBase.asLong());
+        }
+
+        JavaConstant immOffset = asImmediate(offset);
+        if (immOffset != null && SPARCAssembler.isSimm13(immOffset)) {
+            return lower(base, immOffset.asLong());
+        }
+
+        return base.graph().unique(new SPARCIndexedAddressNode(base, offset));
+    }
+
+    private AddressNode lower(ValueNode base, long displacement) {
+        if (base instanceof AddNode) {
+            AddNode add = (AddNode) base;
+
+            JavaConstant immX = asImmediate(add.getX());
+            if (immX != null && SPARCAssembler.isSimm13(displacement + immX.asLong())) {
+                return lower(add.getY(), displacement + immX.asLong());
+            }
+
+            JavaConstant immY = asImmediate(add.getY());
+            if (immY != null && SPARCAssembler.isSimm13(displacement + immY.asLong())) {
+                return lower(add.getX(), displacement + immY.asLong());
+            }
+
+            if (displacement == 0) {
+                return lower(add.getX(), add.getY());
+            }
+        }
+
+        assert SPARCAssembler.isSimm13(displacement);
+        return base.graph().unique(new SPARCImmediateAddressNode(base, (int) displacement));
+    }
+
+    private JavaConstant asImmediate(ValueNode value) {
+        JavaConstant c = value.asJavaConstant();
+        if (c != null && c.getKind().isNumericInteger() && !codeCache.needsDataPatch(c)) {
+            return c;
+        } else {
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCImmediateAddressNode.java	Mon Jun 08 19:19:51 2015 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.graal.compiler.sparc;
+
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.sparc.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.memory.address.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.jvmci.meta.*;
+
+/**
+ * Represents an address of the form [base + simm13].
+ */
+@NodeInfo
+public class SPARCImmediateAddressNode extends AddressNode implements LIRLowerable {
+
+    public static final NodeClass<SPARCImmediateAddressNode> TYPE = NodeClass.create(SPARCImmediateAddressNode.class);
+
+    @Input private ValueNode base;
+    private int displacement;
+
+    public SPARCImmediateAddressNode(ValueNode base, int displacement) {
+        super(TYPE);
+        assert SPARCAssembler.isSimm13(displacement);
+        this.base = base;
+        this.displacement = displacement;
+    }
+
+    public void generate(NodeLIRBuilderTool gen) {
+        SPARCLIRGenerator tool = (SPARCLIRGenerator) gen.getLIRGeneratorTool();
+
+        AllocatableValue baseValue = tool.asAllocatable(gen.operand(base));
+
+        LIRKind kind = tool.getLIRKind(stamp());
+        gen.setResult(this, new SPARCImmediateAddressValue(kind, baseValue, displacement));
+    }
+
+    public ValueNode getBase() {
+        return base;
+    }
+
+    public void setBase(ValueNode base) {
+        updateUsages(this.base, base);
+        this.base = base;
+    }
+
+    public int getDisplacement() {
+        return displacement;
+    }
+
+    public void setDisplacement(int displacement) {
+        this.displacement = displacement;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCIndexedAddressNode.java	Mon Jun 08 19:19:51 2015 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.graal.compiler.sparc;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.sparc.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.memory.address.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.jvmci.meta.*;
+
+/**
+ * Represents an address of the form [base + index].
+ */
+@NodeInfo
+public class SPARCIndexedAddressNode extends AddressNode implements LIRLowerable {
+
+    public static final NodeClass<SPARCIndexedAddressNode> TYPE = NodeClass.create(SPARCIndexedAddressNode.class);
+
+    @Input private ValueNode base;
+    @Input private ValueNode index;
+
+    public SPARCIndexedAddressNode(ValueNode base, ValueNode index) {
+        super(TYPE);
+        this.base = base;
+        this.index = index;
+    }
+
+    public void generate(NodeLIRBuilderTool gen) {
+        SPARCLIRGenerator tool = (SPARCLIRGenerator) gen.getLIRGeneratorTool();
+
+        AllocatableValue baseValue = tool.asAllocatable(gen.operand(base));
+        AllocatableValue indexValue = tool.asAllocatable(gen.operand(index));
+
+        LIRKind kind = tool.getLIRKind(stamp());
+        gen.setResult(this, new SPARCIndexedAddressValue(kind, baseValue, indexValue));
+    }
+
+    public ValueNode getBase() {
+        return base;
+    }
+
+    public void setBase(ValueNode base) {
+        updateUsages(this.base, base);
+        this.base = base;
+    }
+
+    public ValueNode getIndex() {
+        return index;
+    }
+
+    public void setIndex(ValueNode index) {
+        updateUsages(this.index, index);
+        this.index = index;
+    }
+}
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Jun 08 19:19:45 2015 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Jun 08 19:19:51 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -140,74 +140,18 @@
         append(new LoadDataAddressOp(dst, data));
     }
 
-    @Override
-    public SPARCAddressValue emitAddress(Value base, long displacement, Value index, int scale) {
-        AllocatableValue baseRegister;
-        long finalDisp = displacement;
-        if (isConstant(base)) {
-            if (asConstant(base).isNull()) {
-                baseRegister = SPARC.g0.asValue(base.getLIRKind());
-            } else if (asConstant(base).getKind() != Kind.Object) {
-                finalDisp += asConstant(base).asLong();
-                baseRegister = Value.ILLEGAL;
-            } else {
-                baseRegister = load(base);
-            }
-        } else {
-            baseRegister = asAllocatable(base);
-        }
-
-        AllocatableValue indexRegister;
-        if (!index.equals(Value.ILLEGAL) && scale != 0) {
-            if (isConstant(index)) {
-                finalDisp += asConstant(index).asLong() * scale;
-                indexRegister = Value.ILLEGAL;
-            } else {
-                Value longIndex = index.getKind() == Kind.Long ? index : emitSignExtend(index, 32, 64);
-                if (scale != 1) {
-                    if (CodeUtil.isPowerOf2(scale)) {
-                        indexRegister = emitShl(longIndex, JavaConstant.forLong(CodeUtil.log2(scale)));
-                    } else {
-                        indexRegister = emitMul(longIndex, JavaConstant.forLong(scale), false);
-                    }
-                } else {
-                    indexRegister = asAllocatable(longIndex);
-                }
-            }
-        } else {
-            indexRegister = Value.ILLEGAL;
-        }
-
-        int displacementInt;
-
-        // If we don't have an index register we can use a displacement, otherwise load the
-        // displacement into a register and add it to the base.
-        if (indexRegister.equals(Value.ILLEGAL) && SPARCAssembler.isSimm13(finalDisp)) {
-            displacementInt = (int) finalDisp;
-        } else {
-            displacementInt = 0;
-            if (baseRegister.equals(Value.ILLEGAL)) {
-                baseRegister = load(JavaConstant.forLong(finalDisp));
-            } else {
-                if (finalDisp == 0) {
-                    // Nothing to do. Just use the base register.
-                } else {
-                    Variable longBaseRegister = newVariable(LIRKind.derivedReference(Kind.Long));
-                    emitMove(longBaseRegister, baseRegister);
-                    baseRegister = emitAdd(longBaseRegister, JavaConstant.forLong(finalDisp), false);
-                }
-            }
-        }
-
-        LIRKind resultKind = getAddressKind(base, displacement, index);
-        return new SPARCAddressValue(resultKind, baseRegister, indexRegister, displacementInt);
-    }
-
     protected SPARCAddressValue asAddressValue(Value address) {
         if (address instanceof SPARCAddressValue) {
             return (SPARCAddressValue) address;
         } else {
-            return emitAddress(address, 0, Value.ILLEGAL, 0);
+            LIRKind kind = address.getLIRKind();
+            if (address instanceof JavaConstant) {
+                long displacement = ((JavaConstant) address).asLong();
+                if (SPARCAssembler.isSimm13(displacement)) {
+                    return new SPARCImmediateAddressValue(kind, SPARC.g0.asValue(kind), (int) displacement);
+                }
+            }
+            return new SPARCImmediateAddressValue(kind, asAllocatable(address), 0);
         }
     }
 
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java	Mon Jun 08 19:19:45 2015 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java	Mon Jun 08 19:19:51 2015 +0200
@@ -108,8 +108,7 @@
         Kind localFromKind = fromKind;
         Kind localToKind = toKind;
         return builder -> {
-            Value address = access.accessLocation().generateAddress(builder, gen, operand(access.object()));
-            Value v = getLIRGeneratorTool().emitSignExtendLoad(LIRKind.value(localFromKind), address, getState(access));
+            Value v = getLIRGeneratorTool().emitSignExtendLoad(LIRKind.value(localFromKind), operand(access.getAddress()), getState(access));
             return getLIRGeneratorTool().emitReinterpret(LIRKind.value(localToKind), v);
         };
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Mon Jun 08 19:19:45 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Mon Jun 08 19:19:51 2015 +0200
@@ -24,6 +24,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.compiler.sparc.*;
 import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
@@ -60,7 +61,7 @@
         HotSpotWordTypes wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind);
         Plugins plugins = createGraphBuilderPlugins(runtime, metaAccess, constantReflection, foreignCalls, stampProvider, snippetReflection, replacements, wordTypes);
         replacements.setGraphBuilderPlugins(plugins);
-        HotSpotSuitesProvider suites = createSuites(runtime, plugins);
+        HotSpotSuitesProvider suites = createSuites(runtime, plugins, codeCache);
         HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, suites, registers, snippetReflection, wordTypes, plugins);
 
         return createBackend(runtime, providers);
@@ -74,8 +75,8 @@
         return plugins;
     }
 
-    protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime, Plugins plugins) {
-        return new HotSpotSuitesProvider(runtime, plugins);
+    protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime, Plugins plugins, CodeCacheProvider codeCache) {
+        return new HotSpotSuitesProvider(runtime, plugins, new SPARCAddressLowering(codeCache));
     }
 
     protected SPARCHotSpotBackend createBackend(HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Jun 08 19:19:45 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Jun 08 19:19:51 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -193,7 +193,7 @@
     private void moveValueToThread(Value v, int offset) {
         LIRKind wordKind = LIRKind.value(getProviders().getCodeCache().getTarget().wordKind);
         RegisterValue thread = getProviders().getRegisters().getThreadRegister().asValue(wordKind);
-        SPARCAddressValue pendingDeoptAddress = new SPARCAddressValue(wordKind, thread, offset);
+        SPARCAddressValue pendingDeoptAddress = new SPARCImmediateAddressValue(wordKind, thread, offset);
         append(new StoreOp(v.getKind(), pendingDeoptAddress, load(v), null));
     }
 
@@ -258,12 +258,16 @@
         LIRKind kind = newValue.getLIRKind();
         assert kind.equals(expectedValue.getLIRKind());
         Kind memKind = (Kind) kind.getPlatformKind();
-        SPARCAddressValue addressValue = asAddressValue(address);
         Variable result = newVariable(newValue.getLIRKind());
-        append(new CompareAndSwapOp(result, asAllocatable(addressValue), asAllocatable(expectedValue), asAllocatable(newValue)));
+        append(new CompareAndSwapOp(result, asAllocatable(address), asAllocatable(expectedValue), asAllocatable(newValue)));
         return emitConditionalMove(memKind, expectedValue, result, Condition.EQ, true, trueValue, falseValue);
     }
 
+    public void emitPrefetchAllocate(Value address) {
+        SPARCAddressValue addr = asAddressValue(address);
+        append(new SPARCPrefetchOp(addr, config.allocatePrefetchInstr));
+    }
+
     public StackSlot getDeoptimizationRescueSlot() {
         return deoptimizationRescueSlot;
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Mon Jun 08 19:19:45 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Mon Jun 08 19:19:51 2015 +0200
@@ -23,7 +23,6 @@
 package com.oracle.graal.hotspot.sparc;
 
 import static com.oracle.graal.hotspot.HotSpotBackend.*;
-import static com.oracle.jvmci.code.ValueUtil.*;
 import static com.oracle.jvmci.sparc.SPARC.*;
 
 import com.oracle.graal.compiler.gen.*;
@@ -33,7 +32,6 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.gen.*;
-import com.oracle.graal.lir.sparc.*;
 import com.oracle.graal.lir.sparc.SPARCMove.CompareAndSwapOp;
 import com.oracle.graal.nodes.CallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.*;
@@ -72,24 +70,12 @@
 
     @Override
     public void visitDirectCompareAndSwap(DirectCompareAndSwapNode x) {
-        Variable address = gen.load(operand(x.object()));
-        Value offset = operand(x.offset());
-        Variable cmpValue = (Variable) gen.loadNonConst(operand(x.expectedValue()));
-        Variable newValue = gen.load(operand(x.newValue()));
+        AllocatableValue address = gen.asAllocatable(operand(x.getAddress()));
+        AllocatableValue cmpValue = gen.asAllocatable(operand(x.expectedValue()));
+        AllocatableValue newValue = gen.asAllocatable(operand(x.newValue()));
         LIRKind kind = cmpValue.getLIRKind();
         assert kind.equals(newValue.getLIRKind());
 
-        if (ValueUtil.isConstant(offset)) {
-            assert !gen.getCodeCache().needsDataPatch(asConstant(offset));
-            Variable longAddress = gen.newVariable(LIRKind.value(Kind.Long));
-            gen.emitMove(longAddress, address);
-            address = getGen().emitAdd(longAddress, asConstant(offset), false);
-        } else {
-            if (isLegal(offset)) {
-                address = getGen().emitAdd(address, offset, false);
-            }
-        }
-
         Variable result = gen.newVariable(newValue.getLIRKind());
         append(new CompareAndSwapOp(result, address, cmpValue, newValue));
         setResult(x, result);
@@ -145,11 +131,6 @@
         append(op);
     }
 
-    public void emitPrefetchAllocate(ValueNode address, ValueNode distance) {
-        SPARCAddressValue addr = getGen().emitAddress(operand(address), 0, getGen().loadNonConst(operand(distance)), 1);
-        append(new SPARCPrefetchOp(addr, getGen().config.allocatePrefetchInstr));
-    }
-
     @Override
     public void visitFullInfopointNode(FullInfopointNode i) {
         if (i.getState() != null && i.getState().bci == BytecodeFrame.AFTER_BCI) {
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java	Mon Jun 08 19:19:45 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java	Mon Jun 08 19:19:51 2015 +0200
@@ -22,108 +22,17 @@
  */
 package com.oracle.graal.lir.sparc;
 
-import com.oracle.jvmci.code.Register;
-import com.oracle.jvmci.code.RegisterValue;
-import com.oracle.jvmci.meta.LIRKind;
-import com.oracle.jvmci.meta.Value;
-import com.oracle.jvmci.meta.AllocatableValue;
-
-import static com.oracle.jvmci.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
-import java.util.*;
-
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.OperandFlag;
-import com.oracle.graal.lir.LIRInstruction.OperandMode;
-
-public final class SPARCAddressValue extends CompositeValue {
+import com.oracle.jvmci.meta.*;
 
-    @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue base;
-    @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue index;
-    protected final int displacement;
-
-    private static final EnumSet<OperandFlag> flags = EnumSet.of(OperandFlag.REG, OperandFlag.ILLEGAL);
+public abstract class SPARCAddressValue extends CompositeValue {
 
-    public SPARCAddressValue(LIRKind kind, AllocatableValue base, int displacement) {
-        this(kind, base, Value.ILLEGAL, displacement);
-    }
-
-    public SPARCAddressValue(LIRKind kind, AllocatableValue base, AllocatableValue index, int displacement) {
+    public SPARCAddressValue(LIRKind kind) {
         super(kind);
-        assert isIllegal(index) || displacement == 0;
-        this.base = base;
-        this.index = index;
-        this.displacement = displacement;
-    }
-
-    @Override
-    public CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) {
-        AllocatableValue newBase = (AllocatableValue) proc.doValue(inst, base, mode, flags);
-        AllocatableValue newIndex = (AllocatableValue) proc.doValue(inst, index, mode, flags);
-        if (!base.identityEquals(newBase) || !index.identityEquals(newIndex)) {
-            return new SPARCAddressValue(getLIRKind(), newBase, newIndex, displacement);
-        }
-        return this;
-    }
-
-    @Override
-    protected void forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueConsumer proc) {
-        proc.visitValue(inst, base, mode, flags);
-        proc.visitValue(inst, index, mode, flags);
     }
 
-    private static Register toRegister(AllocatableValue value) {
-        if (isIllegal(value)) {
-            return Register.None;
-        } else {
-            RegisterValue reg = (RegisterValue) value;
-            return reg.getRegister();
-        }
-    }
-
-    public SPARCAddress toAddress() {
-        if (isLegal(index)) {
-            return new SPARCAddress(toRegister(base), toRegister(index));
-        } else {
-            return new SPARCAddress(toRegister(base), displacement);
-        }
-    }
+    public abstract SPARCAddress toAddress();
 
-    @Override
-    public String toString() {
-        StringBuilder s = new StringBuilder("[");
-        String sep = "";
-        if (isLegal(base)) {
-            s.append(base);
-            sep = " + ";
-        }
-        if (isLegal(index)) {
-            s.append(sep).append(index);
-            sep = " + ";
-        } else {
-            if (displacement < 0) {
-                s.append(" - ").append(-displacement);
-            } else if (displacement > 0) {
-                s.append(sep).append(displacement);
-            }
-        }
-        s.append("]");
-        return s.toString();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof SPARCAddressValue) {
-            SPARCAddressValue addr = (SPARCAddressValue) obj;
-            return getLIRKind().equals(addr.getLIRKind()) && displacement == addr.displacement && base.equals(addr.base) && index.equals(addr.index);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return base.hashCode() ^ index.hashCode() ^ (displacement << 4) ^ getLIRKind().hashCode();
-    }
+    public abstract boolean isValidImplicitNullCheckFor(Value value, int implicitNullCheckLimit);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCImmediateAddressValue.java	Mon Jun 08 19:19:51 2015 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir.sparc;
+
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+import static com.oracle.jvmci.code.ValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.graal.lir.LIRInstruction.OperandMode;
+import com.oracle.jvmci.meta.*;
+
+public final class SPARCImmediateAddressValue extends SPARCAddressValue {
+
+    @Component({REG}) protected AllocatableValue base;
+    protected final int displacement;
+
+    private static final EnumSet<OperandFlag> flags = EnumSet.of(OperandFlag.REG);
+
+    public SPARCImmediateAddressValue(LIRKind kind, AllocatableValue base, int displacement) {
+        super(kind);
+        assert SPARCAssembler.isSimm13(displacement);
+        this.base = base;
+        this.displacement = displacement;
+    }
+
+    @Override
+    public CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) {
+        AllocatableValue newBase = (AllocatableValue) proc.doValue(inst, base, mode, flags);
+        if (!base.identityEquals(newBase)) {
+            return new SPARCImmediateAddressValue(getLIRKind(), newBase, displacement);
+        }
+        return this;
+    }
+
+    @Override
+    protected void forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueConsumer proc) {
+        proc.visitValue(inst, base, mode, flags);
+    }
+
+    @Override
+    public SPARCAddress toAddress() {
+        return new SPARCAddress(asRegister(base), displacement);
+    }
+
+    @Override
+    public boolean isValidImplicitNullCheckFor(Value value, int implicitNullCheckLimit) {
+        return value.equals(base) && displacement >= 0 && displacement < implicitNullCheckLimit;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder("[");
+        String sep = "";
+        if (isLegal(base)) {
+            s.append(base);
+            sep = " + ";
+        }
+        if (displacement < 0) {
+            s.append(" - ").append(-displacement);
+        } else if (displacement > 0) {
+            s.append(sep).append(displacement);
+        }
+        s.append("]");
+        return s.toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof SPARCImmediateAddressValue) {
+            SPARCImmediateAddressValue addr = (SPARCImmediateAddressValue) obj;
+            return getLIRKind().equals(addr.getLIRKind()) && displacement == addr.displacement && base.equals(addr.base);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return base.hashCode() ^ (displacement << 4) ^ getLIRKind().hashCode();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCIndexedAddressValue.java	Mon Jun 08 19:19:51 2015 +0200
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir.sparc;
+
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+import static com.oracle.jvmci.code.ValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.graal.lir.LIRInstruction.OperandMode;
+import com.oracle.jvmci.meta.*;
+
+public final class SPARCIndexedAddressValue extends SPARCAddressValue {
+
+    @Component({REG}) protected AllocatableValue base;
+    @Component({REG}) protected AllocatableValue index;
+
+    private static final EnumSet<OperandFlag> flags = EnumSet.of(OperandFlag.REG);
+
+    public SPARCIndexedAddressValue(LIRKind kind, AllocatableValue base, AllocatableValue index) {
+        super(kind);
+        this.base = base;
+        this.index = index;
+    }
+
+    @Override
+    public CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) {
+        AllocatableValue newBase = (AllocatableValue) proc.doValue(inst, base, mode, flags);
+        AllocatableValue newIndex = (AllocatableValue) proc.doValue(inst, index, mode, flags);
+        if (!base.identityEquals(newBase) || !index.identityEquals(newIndex)) {
+            return new SPARCIndexedAddressValue(getLIRKind(), newBase, newIndex);
+        }
+        return this;
+    }
+
+    @Override
+    protected void forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueConsumer proc) {
+        proc.visitValue(inst, base, mode, flags);
+        proc.visitValue(inst, index, mode, flags);
+    }
+
+    @Override
+    public SPARCAddress toAddress() {
+        return new SPARCAddress(asRegister(base), asRegister(index));
+    }
+
+    @Override
+    public boolean isValidImplicitNullCheckFor(Value value, int implicitNullCheckLimit) {
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder("[");
+        String sep = "";
+        if (isLegal(base)) {
+            s.append(base);
+            sep = " + ";
+        }
+        if (isLegal(index)) {
+            s.append(sep).append(index);
+        }
+        s.append("]");
+        return s.toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof SPARCIndexedAddressValue) {
+            SPARCIndexedAddressValue addr = (SPARCIndexedAddressValue) obj;
+            return getLIRKind().equals(addr.getLIRKind()) && base.equals(addr.base) && index.equals(addr.index);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return base.hashCode() ^ index.hashCode() ^ getLIRKind().hashCode();
+    }
+}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Mon Jun 08 19:19:45 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Mon Jun 08 19:19:51 2015 +0200
@@ -338,7 +338,7 @@
         }
 
         public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
-            if (state == null && value.equals(address.base) && address.index.equals(Value.ILLEGAL) && address.displacement >= 0 && address.displacement < implicitNullCheckLimit) {
+            if (state == null && address.isValidImplicitNullCheckFor(value, implicitNullCheckLimit)) {
                 state = nullCheckState;
                 return true;
             }