Path: blob/master/runtime/compiler/arm/codegen/J9ARMSnippet.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 "j9.h"2324#include "arm/codegen/J9ARMSnippet.hpp"2526#include <stdint.h>27#include "arm/codegen/ARMInstruction.hpp"28#include "codegen/Machine.hpp"29#include "env/CompilerEnv.hpp"30#include "env/IO.hpp"31#include "env/jittypes.h"32#include "il/Node.hpp"33#include "il/Node_inlines.hpp"34#include "runtime/J9CodeCache.hpp"3536TR::ARMMonitorEnterSnippet::ARMMonitorEnterSnippet(37TR::CodeGenerator *codeGen,38TR::Node *monitorNode,39int32_t lwOffset,40//bool isPreserving,41TR::LabelSymbol *incLabel,42TR::LabelSymbol *callLabel,43TR::LabelSymbol *restartLabel)44: _incLabel(incLabel),45_lwOffset(lwOffset),46// _isReservationPreserving(isPreserving),47TR::ARMHelperCallSnippet(codeGen, monitorNode, callLabel, monitorNode->getSymbolReference(), restartLabel)48{49// Helper call, preserves all registers50//51incLabel->setSnippet(this);52gcMap().setGCRegisterMask(0xFFFFFFFF);53}5455uint8_t *TR::ARMMonitorEnterSnippet::emitSnippetBody()56{5758// The 32-bit code for the snippet looks like:59// incLabel:60// mvn tempReg, (OBJECT_HEADER_LOCK_BITS_MASK - OBJECT_HEADER_LOCK_LAST_RECURSION_BIT) -> 0x7f61// and tempReg, dataReg, tempReg62// cmp metaReg, tempReg63// addeq dataReg, dataReg, LOCK_INC_DEC_VALUE64// streq dataReg, [addrReg]65// beq restartLabel66// callLabel:67// bl jitMonitorEntry <- HelperSnippet68// b restartLabel;6970TR::RegisterDependencyConditions *deps = getRestartLabel()->getInstruction()->getDependencyConditions();7172TR::RealRegister *metaReg = cg()->getMethodMetaDataRegister();73TR::RealRegister *dataReg = cg()->machine()->getRealRegister(deps->getPostConditions()->getRegisterDependency(1)->getRealRegister());74TR::RealRegister *addrReg = cg()->machine()->getRealRegister(deps->getPostConditions()->getRegisterDependency(2)->getRealRegister());75TR::RealRegister *tempReg = cg()->machine()->getRealRegister(deps->getPostConditions()->getRegisterDependency(3)->getRealRegister());7677TR::InstOpCode opcode;78TR::InstOpCode::Mnemonic opCodeValue;7980uint8_t *buffer = cg()->getBinaryBufferCursor();8182_incLabel->setCodeLocation(buffer);8384opcode.setOpCodeValue(TR::InstOpCode::mvn);85buffer = opcode.copyBinaryToBuffer(buffer);86tempReg->setRegisterFieldRD((uint32_t *)buffer);87// OBJECT_HEADER_LOCK_BITS_MASK is 0xFF88// OBJECT_HEADER_LOCK_LAST_RECURSION_BIT is 0x8089// Taken out before complement 0x7F90// rotate_imm is 0 and immed_8 is 0x7F, I bit set to 1, result should be 0xFFFFFF8091*(int32_t *)buffer |= ((uint32_t)(ARMConditionCodeAL) << 28 | 0x1 << 25 | (OBJECT_HEADER_LOCK_BITS_MASK - OBJECT_HEADER_LOCK_LAST_RECURSION_BIT));92buffer += ARM_INSTRUCTION_LENGTH;9394opcode.setOpCodeValue(TR::InstOpCode::and_);95buffer = opcode.copyBinaryToBuffer(buffer);96tempReg->setRegisterFieldRD((uint32_t *)buffer);97dataReg->setRegisterFieldRN((uint32_t *)buffer);98tempReg->setRegisterFieldRM((uint32_t *)buffer);99*(int32_t *)buffer |= ((uint32_t)(ARMConditionCodeAL) << 28);100buffer += ARM_INSTRUCTION_LENGTH;101102opcode.setOpCodeValue(TR::InstOpCode::cmp);103buffer = opcode.copyBinaryToBuffer(buffer);104metaReg->setRegisterFieldRN((uint32_t *)buffer);105tempReg->setRegisterFieldRM((uint32_t *)buffer);106*(int32_t *)buffer |= ((uint32_t)(ARMConditionCodeAL) << 28);107buffer += ARM_INSTRUCTION_LENGTH;108109opcode.setOpCodeValue(TR::InstOpCode::add);110buffer = opcode.copyBinaryToBuffer(buffer);111dataReg->setRegisterFieldRD((uint32_t *)buffer);112dataReg->setRegisterFieldRN((uint32_t *)buffer);113*(int32_t *)buffer |= ((uint32_t)(ARMConditionCodeEQ) << 28 | 0x1 << 25 | LOCK_INC_DEC_VALUE);114buffer += ARM_INSTRUCTION_LENGTH;115116opcode.setOpCodeValue(TR::InstOpCode::str);117buffer = opcode.copyBinaryToBuffer(buffer);118dataReg->setRegisterFieldRD((uint32_t *)buffer);119addrReg->setRegisterFieldRN((uint32_t *)buffer); // offset_12 = 0, U = X, B = 0, L = 0120*(int32_t *)buffer |= ((uint32_t)(ARMConditionCodeEQ) << 28);121// No modification needed122buffer += ARM_INSTRUCTION_LENGTH;123124opcode.setOpCodeValue(TR::InstOpCode::b);125buffer = opcode.copyBinaryToBuffer(buffer);126*(int32_t *)buffer |= ((uint32_t)(ARMConditionCodeEQ) << 28 | ((getRestartLabel()->getCodeLocation() - buffer - 8) >> 2) & 0x00FFFFFF);127buffer += ARM_INSTRUCTION_LENGTH;128129cg()->setBinaryBufferCursor(buffer);130buffer = TR::ARMHelperCallSnippet::emitSnippetBody();131132return buffer;133}134135136void137TR::ARMMonitorEnterSnippet::print(TR::FILE *pOutFile, TR_Debug *debug)138{139uint8_t *bufferPos = getIncLabel()->getCodeLocation();140// debug->printSnippetLabel(pOutFile, getIncLabel(), bufferPos, debug->getName(snippet));141debug->printSnippetLabel(pOutFile, getIncLabel(), bufferPos, "Inc Monitor Counter");142143TR::Machine *machine = cg()->machine();144TR::RegisterDependencyConditions *deps = getRestartLabel()->getInstruction()->getDependencyConditions();145TR::LabelSymbol *restartLabel = getRestartLabel();146TR::RealRegister *metaReg = cg()->getMethodMetaDataRegister();147TR::RealRegister *dataReg = machine->getRealRegister(deps->getPostConditions()->getRegisterDependency(1)->getRealRegister());148TR::RealRegister *addrReg = machine->getRealRegister(deps->getPostConditions()->getRegisterDependency(2)->getRealRegister());149TR::RealRegister *tempReg = machine->getRealRegister(deps->getPostConditions()->getRegisterDependency(3)->getRealRegister());150151debug->printPrefix(pOutFile, NULL, bufferPos, 4);152// mvn tempReg, (OBJECT_HEADER_LOCK_BITS_MASK - OBJECT_HEADER_LOCK_LAST_RECURSION_BIT) -> 0x7f153trfprintf(pOutFile, "mvn \t%s, #0x%08x; (OBJECT_HEADER_LOCK_BITS_MASK - OBJECT_HEADER_LOCK_LAST_RECURSION_BIT)", debug->getName(tempReg), (OBJECT_HEADER_LOCK_BITS_MASK - OBJECT_HEADER_LOCK_LAST_RECURSION_BIT));154bufferPos += 4;155156debug->printPrefix(pOutFile, NULL, bufferPos, 4);157// and tempReg, dataReg, tempReg158trfprintf(pOutFile, "and \t%s, %s, %s;", debug->getName(tempReg), debug->getName(dataReg), debug->getName(tempReg));159bufferPos += 4;160161debug->printPrefix(pOutFile, NULL, bufferPos, 4);162// cmp metaReg, tempReg163trfprintf(pOutFile, "cmp \t%s, %s; ", debug->getName(metaReg), debug->getName(tempReg));164bufferPos += 4;165166debug->printPrefix(pOutFile, NULL, bufferPos, 4);167// addeq dataReg, dataReg, LOCK_INC_DEC_VALUE168trfprintf(pOutFile, "addeq \t%s, %s, #0x%08x; Increment the count", debug->getName(dataReg), debug->getName(dataReg), LOCK_INC_DEC_VALUE);169bufferPos += 4;170171debug->printPrefix(pOutFile, NULL, bufferPos, 4);172// streq dataReg, [addrReg]173trfprintf(pOutFile, "streq \t%s, [%s]; Increment the count", debug->getName(dataReg), debug->getName(addrReg));174bufferPos += 4;175176debug->printPrefix(pOutFile, NULL, bufferPos, 4);177// beq restartLabel178trfprintf(pOutFile, "beq\t" POINTER_PRINTF_FORMAT "\t\t; Return to %s", (intptr_t)(restartLabel->getCodeLocation()), debug->getName(restartLabel));179debug->print(pOutFile, (TR::ARMHelperCallSnippet *)this);180}181uint32_t TR::ARMMonitorEnterSnippet::getLength(int32_t estimatedSnippetStart)182{183int32_t len = 28;184len += TR::ARMHelperCallSnippet::getLength(estimatedSnippetStart+len);185return len;186}187188int32_t TR::ARMMonitorEnterSnippet::setEstimatedCodeLocation(int32_t estimatedSnippetStart)189{190_incLabel->setEstimatedCodeLocation(estimatedSnippetStart);191getSnippetLabel()->setEstimatedCodeLocation(estimatedSnippetStart+ 28);192return(estimatedSnippetStart);193}194195196TR::ARMMonitorExitSnippet::ARMMonitorExitSnippet(197TR::CodeGenerator *codeGen,198TR::Node *monitorNode,199int32_t lwOffset,200//bool flag,201//bool isPreserving,202TR::LabelSymbol *decLabel,203//TR::LabelSymbol *restoreAndCallLabel,204TR::LabelSymbol *callLabel,205TR::LabelSymbol *restartLabel)206: _decLabel(decLabel),207//_restoreAndCallLabel(restartLabel),208_lwOffset(lwOffset),209//_isReadOnly(flag),210//_isReservationPreserving(isPreserving),211TR::ARMHelperCallSnippet(codeGen, monitorNode, callLabel, monitorNode->getSymbolReference(), restartLabel)212{213// Helper call, preserves all registers214//215decLabel->setSnippet(this);216gcMap().setGCRegisterMask(0xFFFFFFFF);217}218219uint8_t *TR::ARMMonitorExitSnippet::emitSnippetBody()220{221TR::RegisterDependencyConditions *deps = getRestartLabel()->getInstruction()->getDependencyConditions();222223TR::RealRegister *metaReg = cg()->getMethodMetaDataRegister();224TR::RealRegister *objReg = cg()->machine()->getRealRegister(TR::RealRegister::gr0);225TR::RealRegister *monitorReg = cg()->machine()->getRealRegister(deps->getPostConditions()->getRegisterDependency(1)->getRealRegister());226TR::RealRegister *threadReg = cg()->machine()->getRealRegister(deps->getPostConditions()->getRegisterDependency(2)->getRealRegister());227228TR::InstOpCode opcode;229TR::InstOpCode::Mnemonic opCodeValue;230231uint8_t *buffer = cg()->getBinaryBufferCursor();232#if 0233if (0 /*_isReadOnly*/)234{235// THIS CODE IS CURRENTLY DISABLED236// BEFORE THIS CODE CAN BE ENABLED IT MUST BE UPDATED FOR THE NEW LOCK FIELDS237// decLabel (actual restoreAndCallLabel):238// andi threadReg, monitorReg, 0x3239// or threadReg, metaReg, threadReg240// stwcx. [objReg, offsetReg], threadReg241// beq callLabel242// b loopLabel243// callLabel:244// bl jitMonitorExit245// b doneLabel;246247TR::RealRegister *offsetReg = cg()->machine()->getRealRegister(TR::RealRegister::gr4);248_decLabel->setCodeLocation(buffer);249250opcode.setOpCodeValue(ARMOp_andi_r);251buffer = opcode.copyBinaryToBuffer(buffer);252monitorReg->setRegisterFieldRS((uint32_t *)buffer);253threadReg->setRegisterFieldRA((uint32_t *)buffer);254*(int32_t *)buffer |= (0x3);255buffer += ARM_INSTRUCTION_LENGTH;256257opcode.setOpCodeValue(ARMOp_or);258buffer = opcode.copyBinaryToBuffer(buffer);259threadReg->setRegisterFieldRA((uint32_t *)buffer);260threadReg->setRegisterFieldRS((uint32_t *)buffer);261metaReg->setRegisterFieldRB((uint32_t *)buffer);262buffer += ARM_INSTRUCTION_LENGTH;263264if (cg()->comp()->target().is64Bit() && !fej9->generateCompressedLockWord())265opCodeValue = ARMOp_stdcx_r;266else267opCodeValue = ARMOp_stwcx_r;268opcode.setOpCodeValue(opCodeValue);269buffer = opcode.copyBinaryToBuffer(buffer);270threadReg->setRegisterFieldRS((uint32_t *)buffer);271objReg->setRegisterFieldRA((uint32_t *)buffer);272offsetReg->setRegisterFieldRB((uint32_t *)buffer);273buffer += ARM_INSTRUCTION_LENGTH;274275opcode.setOpCodeValue(ARMOp_beq);276buffer = opcode.copyBinaryToBuffer(buffer);277cndReg->setRegisterFieldBI((uint32_t *)buffer);278*(int32_t *)buffer |= 8;279buffer += ARM_INSTRUCTION_LENGTH;280281opcode.setOpCodeValue(TR::InstOpCode::b);282buffer = opcode.copyBinaryToBuffer(buffer);283*(int32_t *)buffer |= ((uint32_t)(ARMConditionCodeAL) << 28 | ((getRestoreAndCallLabel()->getCodeLocation()-buffer) >> 2) & 0x00FFFFFF);284buffer += ARM_INSTRUCTION_LENGTH;285286cg()->setBinaryBufferCursor(buffer);287buffer = TR::ARMHelperCallSnippet::emitSnippetBody();288289return buffer;290291}292#endif293// The 32-bit code for the snippet looks like:294// decLabel:295// mvn threadReg, OBJECT_HEADER_LOCK_RECURSION_MASK // mask out count field296// and threadReg, monitorReg, threadReg297// cmp metaReg, threadReg298// subeq monitorReg, monitorReg, LOCK_INC_DEC_VALUE299// streq [objReg, monitor offset], monitorReg300// beq restartLabel301// callLabel:302// bl jitMonitorExit // inflated or flc bit set303// b restartLabel304305// reservationPreserving exit snippet looks like: (Not for ARM)306// decLabel:307// li threadReg, OWING_NON_INFLATED_COMPLEMENT308// andc threadReg, monitorReg, threadReg309// cmpl cndReg, threadReg, metaReg310// bne callLabel311// andi_r threadReg, monitorReg, OBJECT_HEADER_LOCK_RECURSION_MASK312// beq callLabel313// andi_r threadReg, monitorReg, OWING_NON_INFLATED_COMPLEMENT314// cmpli cndReg, threadReg, LOCK_RES_CONTENDED_VALUE315// beq callLabel316// addi monitorReg, monitorReg, -INC317// st monitorReg, [objReg, lwOffset]318// b restartLabel319// callLabel:320// bl jitMonitorExit321// b restartLabel322323_decLabel->setCodeLocation(buffer);324#if 0325if (0/*isReservationPreserving()*/)326{327opcode.setOpCodeValue(ARMOp_li);328buffer = opcode.copyBinaryToBuffer(buffer);329threadReg->setRegisterFieldRT((uint32_t *)buffer);330*(int32_t *)buffer |= LOCK_OWNING_NON_INFLATED_COMPLEMENT;331buffer += ARM_INSTRUCTION_LENGTH;332333opcode.setOpCodeValue(ARMOp_andc);334buffer = opcode.copyBinaryToBuffer(buffer);335threadReg->setRegisterFieldRA((uint32_t *)buffer);336monitorReg->setRegisterFieldRS((uint32_t *)buffer);337threadReg->setRegisterFieldRB((uint32_t *)buffer);338buffer += ARM_INSTRUCTION_LENGTH;339340opcode.setOpCodeValue(Op_cmpl);341buffer = opcode.copyBinaryToBuffer(buffer);342cndReg->setRegisterFieldRT((uint32_t *)buffer);343threadReg->setRegisterFieldRA((uint32_t *)buffer);344metaReg->setRegisterFieldRB((uint32_t *)buffer);345buffer += ARM_INSTRUCTION_LENGTH;346347opcode.setOpCodeValue(ARMOp_bne);348buffer = opcode.copyBinaryToBuffer(buffer);349cndReg->setRegisterFieldBI((uint32_t *)buffer);350*(int32_t *)buffer |= 36;351buffer += ARM_INSTRUCTION_LENGTH;352353opcode.setOpCodeValue(ARMOp_andi_r);354buffer = opcode.copyBinaryToBuffer(buffer);355threadReg->setRegisterFieldRA((uint32_t *)buffer);356monitorReg->setRegisterFieldRS((uint32_t *)buffer);357*(int32_t *)buffer |= OBJECT_HEADER_LOCK_RECURSION_MASK;358buffer += ARM_INSTRUCTION_LENGTH;359360opcode.setOpCodeValue(ARMOp_beq);361buffer = opcode.copyBinaryToBuffer(buffer);362cndReg->setRegisterFieldBI((uint32_t *)buffer);363*(int32_t *)buffer |= 28;364buffer += ARM_INSTRUCTION_LENGTH;365366opcode.setOpCodeValue(ARMOp_andi_r);367buffer = opcode.copyBinaryToBuffer(buffer);368threadReg->setRegisterFieldRA((uint32_t *)buffer);369monitorReg->setRegisterFieldRS((uint32_t *)buffer);370*(int32_t *)buffer |= LOCK_OWNING_NON_INFLATED_COMPLEMENT;371buffer += ARM_INSTRUCTION_LENGTH;372373opcode.setOpCodeValue(Op_cmpli);374buffer = opcode.copyBinaryToBuffer(buffer);375cndReg->setRegisterFieldRT((uint32_t *)buffer);376threadReg->setRegisterFieldRA((uint32_t *)buffer);377*(int32_t *)buffer |= LOCK_RES_CONTENDED_VALUE;378buffer += ARM_INSTRUCTION_LENGTH;379380opcode.setOpCodeValue(ARMOp_beq);381buffer = opcode.copyBinaryToBuffer(buffer);382cndReg->setRegisterFieldBI((uint32_t *)buffer);383*(int32_t *)buffer |= 16;384buffer += ARM_INSTRUCTION_LENGTH;385}386else387#endif388{389opcode.setOpCodeValue(TR::InstOpCode::mvn);390buffer = opcode.copyBinaryToBuffer(buffer);391threadReg->setRegisterFieldRD((uint32_t *)buffer);392// 32-bit immediate shifter_operand393// rotate_imm = 0394// immed_8 = OBJECT_HEADER_LOCK_RECURSION_MASK (0xF8)395*(int32_t *)buffer |= ((uint32_t)(ARMConditionCodeAL) << 28 | 0x1 << 25 | OBJECT_HEADER_LOCK_RECURSION_MASK);396buffer += ARM_INSTRUCTION_LENGTH;397398opcode.setOpCodeValue(TR::InstOpCode::and_);399buffer = opcode.copyBinaryToBuffer(buffer);400threadReg->setRegisterFieldRD((uint32_t *)buffer);401monitorReg->setRegisterFieldRN((uint32_t *)buffer);402threadReg->setRegisterFieldRM((uint32_t *)buffer);403*(int32_t *)buffer |= ((uint32_t)(ARMConditionCodeAL) << 28);404buffer += ARM_INSTRUCTION_LENGTH;405406opcode.setOpCodeValue(TR::InstOpCode::cmp);407buffer = opcode.copyBinaryToBuffer(buffer);408metaReg->setRegisterFieldRN((uint32_t *)buffer);409threadReg->setRegisterFieldRM((uint32_t *)buffer);410*(int32_t *)buffer |= ((uint32_t)(ARMConditionCodeAL) << 28);411buffer += ARM_INSTRUCTION_LENGTH;412413opcode.setOpCodeValue(TR::InstOpCode::sub);414buffer = opcode.copyBinaryToBuffer(buffer);415monitorReg->setRegisterFieldRD((uint32_t *)buffer);416monitorReg->setRegisterFieldRN((uint32_t *)buffer);417*(int32_t *)buffer |= ((uint32_t)(ARMConditionCodeEQ) << 28 | 0x1 << 25 | (LOCK_INC_DEC_VALUE & 0xFFFF));418buffer += ARM_INSTRUCTION_LENGTH;419420opcode.setOpCodeValue(TR::InstOpCode::str);421buffer = opcode.copyBinaryToBuffer(buffer);422monitorReg->setRegisterFieldRD((uint32_t *)buffer);423objReg->setRegisterFieldRN((uint32_t *)buffer);424// Store base register offset425// P(24)=1(offset addressing), U=1(23)(add offset), I=0(immed), B=0(word), L=0(store)426*(int32_t *)buffer |= ((uint32_t)(ARMConditionCodeEQ) << 28 | 0x1 << 24 | 0x1 << 23 | _lwOffset & 0xFFF);427buffer += ARM_INSTRUCTION_LENGTH;428429opcode.setOpCodeValue(TR::InstOpCode::b);430buffer = opcode.copyBinaryToBuffer(buffer);431// Back to restartLabel432*(int32_t *)buffer |= ((uint32_t)(ARMConditionCodeEQ) << 28 |((getRestartLabel()->getCodeLocation() - buffer - 8) >> 2) & 0x00FFFFFF);433buffer += ARM_INSTRUCTION_LENGTH;434}435436cg()->setBinaryBufferCursor(buffer);437buffer = TR::ARMHelperCallSnippet::emitSnippetBody();438439return buffer;440}441442443void444TR::ARMMonitorExitSnippet::print(TR::FILE *pOutFile, TR_Debug *debug)445{446uint8_t *bufferPos = getDecLabel()->getCodeLocation();447// debug->printSnippetLabel(pOutFile, getDecLabel(), bufferPos, debug->getName(snippet));448debug->printSnippetLabel(pOutFile, getDecLabel(), bufferPos, "Dec Monitor Counter");449450TR::Machine *machine = cg()->machine();451TR::RegisterDependencyConditions *deps = getRestartLabel()->getInstruction()->getDependencyConditions();452TR::LabelSymbol *restartLabel = getRestartLabel();453TR::RealRegister *metaReg = cg()->getMethodMetaDataRegister();454TR::RealRegister *objReg = machine->getRealRegister(TR::RealRegister::gr0);455TR::RealRegister *monitorReg = machine->getRealRegister(deps->getPostConditions()->getRegisterDependency(1)->getRealRegister());456TR::RealRegister *threadReg = machine->getRealRegister(deps->getPostConditions()->getRegisterDependency(2)->getRealRegister());457458debug->printPrefix(pOutFile, NULL, bufferPos, 4);459// mvn threadReg, OBJECT_HEADER_LOCK_RECURSION_MASK // mask out count field460trfprintf(pOutFile, "mvn\t%s, #0x%08x; OBJECT_HEADER_LOCK_RECURSION_MASK", debug->getName(threadReg), OBJECT_HEADER_LOCK_RECURSION_MASK);461bufferPos += 4;462463debug->printPrefix(pOutFile, NULL, bufferPos, 4);464// and threadReg, monitorReg, threadReg465trfprintf(pOutFile, "and\t%s, %s, %s; ", debug->getName(threadReg), debug->getName(monitorReg), debug->getName(threadReg));466bufferPos += 4;467468debug->printPrefix(pOutFile, NULL, bufferPos, 4);469// cmp metaReg, threadReg470trfprintf(pOutFile, "cmp\t%s, %s; ", debug->getName(metaReg), debug->getName(threadReg));471bufferPos += 4;472473debug->printPrefix(pOutFile, NULL, bufferPos, 4);474// subeq monitorReg, monitorReg, LOCK_INC_DEC_VALUE475trfprintf(pOutFile, "subeq\t%s, %s, #0x%08x; Decrement the count", debug->getName(monitorReg), debug->getName(monitorReg), LOCK_INC_DEC_VALUE);476bufferPos += 4;477478debug->printPrefix(pOutFile, NULL, bufferPos, 4);479// streq monitorReg, [objReg, monitor offset]480trfprintf(pOutFile, "streq\t%s, [%s, %d]; ", debug->getName(monitorReg), debug->getName(objReg), getLockWordOffset());481bufferPos += 4;482483debug->printPrefix(pOutFile, NULL, bufferPos, 4);484// beq restartLabel485trfprintf(pOutFile, "beq\t" POINTER_PRINTF_FORMAT "\t\t; Return to %s", (intptr_t)(restartLabel->getCodeLocation()), debug->getName(restartLabel));486487debug->print(pOutFile, (TR::ARMHelperCallSnippet *)this);488}489490491492uint32_t TR::ARMMonitorExitSnippet::getLength(int32_t estimatedSnippetStart)493{494495int32_t len;496len = ARM_INSTRUCTION_LENGTH*6;497len += TR::ARMHelperCallSnippet::getLength(estimatedSnippetStart + len);498return len;499}500501int32_t TR::ARMMonitorExitSnippet::setEstimatedCodeLocation(int32_t estimatedSnippetStart)502{503int32_t len;504_decLabel->setEstimatedCodeLocation(estimatedSnippetStart);505506len = ARM_INSTRUCTION_LENGTH*6;507508getSnippetLabel()->setEstimatedCodeLocation(estimatedSnippetStart+len);509return(estimatedSnippetStart);510}511512513