Path: blob/master/runtime/compiler/z/codegen/J9S390Snippet.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 "z/codegen/J9S390Snippet.hpp"2324#include <stdint.h>25#include "j9.h"26#include "thrdsup.h"27#include "thrtypes.h"28#include "codegen/CodeGenerator.hpp"29#include "codegen/GCStackMap.hpp"30#include "codegen/Machine.hpp"31#include "codegen/S390PrivateLinkage.hpp"32#include "codegen/SnippetGCMap.hpp"33#include "env/CompilerEnv.hpp"34#include "env/IO.hpp"35#include "env/jittypes.h"36#include "env/VMJ9.h"37#include "il/Node.hpp"38#include "il/Node_inlines.hpp"39#include "env/VMJ9.h"40#include "runtime/CodeCacheManager.hpp"41#include "z/codegen/S390Instruction.hpp"42#include "z/codegen/S390Snippets.hpp"4344TR::S390HeapAllocSnippet::S390HeapAllocSnippet(45TR::CodeGenerator *codeGen,46TR::Node *node,47TR::LabelSymbol *callLabel,48TR::SymbolReference *destination,49TR::LabelSymbol *restartLabel)50: _restartLabel(restartLabel), _destination(destination), _isLongBranch(false), _length(0),51TR::Snippet(codeGen, node, callLabel, destination->canCauseGC())52{53if (destination->canCauseGC())54{55// Helper call, preserves all registers56//57gcMap().setGCRegisterMask(0x0000FFFF);58}59}606162uint8_t *63TR::S390HeapAllocSnippet::emitSnippetBody()64{65TR::CodeGenerator * codeGen = cg();66TR::Compilation *comp = codeGen->comp();67TR_J9VMBase *fej9 = (TR_J9VMBase *)(codeGen->fe());68uint8_t * buffer = codeGen->getBinaryBufferCursor();69int32_t distance;70int32_t jumpToCallDistance = -1;71intptr_t branchToCallLocation = -1;7273TR::Machine *machine = codeGen->machine();74TR::RegisterDependencyConditions *deps = getRestartLabel()->getInstruction()->getDependencyConditions();75TR::RealRegister * resReg = machine->getRealRegister(deps->getPostConditions()->getRegisterDependency(2)->getRealRegister());76uint32_t resRegEncoding = resReg->getRegisterNumber() - 1;77bool is64BitTarget = comp->target().is64Bit();7879getSnippetLabel()->setCodeLocation(buffer);8081TR_ASSERT(jumpToCallDistance == -1 || jumpToCallDistance == (((intptr_t)buffer) - branchToCallLocation), "Jump in Heap Alloc Misaligned.");8283// The code for the none-G5 32bit snippet looks like:84// BRASL gr14, jitNewXXXX;85// LR/LGR resReg, gr2;86// BRC[L] restartLabel;8788*(uint16_t *) buffer = 0xc0e5;89buffer += 2;9091intptr_t destAddr = (intptr_t) getDestination()->getSymbol()->castToMethodSymbol()->getMethodAddress();9293#if defined(TR_TARGET_64BIT)94#if defined(J9ZOS390)95if (comp->getOption(TR_EnableRMODE64))96#endif97{98if (NEEDS_TRAMPOLINE(destAddr, buffer, cg()))99{100uint32_t rEP = (uint32_t) cg()->getEntryPointRegister() - 1;101// Destination is beyond our reachable jump distance, we'll find the102// trampoline.103destAddr = TR::CodeCacheManager::instance()->findHelperTrampoline(getDestination()->getReferenceNumber(), (void *)buffer);104this->setUsedTrampoline(true);105106// We clobber rEP if we take a trampoline. Update our register map if necessary.107if (gcMap().getStackMap() != NULL)108{109gcMap().getStackMap()->maskRegisters(~(0x1 << (rEP)));110}111}112}113#endif114115TR_ASSERT(CHECK_32BIT_TRAMPOLINE_RANGE(destAddr, buffer), "Helper Call is not reachable.");116this->setSnippetDestAddr(destAddr);117118*(int32_t *) buffer = (int32_t)((destAddr - (intptr_t)(buffer - 2)) / 2);119if (comp->compileRelocatableCode() || comp->isOutOfProcessCompilation())120{121cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(buffer, (uint8_t*) getDestination(), TR_HelperAddress, cg()),122__FILE__, __LINE__, getNode());123}124125buffer += sizeof(int32_t);126127if (gcMap().getStackMap() != NULL)128{129gcMap().getStackMap()->resetRegistersBits(codeGen->registerBitMask(resReg->getRegisterNumber()));130}131132gcMap().registerStackMap(buffer, cg());133134if (is64BitTarget)135{136*(uint32_t *) buffer = 0xb9040002 | (resRegEncoding << 4);137buffer += 4;138}139else140{141*(uint16_t *) buffer = 0x1802 | (resRegEncoding << 4);142buffer += 2;143}144145distance = (intptr_t) getRestartLabel()->getCodeLocation() - (intptr_t) buffer;146distance >>= 1;147if (!isLongBranch())148{149*(int32_t *) buffer = 0xa7f40000 | (distance & 0x0000ffff);150buffer += 4;151}152else153{154*(uint16_t *) buffer = 0xc0f4;155buffer += 2;156*(int32_t *) buffer = distance;157buffer += 4;158}159160return buffer;161}162163uint32_t164TR::S390HeapAllocSnippet::getLength(int32_t estimatedCodeStart)165{166TR::CodeGenerator * codeGen = cg();167TR::Compilation *comp = codeGen->comp();168int32_t distance;169uint32_t length = getMyLength();170171if (length != 0)172{173return length;174}175176distance = estimatedCodeStart +177(comp->target().is64Bit() ? 10 : 8) -178getRestartLabel()->getEstimatedCodeLocation();179180// to be conservative: we use the byte count as half-word count, accounting for length estimation deviation181if (distance<MIN_IMMEDIATE_VAL || distance>MAX_IMMEDIATE_VAL)182{183setIsLongBranch(true);184}185if (comp->target().is64Bit())186{187if (isLongBranch())188length = 16;189else190length = 14;191}192else193{194if (isLongBranch())195length = 14;196else197length = 12;198}199200setMyLength(length);201202return length;203}204205void206TR::S390HeapAllocSnippet::print(TR::FILE *pOutFile, TR_Debug *debug)207{208if (pOutFile == NULL)209{210return;211}212213TR::Compilation *comp = cg()->comp();214TR_J9VMBase *fej9 = (TR_J9VMBase *)(comp->fe());215uint8_t * buffer = getSnippetLabel()->getCodeLocation();216int32_t distance;217bool is64BitTarget = comp->target().is64Bit();218219TR::Machine *machine = cg()->machine();220TR::RegisterDependencyConditions *deps = getRestartLabel()->getInstruction()->getDependencyConditions();221TR::RealRegister * resReg = machine->getRealRegister(deps->getPostConditions()->getRegisterDependency(2)->getRealRegister());222223debug->printSnippetLabel(pOutFile, getSnippetLabel(), buffer, "HeapAlloc Snippet", debug->getName(getDestination()));224225226// The code for the snippet looks like:227// BRASL gr14, jitNewXXXX;228// LR/LGR resReg, gr2;229// BRC[L] restartLabel;230231distance = (intptr_t) getDestination()->getSymbol()->castToMethodSymbol()->getMethodAddress() - (intptr_t) buffer;232233debug->printPrefix(pOutFile, NULL, buffer, 6);234trfprintf(pOutFile, "BRASL \tGPR14, 0x%8x", distance >> 1);235buffer += 6;236237if (comp->target().is64Bit())238{239debug->printPrefix(pOutFile, NULL, buffer, 4);240trfprintf(pOutFile, "LGR \t%s,GPR2", debug->getName(resReg));241buffer += 4;242}243else244{245debug->printPrefix(pOutFile, NULL, buffer, 2);246trfprintf(pOutFile, "LR \t%s, GPR2", debug->getName(resReg));247buffer += 2;248}249250distance = (intptr_t) getRestartLabel()->getCodeLocation() - (intptr_t) buffer;251distance >>= 1;252if (!isLongBranch())253{254debug->printPrefix(pOutFile, NULL, buffer, 4);255trfprintf(pOutFile, "BRC \t");256debug->print(pOutFile, getRestartLabel());257buffer += 4;258}259else260{261debug->printPrefix(pOutFile, NULL, buffer, 6);262trfprintf(pOutFile, "BRCL \t");263debug->print(pOutFile, getRestartLabel());264buffer += 6;265}266}267268uint32_t269TR::S390RestoreGPR7Snippet::getLength(int32_t estimatedSnippetStart)270{271272if (cg()->comp()->target().is64Bit())273#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)274return 6*3 + 6 + 4;275#else276return 6*1 + 6 + 4;277#endif278else279#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)280return 4*3 + 6 + 4;281#else282return 4*1 + 6 + 4;283#endif284}285286uint8_t *287TR::S390RestoreGPR7Snippet::emitSnippetBody()288{289uint8_t * cursor = cg()->getBinaryBufferCursor();290uint8_t * startPointCursor = cg()->getBinaryBufferCursor();291getSnippetLabel()->setCodeLocation(cursor);292TR_J9VMBase *fej9 = (TR_J9VMBase *)(cg()->fe());293294int32_t tempOffset = fej9->thisThreadGetTempSlotOffset();295#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)296int32_t returnOffset = fej9->thisThreadGetReturnValueOffset();297int32_t sspOffset = fej9->thisThreadGetSystemSPOffset();298#endif299300301//E370DXXX0058302if (cg()->comp()->target().is64Bit())//generate LG303{304#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)305*(int32_t *) cursor = 0xE340D000|sspOffset;306cursor += sizeof(int32_t);307*(int16_t *) cursor = 0x0024;308cursor += sizeof(int16_t);309#endif310311//restore gpr7 from tempslot, 6bytes312*(int32_t *) cursor = 0xE370D000|tempOffset;313cursor += sizeof(int32_t);314*(int16_t *) cursor = 0x0004;315cursor += sizeof(int16_t);316317#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)318//restore gpr4 from returnValue, 6 bytes319*(int32_t *) cursor = 0xE340D000|returnOffset;320cursor += sizeof(int32_t);321*(int16_t *) cursor = 0x0004;322cursor += sizeof(int16_t);323#endif324}325else326{ //generate L327#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)328TR_ASSERT(tempOffset < 4096 && returnOffset < 4096, "if > 4k then must use LY, not L.");329#else330TR_ASSERT(tempOffset < 4096, "if > 4k then must use LY, not L.");331#endif332333#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)334//store GPR4 onto vmThread->ssp335*(int32_t *) cursor = 0x5040D000|(sspOffset & 0x0FFF);336cursor += sizeof(int32_t);337#endif338339//gpr7, 4bytes340*(int32_t *) cursor = 0x5870D000|(tempOffset & 0x0FFF);341cursor += sizeof(int32_t);342343#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)344//gpr4, 4bytes345*(int32_t *) cursor = 0x5840D000|(returnOffset & 0x0FFF);346cursor += sizeof(int32_t);347#endif348}349350351cg()->addRelocation(new (cg()->trHeapMemory()) TR::LabelRelative32BitRelocation(cursor, getTargetLabel()));352// 6 bytes353// BRCL 0xf, <target>354*(int16_t *) cursor = 0xC0F4;355cursor += sizeof(int16_t);356357// BRCL - Add Relocation the data constants to this LARL.358*(int32_t *) cursor = 0xDEADBEEF;359cursor += sizeof(int32_t);360361#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)362if (cg()->comp()->target().is64Bit())363TR_ASSERT(((U_8*)cursor) - startPointCursor == 24,364"for 64bit, DAA eyecatcher should be generated at offset 24 bytes");365else366TR_ASSERT(((U_8*)cursor) - startPointCursor == 18,367"for 31bit, DAA eyecatcher should be generated at offset 18 bytes");368#endif369370*(int32_t *) cursor = 0xDAA0CA11;371cursor += sizeof(int32_t);372373return cursor;374}375376void377TR_Debug::print(TR::FILE *pOutFile, TR::S390RestoreGPR7Snippet *snippet)378{379uint8_t * buffer = snippet->getSnippetLabel()->getCodeLocation();380printSnippetLabel(pOutFile, snippet->getSnippetLabel(), buffer, "Restore GPR 7 after signal handler");381382#ifdef J9VM_JIT_FREE_SYSTEM_STACK_POINTER383//save GPR4 to384if (_comp->target().is64Bit())385{386printPrefix(pOutFile, NULL, buffer, 6);387trfprintf(pOutFile, "STG GPR7, SSP(GPR13)", snippet->getTargetLabel()->getCodeLocation());388buffer += 6;389}390else391{392printPrefix(pOutFile, NULL, buffer, 4);393trfprintf(pOutFile, "ST GPR7, SSP(GPR13)", snippet->getTargetLabel()->getCodeLocation());394buffer += 4;395}396#endif397398//0x4a2af68a (???) e370d0980058 LY R7,152(,R13)399if (_comp->target().is64Bit())400{401printPrefix(pOutFile, NULL, buffer, 6);402trfprintf(pOutFile, "LG GPR7, 152(GPR13)", snippet->getTargetLabel()->getCodeLocation());403buffer += 6;404}405else406{407printPrefix(pOutFile, NULL, buffer, 4);408trfprintf(pOutFile, "L GPR7, 144(GPR13)", snippet->getTargetLabel()->getCodeLocation());409buffer += 4;410}411412#ifdef J9VM_JIT_FREE_SYSTEM_STACK_POINTER413// L R4,136(,R13)414if (_comp->target().is64Bit())415{416printPrefix(pOutFile, NULL, buffer, 6);417trfprintf(pOutFile, "LG GPR4, 136(GPR13)", snippet->getTargetLabel()->getCodeLocation());418buffer += 6;419}420else421{422printPrefix(pOutFile, NULL, buffer, 4);423trfprintf(pOutFile, "L GPR4, 136(GPR13)", snippet->getTargetLabel()->getCodeLocation());424buffer += 4;425}426#endif427428//0x4a2af690 (???) c0f4fff1bb80 BRCL 15,*-1870080429printPrefix(pOutFile, NULL, buffer, 6);430trfprintf(pOutFile, "BRCL 0xF, targetLabel(%p)", snippet->getTargetLabel()->getCodeLocation());431buffer += 6;432433printPrefix(pOutFile, NULL, buffer, 4);434trfprintf(pOutFile, "Eye Catcher = 0xDAA0CA11", snippet->getTargetLabel()->getCodeLocation());435buffer += 4;436}437438439440