# HG changeset patch # User Josef Eisl # Date 1430306383 -7200 # Node ID 5b913e45262925e3477c3f629d8ea622e5fc4a2c # Parent 9965d71c8971adf78bcd03815c4d7c4579d204e6 AMD64SpillMoveFactory: implement #createStackMove. diff -r 9965d71c8971 -r 5b913e452629 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- 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 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) {