changeset 21201:5b913e452629

AMD64SpillMoveFactory: implement #createStackMove.
author Josef Eisl <josef.eisl@jku.at>
date Wed, 29 Apr 2015 13:19:43 +0200
parents 9965d71c8971
children a03e95b6d629
files graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/PhiResolver.java
diffstat 1 files changed, 46 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Tue Apr 28 18:24:30 2015 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed Apr 29 13:19:43 2015 +0200
@@ -32,6 +32,8 @@
 import static com.oracle.graal.lir.amd64.AMD64Arithmetic.*;
 import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.*;
 
+import java.util.*;
+
 import com.oracle.graal.amd64.*;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -61,12 +63,14 @@
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.ReturnOp;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.StrategySwitchOp;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp;
+import com.oracle.graal.lir.amd64.AMD64Move.AMD64StackMove;
 import com.oracle.graal.lir.amd64.AMD64Move.LeaDataOp;
 import com.oracle.graal.lir.amd64.AMD64Move.LeaOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MembarOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp;
 import com.oracle.graal.lir.amd64.AMD64Move.StackLeaOp;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.phases.util.*;
 
@@ -78,12 +82,54 @@
     private static final RegisterValue RCX_I = AMD64.rcx.asValue(LIRKind.value(Kind.Int));
     private AMD64SpillMoveFactory moveFactory;
 
+    private static class RegisterBackupPair {
+        public final Register register;
+        public final StackSlotValue backupSlot;
+
+        RegisterBackupPair(Register register, StackSlotValue backupSlot) {
+            this.register = register;
+            this.backupSlot = backupSlot;
+        }
+    }
+
     private class AMD64SpillMoveFactory implements LIRGeneratorTool.SpillMoveFactory {
+        private Map<PlatformKind.Key, RegisterBackupPair> categorized;
 
         @Override
         public LIRInstruction createMove(AllocatableValue result, Value input) {
             return AMD64LIRGenerator.this.createMove(result, input);
         }
+
+        @Override
+        public LIRInstruction createStackMove(AllocatableValue result, Value input) {
+            RegisterBackupPair backup = getScratchRegister(input.getPlatformKind());
+            return new AMD64StackMove(result, input, backup.register, backup.backupSlot);
+        }
+
+        private RegisterBackupPair getScratchRegister(PlatformKind kind) {
+            PlatformKind.Key key = kind.getKey();
+            if (categorized == null) {
+                categorized = new HashMap<>();
+            } else if (categorized.containsKey(key)) {
+                return categorized.get(key);
+            }
+
+            FrameMapBuilder frameMapBuilder = getResult().getFrameMapBuilder();
+            RegisterConfig registerConfig = frameMapBuilder.getRegisterConfig();
+
+            Register[] availableRegister = registerConfig.filterAllocatableRegisters(kind, registerConfig.getAllocatableRegisters());
+            assert availableRegister != null && availableRegister.length > 1;
+            Register scratchRegister = availableRegister[0];
+
+            Architecture arch = frameMapBuilder.getCodeCache().getTarget().arch;
+            LIRKind largestKind = LIRKind.value(arch.getLargestStorableKind(scratchRegister.getRegisterCategory()));
+            VirtualStackSlot backupSlot = frameMapBuilder.allocateSpillSlot(largestKind);
+
+            RegisterBackupPair value = new RegisterBackupPair(scratchRegister, backupSlot);
+            categorized.put(key, value);
+
+            return value;
+        }
     }
 
     public AMD64LIRGenerator(LIRKindTool lirKindTool, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes) {