changeset 22929:098c285cc3b8

Move memory operations into ArithmeticLIRGenerator.
author Roland Schatz <roland.schatz@oracle.com>
date Mon, 02 Nov 2015 18:25:48 +0100
parents de89e36eaec6
children 33c69b58ff65
files graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64ArithmeticLIRGenerator.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeMatchRules.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCArithmeticLIRGenerator.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeMatchRules.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/ArithmeticLIRGeneratorTool.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FloatingReadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/ReadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/WriteNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java
diffstat 14 files changed, 192 insertions(+), 185 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64ArithmeticLIRGenerator.java	Mon Nov 02 17:52:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64ArithmeticLIRGenerator.java	Mon Nov 02 18:25:48 2015 +0100
@@ -34,6 +34,8 @@
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.BSR;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.LZCNT;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOV;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSD;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSS;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD;
@@ -46,14 +48,17 @@
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SAR;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SHL;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift.SHR;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.BYTE;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.DWORD;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.PD;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.PS;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.QWORD;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SD;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SS;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.WORD;
 import static com.oracle.graal.lir.LIRValueUtil.asConstantValue;
 import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant;
+import static com.oracle.graal.lir.LIRValueUtil.isConstantValue;
 import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
 import static com.oracle.graal.lir.amd64.AMD64Arithmetic.DREM;
 import static com.oracle.graal.lir.amd64.AMD64Arithmetic.FREM;
@@ -69,13 +74,17 @@
 import jdk.vm.ci.code.RegisterValue;
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.LIRKind;
 import jdk.vm.ci.meta.PlatformKind;
+import jdk.vm.ci.meta.VMConstant;
 import jdk.vm.ci.meta.Value;
 
 import com.oracle.graal.asm.NumUtil;
 import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
+import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp;
 import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp;
 import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MROp;
 import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMIOp;
@@ -91,6 +100,7 @@
 import com.oracle.graal.lir.amd64.AMD64Arithmetic.FPDivRemOp;
 import com.oracle.graal.lir.amd64.AMD64ArithmeticLIRGeneratorTool;
 import com.oracle.graal.lir.amd64.AMD64Binary;
+import com.oracle.graal.lir.amd64.AMD64BinaryConsumer;
 import com.oracle.graal.lir.amd64.AMD64ClearRegisterOp;
 import com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp;
 import com.oracle.graal.lir.amd64.AMD64MulDivOp;
@@ -893,4 +903,138 @@
         getLIRGen().append(new AMD64MathIntrinsicOp(TAN, result, getLIRGen().asAllocatable(input)));
         return result;
     }
+
+    protected AMD64LIRGenerator getAMD64LIRGen() {
+        return (AMD64LIRGenerator) getLIRGen();
+    }
+
+    @Override
+    public Variable emitLoad(LIRKind kind, Value address, LIRFrameState state) {
+        AMD64AddressValue loadAddress = getAMD64LIRGen().asAddressValue(address);
+        Variable result = getLIRGen().newVariable(getLIRGen().toRegisterKind(kind));
+        switch ((AMD64Kind) kind.getPlatformKind()) {
+            case BYTE:
+                getLIRGen().append(new AMD64Unary.MemoryOp(MOVSXB, DWORD, result, loadAddress, state));
+                break;
+            case WORD:
+                getLIRGen().append(new AMD64Unary.MemoryOp(MOVSX, DWORD, result, loadAddress, state));
+                break;
+            case DWORD:
+                getLIRGen().append(new AMD64Unary.MemoryOp(MOV, DWORD, result, loadAddress, state));
+                break;
+            case QWORD:
+                getLIRGen().append(new AMD64Unary.MemoryOp(MOV, QWORD, result, loadAddress, state));
+                break;
+            case SINGLE:
+                getLIRGen().append(new AMD64Unary.MemoryOp(MOVSS, SS, result, loadAddress, state));
+                break;
+            case DOUBLE:
+                getLIRGen().append(new AMD64Unary.MemoryOp(MOVSD, SD, result, loadAddress, state));
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    protected void emitStoreConst(AMD64Kind kind, AMD64AddressValue address, ConstantValue value, LIRFrameState state) {
+        Constant c = value.getConstant();
+        if (JavaConstant.isNull(c)) {
+            assert kind == AMD64Kind.DWORD || kind == AMD64Kind.QWORD;
+            OperandSize size = kind == AMD64Kind.DWORD ? DWORD : QWORD;
+            getLIRGen().append(new AMD64BinaryConsumer.MemoryConstOp(AMD64MIOp.MOV, size, address, 0, state));
+            return;
+        } else if (c instanceof VMConstant) {
+            // only 32-bit constants can be patched
+            if (kind == AMD64Kind.DWORD) {
+                if (getLIRGen().target().inlineObjects || !(c instanceof JavaConstant)) {
+                    // if c is a JavaConstant, it's an oop, otherwise it's a metaspace constant
+                    assert !(c instanceof JavaConstant) || ((JavaConstant) c).getJavaKind() == JavaKind.Object;
+                    getLIRGen().append(new AMD64BinaryConsumer.MemoryVMConstOp(AMD64MIOp.MOV, address, (VMConstant) c, state));
+                    return;
+                }
+            }
+        } else {
+            JavaConstant jc = (JavaConstant) c;
+            assert jc.getJavaKind().isPrimitive();
+
+            AMD64MIOp op = AMD64MIOp.MOV;
+            OperandSize size;
+            long imm;
+
+            switch (kind) {
+                case BYTE:
+                    op = AMD64MIOp.MOVB;
+                    size = BYTE;
+                    imm = jc.asInt();
+                    break;
+                case WORD:
+                    size = WORD;
+                    imm = jc.asInt();
+                    break;
+                case DWORD:
+                    size = DWORD;
+                    imm = jc.asInt();
+                    break;
+                case QWORD:
+                    size = QWORD;
+                    imm = jc.asLong();
+                    break;
+                case SINGLE:
+                    size = DWORD;
+                    imm = Float.floatToRawIntBits(jc.asFloat());
+                    break;
+                case DOUBLE:
+                    size = QWORD;
+                    imm = Double.doubleToRawLongBits(jc.asDouble());
+                    break;
+                default:
+                    throw JVMCIError.shouldNotReachHere("unexpected kind " + kind);
+            }
+
+            if (NumUtil.isInt(imm)) {
+                getLIRGen().append(new AMD64BinaryConsumer.MemoryConstOp(op, size, address, (int) imm, state));
+                return;
+            }
+        }
+
+        // fallback: load, then store
+        emitStore(kind, address, getLIRGen().asAllocatable(value), state);
+    }
+
+    protected void emitStore(AMD64Kind kind, AMD64AddressValue address, AllocatableValue value, LIRFrameState state) {
+        switch (kind) {
+            case BYTE:
+                getLIRGen().append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOVB, BYTE, address, value, state));
+                break;
+            case WORD:
+                getLIRGen().append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOV, WORD, address, value, state));
+                break;
+            case DWORD:
+                getLIRGen().append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOV, DWORD, address, value, state));
+                break;
+            case QWORD:
+                getLIRGen().append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOV, QWORD, address, value, state));
+                break;
+            case SINGLE:
+                getLIRGen().append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOVSS, SS, address, value, state));
+                break;
+            case DOUBLE:
+                getLIRGen().append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOVSD, SD, address, value, state));
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public void emitStore(LIRKind lirKind, Value address, Value input, LIRFrameState state) {
+        AMD64AddressValue storeAddress = getAMD64LIRGen().asAddressValue(address);
+        AMD64Kind kind = (AMD64Kind) lirKind.getPlatformKind();
+        if (isConstantValue(input)) {
+            emitStoreConst(kind, storeAddress, asConstantValue(input), state);
+        } else {
+            emitStore(kind, storeAddress, getLIRGen().asAllocatable(input), state);
+        }
+    }
 }
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Mon Nov 02 17:52:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Mon Nov 02 18:25:48 2015 +0100
@@ -24,11 +24,6 @@
 package com.oracle.graal.compiler.amd64;
 
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.CMP;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOV;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSD;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSS;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.TEST;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.TESTB;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.BYTE;
@@ -36,8 +31,6 @@
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.PD;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.PS;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.QWORD;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SD;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SS;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.WORD;
 import static com.oracle.graal.lir.LIRValueUtil.asConstantValue;
 import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant;
@@ -60,7 +53,6 @@
 
 import com.oracle.graal.asm.NumUtil;
 import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp;
-import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MROp;
 import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp;
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
@@ -94,7 +86,6 @@
 import com.oracle.graal.lir.amd64.AMD64Move.LeaDataOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MembarOp;
 import com.oracle.graal.lir.amd64.AMD64Move.StackLeaOp;
-import com.oracle.graal.lir.amd64.AMD64Unary;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
 import com.oracle.graal.lir.gen.LIRGenerator;
 import com.oracle.graal.phases.util.Providers;
@@ -192,136 +183,6 @@
     }
 
     @Override
-    public Variable emitLoad(LIRKind kind, Value address, LIRFrameState state) {
-        AMD64AddressValue loadAddress = asAddressValue(address);
-        Variable result = newVariable(toRegisterKind(kind));
-        switch ((AMD64Kind) kind.getPlatformKind()) {
-            case BYTE:
-                append(new AMD64Unary.MemoryOp(MOVSXB, DWORD, result, loadAddress, state));
-                break;
-            case WORD:
-                append(new AMD64Unary.MemoryOp(MOVSX, DWORD, result, loadAddress, state));
-                break;
-            case DWORD:
-                append(new AMD64Unary.MemoryOp(MOV, DWORD, result, loadAddress, state));
-                break;
-            case QWORD:
-                append(new AMD64Unary.MemoryOp(MOV, QWORD, result, loadAddress, state));
-                break;
-            case SINGLE:
-                append(new AMD64Unary.MemoryOp(MOVSS, SS, result, loadAddress, state));
-                break;
-            case DOUBLE:
-                append(new AMD64Unary.MemoryOp(MOVSD, SD, result, loadAddress, state));
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-        return result;
-    }
-
-    protected void emitStoreConst(AMD64Kind kind, AMD64AddressValue address, ConstantValue value, LIRFrameState state) {
-        Constant c = value.getConstant();
-        if (JavaConstant.isNull(c)) {
-            assert kind == AMD64Kind.DWORD || kind == AMD64Kind.QWORD;
-            OperandSize size = kind == AMD64Kind.DWORD ? DWORD : QWORD;
-            append(new AMD64BinaryConsumer.MemoryConstOp(AMD64MIOp.MOV, size, address, 0, state));
-            return;
-        } else if (c instanceof VMConstant) {
-            // only 32-bit constants can be patched
-            if (kind == AMD64Kind.DWORD) {
-                if (target().inlineObjects || !(c instanceof JavaConstant)) {
-                    // if c is a JavaConstant, it's an oop, otherwise it's a metaspace constant
-                    assert !(c instanceof JavaConstant) || ((JavaConstant) c).getJavaKind() == JavaKind.Object;
-                    append(new AMD64BinaryConsumer.MemoryVMConstOp(AMD64MIOp.MOV, address, (VMConstant) c, state));
-                    return;
-                }
-            }
-        } else {
-            JavaConstant jc = (JavaConstant) c;
-            assert jc.getJavaKind().isPrimitive();
-
-            AMD64MIOp op = AMD64MIOp.MOV;
-            OperandSize size;
-            long imm;
-
-            switch (kind) {
-                case BYTE:
-                    op = AMD64MIOp.MOVB;
-                    size = BYTE;
-                    imm = jc.asInt();
-                    break;
-                case WORD:
-                    size = WORD;
-                    imm = jc.asInt();
-                    break;
-                case DWORD:
-                    size = DWORD;
-                    imm = jc.asInt();
-                    break;
-                case QWORD:
-                    size = QWORD;
-                    imm = jc.asLong();
-                    break;
-                case SINGLE:
-                    size = DWORD;
-                    imm = Float.floatToRawIntBits(jc.asFloat());
-                    break;
-                case DOUBLE:
-                    size = QWORD;
-                    imm = Double.doubleToRawLongBits(jc.asDouble());
-                    break;
-                default:
-                    throw JVMCIError.shouldNotReachHere("unexpected kind " + kind);
-            }
-
-            if (NumUtil.isInt(imm)) {
-                append(new AMD64BinaryConsumer.MemoryConstOp(op, size, address, (int) imm, state));
-                return;
-            }
-        }
-
-        // fallback: load, then store
-        emitStore(kind, address, asAllocatable(value), state);
-    }
-
-    protected void emitStore(AMD64Kind kind, AMD64AddressValue address, AllocatableValue value, LIRFrameState state) {
-        switch (kind) {
-            case BYTE:
-                append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOVB, BYTE, address, value, state));
-                break;
-            case WORD:
-                append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOV, WORD, address, value, state));
-                break;
-            case DWORD:
-                append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOV, DWORD, address, value, state));
-                break;
-            case QWORD:
-                append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOV, QWORD, address, value, state));
-                break;
-            case SINGLE:
-                append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOVSS, SS, address, value, state));
-                break;
-            case DOUBLE:
-                append(new AMD64BinaryConsumer.MemoryMROp(AMD64MROp.MOVSD, SD, address, value, state));
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public void emitStore(LIRKind lirKind, Value address, Value input, LIRFrameState state) {
-        AMD64AddressValue storeAddress = asAddressValue(address);
-        AMD64Kind kind = (AMD64Kind) lirKind.getPlatformKind();
-        if (isConstantValue(input)) {
-            emitStoreConst(kind, storeAddress, asConstantValue(input), state);
-        } else {
-            emitStore(kind, storeAddress, asAllocatable(input), state);
-        }
-    }
-
-    @Override
     public Variable emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) {
         LIRKind kind = newValue.getLIRKind();
         assert kind.equals(expectedValue.getLIRKind());
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeMatchRules.java	Mon Nov 02 17:52:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeMatchRules.java	Mon Nov 02 18:25:48 2015 +0100
@@ -252,7 +252,7 @@
     private Value emitReinterpretMemory(LIRKind to, Access access) {
         AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
         LIRFrameState state = getState(access);
-        return getLIRGeneratorTool().emitLoad(to, address, state);
+        return getArithmeticLIRGenerator().emitLoad(to, address, state);
     }
 
     @MatchRule("(If (IntegerTest Read=access value))")
@@ -374,7 +374,7 @@
     public ComplexMatchResult writeNarrow(WriteNode root, NarrowNode narrow) {
         return builder -> {
             LIRKind writeKind = getLIRGeneratorTool().getLIRKind(root.value().stamp());
-            getLIRGeneratorTool().emitStore(writeKind, operand(root.getAddress()), operand(narrow.getValue()), state(root));
+            getArithmeticLIRGenerator().emitStore(writeKind, operand(root.getAddress()), operand(narrow.getValue()), state(root));
             return null;
         };
     }
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCArithmeticLIRGenerator.java	Mon Nov 02 17:52:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCArithmeticLIRGenerator.java	Mon Nov 02 18:25:48 2015 +0100
@@ -59,9 +59,9 @@
 import static jdk.vm.ci.meta.JavaConstant.forLong;
 import static jdk.vm.ci.sparc.SPARC.g0;
 import static jdk.vm.ci.sparc.SPARCKind.DOUBLE;
-import static jdk.vm.ci.sparc.SPARCKind.XWORD;
 import static jdk.vm.ci.sparc.SPARCKind.SINGLE;
 import static jdk.vm.ci.sparc.SPARCKind.WORD;
+import static jdk.vm.ci.sparc.SPARCKind.XWORD;
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.meta.AllocatableValue;
 import jdk.vm.ci.meta.JavaConstant;
@@ -79,6 +79,7 @@
 import com.oracle.graal.lir.LIRFrameState;
 import com.oracle.graal.lir.Variable;
 import com.oracle.graal.lir.gen.ArithmeticLIRGenerator;
+import com.oracle.graal.lir.sparc.SPARCAddressValue;
 import com.oracle.graal.lir.sparc.SPARCArithmetic;
 import com.oracle.graal.lir.sparc.SPARCArithmetic.FloatConvertOp;
 import com.oracle.graal.lir.sparc.SPARCArithmetic.MulHighOp;
@@ -88,7 +89,10 @@
 import com.oracle.graal.lir.sparc.SPARCArithmetic.SPARCIMulccOp;
 import com.oracle.graal.lir.sparc.SPARCArithmetic.SPARCLMulccOp;
 import com.oracle.graal.lir.sparc.SPARCBitManipulationOp;
+import com.oracle.graal.lir.sparc.SPARCMove.LoadOp;
 import com.oracle.graal.lir.sparc.SPARCMove.MoveFpGp;
+import com.oracle.graal.lir.sparc.SPARCMove.StoreConstantOp;
+import com.oracle.graal.lir.sparc.SPARCMove.StoreOp;
 import com.oracle.graal.lir.sparc.SPARCOP3Op;
 import com.oracle.graal.lir.sparc.SPARCOPFOp;
 
@@ -667,4 +671,26 @@
             return emitConvertMove(to, input);
         }
     }
+
+    @Override
+    public Variable emitLoad(LIRKind kind, Value address, LIRFrameState state) {
+        SPARCAddressValue loadAddress = getLIRGen().asAddressValue(address);
+        Variable result = getLIRGen().newVariable(getLIRGen().toRegisterKind(kind));
+        getLIRGen().append(new LoadOp(kind.getPlatformKind(), result, loadAddress, state));
+        return result;
+    }
+
+    @Override
+    public void emitStore(LIRKind kind, Value address, Value inputVal, LIRFrameState state) {
+        SPARCAddressValue storeAddress = getLIRGen().asAddressValue(address);
+        if (isJavaConstant(inputVal)) {
+            JavaConstant c = asJavaConstant(inputVal);
+            if (c.isDefaultForKind()) {
+                getLIRGen().append(new StoreConstantOp(kind.getPlatformKind(), storeAddress, c, state));
+                return;
+            }
+        }
+        Variable input = getLIRGen().load(inputVal);
+        getLIRGen().append(new StoreOp(kind.getPlatformKind(), storeAddress, input, state));
+    }
 }
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeMatchRules.java	Mon Nov 02 17:52:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeMatchRules.java	Mon Nov 02 18:25:48 2015 +0100
@@ -122,7 +122,7 @@
         SPARCKind localToKind = toKind;
         return builder -> {
             // Loads are always zero extending load
-            Value v = getLIRGeneratorTool().emitLoad(LIRKind.value(localFromKind), operand(access.getAddress()), getState(access));
+            Value v = getArithmeticLIRGenerator().emitLoad(LIRKind.value(localFromKind), operand(access.getAddress()), getState(access));
             return getArithmeticLIRGenerator().emitReinterpret(LIRKind.value(localToKind), v);
         };
     }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Nov 02 17:52:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Nov 02 18:25:48 2015 +0100
@@ -501,7 +501,7 @@
         LIRKind wordKind = LIRKind.value(target().arch.getWordKind());
         RegisterValue thread = getProviders().getRegisters().getThreadRegister().asValue(wordKind);
         AMD64AddressValue address = new AMD64AddressValue(wordKind, thread, offset);
-        emitStore(v.getLIRKind(), address, v, null);
+        arithmeticLIRGen.emitStore(v.getLIRKind(), address, v, null);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Nov 02 17:52:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Nov 02 18:25:48 2015 +0100
@@ -25,9 +25,7 @@
 import static com.oracle.graal.hotspot.HotSpotBackend.FETCH_UNROLL_INFO;
 import static com.oracle.graal.hotspot.HotSpotBackend.UNCOMMON_TRAP;
 import static com.oracle.graal.lir.LIRValueUtil.asConstant;
-import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant;
 import static com.oracle.graal.lir.LIRValueUtil.isConstantValue;
-import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
 import static jdk.vm.ci.sparc.SPARC.d32;
 import static jdk.vm.ci.sparc.SPARC.d34;
 import static jdk.vm.ci.sparc.SPARC.d36;
@@ -116,9 +114,7 @@
 import com.oracle.graal.lir.sparc.SPARCFrameMapBuilder;
 import com.oracle.graal.lir.sparc.SPARCImmediateAddressValue;
 import com.oracle.graal.lir.sparc.SPARCMove.CompareAndSwapOp;
-import com.oracle.graal.lir.sparc.SPARCMove.LoadOp;
 import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp;
-import com.oracle.graal.lir.sparc.SPARCMove.StoreConstantOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StoreOp;
 import com.oracle.graal.lir.sparc.SPARCSaveRegistersOp;
 
@@ -278,28 +274,6 @@
         append(new SPARCHotSpotDeoptimizeCallerOp());
     }
 
-    @Override
-    public Variable emitLoad(LIRKind kind, Value address, LIRFrameState state) {
-        SPARCAddressValue loadAddress = asAddressValue(address);
-        Variable result = newVariable(toRegisterKind(kind));
-        append(new LoadOp(kind.getPlatformKind(), result, loadAddress, state));
-        return result;
-    }
-
-    @Override
-    public void emitStore(LIRKind kind, Value address, Value inputVal, LIRFrameState state) {
-        SPARCAddressValue storeAddress = asAddressValue(address);
-        if (isJavaConstant(inputVal)) {
-            JavaConstant c = asJavaConstant(inputVal);
-            if (c.isDefaultForKind()) {
-                append(new StoreConstantOp(kind.getPlatformKind(), storeAddress, c, state));
-                return;
-            }
-        }
-        Variable input = load(inputVal);
-        append(new StoreOp(kind.getPlatformKind(), storeAddress, input, state));
-    }
-
     public Variable emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) {
         LIRKind kind = newValue.getLIRKind();
         assert kind.equals(expectedValue.getLIRKind());
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/ArithmeticLIRGeneratorTool.java	Mon Nov 02 17:52:27 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/ArithmeticLIRGeneratorTool.java	Mon Nov 02 18:25:48 2015 +0100
@@ -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
@@ -27,9 +27,10 @@
 
 import com.oracle.graal.compiler.common.calc.FloatConvert;
 import com.oracle.graal.lir.LIRFrameState;
+import com.oracle.graal.lir.Variable;
 
 /**
- * This interface can be used to generate LIR for arithmetic operations.
+ * This interface can be used to generate LIR for arithmetic and simple memory access operations.
  *
  * The setFlags flag in emitAdd, emitSub and emitMul indicates, that the instruction must set the
  * flags register to be used for a later branch. (On AMD64, the condition codes are set in every
@@ -92,4 +93,9 @@
     Value emitBitScanForward(Value operand);
 
     Value emitBitScanReverse(Value operand);
+
+    Variable emitLoad(LIRKind kind, Value address, LIRFrameState state);
+
+    void emitStore(LIRKind kind, Value address, Value input, LIRFrameState state);
+
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java	Mon Nov 02 17:52:27 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java	Mon Nov 02 18:25:48 2015 +0100
@@ -116,19 +116,15 @@
     Value emitJavaConstant(JavaConstant constant);
 
     /**
-     * Some backends need to convert sub-word kinds to a larger kind in {@link #emitLoad} and
-     * {@link #emitLoadConstant} because sub-word registers can't be accessed. This method converts
-     * the {@link LIRKind} of a memory location or constant to the {@link LIRKind} that will be used
-     * when it is loaded into a register.
+     * Some backends need to convert sub-word kinds to a larger kind in
+     * {@link ArithmeticLIRGeneratorTool#emitLoad} and {@link #emitLoadConstant} because sub-word
+     * registers can't be accessed. This method converts the {@link LIRKind} of a memory location or
+     * constant to the {@link LIRKind} that will be used when it is loaded into a register.
      */
     LIRKind toRegisterKind(LIRKind kind);
 
     AllocatableValue emitLoadConstant(LIRKind kind, Constant constant);
 
-    Variable emitLoad(LIRKind kind, Value address, LIRFrameState state);
-
-    void emitStore(LIRKind kind, Value address, Value input, LIRFrameState state);
-
     void emitNullCheck(Value address, LIRFrameState state);
 
     Variable emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FloatingReadNode.java	Mon Nov 02 17:52:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FloatingReadNode.java	Mon Nov 02 18:25:48 2015 +0100
@@ -75,7 +75,7 @@
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         LIRKind readKind = gen.getLIRGeneratorTool().getLIRKind(stamp());
-        gen.setResult(this, gen.getLIRGeneratorTool().emitLoad(readKind, gen.operand(address), null));
+        gen.setResult(this, gen.getLIRGeneratorTool().getArithmetic().emitLoad(readKind, gen.operand(address), null));
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/ReadNode.java	Mon Nov 02 17:52:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/ReadNode.java	Mon Nov 02 18:25:48 2015 +0100
@@ -90,7 +90,7 @@
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         LIRKind readKind = gen.getLIRGeneratorTool().getLIRKind(stamp());
-        gen.setResult(this, gen.getLIRGeneratorTool().emitLoad(readKind, gen.operand(address), gen.state(this)));
+        gen.setResult(this, gen.getLIRGeneratorTool().getArithmetic().emitLoad(readKind, gen.operand(address), gen.state(this)));
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/WriteNode.java	Mon Nov 02 17:52:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/WriteNode.java	Mon Nov 02 18:25:48 2015 +0100
@@ -72,7 +72,7 @@
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         LIRKind writeKind = gen.getLIRGeneratorTool().getLIRKind(value().stamp());
-        gen.getLIRGeneratorTool().emitStore(writeKind, gen.operand(address), gen.operand(value()), gen.state(this));
+        gen.getLIRGeneratorTool().getArithmetic().emitStore(writeKind, gen.operand(address), gen.operand(value()), gen.state(this));
     }
 
     @Override
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java	Mon Nov 02 17:52:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java	Mon Nov 02 18:25:48 2015 +0100
@@ -70,7 +70,7 @@
     public void generate(NodeLIRBuilderTool builder) {
         LIRGeneratorTool gen = builder.getLIRGeneratorTool();
         LIRKind kind = gen.target().getLIRKind(readKind);
-        Value loaded = gen.emitLoad(kind, builder.operand(address), null);
+        Value loaded = gen.getArithmetic().emitLoad(kind, builder.operand(address), null);
         switch (readKind) {
             case Byte:
                 loaded = gen.getArithmetic().emitSignExtend(loaded, 8, 32);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java	Mon Nov 02 17:52:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java	Mon Nov 02 18:25:48 2015 +0100
@@ -59,7 +59,7 @@
     public void generate(NodeLIRBuilderTool gen) {
         Value v = gen.operand(value);
         LIRKind lirKind = gen.getLIRGeneratorTool().target().getLIRKind(kind);
-        gen.getLIRGeneratorTool().emitStore(lirKind, gen.operand(address), v, null);
+        gen.getLIRGeneratorTool().getArithmetic().emitStore(lirKind, gen.operand(address), v, null);
     }
 
     public ValueNode getAddress() {