Path: blob/master/runtime/compiler/z/codegen/J9Linkage.cpp
6004 views
/*******************************************************************************1* Copyright (c) 2000, 2021 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 "codegen/Linkage.hpp"23#include "codegen/Linkage_inlines.hpp"24#include "codegen/S390GenerateInstructions.hpp"25#include "compile/Compilation.hpp"26#include "il/ParameterSymbol.hpp"2728TR::Instruction *29J9::Z::Linkage::loadUpArguments(TR::Instruction * cursor)30{31TR::Compilation *comp = self()->comp();32TR::RealRegister * stackPtr = self()->getStackPointerRealRegister();33TR::ResolvedMethodSymbol * bodySymbol = comp->getJittedMethodSymbol();34ListIterator<TR::ParameterSymbol> paramIterator(&(bodySymbol->getParameterList()));35TR::ParameterSymbol * paramCursor = paramIterator.getFirst();36TR::Node * firstNode = comp->getStartTree()->getNode();37int32_t numIntArgs = 0, numFloatArgs = 0;38uint32_t binLocalRegs = 0x1<<14; // Binary pattern representing reg14 as free for local alloc3940bool isRecompilable = false;41if (comp->getRecompilationInfo() && comp->getRecompilationInfo()->couldBeCompiledAgain())42{43isRecompilable = true;44}4546while ((paramCursor != NULL) && ((numIntArgs < self()->getNumIntegerArgumentRegisters()) || (numFloatArgs < self()->getNumFloatArgumentRegisters())))47{48TR::RealRegister * argRegister;49int32_t offset = paramCursor->getParameterOffset();5051// If FSD, the JIT will conservatively store all parameters to stack later in saveArguments.52// Hence, we need to load the value into a parameter register for I2J transitions.53bool hasToLoadFromStack = paramCursor->isReferencedParameter() || paramCursor->isParmHasToBeOnStack() || comp->getOption(TR_FullSpeedDebug);5455switch (paramCursor->getDataType())56{57case TR::Int8:58case TR::Int16:59case TR::Int32:60if (hasToLoadFromStack && numIntArgs < self()->getNumIntegerArgumentRegisters())61{62argRegister = self()->getRealRegister(self()->getIntegerArgumentRegister(numIntArgs));63TR::MemoryReference* memRef = generateS390MemoryReference(stackPtr, offset, self()->cg());64cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::L, firstNode, argRegister,65memRef, cursor);66cursor->setBinLocalFreeRegs(binLocalRegs);67}68numIntArgs++;69break;70case TR::Address:71if ((hasToLoadFromStack || isRecompilable) &&72numIntArgs < self()->getNumIntegerArgumentRegisters())73{74argRegister = self()->getRealRegister(self()->getIntegerArgumentRegister(numIntArgs));75TR::MemoryReference* memRef = generateS390MemoryReference(stackPtr, offset, self()->cg());76cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::getLoadOpCode(), firstNode, argRegister,77memRef, cursor);78cursor->setBinLocalFreeRegs(binLocalRegs);79}80numIntArgs++;81break;82case TR::Int64:83if (hasToLoadFromStack && numIntArgs < self()->getNumIntegerArgumentRegisters())84{85argRegister = self()->getRealRegister(self()->getIntegerArgumentRegister(numIntArgs));86TR::MemoryReference* memRef = generateS390MemoryReference(stackPtr, offset, self()->cg());87cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::getLoadOpCode(), firstNode, argRegister,88memRef, cursor);89cursor->setBinLocalFreeRegs(binLocalRegs);90if (comp->target().is32Bit() && numIntArgs < self()->getNumIntegerArgumentRegisters() - 1)91{92argRegister = self()->getRealRegister(self()->getIntegerArgumentRegister(numIntArgs + 1));93cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::L, firstNode, argRegister,94generateS390MemoryReference(stackPtr, offset + 4, self()->cg()), cursor);95cursor->setBinLocalFreeRegs(binLocalRegs);96}97}98numIntArgs += (comp->target().is64Bit()) ? 1 : 2;99break;100case TR::Float:101if (hasToLoadFromStack && numFloatArgs < self()->getNumFloatArgumentRegisters())102{103argRegister = self()->getRealRegister(self()->getFloatArgumentRegister(numFloatArgs));104TR::MemoryReference* memRef = generateS390MemoryReference(stackPtr, offset, self()->cg());105cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::LE, firstNode, argRegister,106memRef, cursor);107cursor->setBinLocalFreeRegs(binLocalRegs);108}109numFloatArgs++;110break;111case TR::Double:112if (hasToLoadFromStack && numFloatArgs < self()->getNumFloatArgumentRegisters())113{114argRegister = self()->getRealRegister(self()->getFloatArgumentRegister(numFloatArgs));115TR::MemoryReference* memRef = generateS390MemoryReference(stackPtr, offset, self()->cg());116cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::LD, firstNode, argRegister,117memRef, cursor);118cursor->setBinLocalFreeRegs(binLocalRegs);119}120numFloatArgs++;121break;122}123paramCursor = paramIterator.getNext();124}125return cursor;126}127128129