Path: blob/master/runtime/compiler/p/codegen/J9PPCInstruction.cpp
6004 views
/*******************************************************************************1* Copyright (c) 2000, 2020 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#include "p/codegen/PPCInstruction.hpp"2324#include "codegen/CodeGenerator.hpp"25#include "codegen/Relocation.hpp"26#include "compile/ResolvedMethod.hpp"27#include "env/CompilerEnv.hpp"28#include "env/jittypes.h"29#include "env/VMJ9.h"30#include "il/Node.hpp"31#include "il/Node_inlines.hpp"32#include "il/SymbolReference.hpp"33#include "infra/Assert.hpp"34#include "p/codegen/CallSnippet.hpp"35#include "runtime/CodeCacheManager.hpp"36#include "runtime/Runtime.hpp"3738uint8_t *TR::PPCDepImmSymInstruction::generateBinaryEncoding()39{40TR_J9VMBase *fej9 = (TR_J9VMBase *)(cg()->fe());41TR::Compilation *comp = cg()->comp();42uint8_t *instructionStart = cg()->getBinaryBufferCursor();43uint8_t *cursor = getOpCode().copyBinaryToBuffer(instructionStart);44intptr_t imm = getAddrImmediate();4546if (getOpCodeValue() == TR::InstOpCode::bl || getOpCodeValue() == TR::InstOpCode::b)47{48int32_t refNum = getSymbolReference()->getReferenceNumber();49TR::ResolvedMethodSymbol *sym = getSymbolReference()->getSymbol()->getResolvedMethodSymbol();50TR_ResolvedMethod *resolvedMethod = sym == NULL ? NULL : sym->getResolvedMethod();51TR::LabelSymbol *label = getSymbolReference()->getSymbol()->getLabelSymbol();52bool callToSelf = comp->isRecursiveMethodTarget(resolvedMethod);5354if (cg()->hasCodeCacheSwitched())55{56TR::SymbolReference *calleeSymRef = NULL;5758if (label == NULL)59{60calleeSymRef = getSymbolReference();61}62else63{64if (label->getSnippet() != NULL)65{66TR::Snippet *snippet = label->getSnippet();67if (snippet->getKind() == TR::Snippet::IsCall)68{69calleeSymRef = ((TR::PPCCallSnippet *)snippet)->getRealMethodSymbolReference();70}71}7273if (calleeSymRef == NULL && getNode() != NULL)74{75calleeSymRef = getNode()->getSymbolReference();76}77}7879if (calleeSymRef != NULL)80{81if (calleeSymRef->getReferenceNumber() >= TR_PPCnumRuntimeHelpers &&82(calleeSymRef->getReferenceNumber() < cg()->symRefTab()->getNonhelperIndex(TR::SymbolReferenceTable::firstPerCodeCacheHelperSymbol) ||83calleeSymRef->getReferenceNumber() > cg()->symRefTab()->getNonhelperIndex(TR::SymbolReferenceTable::lastPerCodeCacheHelperSymbol)))84{85fej9->reserveTrampolineIfNecessary(comp, calleeSymRef, true);86}87}88else89{90TR_ASSERT(false, "Missing possible re-reservation for trampolines.");91}92}9394if (callToSelf)95{96intptr_t jitToJitStart = cg()->getLinkage()->entryPointFromCompiledMethod();97*(int32_t *)cursor |= (reinterpret_cast<uint8_t *>(jitToJitStart) - cursor) & 0x03fffffc;98}99else if (label != NULL)100{101cg()->addRelocation(new (cg()->trHeapMemory()) TR::LabelRelative24BitRelocation(cursor, label));102((TR::PPCCallSnippet *)getCallSnippet())->setCallRA(cursor + 4);103}104else105{106if (comp->target().cpu.isTargetWithinIFormBranchRange(imm, (intptr_t)cursor))107{108*(int32_t *)cursor |= (imm - (intptr_t)cursor) & 0x03fffffc;109}110else111{112intptr_t targetAddress;113if (refNum < TR_PPCnumRuntimeHelpers)114{115targetAddress = TR::CodeCacheManager::instance()->findHelperTrampoline(refNum, (void *)cursor);116}117else if (refNum >= cg()->symRefTab()->getNonhelperIndex(TR::SymbolReferenceTable::firstPerCodeCacheHelperSymbol) &&118refNum <= cg()->symRefTab()->getNonhelperIndex(TR::SymbolReferenceTable::lastPerCodeCacheHelperSymbol))119{120TR_ASSERT(cg()->hasCodeCacheSwitched(), "Expecting per-codecache helper to be unreachable only when codecache was switched");121TR_CCPreLoadedCode helper = (TR_CCPreLoadedCode)(refNum - cg()->symRefTab()->getNonhelperIndex(TR::SymbolReferenceTable::firstPerCodeCacheHelperSymbol));122_addrImmediate = (uintptr_t)fej9->getCCPreLoadedCodeAddress(cg()->getCodeCache(), helper, cg());123targetAddress = (intptr_t)_addrImmediate;124}125else126{127// Must use the trampoline as the target and not the label128//129targetAddress = (intptr_t)fej9->methodTrampolineLookup(comp, getSymbolReference(), (void *)cursor);130}131132TR_ASSERT_FATAL(comp->target().cpu.isTargetWithinIFormBranchRange(targetAddress, (intptr_t)cursor),133"Call target address is out of range");134*(int32_t *)cursor |= (targetAddress - (intptr_t)cursor) & 0x03fffffc;135}136}137138if ((comp->compileRelocatableCode()139#ifdef J9VM_OPT_JITSERVER140|| comp->isOutOfProcessCompilation()141#endif142) &&143label == NULL &&144!callToSelf)145{146bool callIsJ2ITransition = runtimeHelperValue(TR_j2iTransition) == getSymbolReference()->getMethodAddress();147if (sym && !sym->isHelper() && resolvedMethod && !callIsJ2ITransition)148{149cg()->addProjectSpecializedRelocation(cursor, (uint8_t *)getSymbolReference()->getMethodAddress(), NULL, TR_MethodCallAddress,150__FILE__, __LINE__, getNode());151}152else153{154cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor,(uint8_t *)getSymbolReference(),TR_HelperAddress, cg()),155__FILE__, __LINE__, getNode());156}157}158}159else160{161intptr_t distance = imm - (intptr_t)cursor;162// Place holder only: non-TR::InstOpCode::b[l] usage of this instruction doesn't163// exist at this moment.164*(int32_t *)cursor |= distance & 0x03fffffc;165}166167cursor += 4;168setBinaryLength(cursor - instructionStart);169setBinaryEncoding(instructionStart);170cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength());171return cursor;172}173174175