001/* 002 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.hotspot.sparc; 024 025import static com.oracle.graal.hotspot.HotSpotBackend.*; 026import static jdk.internal.jvmci.sparc.SPARC.*; 027 028import com.oracle.graal.compiler.common.spi.*; 029import com.oracle.graal.compiler.gen.*; 030import com.oracle.graal.compiler.sparc.*; 031import com.oracle.graal.hotspot.*; 032import com.oracle.graal.hotspot.nodes.*; 033import com.oracle.graal.lir.*; 034import com.oracle.graal.lir.gen.*; 035import com.oracle.graal.lir.sparc.SPARCMove.*; 036import com.oracle.graal.nodes.*; 037import com.oracle.graal.nodes.CallTargetNode.*; 038import com.oracle.graal.nodes.spi.*; 039 040import jdk.internal.jvmci.code.*; 041 042import com.oracle.graal.debug.*; 043 044import jdk.internal.jvmci.hotspot.*; 045import jdk.internal.jvmci.meta.*; 046 047public class SPARCHotSpotNodeLIRBuilder extends SPARCNodeLIRBuilder implements HotSpotNodeLIRBuilder { 048 049 private HotSpotGraalRuntimeProvider runtime; 050 051 public SPARCHotSpotNodeLIRBuilder(HotSpotGraalRuntimeProvider runtime, StructuredGraph graph, LIRGeneratorTool lirGen) { 052 super(graph, lirGen); 053 this.runtime = runtime; 054 assert gen instanceof SPARCHotSpotLIRGenerator; 055 assert getDebugInfoBuilder() instanceof HotSpotDebugInfoBuilder; 056 ((SPARCHotSpotLIRGenerator) gen).setLockStack(((HotSpotDebugInfoBuilder) getDebugInfoBuilder()).lockStack()); 057 } 058 059 @Override 060 protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeValueMap nodeValueMap) { 061 HotSpotLockStack lockStack = new HotSpotLockStack(gen.getResult().getFrameMapBuilder(), LIRKind.value(Kind.Long)); 062 return new HotSpotDebugInfoBuilder(nodeValueMap, lockStack); 063 } 064 065 private SPARCHotSpotLIRGenerator getGen() { 066 return (SPARCHotSpotLIRGenerator) gen; 067 } 068 069 @Override 070 public void visitSafepointNode(SafepointNode i) { 071 LIRFrameState info = state(i); 072 append(new SPARCHotSpotSafepointOp(info, getGen().config, gen)); 073 } 074 075 @Override 076 public void visitDirectCompareAndSwap(DirectCompareAndSwapNode x) { 077 AllocatableValue address = gen.asAllocatable(operand(x.getAddress())); 078 AllocatableValue cmpValue = gen.asAllocatable(operand(x.expectedValue())); 079 AllocatableValue newValue = gen.asAllocatable(operand(x.newValue())); 080 LIRKind kind = cmpValue.getLIRKind(); 081 assert kind.equals(newValue.getLIRKind()); 082 083 Variable result = gen.newVariable(newValue.getLIRKind()); 084 append(new CompareAndSwapOp(result, address, cmpValue, newValue)); 085 setResult(x, result); 086 } 087 088 @Override 089 protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { 090 InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind(); 091 if (invokeKind.isIndirect()) { 092 append(new SPARCHotspotDirectVirtualCallOp(callTarget.targetMethod(), result, parameters, temps, callState, invokeKind, runtime.getConfig())); 093 } else { 094 assert invokeKind.isDirect(); 095 HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod(); 096 assert resolvedMethod.isConcrete() : "Cannot make direct call to abstract method."; 097 append(new SPARCHotspotDirectStaticCallOp(callTarget.targetMethod(), result, parameters, temps, callState, invokeKind, runtime.getConfig())); 098 } 099 } 100 101 @Override 102 protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { 103 Value metaspaceMethodSrc = operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod()); 104 AllocatableValue metaspaceMethod = g5.asValue(metaspaceMethodSrc.getLIRKind()); 105 gen.emitMove(metaspaceMethod, metaspaceMethodSrc); 106 107 Value targetAddressSrc = operand(callTarget.computedAddress()); 108 AllocatableValue targetAddress = o7.asValue(targetAddressSrc.getLIRKind()); 109 gen.emitMove(targetAddress, targetAddressSrc); 110 append(new SPARCIndirectCallOp(callTarget.targetMethod(), result, parameters, temps, metaspaceMethod, targetAddress, callState, runtime.getConfig())); 111 } 112 113 @Override 114 public void emitPatchReturnAddress(ValueNode address) { 115 append(new SPARCHotSpotPatchReturnAddressOp(gen.load(operand(address)))); 116 } 117 118 public void emitJumpToExceptionHandler(ValueNode address) { 119 append(new SPARCHotSpotJumpToExceptionHandlerOp(gen.load(operand(address)))); 120 } 121 122 @Override 123 public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) { 124 Variable handler = gen.load(operand(handlerInCallerPc)); 125 ForeignCallLinkage linkage = gen.getForeignCalls().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER); 126 CallingConvention linkageCc = linkage.getOutgoingCallingConvention(); 127 assert linkageCc.getArgumentCount() == 2; 128 RegisterValue exceptionFixed = (RegisterValue) linkageCc.getArgument(0); 129 RegisterValue exceptionPcFixed = (RegisterValue) linkageCc.getArgument(1); 130 gen.emitMove(exceptionFixed, operand(exception)); 131 gen.emitMove(exceptionPcFixed, operand(exceptionPc)); 132 Register thread = getGen().getProviders().getRegisters().getThreadRegister(); 133 SPARCHotSpotJumpToExceptionHandlerInCallerOp op = new SPARCHotSpotJumpToExceptionHandlerInCallerOp(handler, exceptionFixed, exceptionPcFixed, getGen().config.threadIsMethodHandleReturnOffset, 134 thread); 135 append(op); 136 } 137 138 @Override 139 protected void emitPrologue(StructuredGraph graph) { 140 super.emitPrologue(graph); 141 AllocatableValue var = getGen().getSafepointAddressValue(); 142 append(new SPARCHotSpotSafepointOp.SPARCLoadSafepointPollAddress(var, getGen().config)); 143 getGen().append(((HotSpotDebugInfoBuilder) getDebugInfoBuilder()).lockStack()); 144 } 145 146 @Override 147 public void visitFullInfopointNode(FullInfopointNode i) { 148 if (i.getState() != null && i.getState().bci == BytecodeFrame.AFTER_BCI) { 149 Debug.log("Ignoring InfopointNode for AFTER_BCI"); 150 } else { 151 super.visitFullInfopointNode(i); 152 } 153 } 154}