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