diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/alloc/SaveCalleeSaveRegisters.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/alloc/SaveCalleeSaveRegisters.java index e61fbbdf7ce7..4b236dc5a230 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/alloc/SaveCalleeSaveRegisters.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/alloc/SaveCalleeSaveRegisters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -25,6 +25,7 @@ package jdk.graal.compiler.lir.alloc; import java.util.ArrayList; +import java.util.List; import jdk.graal.compiler.core.common.LIRKind; import jdk.graal.compiler.core.common.cfg.BasicBlock; @@ -32,7 +33,6 @@ import jdk.graal.compiler.lir.LIRInsertionBuffer; import jdk.graal.compiler.lir.LIRInstruction; import jdk.graal.compiler.lir.StandardOp; -import jdk.graal.compiler.lir.Variable; import jdk.graal.compiler.lir.gen.LIRGenerationResult; import jdk.graal.compiler.lir.gen.LIRGeneratorTool; import jdk.graal.compiler.lir.gen.MoveFactory; @@ -43,6 +43,7 @@ import jdk.vm.ci.code.RegisterArray; import jdk.vm.ci.code.RegisterValue; import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.meta.AllocatableValue; import jdk.vm.ci.meta.PlatformKind; public class SaveCalleeSaveRegisters extends PreAllocationOptimizationPhase { @@ -54,7 +55,7 @@ protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PreA return; } LIR lir = lirGenRes.getLIR(); - RegisterMap savedRegisters = saveAtEntry(lir, context.lirGen, lirGenRes, calleeSaveRegisters, target.arch); + RegisterMap savedRegisters = saveAtEntry(lir, context.lirGen, lirGenRes, calleeSaveRegisters, target.arch); for (int blockId : lir.getBlocks()) { if (LIR.isBlockDeleted(blockId)) { @@ -67,7 +68,7 @@ protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PreA } } - private static RegisterMap saveAtEntry(LIR lir, LIRGeneratorTool lirGen, LIRGenerationResult lirGenRes, RegisterArray calleeSaveRegisters, Architecture arch) { + private static RegisterMap saveAtEntry(LIR lir, LIRGeneratorTool lirGen, LIRGenerationResult lirGenRes, RegisterArray calleeSaveRegisters, Architecture arch) { BasicBlock startBlock = lir.getControlFlowGraph().getStartBlock(); ArrayList instructions = lir.getLIRforBlock(startBlock); int insertionIndex = lirGenRes.getFirstInsertPosition(); @@ -76,12 +77,13 @@ private static RegisterMap saveAtEntry(LIR lir, LIRGeneratorTool lirGe StandardOp.LabelOp entry = (StandardOp.LabelOp) instructions.get(insertionIndex - 1); RegisterValue[] savedRegisterValues = new RegisterValue[calleeSaveRegisters.size()]; int savedRegisterValueIndex = 0; - RegisterMap saveMap = new RegisterMap<>(arch); + List allocatables = lirGenRes.getRegisterConfig().getAllocatableRegisters().asList(); + RegisterMap saveMap = new RegisterMap<>(arch); for (Register register : calleeSaveRegisters) { - PlatformKind registerPlatformKind = arch.getLargestStorableKind(register.getRegisterCategory()); + PlatformKind registerPlatformKind = lirGenRes.getRegisterConfig().getCalleeSaveRegisterStorageKind(arch, register); LIRKind lirKind = LIRKind.value(registerPlatformKind); RegisterValue registerValue = register.asValue(lirKind); - Variable saveVariable = lirGen.newVariable(lirKind); + AllocatableValue saveVariable = allocatables.contains(registerValue.getRegister()) ? lirGen.newVariable(lirKind) : lirGenRes.getFrameMapBuilder().allocateSpillSlot(lirKind); LIRInstruction save = lirGen.getSpillMoveFactory().createMove(saveVariable, registerValue); buffer.append(insertionIndex, save); save.setComment(lirGenRes, "SaveCalleeSavedRegisters: saveAtEntry"); @@ -93,14 +95,14 @@ private static RegisterMap saveAtEntry(LIR lir, LIRGeneratorTool lirGe return saveMap; } - private static void restoreAtExit(LIR lir, MoveFactory moveFactory, LIRGenerationResult lirGenRes, RegisterMap calleeSaveRegisters, BasicBlock block) { + private static void restoreAtExit(LIR lir, MoveFactory moveFactory, LIRGenerationResult lirGenRes, RegisterMap calleeSaveRegisters, BasicBlock block) { ArrayList instructions = lir.getLIRforBlock(block); int insertionIndex = instructions.size() - 1; LIRInsertionBuffer buffer = new LIRInsertionBuffer(); buffer.init(instructions); LIRInstruction lirInstruction = instructions.get(insertionIndex); assert lirInstruction instanceof StandardOp.BlockEndOp : lirInstruction; - calleeSaveRegisters.forEach((Register register, Variable saved) -> { + calleeSaveRegisters.forEach((Register register, AllocatableValue saved) -> { LIRInstruction restore = moveFactory.createMove(register.asValue(saved.getValueKind()), saved); buffer.append(insertionIndex, restore); restore.setComment(lirGenRes, "SaveCalleeSavedRegisters: restoreAtExit"); diff --git a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64RegisterConfig.java b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64RegisterConfig.java index 66d1df2a37bb..61fc073933ff 100644 --- a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64RegisterConfig.java +++ b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64RegisterConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -63,6 +63,7 @@ import static jdk.vm.ci.amd64.AMD64.xmm7; import static jdk.vm.ci.amd64.AMD64.xmm8; import static jdk.vm.ci.amd64.AMD64.xmm9; +import static jdk.vm.ci.amd64.AMD64Kind.V128_QWORD; import java.util.ArrayList; import java.util.Arrays; @@ -85,6 +86,7 @@ import jdk.graal.compiler.core.common.LIRKind; import jdk.vm.ci.amd64.AMD64; import jdk.vm.ci.amd64.AMD64Kind; +import jdk.vm.ci.code.Architecture; import jdk.vm.ci.code.CallingConvention; import jdk.vm.ci.code.CallingConvention.Type; import jdk.vm.ci.code.Register; @@ -234,6 +236,15 @@ public RegisterArray getCalleeSaveRegisters() { return calleeSaveRegisters; } + @Override + public PlatformKind getCalleeSaveRegisterStorageKind(Architecture arch, Register calleeSaveRegister) { + if (Platform.includedIn(Platform.WINDOWS.class) && AMD64.XMM.equals(calleeSaveRegister.getRegisterCategory())) { + VMError.guarantee(calleeSaveRegister.encoding() >= xmm6.encoding() && calleeSaveRegister.encoding() <= xmm15.encoding(), "unexpected callee saved register %s", calleeSaveRegister); + return V128_QWORD; + } + return SubstrateRegisterConfig.super.getCalleeSaveRegisterStorageKind(arch, calleeSaveRegister); + } + @Override public RegisterArray getCallerSaveRegisters() { return getAllocatableRegisters(); @@ -405,7 +416,7 @@ public CallingConvention getCallingConvention(Type t, JavaType returnType, JavaT kinds = Arrays.copyOf(kinds, kinds.length + 1); locations = Arrays.copyOf(locations, locations.length + 1); kinds[kinds.length - 1] = JavaKind.Int; - locations[locations.length - 1] = AMD64.rax.asValue(LIRKind.value(AMD64Kind.DWORD)); + locations[locations.length - 1] = rax.asValue(LIRKind.value(AMD64Kind.DWORD)); if (type.customABI()) { var extendsParametersAssignment = Arrays.copyOf(type.fixedParameterAssignment, type.fixedParameterAssignment.length + 1); extendsParametersAssignment[extendsParametersAssignment.length - 1] = AssignedLocation.forRegister(rax, JavaKind.Long);