1 /* 2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 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 25 package org.graalvm.compiler.hotspot.sparc; 26 27 import static jdk.vm.ci.sparc.SPARC.g5; 28 import static jdk.vm.ci.sparc.SPARC.o7; 29 import static org.graalvm.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER_IN_CALLER; 30 31 import org.graalvm.compiler.core.common.LIRKind; 32 import org.graalvm.compiler.core.common.spi.ForeignCallLinkage; 33 import org.graalvm.compiler.core.gen.DebugInfoBuilder; 34 import org.graalvm.compiler.core.sparc.SPARCNodeLIRBuilder; 35 import org.graalvm.compiler.core.sparc.SPARCNodeMatchRules; 36 import org.graalvm.compiler.hotspot.HotSpotDebugInfoBuilder; 37 import org.graalvm.compiler.hotspot.HotSpotLIRGenerator; 38 import org.graalvm.compiler.hotspot.HotSpotLockStack; 39 import org.graalvm.compiler.hotspot.HotSpotNodeLIRBuilder; 40 import org.graalvm.compiler.hotspot.nodes.HotSpotDirectCallTargetNode; 41 import org.graalvm.compiler.hotspot.nodes.HotSpotIndirectCallTargetNode; 42 import org.graalvm.compiler.lir.LIRFrameState; 43 import org.graalvm.compiler.lir.Variable; 44 import org.graalvm.compiler.lir.gen.LIRGeneratorTool; 45 import org.graalvm.compiler.lir.sparc.SPARCBreakpointOp; 46 import org.graalvm.compiler.nodes.BreakpointNode; 47 import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind; 48 import org.graalvm.compiler.nodes.DirectCallTargetNode; 49 import org.graalvm.compiler.nodes.FullInfopointNode; 50 import org.graalvm.compiler.nodes.IndirectCallTargetNode; 51 import org.graalvm.compiler.nodes.NodeView; 52 import org.graalvm.compiler.nodes.SafepointNode; 53 import org.graalvm.compiler.nodes.StructuredGraph; 54 import org.graalvm.compiler.nodes.ValueNode; 55 import org.graalvm.compiler.nodes.spi.NodeValueMap; 56 57 import jdk.vm.ci.code.BytecodeFrame; 58 import jdk.vm.ci.code.CallingConvention; 59 import jdk.vm.ci.code.Register; 60 import jdk.vm.ci.code.RegisterValue; 61 import jdk.vm.ci.hotspot.HotSpotCallingConventionType; 62 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; 63 import jdk.vm.ci.meta.AllocatableValue; 64 import jdk.vm.ci.meta.JavaType; 65 import jdk.vm.ci.meta.Value; 66 import jdk.vm.ci.sparc.SPARCKind; 67 68 public class SPARCHotSpotNodeLIRBuilder extends SPARCNodeLIRBuilder implements HotSpotNodeLIRBuilder { 69 70 public SPARCHotSpotNodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool lirGen, SPARCNodeMatchRules nodeMatchRules) { 71 super(graph, lirGen, nodeMatchRules); 72 assert gen instanceof SPARCHotSpotLIRGenerator; 73 assert getDebugInfoBuilder() instanceof HotSpotDebugInfoBuilder; 74 ((SPARCHotSpotLIRGenerator) gen).setDebugInfoBuilder(((HotSpotDebugInfoBuilder) getDebugInfoBuilder())); 75 } 76 77 @Override 78 protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeValueMap nodeValueMap) { 79 HotSpotLockStack lockStack = new HotSpotLockStack(gen.getResult().getFrameMapBuilder(), LIRKind.value(SPARCKind.XWORD)); 80 return new HotSpotDebugInfoBuilder(nodeValueMap, lockStack, (HotSpotLIRGenerator) gen); 81 } 82 83 private SPARCHotSpotLIRGenerator getGen() { 84 return (SPARCHotSpotLIRGenerator) gen; 85 } 86 87 @Override 88 public void visitSafepointNode(SafepointNode i) { 89 LIRFrameState info = state(i); 90 Register thread = getGen().getProviders().getRegisters().getThreadRegister(); 91 append(new SPARCHotSpotSafepointOp(info, getGen().config, thread, gen)); 92 } 93 94 @Override 95 protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { 96 InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind(); 97 if (invokeKind.isIndirect()) { 98 append(new SPARCHotspotDirectVirtualCallOp(callTarget.targetMethod(), result, parameters, temps, callState, invokeKind, getGen().config)); 99 } else { 100 assert invokeKind.isDirect(); 101 HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod(); 102 assert resolvedMethod.isConcrete() : "Cannot make direct call to abstract method."; 103 append(new SPARCHotspotDirectStaticCallOp(callTarget.targetMethod(), result, parameters, temps, callState, invokeKind, getGen().config)); 104 } 105 } 106 107 @Override 108 protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { 109 Value metaspaceMethodSrc = operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod()); 110 AllocatableValue metaspaceMethod = g5.asValue(metaspaceMethodSrc.getValueKind()); 111 gen.emitMove(metaspaceMethod, metaspaceMethodSrc); 112 113 Value targetAddressSrc = operand(callTarget.computedAddress()); 114 AllocatableValue targetAddress = o7.asValue(targetAddressSrc.getValueKind()); 115 gen.emitMove(targetAddress, targetAddressSrc); 116 append(new SPARCIndirectCallOp(callTarget.targetMethod(), result, parameters, temps, metaspaceMethod, targetAddress, callState, getGen().config)); 117 } 118 119 @Override 120 public void emitPatchReturnAddress(ValueNode address) { 121 append(new SPARCHotSpotPatchReturnAddressOp(gen.load(operand(address)))); 122 } 123 124 @Override 125 public void emitJumpToExceptionHandler(ValueNode address) { 126 append(new SPARCHotSpotJumpToExceptionHandlerOp(gen.load(operand(address)))); 127 } 128 129 @Override 130 public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) { 131 Variable handler = gen.load(operand(handlerInCallerPc)); 132 ForeignCallLinkage linkage = gen.getForeignCalls().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER); 133 CallingConvention linkageCc = linkage.getOutgoingCallingConvention(); 134 assert linkageCc.getArgumentCount() == 2; 135 RegisterValue exceptionFixed = (RegisterValue) linkageCc.getArgument(0); 136 RegisterValue exceptionPcFixed = (RegisterValue) linkageCc.getArgument(1); 137 gen.emitMove(exceptionFixed, operand(exception)); 138 gen.emitMove(exceptionPcFixed, operand(exceptionPc)); 139 Register thread = getGen().getProviders().getRegisters().getThreadRegister(); 140 SPARCHotSpotJumpToExceptionHandlerInCallerOp op = new SPARCHotSpotJumpToExceptionHandlerInCallerOp(handler, exceptionFixed, exceptionPcFixed, getGen().config.threadIsMethodHandleReturnOffset, 141 thread); 142 append(op); 143 } 144 145 @Override 146 protected void emitPrologue(StructuredGraph graph) { 147 super.emitPrologue(graph); 148 SPARCHotSpotSafepointOp.emitPrologue(this, getGen()); 149 } 150 151 @Override 152 public void visitFullInfopointNode(FullInfopointNode i) { 153 if (i.getState() != null && i.getState().bci == BytecodeFrame.AFTER_BCI) { 154 i.getDebug().log("Ignoring InfopointNode for AFTER_BCI"); 155 } else { 156 super.visitFullInfopointNode(i); 157 } 158 } 159 160 @Override 161 public void visitBreakpointNode(BreakpointNode node) { 162 JavaType[] sig = new JavaType[node.arguments().size()]; 163 for (int i = 0; i < sig.length; i++) { 164 sig[i] = node.arguments().get(i).stamp(NodeView.DEFAULT).javaType(gen.getMetaAccess()); 165 } 166 167 Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments()); 168 append(new SPARCBreakpointOp(parameters)); 169 } 170 }