From 1977c6603e529a5aaf9f95eae74ebb7017bf0b47 Mon Sep 17 00:00:00 2001 From: Spencer Comin Date: Wed, 18 Sep 2024 11:15:59 -0400 Subject: [PATCH] AArch64: Use enum for dmb limitations This commit replaces the use of magic numbers for the limitation immediate for dmb instructions with an enum, and adds a debug printer for synchronization instructions to print out the limitation mnemonic rather than the literal hex constant. Signed-off-by: Spencer Comin --- compiler/aarch64/codegen/ARM64Debug.cpp | 35 +++++++++++++++++-- compiler/aarch64/codegen/ARM64Instruction.hpp | 12 +++---- .../aarch64/codegen/GenerateInstructions.cpp | 6 ++-- .../aarch64/codegen/GenerateInstructions.hpp | 2 +- compiler/aarch64/codegen/OMRInstOpCode.hpp | 31 +++++++++++----- compiler/aarch64/codegen/OMRTreeEvaluator.cpp | 14 ++++---- compiler/ras/Debug.hpp | 2 ++ 7 files changed, 75 insertions(+), 27 deletions(-) diff --git a/compiler/aarch64/codegen/ARM64Debug.cpp b/compiler/aarch64/codegen/ARM64Debug.cpp index 2eb7d8d4756..f79a6ffd982 100644 --- a/compiler/aarch64/codegen/ARM64Debug.cpp +++ b/compiler/aarch64/codegen/ARM64Debug.cpp @@ -1113,7 +1113,7 @@ TR_Debug::print(TR::FILE *pOutFile, TR::Instruction *instr) print(pOutFile, (TR::ARM64ImmInstruction *)instr); break; case OMR::Instruction::IsSynchronization: - print(pOutFile, (TR::ARM64ImmInstruction *)instr); // printing handled by superclass + print(pOutFile, (TR::ARM64SynchronizationInstruction *)instr); break; case OMR::Instruction::IsException: print(pOutFile, (TR::ARM64ImmInstruction *)instr); // printing handled by superclass @@ -1780,7 +1780,7 @@ TR_Debug::print(TR::FILE *pOutFile, TR::ARM64Trg1Src1ImmInstruction *instr) done = true; trfprintf(pOutFile, "sxt%cw \t", (imms == 7) ? 'b' : 'h'); print(pOutFile, instr->getTargetRegister(), TR_WordReg); trfprintf(pOutFile, ", "); - print(pOutFile, instr->getSource1Register(), TR_WordReg); + print(pOutFile, instr->getSource1Register(), TR_WordReg); } } if (!done) @@ -2230,6 +2230,37 @@ TR_Debug::print(TR::FILE *pOutFile, TR::ARM64Src2CondInstruction *instr) trfflush(_comp->getOutFile()); } +static const char * +getBarrierLimitationName(TR::InstOpCode::AArch64BarrierLimitation lim) + { + switch (lim) + { + case TR::InstOpCode::sy: return "sy"; + case TR::InstOpCode::st: return "st"; + case TR::InstOpCode::ld: return "ld"; + case TR::InstOpCode::ish: return "ish"; + case TR::InstOpCode::ishst: return "ishst"; + case TR::InstOpCode::ishld: return "ishld"; + case TR::InstOpCode::nsh: return "nsh"; + case TR::InstOpCode::nshst: return "nshst"; + case TR::InstOpCode::nshld: return "nshld"; + case TR::InstOpCode::osh: return "osh"; + case TR::InstOpCode::oshst: return "oshst"; + case TR::InstOpCode::oshld: return "oshld"; + + default: return "???"; + } + } + +void +TR_Debug::print(TR::FILE *pOutFile, TR::ARM64SynchronizationInstruction *instr) + { + printPrefix(pOutFile, instr); + const char *lim = getBarrierLimitationName(static_cast(instr->getSourceImmediate())); + trfprintf(pOutFile, "%s \t%s", getOpCodeName(&instr->getOpCode()), lim); + trfflush(_comp->getOutFile()); + } + void TR_Debug::print(TR::FILE *pOutFile, TR::ARM64CondTrg1Src2Instruction *instr) { diff --git a/compiler/aarch64/codegen/ARM64Instruction.hpp b/compiler/aarch64/codegen/ARM64Instruction.hpp index 35399765cb4..692f30e69d9 100644 --- a/compiler/aarch64/codegen/ARM64Instruction.hpp +++ b/compiler/aarch64/codegen/ARM64Instruction.hpp @@ -2325,7 +2325,7 @@ class ARM64Trg1Src1ImmInstruction : public ARM64Trg1Src1Instruction * @brief Sets the N bit (bit 22) * @param[in] n : N bit value * @return N bit value - */ + */ bool setNbit(bool n) { return (_Nbit = n);} /** @@ -4696,8 +4696,8 @@ class ARM64SynchronizationInstruction : public ARM64ImmInstruction * @param[in] cg : CodeGenerator */ ARM64SynchronizationInstruction(TR::InstOpCode::Mnemonic op, TR::Node *node, - uint32_t imm, TR::CodeGenerator *cg) - : ARM64ImmInstruction(op, node, imm, cg) + TR::InstOpCode::AArch64BarrierLimitation lim, TR::CodeGenerator *cg) + : ARM64ImmInstruction(op, node, static_cast(lim), cg) { } @@ -4710,9 +4710,9 @@ class ARM64SynchronizationInstruction : public ARM64ImmInstruction * @param[in] cg : CodeGenerator */ ARM64SynchronizationInstruction(TR::InstOpCode::Mnemonic op, TR::Node *node, - uint32_t imm, TR::Instruction *precedingInstruction, - TR::CodeGenerator *cg) - : ARM64ImmInstruction(op, node, imm, precedingInstruction, cg) + TR::InstOpCode::AArch64BarrierLimitation lim, + TR::Instruction *precedingInstruction, TR::CodeGenerator *cg) + : ARM64ImmInstruction(op, node, static_cast(lim), precedingInstruction, cg) { } diff --git a/compiler/aarch64/codegen/GenerateInstructions.cpp b/compiler/aarch64/codegen/GenerateInstructions.cpp index 3cbe40b1ec0..677c2318dac 100644 --- a/compiler/aarch64/codegen/GenerateInstructions.cpp +++ b/compiler/aarch64/codegen/GenerateInstructions.cpp @@ -641,11 +641,11 @@ TR::Instruction *generateCIncInstruction(TR::CodeGenerator *cg, TR::Node *node, } TR::ARM64SynchronizationInstruction *generateSynchronizationInstruction(TR::CodeGenerator *cg, TR::InstOpCode::Mnemonic op, - TR::Node *node, uint32_t imm, TR::Instruction *preced) + TR::Node *node, TR::InstOpCode::AArch64BarrierLimitation lim, TR::Instruction *preced) { if (preced) - return new (cg->trHeapMemory()) TR::ARM64SynchronizationInstruction(op, node, imm, preced, cg); - return new (cg->trHeapMemory()) TR::ARM64SynchronizationInstruction(op, node, imm, cg); + return new (cg->trHeapMemory()) TR::ARM64SynchronizationInstruction(op, node, lim, preced, cg); + return new (cg->trHeapMemory()) TR::ARM64SynchronizationInstruction(op, node, lim, cg); } TR::ARM64ExceptionInstruction *generateExceptionInstruction(TR::CodeGenerator *cg, TR::InstOpCode::Mnemonic op, diff --git a/compiler/aarch64/codegen/GenerateInstructions.hpp b/compiler/aarch64/codegen/GenerateInstructions.hpp index f1f1b0d0395..136e3d3dea8 100644 --- a/compiler/aarch64/codegen/GenerateInstructions.hpp +++ b/compiler/aarch64/codegen/GenerateInstructions.hpp @@ -1183,7 +1183,7 @@ TR::ARM64SynchronizationInstruction *generateSynchronizationInstruction( TR::CodeGenerator *cg, TR::InstOpCode::Mnemonic op, TR::Node *node, - uint32_t imm, + TR::InstOpCode::AArch64BarrierLimitation lim, TR::Instruction *preced = NULL); /* diff --git a/compiler/aarch64/codegen/OMRInstOpCode.hpp b/compiler/aarch64/codegen/OMRInstOpCode.hpp index e43b54a5d28..b9f8db332de 100644 --- a/compiler/aarch64/codegen/OMRInstOpCode.hpp +++ b/compiler/aarch64/codegen/OMRInstOpCode.hpp @@ -56,16 +56,31 @@ class InstOpCode: public OMR::InstOpCode InstOpCode(Mnemonic m) : OMR::InstOpCode(m) {} public: + enum AArch64BarrierLimitation + { + sy = 0xF, // Full System full barrier + st = 0xE, // Full System write barrier + ld = 0xD, // Full System read barrier + ish = 0xB, // Inner Shareable full barrier + ishst = 0xA, // Inner Shareable write barrier + ishld = 0x9, // Inner Shareable read barrier + nsh = 0x7, // Non-shareable full barrier + nshst = 0x6, // Non-shareable write barrier + nshld = 0x5, // Non-shareable read barrier + osh = 0x3, // Outer Shareable full barrier + oshst = 0x2, // Outer Shareable write barrier + oshld = 0x1 // Outer Shareable load barrier + }; - typedef uint32_t OpCodeBinaryEntry; - static const OpCodeBinaryEntry binaryEncodings[ARM64NumOpCodes]; + typedef uint32_t OpCodeBinaryEntry; + static const OpCodeBinaryEntry binaryEncodings[ARM64NumOpCodes]; - /* - * @brief Answers binary encoding of Mnemonic - * @param[in] m : mnemonic - * @return binary encoding - */ - static const OpCodeBinaryEntry getOpCodeBinaryEncoding(Mnemonic m) + /* + * @brief Answers binary encoding of Mnemonic + * @param[in] m : mnemonic + * @return binary encoding + */ + static const OpCodeBinaryEntry getOpCodeBinaryEncoding(Mnemonic m) { return binaryEncodings[m]; } diff --git a/compiler/aarch64/codegen/OMRTreeEvaluator.cpp b/compiler/aarch64/codegen/OMRTreeEvaluator.cpp index c3121e6a724..f43256af930 100644 --- a/compiler/aarch64/codegen/OMRTreeEvaluator.cpp +++ b/compiler/aarch64/codegen/OMRTreeEvaluator.cpp @@ -6059,7 +6059,7 @@ TR::Register *commonLoadEvaluator(TR::Node *node, TR::InstOpCode::Mnemonic op, i if (needSync) { - generateSynchronizationInstruction(cg, TR::InstOpCode::dmb, node, 0x9); // dmb ishld + generateSynchronizationInstruction(cg, TR::InstOpCode::dmb, node, TR::InstOpCode::ishld); } tempMR->decNodeReferenceCounts(cg); @@ -6125,7 +6125,7 @@ OMR::ARM64::TreeEvaluator::aloadEvaluator(TR::Node *node, TR::CodeGenerator *cg) bool needSync = (node->getSymbolReference()->getSymbol()->isSyncVolatile() && cg->comp()->target().isSMP()); if (needSync) { - generateSynchronizationInstruction(cg, TR::InstOpCode::dmb, node, 0x9); // dmb ishld + generateSynchronizationInstruction(cg, TR::InstOpCode::dmb, node, TR::InstOpCode::ishld); } tempMR->decNodeReferenceCounts(cg); @@ -6195,7 +6195,7 @@ TR::Register *commonStoreEvaluator(TR::Node *node, TR::InstOpCode::Mnemonic op, if (needSync) { - generateSynchronizationInstruction(cg, TR::InstOpCode::dmb, node, 0xA); // dmb ishst + generateSynchronizationInstruction(cg, TR::InstOpCode::dmb, node, TR::InstOpCode::ishst); } TR::Node *valueChildRoot = NULL; @@ -6253,7 +6253,7 @@ TR::Register *commonStoreEvaluator(TR::Node *node, TR::InstOpCode::Mnemonic op, // ordered and lazySet operations will not generate a post-write sync if (!lazyVolatile) { - generateSynchronizationInstruction(cg, TR::InstOpCode::dmb, node, 0xB); // dmb ish + generateSynchronizationInstruction(cg, TR::InstOpCode::dmb, node, TR::InstOpCode::ish); } } @@ -8001,7 +8001,7 @@ static TR::Register *intrinsicAtomicAdd(TR::Node *node, TR::CodeGenerator *cg) generateTrg1MemSrc1Instruction(cg, storeop, node, oldValueReg, TR::MemoryReference::createWithDisplacement(cg, addressReg, 0), newValueReg); generateCompareBranchInstruction(cg, TR::InstOpCode::cbnzx, node, oldValueReg, loopLabel); - generateSynchronizationInstruction(cg, TR::InstOpCode::dmb, node, 0xB); // dmb ish + generateSynchronizationInstruction(cg, TR::InstOpCode::dmb, node, TR::InstOpCode::ish); //Set the conditions and dependencies auto conditions = new (cg->trHeapMemory()) TR::RegisterDependencyConditions(0, 4, cg->trMemory()); @@ -8166,7 +8166,7 @@ TR::Register *intrinsicAtomicFetchAndAdd(TR::Node *node, TR::CodeGenerator *cg) generateTrg1MemSrc1Instruction(cg, storeop, node, tempReg, TR::MemoryReference::createWithDisplacement(cg, addressReg, 0), newValueReg); generateCompareBranchInstruction(cg, TR::InstOpCode::cbnzx, node, tempReg, loopLabel); - generateSynchronizationInstruction(cg, TR::InstOpCode::dmb, node, 0xB); // dmb ish + generateSynchronizationInstruction(cg, TR::InstOpCode::dmb, node, TR::InstOpCode::ish); //Set the conditions and dependencies const int numDeps = (valueReg != NULL) ? 5 : 4; @@ -8281,7 +8281,7 @@ TR::Register *intrinsicAtomicSwap(TR::Node *node, TR::CodeGenerator *cg) generateTrg1MemSrc1Instruction(cg, storeop, node, tempReg, TR::MemoryReference::createWithDisplacement(cg, addressReg, 0), valueReg); generateCompareBranchInstruction(cg, TR::InstOpCode::cbnzx, node, tempReg, loopLabel); - generateSynchronizationInstruction(cg, TR::InstOpCode::dmb, node, 0xB); // dmb ish + generateSynchronizationInstruction(cg, TR::InstOpCode::dmb, node, TR::InstOpCode::ish); //Set the conditions and dependencies auto conditions = new (cg->trHeapMemory()) TR::RegisterDependencyConditions(0, 4, cg->trMemory()); diff --git a/compiler/ras/Debug.hpp b/compiler/ras/Debug.hpp index bf474d2f45a..f2010d25845 100644 --- a/compiler/ras/Debug.hpp +++ b/compiler/ras/Debug.hpp @@ -374,6 +374,7 @@ namespace TR { class ARM64Src2Instruction; } namespace TR { class ARM64ZeroSrc2Instruction; } namespace TR { class ARM64Src1ImmCondInstruction; } namespace TR { class ARM64Src2CondInstruction; } +namespace TR { class ARM64SynchronizationInstruction; } namespace TR { class ARM64HelperCallSnippet; } namespace TR { class LabelInstruction; } @@ -1168,6 +1169,7 @@ class TR_Debug void print(TR::FILE *, TR::ARM64ZeroSrc2Instruction *); void print(TR::FILE *, TR::ARM64Src1ImmCondInstruction *); void print(TR::FILE *, TR::ARM64Src2CondInstruction *); + void print(TR::FILE *, TR::ARM64SynchronizationInstruction *); #ifdef J9_PROJECT_SPECIFIC void print(TR::FILE *, TR::ARM64VirtualGuardNOPInstruction *); #endif