# HG changeset patch # User Doug Simon # Date 1376057041 -7200 # Node ID a5105213af335abbcc1ac156d19b26269b7b0ea8 # Parent 3209552fdb4e00ccacef3ac1b299ec5f71fcec01 Graal now complies with native ABI callee/caller save conventions for foreign calls (GRAAL-413) diff -r 3209552fdb4e -r a5105213af33 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java Fri Aug 09 13:48:08 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java Fri Aug 09 16:04:01 2013 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.amd64; -import static com.oracle.graal.amd64.AMD64.*; +import java.util.*; import com.oracle.graal.amd64.*; import com.oracle.graal.api.code.*; @@ -35,6 +35,8 @@ */ public class AMD64HotSpotGraalRuntime extends HotSpotGraalRuntime { + private Value[] nativeABICallerSaveRegisters; + protected AMD64HotSpotGraalRuntime() { } @@ -76,7 +78,62 @@ } @Override - protected Value[] getRuntimeCallVolatileRegisters() { - return new Value[]{r10.asValue(), r11.asValue()}; + protected Value[] getNativeABICallerSaveRegisters() { + if (nativeABICallerSaveRegisters == null) { + List callerSave = new ArrayList<>(Arrays.asList(getRuntime().lookupRegisterConfig().getAllocatableRegisters())); + if (getConfig().windowsOs) { + // http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx + callerSave.remove(AMD64.rdi); + callerSave.remove(AMD64.rsi); + callerSave.remove(AMD64.rbx); + callerSave.remove(AMD64.rbp); + callerSave.remove(AMD64.rsp); + callerSave.remove(AMD64.r12); + callerSave.remove(AMD64.r13); + callerSave.remove(AMD64.r14); + callerSave.remove(AMD64.r15); + callerSave.remove(AMD64.xmm6); + callerSave.remove(AMD64.xmm7); + callerSave.remove(AMD64.xmm8); + callerSave.remove(AMD64.xmm9); + callerSave.remove(AMD64.xmm10); + callerSave.remove(AMD64.xmm11); + callerSave.remove(AMD64.xmm12); + callerSave.remove(AMD64.xmm13); + callerSave.remove(AMD64.xmm14); + callerSave.remove(AMD64.xmm15); + } else { + /* + * System V Application Binary Interface, AMD64 Architecture Processor Supplement + * + * Draft Version 0.96 + * + * http://www.uclibc.org/docs/psABI-x86_64.pdf + * + * 3.2.1 + * + * ... + * + * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12 + * through %r15 "belong" to the calling function and the called function is required + * to preserve their values. In other words, a called function must preserve these + * registers' values for its caller. Remaining registers "belong" to the called + * function. If a calling function wants to preserve such a register value across a + * function call, it must save the value in its local stack frame. + */ + callerSave.remove(AMD64.rbp); + callerSave.remove(AMD64.rbx); + callerSave.remove(AMD64.r12); + callerSave.remove(AMD64.r13); + callerSave.remove(AMD64.r14); + callerSave.remove(AMD64.r15); + } + nativeABICallerSaveRegisters = new Value[callerSave.size()]; + for (int i = 0; i < callerSave.size(); i++) { + nativeABICallerSaveRegisters[i] = callerSave.get(i).asValue(); + } + } + + return nativeABICallerSaveRegisters; } } diff -r 3209552fdb4e -r a5105213af33 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java Fri Aug 09 13:48:08 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java Fri Aug 09 16:04:01 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.sparc.*; @@ -69,8 +70,7 @@ } @Override - protected Value[] getRuntimeCallVolatileRegisters() { - // TODO: is this correct? - return new Value[0]; + protected Value[] getNativeABICallerSaveRegisters() { + throw GraalInternalError.unimplemented(); } } diff -r 3209552fdb4e -r a5105213af33 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java Fri Aug 09 13:48:08 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java Fri Aug 09 16:04:01 2013 +0200 @@ -126,7 +126,7 @@ CallingConvention incomingCc = incomingCcType == null ? null : createCallingConvention(descriptor, incomingCcType); HotSpotForeignCallLinkage linkage = new HotSpotForeignCallLinkage(descriptor, address, effect, transition, outgoingCc, incomingCc, reexecutable, killedLocations); if (outgoingCcType == Type.NativeCall) { - linkage.temporaries = graalRuntime().getRuntimeCallVolatileRegisters(); + linkage.temporaries = graalRuntime().getNativeABICallerSaveRegisters(); } return linkage; } diff -r 3209552fdb4e -r a5105213af33 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Fri Aug 09 13:48:08 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Fri Aug 09 16:04:01 2013 +0200 @@ -32,7 +32,6 @@ import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.logging.*; import com.oracle.graal.hotspot.meta.*; @@ -255,11 +254,9 @@ protected abstract HotSpotRuntime createRuntime(); /** - * Gets the registers that are treated volatile by foreign calls into the runtime. These - * registers must be spilled across all native foreign runtime calls, even for calls that are - * declared as {@link RegisterEffect#PRESERVES_REGISTERS register preserving}. + * Gets the registers that must be saved across a foreign call into the runtime. */ - protected abstract Value[] getRuntimeCallVolatileRegisters(); + protected abstract Value[] getNativeABICallerSaveRegisters(); public HotSpotVMConfig getConfig() { return config;