зеркало из https://github.com/dotnet/llilc.git
Implement support for the abs intrinsic.
Note only floating point cases make it through as intrinsics. Also make sure we honor the alignment requests of the read-only data sections. Abs uses a 16-byte aligned constant mask. Closes #329.
This commit is contained in:
Родитель
f3a0c73299
Коммит
9e82cdd1f0
|
@ -274,9 +274,7 @@ public:
|
|||
// Used for testing, client can force verification.
|
||||
bool verForceVerification(void) override { return false; };
|
||||
|
||||
bool abs(IRNode *Arg1, IRNode **RetVal) override {
|
||||
throw NotYetImplementedException("abs");
|
||||
};
|
||||
bool abs(IRNode *Arg1, IRNode **RetVal) override;
|
||||
|
||||
IRNode *argList() override;
|
||||
IRNode *instParam() override;
|
||||
|
|
|
@ -50,11 +50,22 @@ uint8_t *EEMemoryManager::allocateDataSection(uintptr_t Size,
|
|||
// We don't expect to see RW data requests.
|
||||
assert(IsReadOnly);
|
||||
|
||||
// Pad for alignment needs.
|
||||
unsigned int Offset = ((uint64_t)ReadOnlyDataUnallocated) % Alignment;
|
||||
if (Offset > 0) {
|
||||
ReadOnlyDataUnallocated += Alignment - Offset;
|
||||
}
|
||||
assert((((uint64_t)ReadOnlyDataUnallocated) % Alignment) == 0);
|
||||
|
||||
// There are multiple read-only sections, so we need to keep
|
||||
// track of the current allocation point in the read-only memory region.
|
||||
uint8_t *Result = ReadOnlyDataUnallocated;
|
||||
ReadOnlyDataUnallocated += Size;
|
||||
|
||||
// Make sure we are not allocating more than we expected to.
|
||||
assert(ReadOnlyDataUnallocated <=
|
||||
(ReadOnlyDataBlock + this->Context->ReadOnlyDataSize));
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
|
|
@ -4518,6 +4518,28 @@ bool GenIR::disableCastClassOptimization() {
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Optionally generate inline code for the \p abs opcode
|
||||
///
|
||||
/// \param Argument input value for abs
|
||||
/// \param Result [out] resulting absolute value, if we decided to expand
|
||||
/// \returns true if Result represents the absolute value.
|
||||
bool GenIR::abs(IRNode *Argument, IRNode **Result) {
|
||||
Type *Ty = Argument->getType();
|
||||
|
||||
// Only the floating point cases of System.Math.Abs are implemented via
|
||||
// 'internallcall'.
|
||||
if (Ty->isFloatingPointTy()) {
|
||||
Type *Types[] = {Ty};
|
||||
Value *FAbs = Intrinsic::getDeclaration(JitContext->CurrentModule,
|
||||
Intrinsic::fabs, Types);
|
||||
Value *Abs = LLVMBuilder->CreateCall(FAbs, Argument);
|
||||
*Result = (IRNode *)Abs;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region STACK MAINTENANCE
|
||||
|
|
Загрузка…
Ссылка в новой задаче