| 4132 | } |
| 4133 | } |
| 4134 | void compileAtomicCompareExchange(unsigned MemoryIndex, uint64_t MemoryOffset, |
| 4135 | [[maybe_unused]] unsigned Alignment, |
| 4136 | LLVM::Type IntType, LLVM::Type TargetType, |
| 4137 | bool Signed = false) noexcept { |
| 4138 | |
| 4139 | auto Replacement = Builder.createSExtOrTrunc(stackPop(), TargetType); |
| 4140 | auto Expected = Builder.createSExtOrTrunc(stackPop(), TargetType); |
| 4141 | auto Offset = Builder.createZExt(Stack.back(), Context.Int64Ty); |
| 4142 | if (MemoryOffset != 0) { |
| 4143 | Offset = Builder.createAdd(Offset, LLContext.getInt64(MemoryOffset)); |
| 4144 | } |
| 4145 | compileAtomicCheckOffsetAlignment(Offset, TargetType); |
| 4146 | auto VPtr = Builder.createInBoundsGEP1( |
| 4147 | Context.Int8Ty, Context.getMemory(Builder, ExecCtx, MemoryIndex), |
| 4148 | Offset); |
| 4149 | auto Ptr = Builder.createBitCast(VPtr, TargetType.getPointerTo()); |
| 4150 | |
| 4151 | auto Ret = Builder.createAtomicCmpXchg( |
| 4152 | Ptr, switchEndian(Expected), switchEndian(Replacement), |
| 4153 | LLVMAtomicOrderingSequentiallyConsistent, |
| 4154 | LLVMAtomicOrderingSequentiallyConsistent); |
| 4155 | #if LLVM_VERSION_MAJOR >= 13 |
| 4156 | Ret.setAlignment(1 << Alignment); |
| 4157 | #endif |
| 4158 | auto OldVal = Builder.createExtractValue(Ret, 0); |
| 4159 | OldVal = switchEndian(OldVal); |
| 4160 | if (Signed) { |
| 4161 | Stack.back() = Builder.createSExt(OldVal, IntType); |
| 4162 | } else { |
| 4163 | Stack.back() = Builder.createZExt(OldVal, IntType); |
| 4164 | } |
| 4165 | } |
| 4166 | |
| 4167 | void compileReturn() noexcept { |
| 4168 | updateInstrCount(); |
nothing calls this directly
no test coverage detected