12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package org.graalvm.compiler.hotspot.aarch64; 25 26 import static org.graalvm.compiler.lir.LIRValueUtil.asConstant; 27 import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue; 28 29 import java.util.function.Function; 30 31 import org.graalvm.compiler.asm.Label; 32 import org.graalvm.compiler.asm.NumUtil; 33 import org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode; 34 import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ConditionFlag; 35 import org.graalvm.compiler.core.aarch64.AArch64ArithmeticLIRGenerator; 36 import org.graalvm.compiler.core.aarch64.AArch64LIRGenerator; 37 import org.graalvm.compiler.core.common.LIRKind; 38 import org.graalvm.compiler.core.common.calc.Condition; 39 import org.graalvm.compiler.core.common.spi.ForeignCallLinkage; 40 import org.graalvm.compiler.core.common.spi.LIRKindTool; 41 import org.graalvm.compiler.debug.GraalError; 42 import org.graalvm.compiler.hotspot.CompressEncoding; 43 import org.graalvm.compiler.hotspot.HotSpotBackend; 44 import org.graalvm.compiler.hotspot.HotSpotDebugInfoBuilder; 45 import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; 46 import org.graalvm.compiler.hotspot.HotSpotLIRGenerationResult; 47 import org.graalvm.compiler.hotspot.HotSpotLIRGenerator; 48 import org.graalvm.compiler.hotspot.HotSpotLockStack; 49 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; 50 import org.graalvm.compiler.hotspot.meta.HotSpotProviders; 51 import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider; 52 import org.graalvm.compiler.hotspot.stubs.Stub; 53 import org.graalvm.compiler.lir.LIRFrameState; 54 import org.graalvm.compiler.lir.LIRInstruction; 55 import org.graalvm.compiler.lir.LabelRef; 56 import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp; 57 import org.graalvm.compiler.lir.SwitchStrategy; 58 import org.graalvm.compiler.lir.Variable; 59 import org.graalvm.compiler.lir.VirtualStackSlot; 60 import org.graalvm.compiler.lir.aarch64.AArch64AddressValue; 61 import org.graalvm.compiler.lir.aarch64.AArch64Call; 62 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.StrategySwitchOp; 63 import org.graalvm.compiler.lir.aarch64.AArch64FrameMapBuilder; 64 import org.graalvm.compiler.lir.aarch64.AArch64Move.StoreOp; 65 import org.graalvm.compiler.lir.aarch64.AArch64PrefetchOp; 66 import org.graalvm.compiler.lir.gen.LIRGenerationResult; 67 68 import jdk.vm.ci.aarch64.AArch64; 69 import jdk.vm.ci.aarch64.AArch64Kind; 70 import jdk.vm.ci.code.CallingConvention; 71 import jdk.vm.ci.code.Register; 72 import jdk.vm.ci.code.RegisterValue; 73 import jdk.vm.ci.code.StackSlot; 74 import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant; 75 import jdk.vm.ci.hotspot.HotSpotObjectConstant; 76 import jdk.vm.ci.meta.AllocatableValue; 77 import jdk.vm.ci.meta.Constant; 78 import jdk.vm.ci.meta.DeoptimizationAction; 79 import jdk.vm.ci.meta.DeoptimizationReason; 80 import jdk.vm.ci.meta.JavaConstant; 81 import jdk.vm.ci.meta.JavaKind; 82 import jdk.vm.ci.meta.PlatformKind; 83 import jdk.vm.ci.meta.Value; 112 } 113 114 @SuppressWarnings("unused") private LIRFrameState currentRuntimeCallInfo; 115 116 @Override 117 protected void emitForeignCallOp(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) { 118 currentRuntimeCallInfo = info; 119 if (AArch64Call.isNearCall(linkage)) { 120 append(new AArch64Call.DirectNearForeignCallOp(linkage, result, arguments, temps, info, label)); 121 } else { 122 append(new AArch64Call.DirectFarForeignCallOp(linkage, result, arguments, temps, info, label)); 123 } 124 } 125 126 @Override 127 public void emitTailcall(Value[] args, Value address) { 128 throw GraalError.unimplemented(); 129 } 130 131 @Override 132 public SaveRegistersOp emitSaveAllRegisters() { 133 throw GraalError.unimplemented(); 134 } 135 136 @Override 137 public VirtualStackSlot getLockSlot(int lockDepth) { 138 return getLockStack().makeLockSlot(lockDepth); 139 } 140 141 private HotSpotLockStack getLockStack() { 142 assert debugInfoBuilder != null && debugInfoBuilder.lockStack() != null; 143 return debugInfoBuilder.lockStack(); 144 } 145 146 @Override 147 public void emitCompareBranch(PlatformKind cmpKind, Value x, Value y, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, 148 double trueDestinationProbability) { 149 Value localX = x; 150 Value localY = y; 151 if (localX instanceof HotSpotObjectConstant) { 176 } else if (c instanceof HotSpotObjectConstant) { 177 localB = load(localB); 178 } 179 } 180 return super.emitCompare(cmpKind, localA, localB, condition, unorderedIsTrue); 181 } 182 183 @Override 184 public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) { 185 LIRKind inputKind = pointer.getValueKind(LIRKind.class); 186 assert inputKind.getPlatformKind() == AArch64Kind.QWORD; 187 if (inputKind.isReference(0)) { 188 // oop 189 Variable result = newVariable(LIRKind.reference(AArch64Kind.DWORD)); 190 append(new AArch64HotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull)); 191 return result; 192 } else { 193 // metaspace pointer 194 Variable result = newVariable(LIRKind.value(AArch64Kind.DWORD)); 195 AllocatableValue base = Value.ILLEGAL; 196 if (encoding.base != 0) { 197 base = emitLoadConstant(LIRKind.value(AArch64Kind.QWORD), JavaConstant.forLong(encoding.base)); 198 } 199 append(new AArch64HotSpotMove.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull)); 200 return result; 201 } 202 } 203 204 @Override 205 public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) { 206 LIRKind inputKind = pointer.getValueKind(LIRKind.class); 207 assert inputKind.getPlatformKind() == AArch64Kind.DWORD; 208 if (inputKind.isReference(0)) { 209 // oop 210 Variable result = newVariable(LIRKind.reference(AArch64Kind.QWORD)); 211 append(new AArch64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull)); 212 return result; 213 } else { 214 // metaspace pointer 215 Variable result = newVariable(LIRKind.value(AArch64Kind.QWORD)); 216 AllocatableValue base = Value.ILLEGAL; 217 if (encoding.base != 0) { 218 base = emitLoadConstant(LIRKind.value(AArch64Kind.QWORD), JavaConstant.forLong(encoding.base)); 219 } 220 append(new AArch64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull)); 221 return result; 222 } 223 } 224 225 @Override 226 public void emitPrefetchAllocate(Value address) { 227 append(new AArch64PrefetchOp(asAddressValue(address), config.allocatePrefetchInstr)); 228 } 229 230 @Override 231 public void beforeRegisterAllocation() { 232 super.beforeRegisterAllocation(); 233 boolean hasDebugInfo = getResult().getLIR().hasDebugInfo(); 234 if (hasDebugInfo) { 235 getResult().setDeoptimizationRescueSlot(((AArch64FrameMapBuilder) getResult().getFrameMapBuilder()).allocateDeoptimizationRescueSlot()); 236 } 237 238 getResult().setMaxInterpreterFrameSize(debugInfoBuilder.maxInterpreterFrameSize()); 239 } 240 241 private Label label; 242 243 @Override 244 public Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState state, Value... args) { 245 HotSpotForeignCallLinkage hotspotLinkage = (HotSpotForeignCallLinkage) linkage; | 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package org.graalvm.compiler.hotspot.aarch64; 25 26 import static org.graalvm.compiler.lir.LIRValueUtil.asConstant; 27 import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue; 28 29 import java.util.function.Function; 30 31 import org.graalvm.compiler.asm.Label; 32 import org.graalvm.compiler.core.common.NumUtil; 33 import org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode; 34 import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ConditionFlag; 35 import org.graalvm.compiler.core.aarch64.AArch64ArithmeticLIRGenerator; 36 import org.graalvm.compiler.core.aarch64.AArch64LIRGenerator; 37 import org.graalvm.compiler.core.common.CompressEncoding; 38 import org.graalvm.compiler.core.common.LIRKind; 39 import org.graalvm.compiler.core.common.calc.Condition; 40 import org.graalvm.compiler.core.common.spi.ForeignCallLinkage; 41 import org.graalvm.compiler.core.common.spi.LIRKindTool; 42 import org.graalvm.compiler.debug.GraalError; 43 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; 44 import org.graalvm.compiler.hotspot.HotSpotBackend; 45 import org.graalvm.compiler.hotspot.HotSpotDebugInfoBuilder; 46 import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; 47 import org.graalvm.compiler.hotspot.HotSpotLIRGenerationResult; 48 import org.graalvm.compiler.hotspot.HotSpotLIRGenerator; 49 import org.graalvm.compiler.hotspot.HotSpotLockStack; 50 import org.graalvm.compiler.hotspot.meta.HotSpotProviders; 51 import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider; 52 import org.graalvm.compiler.hotspot.stubs.Stub; 53 import org.graalvm.compiler.lir.LIRFrameState; 54 import org.graalvm.compiler.lir.LIRInstruction; 55 import org.graalvm.compiler.lir.LabelRef; 56 import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp; 57 import org.graalvm.compiler.lir.SwitchStrategy; 58 import org.graalvm.compiler.lir.Variable; 59 import org.graalvm.compiler.lir.VirtualStackSlot; 60 import org.graalvm.compiler.lir.aarch64.AArch64AddressValue; 61 import org.graalvm.compiler.lir.aarch64.AArch64CCall; 62 import org.graalvm.compiler.lir.aarch64.AArch64Call; 63 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.StrategySwitchOp; 64 import org.graalvm.compiler.lir.aarch64.AArch64FrameMapBuilder; 65 import org.graalvm.compiler.lir.aarch64.AArch64Move; 66 import org.graalvm.compiler.lir.aarch64.AArch64Move.StoreOp; 67 import org.graalvm.compiler.lir.aarch64.AArch64PrefetchOp; 68 import org.graalvm.compiler.lir.gen.LIRGenerationResult; 69 70 import jdk.vm.ci.aarch64.AArch64; 71 import jdk.vm.ci.aarch64.AArch64Kind; 72 import jdk.vm.ci.code.CallingConvention; 73 import jdk.vm.ci.code.Register; 74 import jdk.vm.ci.code.RegisterValue; 75 import jdk.vm.ci.code.StackSlot; 76 import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant; 77 import jdk.vm.ci.hotspot.HotSpotObjectConstant; 78 import jdk.vm.ci.meta.AllocatableValue; 79 import jdk.vm.ci.meta.Constant; 80 import jdk.vm.ci.meta.DeoptimizationAction; 81 import jdk.vm.ci.meta.DeoptimizationReason; 82 import jdk.vm.ci.meta.JavaConstant; 83 import jdk.vm.ci.meta.JavaKind; 84 import jdk.vm.ci.meta.PlatformKind; 85 import jdk.vm.ci.meta.Value; 114 } 115 116 @SuppressWarnings("unused") private LIRFrameState currentRuntimeCallInfo; 117 118 @Override 119 protected void emitForeignCallOp(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) { 120 currentRuntimeCallInfo = info; 121 if (AArch64Call.isNearCall(linkage)) { 122 append(new AArch64Call.DirectNearForeignCallOp(linkage, result, arguments, temps, info, label)); 123 } else { 124 append(new AArch64Call.DirectFarForeignCallOp(linkage, result, arguments, temps, info, label)); 125 } 126 } 127 128 @Override 129 public void emitTailcall(Value[] args, Value address) { 130 throw GraalError.unimplemented(); 131 } 132 133 @Override 134 public void emitCCall(long address, CallingConvention nativeCallingConvention, Value[] args) { 135 Value[] argLocations = new Value[args.length]; 136 getResult().getFrameMapBuilder().callsMethod(nativeCallingConvention); 137 for (int i = 0; i < args.length; i++) { 138 Value arg = args[i]; 139 AllocatableValue loc = nativeCallingConvention.getArgument(i); 140 emitMove(loc, arg); 141 argLocations[i] = loc; 142 } 143 Value ptr = emitLoadConstant(LIRKind.value(AArch64Kind.QWORD), JavaConstant.forLong(address)); 144 append(new AArch64CCall(nativeCallingConvention.getReturn(), ptr, argLocations)); 145 } 146 147 public SaveRegistersOp emitSaveAllRegisters() { 148 throw GraalError.unimplemented(); 149 } 150 151 @Override 152 public VirtualStackSlot getLockSlot(int lockDepth) { 153 return getLockStack().makeLockSlot(lockDepth); 154 } 155 156 private HotSpotLockStack getLockStack() { 157 assert debugInfoBuilder != null && debugInfoBuilder.lockStack() != null; 158 return debugInfoBuilder.lockStack(); 159 } 160 161 @Override 162 public void emitCompareBranch(PlatformKind cmpKind, Value x, Value y, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, 163 double trueDestinationProbability) { 164 Value localX = x; 165 Value localY = y; 166 if (localX instanceof HotSpotObjectConstant) { 191 } else if (c instanceof HotSpotObjectConstant) { 192 localB = load(localB); 193 } 194 } 195 return super.emitCompare(cmpKind, localA, localB, condition, unorderedIsTrue); 196 } 197 198 @Override 199 public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) { 200 LIRKind inputKind = pointer.getValueKind(LIRKind.class); 201 assert inputKind.getPlatformKind() == AArch64Kind.QWORD; 202 if (inputKind.isReference(0)) { 203 // oop 204 Variable result = newVariable(LIRKind.reference(AArch64Kind.DWORD)); 205 append(new AArch64HotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull)); 206 return result; 207 } else { 208 // metaspace pointer 209 Variable result = newVariable(LIRKind.value(AArch64Kind.DWORD)); 210 AllocatableValue base = Value.ILLEGAL; 211 if (encoding.hasBase()) { 212 base = emitLoadConstant(LIRKind.value(AArch64Kind.QWORD), JavaConstant.forLong(encoding.getBase())); 213 } 214 append(new AArch64HotSpotMove.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull)); 215 return result; 216 } 217 } 218 219 @Override 220 public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) { 221 LIRKind inputKind = pointer.getValueKind(LIRKind.class); 222 assert inputKind.getPlatformKind() == AArch64Kind.DWORD; 223 if (inputKind.isReference(0)) { 224 // oop 225 Variable result = newVariable(LIRKind.reference(AArch64Kind.QWORD)); 226 append(new AArch64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull)); 227 return result; 228 } else { 229 // metaspace pointer 230 Variable result = newVariable(LIRKind.value(AArch64Kind.QWORD)); 231 AllocatableValue base = Value.ILLEGAL; 232 if (encoding.hasBase()) { 233 base = emitLoadConstant(LIRKind.value(AArch64Kind.QWORD), JavaConstant.forLong(encoding.getBase())); 234 } 235 append(new AArch64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull)); 236 return result; 237 } 238 } 239 240 @Override 241 public void emitNullCheck(Value address, LIRFrameState state) { 242 if (address.getValueKind().getPlatformKind() == AArch64Kind.DWORD) { 243 CompressEncoding encoding = config.getOopEncoding(); 244 Value uncompressed = emitUncompress(address, encoding, false); 245 append(new AArch64Move.NullCheckOp(asAddressValue(uncompressed), state)); 246 } else { 247 super.emitNullCheck(address, state); 248 } 249 } 250 251 @Override 252 public void emitPrefetchAllocate(Value address) { 253 append(new AArch64PrefetchOp(asAddressValue(address), config.allocatePrefetchInstr)); 254 } 255 256 @Override 257 public void beforeRegisterAllocation() { 258 super.beforeRegisterAllocation(); 259 boolean hasDebugInfo = getResult().getLIR().hasDebugInfo(); 260 if (hasDebugInfo) { 261 getResult().setDeoptimizationRescueSlot(((AArch64FrameMapBuilder) getResult().getFrameMapBuilder()).allocateDeoptimizationRescueSlot()); 262 } 263 264 getResult().setMaxInterpreterFrameSize(debugInfoBuilder.maxInterpreterFrameSize()); 265 } 266 267 private Label label; 268 269 @Override 270 public Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState state, Value... args) { 271 HotSpotForeignCallLinkage hotspotLinkage = (HotSpotForeignCallLinkage) linkage; |